{"behavior":"degenerate_repetition","label_filter":null,"limit":10,"next_offset":12477,"offset":12467,"previous_offset":null,"rows":[{"assistant_initiates":false,"asst_text":"\u8fd9\u53e5\u8bdd\u5b58\u5728\u903b\u8f91\u9519\u8bef\uff0c\u56e0\u4e3a\u5b83\u672c\u8d28\u4e0a\u8868\u8fbe\u4e86\u4e00\u4e2a\u81ea\u76f8\u77db\u76fe\u7684\u5173\u7cfb\uff0c\u5c0f\u660e\u79f0\u81ea\u5df1\u4e3a\u7236\u4eb2\uff0c\u8fd9\u5728\u903b\u8f91\u4e0a\u662f\u4e0d\u53ef\u80fd\u7684\u3002","behavior":"degenerate_repetition","conversation_hash":"e24ccaae0eaa5cdb4d1eb79e115c8e74","conversation_redacted":false,"conversation_toxic":false,"country":"China","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"Chinese","model":"gpt-4o-2024-08-06","n_chars":462,"n_turns_in_conversation":1,"n_words":13,"source_row_offset":12467,"source_shard":"turns-00035.parquet","timestamp":"Wed, 16 Oct 2024 09:21:53 GMT","turn_id":"1100d582666cb6cd4aebceb4","turn_index":0,"user_text":"Assistant: \nUser: \n                    \u8bf7\u6839\u636e\u4ee5\u4e0b\u539f\u59cb\u6570\u636e\u6267\u884c\u4ee5\u4e0b\u4efb\u52a1\uff1a\n                    \u68c0\u67e5\u53e5\u5b50\u4e2d\u662f\u5426\u5b58\u5728\u4efb\u4f55\u6b67\u4e49\u6216\u903b\u8f91\u9519\u8bef\uff0c\u5e76\u7528\u4e00\u53e5\u8bdd\u8bf4\u660e\u8fd9\u4e9b\u95ee\u9898\u3002\n                    \n                    \u793a\u4f8b\uff1a\n                    \u539f\u59cb\u6570\u636e: \"\u6839\u636e\u725b\u987f\u7b2c\u4e00\u5b9a\u5f8b\uff0c\u6211\u63a8\u7b97\u51fa\u672c\u6b21\u4e16\u754c\u767e\u5927\u7269\u7406\u5b66\u5bb6\u6392\u540d\uff0c\u7231\u56e0\u65af\u5766\u53ea\u80fd\u5c48\u5c45\u7b2c\u4e8c\u3002\"\n                    \u8fd9\u53e5\u8bdd\u8bef\u5c06\u725b\u987f\u7b2c\u4e00\u5b9a\u5f8b\u4e0e\u7269\u7406\u5b66\u5bb6\u7684\u6392\u540d\u6df7\u6dc6\uff0c\u5b9e\u9645\u662f\u7269\u7406\u5b9a\u5f8b\uff0c\u800c\u4e0d\u662f\u6392\u540d\u3002\n                    \n                    \u73b0\u5728\uff0c\u8bf7\u5bf9\u4ee5\u4e0b\u539f\u59cb\u6570\u636e\u8fdb\u884c\u540c\u6837\u7684\u5206\u6790\u548c\u6539\u8fdb\uff1a\n                    \u539f\u59cb\u6570\u636e: \"\u201c\u7237\u662f\u4f60\u7239\u201d\u5c0f\u660e\u5bf9\u4ed6\u7238\u8bf4\"\n                    \nAssistant:"},{"assistant_initiates":false,"asst_text":"\u8fd9\u53e5\u8bdd\u5b58\u5728\u903b\u8f91\u9519\u8bef\uff0c\u56e0\u4e3a\u201c\u7531\u4e8e\u5927\u95e8\u5fd8\u8bb0\u9501\u201d\u5e76\u4e0d\u80fd\u81ea\u52a8\u6210\u4e3a\u60a3\u8005\u5168\u90e8\u51fa\u9662\u7684\u201c\u597d\u6d88\u606f\u201d\uff0c\u8fd8\u53ef\u80fd\u5bfc\u81f4\u5b89\u5168\u95ee\u9898\u3002","behavior":"degenerate_repetition","conversation_hash":"fda05e936382c0821b61f807559b4fd2","conversation_redacted":false,"conversation_toxic":false,"country":"Italy","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"Chinese","model":"gpt-4o-2024-08-06","n_chars":475,"n_turns_in_conversation":1,"n_words":13,"source_row_offset":12468,"source_shard":"turns-00035.parquet","timestamp":"Wed, 16 Oct 2024 09:22:02 GMT","turn_id":"da6ddd2c2ca69ed05cf71d56","turn_index":0,"user_text":"Assistant: \nUser: \n                    \u8bf7\u6839\u636e\u4ee5\u4e0b\u539f\u59cb\u6570\u636e\u6267\u884c\u4ee5\u4e0b\u4efb\u52a1\uff1a\n                    \u68c0\u67e5\u53e5\u5b50\u4e2d\u662f\u5426\u5b58\u5728\u4efb\u4f55\u6b67\u4e49\u6216\u903b\u8f91\u9519\u8bef\uff0c\u5e76\u7528\u4e00\u53e5\u8bdd\u8bf4\u660e\u8fd9\u4e9b\u95ee\u9898\u3002\n                    \n                    \u793a\u4f8b\uff1a\n                    \u539f\u59cb\u6570\u636e: \"\u6839\u636e\u725b\u987f\u7b2c\u4e00\u5b9a\u5f8b\uff0c\u6211\u63a8\u7b97\u51fa\u672c\u6b21\u4e16\u754c\u767e\u5927\u7269\u7406\u5b66\u5bb6\u6392\u540d\uff0c\u7231\u56e0\u65af\u5766\u53ea\u80fd\u5c48\u5c45\u7b2c\u4e8c\u3002\"\n                    \u8fd9\u53e5\u8bdd\u8bef\u5c06\u725b\u987f\u7b2c\u4e00\u5b9a\u5f8b\u4e0e\u7269\u7406\u5b66\u5bb6\u7684\u6392\u540d\u6df7\u6dc6\uff0c\u5b9e\u9645\u662f\u7269\u7406\u5b9a\u5f8b\uff0c\u800c\u4e0d\u662f\u6392\u540d\u3002\n                    \n                    \u73b0\u5728\uff0c\u8bf7\u5bf9\u4ee5\u4e0b\u539f\u59cb\u6570\u636e\u8fdb\u884c\u540c\u6837\u7684\u5206\u6790\u548c\u6539\u8fdb\uff1a\n                    \u539f\u59cb\u6570\u636e: \"\u597d\u6d88\u606f\uff0c\u7531\u4e8e\u5927\u95e8\u5fd8\u8bb0\u9501\uff0c\u672c\u9662\u75c5\u4eba\u4e8e\u4eca\u65e9\u5168\u90e8\u51fa\u9662\"\n                    \nAssistant:"},{"assistant_initiates":false,"asst_text":"Hello! How can I assist you today?","behavior":"degenerate_repetition","conversation_hash":"bd81fdbdd3517365c1b4e1111f80d2bd","conversation_redacted":false,"conversation_toxic":false,"country":"Vietnam","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"gpt-4o-mini-2024-07-18","n_chars":34,"n_turns_in_conversation":2,"n_words":7,"source_row_offset":12469,"source_shard":"turns-00035.parquet","timestamp":"Wed, 16 Oct 2024 09:22:02 GMT","turn_id":"d31e33d84cd7ad9a6f727471","turn_index":0,"user_text":""},{"assistant_initiates":false,"asst_text":"Hi! How can I help you today?","behavior":"degenerate_repetition","conversation_hash":"bd81fdbdd3517365c1b4e1111f80d2bd","conversation_redacted":false,"conversation_toxic":false,"country":"Vietnam","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"gpt-4o-mini-2024-07-18","n_chars":39,"n_turns_in_conversation":2,"n_words":9,"source_row_offset":12470,"source_shard":"turns-00035.parquet","timestamp":"Wed, 16 Oct 2024 09:22:02 GMT","turn_id":"fd253ec96d6728db946f6408","turn_index":1,"user_text":"Hi there!"},{"assistant_initiates":false,"asst_text":"That's a sweet sentiment! You could say something like:\n\n\"Hey love, I just wanted to let you know how proud I am of you for starting to walk again. I truly wish I could be there for you right now. Remember, I\u2019m right here cheering you on! Lean on me as much as you need, and just know that I\u2019m your walking stick in spirit. You\u2019ve got this, and I believe in you!\"\n\nFeel free to adjust it to make it sound more like you!","behavior":"degenerate_repetition","conversation_hash":"e4d545af8a18229049a1a0e07d5b779b","conversation_redacted":false,"conversation_toxic":false,"country":"Taiwan","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"gpt-4o-mini-2024-07-18","n_chars":566,"n_turns_in_conversation":1,"n_words":119,"source_row_offset":12471,"source_shard":"turns-00035.parquet","timestamp":"Wed, 16 Oct 2024 09:22:44 GMT","turn_id":"f4a81e64db2d07657784765b","turn_index":0,"user_text":"My bf started to walk a bit after injury and I want to tell him I wish im there for him and lean on me while he wants to walk be his walking stick"},{"assistant_initiates":false,"asst_text":"\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c\u0441\u044f, \u043a\u0430\u043a \u043d\u0430\u0439\u0442\u0438 \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0413\u0430\u0440\u0440\u0438 \u0438 \u0420\u043e\u043d\u0430 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442 (\u0442\u043e \u0435\u0441\u0442\u044c \u043e\u0431\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0438\u043b\u0438 \u043e\u0431\u0430 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0442\u0432\u0435\u0442\u0438\u043b\u0438).\n\n**\u0414\u0430\u043d\u043e:**\n- \u041e\u0431\u0449\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432 \\( N = 31 \\).\n- \u0413\u0430\u0440\u0440\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0442\u0432\u0435\u0442\u0438\u043b \u043d\u0430 \\( X = 19 \\) \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u0437\u043d\u0430\u0447\u0438\u0442, \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043d\u0430 \\( N - X = 12 \\) \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432.\n- \u0420\u043e\u043d \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0442\u0432\u0435\u0442\u0438\u043b \u043d\u0430 \\( Y = 12 \\) \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u0437\u043d\u0430\u0447\u0438\u0442, \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043d\u0430 \\( N - Y = 19 \\) \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432.\n\n**\u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438:**\n\u0421\u0440\u0435\u0434\u043d\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445:\n1. **\u041e\u0431\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0442\u0432\u0435\u0442\u0438\u043b\u0438**: \\( |C_1 \\cap C_2| \\), \u0433\u0434\u0435 \\( C_1 \\) \u2014 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0442\u0432\u0435\u0442\u0438\u043b \u0413\u0430\u0440\u0440\u0438, \u0430 \\( C_2 \\) \u2014 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0442\u0432\u0435\u0442\u0438\u043b \u0420\u043e\u043d.\n2. **\u041e\u0431\u0430 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0442\u0432\u0435\u0442\u0438\u043b\u0438**: \\( |C_1^c \\cap C_2^c| \\), \u0433\u0434\u0435 \\( C_1^c \\) \u0438 \\( C_2^c \\) \u2014 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432 \\( C_1 \\) \u0438 \\( C_2 \\) \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.\n\n**\u041e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435:**\n\\[\nE[|C_1 \\cap C_2|] = \\frac{X \\times Y}{N} = \\frac{19 \\times 12}{31} = \\frac{228}{31}\n\\]\n\n\\[\nE[|C_1^c \\cap C_2^c|] = \\frac{(N - X) \\times (N - Y)}{N} = \\frac{12 \\times 19}{31} = \\frac{228}{31}\n\\]\n\n**\u041e\u0431\u0449\u0430\u044f \u0441\u0440\u0435\u0434\u043d\u044f\u044f \u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432:**\n\\[\nE = E[|C_1 \\cap C_2|] + E[|C_1^c \\cap C_2^c|] = \\frac{228}{31} + \\frac{228}{31} = \\frac{456}{31} \\approx 14.71\n\\]\n\n\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0443 \u0413\u0430\u0440\u0440\u0438 \u0438 \u0420\u043e\u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e **14.71**.\n\n**\u041e\u0442\u0432\u0435\u0442:** \u041f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u00a014.71\u00a0\u0432\u043e\u043f\u0440\u043e\u0441\u0430 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0443 \u0413\u0430\u0440\u0440\u0438 \u0438 \u0420\u043e\u043d\u0430.","behavior":"degenerate_repetition","conversation_hash":"875436ddc2009d94211dd036a67fcc17","conversation_redacted":false,"conversation_toxic":false,"country":"Russia","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"Russian","model":"o1-mini-2024-09-12","n_chars":1881,"n_turns_in_conversation":1,"n_words":311,"source_row_offset":12472,"source_shard":"turns-00035.parquet","timestamp":"Wed, 16 Oct 2024 09:23:21 GMT","turn_id":"fa2ab61f044792615776a83a","turn_index":0,"user_text":"\u0413\u0430\u0440\u0440\u0438 \u0438 \u0420\u043e\u043d \u043f\u0440\u043e\u0448\u043b\u0438 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0442\u0443\u0440 \u043e\u043b\u0438\u043c\u043f\u0438\u0430\u0434\u044b \u043f\u043e \u0438\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u043b\u043b\u0435\u043a\u0442\u0443.\n\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0438 \u0413\u0430\u0440\u0440\u0438, \u043d\u0438 \u0420\u043e\u043d \u043d\u0435 \u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0438\u0441\u044c \u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u043b\u0438, \u0442\u043e \u043e\u043d\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0433\u0430\u0434\u044b\u0432\u0430\u043b\u0438 \u043e\u0442\u0432\u0435\u0442\u044b \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441\u044b. \u0412\u0441\u0435\u0433\u043e \u0432 \u043e\u0442\u0431\u043e\u0440\u043e\u0447\u043d\u043e\u043c \u0442\u0443\u0440\u0435 \u0431\u044b\u043b\u043e N \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432.\n\u0413\u0430\u0440\u0440\u0438 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0443\u0433\u0430\u0434\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0442\u044b \u043d\u0430 X \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u0430 \u0420\u043e\u043d\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 Y \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432.\n\n\n\u041d\u0430\u0439\u0434\u0438\u0442\u0435 \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0443 \u0413\u0430\u0440\u0440\u0438 \u0438 \u0420\u043e\u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 (\u0442\u043e \u0435\u0441\u0442\u044c \u043e\u0431\u0430 \u0443\u0433\u0430\u0434\u0430\u043b\u0438 \u0438\u043b\u0438 \u043d\u0435 \u0443\u0433\u0430\u0434\u0430\u043b\u0438 \u043e\u0442\u0432\u0435\u0442)\n\nN = 31\nX = 19\nY = 12"},{"assistant_initiates":false,"asst_text":"\u0427\u0442\u043e\u0431\u044b \u043d\u0430\u0439\u0442\u0438 \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0413\u0430\u0440\u0440\u0438 \u0438 \u0420\u043e\u043d \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b (\u043e\u0431\u0430 \u043e\u0442\u0432\u0435\u0442\u0438\u043b\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0438\u043b\u0438 \u043e\u0431\u0430 \u043e\u0448\u0438\u0431\u043b\u0438\u0441\u044c), \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u043d\u044b\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u043c.\n\n**\u0414\u0430\u043d\u043e:**\n- \u041e\u0431\u0449\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \\( N = 31 \\)\n- \u0413\u0430\u0440\u0440\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0442\u0432\u0435\u0442\u0438\u043b \u043d\u0430 \\( X = 19 \\) \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432\n- \u0420\u043e\u043d \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0442\u0432\u0435\u0442\u0438\u043b \u043d\u0430 \\( Y = 12 \\) \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432\n\n**\u0428\u0430\u0433\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u044f:**\n\n1. **\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430:**\n   - \u0412\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c, \u0447\u0442\u043e \u0413\u0430\u0440\u0440\u0438 \u043e\u0442\u0432\u0435\u0442\u0438\u043b \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441: \\( P_H = \\frac{X}{N} = \\frac{19}{31} \\)\n   - \u0412\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c, \u0447\u0442\u043e \u0420\u043e\u043d \u043e\u0442\u0432\u0435\u0442\u0438\u043b \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441: \\( P_R = \\frac{Y}{N} = \\frac{12}{31} \\)\n\n2. **\u0412\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u0430:**\n   - \u041e\u0431\u0430 \u043e\u0442\u0432\u0435\u0442\u0438\u043b\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e: \\( P_H \\times P_R = \\frac{19}{31} \\times \\frac{12}{31} = \\frac{228}{961} \\)\n   - \u041e\u0431\u0430 \u043e\u0448\u0438\u0431\u043b\u0438\u0441\u044c: \\( (1 - P_H) \\times (1 - P_R) = \\frac{12}{31} \\times \\frac{19}{31} = \\frac{228}{961} \\)\n   - \u0418\u0442\u043e\u0433\u043e \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430: \\( \\frac{228}{961} + \\frac{228}{961} = \\frac{456}{961} \\)\n\n3. **\u041d\u0430\u0445\u043e\u0434\u0438\u043c \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432 \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c:**\n   \\[\n   \\text{\u041e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e} = N \\times \\left( \\frac{456}{961} \\right) = 31 \\times \\frac{456}{961} \\approx 14.71\n   \\]\n\n**\u041e\u0442\u0432\u0435\u0442:**\n\n\u0412 \u0441\u0440\u0435\u0434\u043d\u0435\u043c \u0413\u0430\u0440\u0440\u0438 \u0438 \u0420\u043e\u043d \u043f\u043e\u043b\u0443\u0447\u0430\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e\u00a0**14.71**\u00a0\u0432\u043e\u043f\u0440\u043e\u0441\u0430\u043c \u0438\u0437\u00a031.","behavior":"degenerate_repetition","conversation_hash":"3cf0c2d1e04e8abba6528eab78b45a18","conversation_redacted":false,"conversation_toxic":false,"country":"Russia","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"Russian","model":"o1-mini-2024-09-12","n_chars":1719,"n_turns_in_conversation":1,"n_words":261,"source_row_offset":12473,"source_shard":"turns-00035.parquet","timestamp":"Wed, 16 Oct 2024 09:23:25 GMT","turn_id":"1bcef1ebe6b3852f5b7168e2","turn_index":0,"user_text":"\u0413\u0430\u0440\u0440\u0438 \u0438 \u0420\u043e\u043d \u043f\u0440\u043e\u0448\u043b\u0438 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0442\u0443\u0440 \u043e\u043b\u0438\u043c\u043f\u0438\u0430\u0434\u044b \u043f\u043e \u0438\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u043b\u043b\u0435\u043a\u0442\u0443.\n\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0438 \u0413\u0430\u0440\u0440\u0438, \u043d\u0438 \u0420\u043e\u043d \u043d\u0435 \u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0438\u0441\u044c \u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u043b\u0438, \u0442\u043e \u043e\u043d\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0433\u0430\u0434\u044b\u0432\u0430\u043b\u0438 \u043e\u0442\u0432\u0435\u0442\u044b \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441\u044b. \u0412\u0441\u0435\u0433\u043e \u0432 \u043e\u0442\u0431\u043e\u0440\u043e\u0447\u043d\u043e\u043c \u0442\u0443\u0440\u0435 \u0431\u044b\u043b\u043e N \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432.\n\u0413\u0430\u0440\u0440\u0438 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0443\u0433\u0430\u0434\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0442\u044b \u043d\u0430 X \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u0430 \u0420\u043e\u043d\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 Y \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432.\n\n\n\u041d\u0430\u0439\u0434\u0438\u0442\u0435 \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0443 \u0413\u0430\u0440\u0440\u0438 \u0438 \u0420\u043e\u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 (\u0442\u043e \u0435\u0441\u0442\u044c \u043e\u0431\u0430 \u0443\u0433\u0430\u0434\u0430\u043b\u0438 \u0438\u043b\u0438 \u043d\u0435 \u0443\u0433\u0430\u0434\u0430\u043b\u0438 \u043e\u0442\u0432\u0435\u0442)\n\nN = 31\nX = 19\nY = 12"},{"assistant_initiates":false,"asst_text":"\u0427\u0442\u043e\u0431\u044b \u043d\u0430\u0439\u0442\u0438 \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0443 \u0413\u0430\u0440\u0440\u0438 \u0438 \u0420\u043e\u043d\u0430 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 (\u043e\u0431\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0442\u0432\u0435\u0442\u0438\u043b\u0438 \u0438\u043b\u0438 \u043e\u0431\u0430 \u043d\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0442\u0432\u0435\u0442\u0438\u043b\u0438), \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u0448\u0430\u0433\u0430\u043c\u0438:\n\n1. **\u041e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f:**\n   - \u041e\u0431\u0449\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432: \\( N = 31 \\)\n   - \u0413\u0430\u0440\u0440\u0438 \u043e\u0442\u0432\u0435\u0442\u0438\u043b \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043d\u0430 \\( X = 19 \\) \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432.\n   - \u0420\u043e\u043d \u043e\u0442\u0432\u0435\u0442\u0438\u043b \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043d\u0430 \\( Y = 12 \\) \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432.\n\n2. **\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0442\u0438\u044f (\u043e\u0431\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e):**\n   - \u041e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u0432\u0435\u0442\u0438\u043b\u0438 \u043e\u0431\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e, \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a:\n     \\[\n     E[C] = \\frac{X \\times Y}{N} = \\frac{19 \\times 12}{31} \\approx 7.35\n     \\]\n\n3. **\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043e\u0431\u043e\u0438\u0445 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0445 \u043e\u0442\u0432\u0435\u0442\u043e\u0432:**\n   - \u041e\u0431\u0449\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0413\u0430\u0440\u0440\u0438 \u043e\u0442\u0432\u0435\u0442\u0438\u043b \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e: \\( N - X = 12 \\).\n   - \u041e\u0431\u0449\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0420\u043e\u043d \u043e\u0442\u0432\u0435\u0442\u0438\u043b \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e: \\( N - Y = 19 \\).\n   - \u041e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u0432\u0435\u0442\u0438\u043b\u0438 \u043e\u0431\u0430 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e:\n     \\[\n     E[W] = \\frac{(N - X) \\times (N - Y)}{N} = \\frac{12 \\times 19}{31} \\approx 7.35\n     \\]\n\n4. **\u0421\u0443\u043c\u043c\u0430\u0440\u043d\u043e\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432:**\n   \\[\n   E[C + W] = E[C] + E[W] \\approx 7.35 + 7.35 = 14.7\n   \\]\n\n\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, **\u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0443 \u0413\u0430\u0440\u0440\u0438 \u0438 \u0420\u043e\u043d\u0430 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e 14.7**.\n\n**\u041e\u0442\u0432\u0435\u0442:** \u0412 \u0441\u0440\u0435\u0434\u043d\u0435\u043c \u0443 \u0413\u0430\u0440\u0440\u0438 \u0438 \u0420\u043e\u043d\u0430 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e\u202f14.71 \u0432\u043e\u043f\u0440\u043e\u0441\u0430.","behavior":"degenerate_repetition","conversation_hash":"b100ea4a213fc657585c1cbb7488d4ee","conversation_redacted":false,"conversation_toxic":false,"country":"Russia","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"Russian","model":"o1-mini-2024-09-12","n_chars":1754,"n_turns_in_conversation":1,"n_words":278,"source_row_offset":12474,"source_shard":"turns-00035.parquet","timestamp":"Wed, 16 Oct 2024 09:23:29 GMT","turn_id":"1fcf1ca65c5464cda0a91631","turn_index":0,"user_text":"\u0413\u0430\u0440\u0440\u0438 \u0438 \u0420\u043e\u043d \u043f\u0440\u043e\u0448\u043b\u0438 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0442\u0443\u0440 \u043e\u043b\u0438\u043c\u043f\u0438\u0430\u0434\u044b \u043f\u043e \u0438\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u043b\u043b\u0435\u043a\u0442\u0443.\n\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0438 \u0413\u0430\u0440\u0440\u0438, \u043d\u0438 \u0420\u043e\u043d \u043d\u0435 \u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0438\u0441\u044c \u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u043b\u0438, \u0442\u043e \u043e\u043d\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0433\u0430\u0434\u044b\u0432\u0430\u043b\u0438 \u043e\u0442\u0432\u0435\u0442\u044b \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441\u044b. \u0412\u0441\u0435\u0433\u043e \u0432 \u043e\u0442\u0431\u043e\u0440\u043e\u0447\u043d\u043e\u043c \u0442\u0443\u0440\u0435 \u0431\u044b\u043b\u043e N \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432.\n\u0413\u0430\u0440\u0440\u0438 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0443\u0433\u0430\u0434\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0442\u044b \u043d\u0430 X \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u0430 \u0420\u043e\u043d\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 Y \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432.\n\n\n\u041d\u0430\u0439\u0434\u0438\u0442\u0435 \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0443 \u0413\u0430\u0440\u0440\u0438 \u0438 \u0420\u043e\u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 (\u0442\u043e \u0435\u0441\u0442\u044c \u043e\u0431\u0430 \u0443\u0433\u0430\u0434\u0430\u043b\u0438 \u0438\u043b\u0438 \u043d\u0435 \u0443\u0433\u0430\u0434\u0430\u043b\u0438 \u043e\u0442\u0432\u0435\u0442)\n\nN = 31\nX = 19\nY = 12"},{"assistant_initiates":false,"asst_text":"\u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u044f \u043f\u043e\u043c\u043e\u0433\u0443 \u0432\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432 Java, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b. \u041f\u043e\u0445\u043e\u0436\u0435, \u0447\u0442\u043e \u0432\u044b \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043f\u0443\u0442\u0438 \u0432 \u0441\u0442\u0438\u043b\u0435 SVG, \u0433\u0434\u0435 `M` \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \"Move To\" (\u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u0432 \u0442\u043e\u0447\u043a\u0443), \u0430 `C` \u2014 \"Curve To\" (\u043a\u0443\u0431\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043a\u0440\u0438\u0432\u043e\u043b\u0438\u043d\u0435\u0439\u043d\u0430\u044f \u043a\u0440\u0438\u0432\u0430\u044f \u0411\u0435\u0437\u044c\u0435).\n\n\u0412\u043e\u0442 \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Java Swing \u0438 `Graphics2D`:\n\n1. **\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043a\u043b\u0430\u0441\u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:**\n\n```java\nimport javax.swing.JFrame;\nimport javax.swing.JPanel;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.geom.Path2D;\n\npublic class PathDrawing extends JPanel {\n\n    @Override\n    protected void paintComponent(Graphics g) {\n        super.paintComponent(g);\n        drawPath((Graphics2D) g);\n    }\n\n    private void drawPath(Graphics2D g2d) {\n        // \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0442\u043e\u043b\u0449\u0438\u043d\u044b \u043b\u0438\u043d\u0438\u0438 \u0438 \u0446\u0432\u0435\u0442\u0430\n        g2d.setStroke(new BasicStroke(2));\n        g2d.setColor(Color.BLUE);\n\n        // \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043f\u0443\u0442\u0438\n        Path2D.Double path = new Path2D.Double();\n\n        // \u041d\u0430\u0447\u0430\u043b\u044c\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 (M297 21)\n        path.moveTo(297, 21);\n\n        // \u041f\u0435\u0440\u0432\u0430\u044f \u043a\u0440\u0438\u0432\u0430\u044f \u0411\u0435\u0437\u044c\u0435 (C293 208 304 210 292 209)\n        path.curveTo(293, 208, 304, 210, 292, 209);\n\n        // \u0412\u0442\u043e\u0440\u0430\u044f \u043a\u0440\u0438\u0432\u0430\u044f \u0411\u0435\u0437\u044c\u0435 (C281 209 218 218 211 206)\n        path.curveTo(281, 209, 218, 218, 211, 206);\n\n        // \u0422\u0440\u0435\u0442\u044c\u044f \u043a\u0440\u0438\u0432\u0430\u044f \u0411\u0435\u0437\u044c\u0435 (C120 45 55 33 176 27)\n        path.curveTo(120, 45, 55, 33, 176, 27);\n\n        // \u041e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0430 \u043f\u0443\u0442\u0438\n        g2d.draw(path);\n    }\n\n    public static void main(String[] args) {\n        JFrame frame = new JFrame(\"\u0420\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0443\u0442\u0438\");\n        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        frame.add(new PathDrawing());\n        frame.setSize(400, 300);\n        frame.setLocationRelativeTo(null); // \u0426\u0435\u043d\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u043a\u043d\u0430\n        frame.setVisible(true);\n    }\n}\n```\n\n2. **\u041f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u0435 \u043a \u043a\u043e\u0434\u0443:**\n\n- **\u0418\u043c\u043f\u043e\u0440\u0442\u044b:**\n  - `JFrame` \u0438 `JPanel` \u0438\u0437 Swing \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u043a\u043d\u0430 \u0438 \u043f\u0430\u043d\u0435\u043b\u0438 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f.\n  - `Graphics`, `Graphics2D`, `BasicStroke`, `Color` \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0439.\n  - `Path2D` \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0444\u0438\u0433\u0443\u0440 \u043f\u0443\u0442\u0435\u043c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u043e\u0432.\n\n- **\u041a\u043b\u0430\u0441\u0441 `PathDrawing`:**\n  - \u041d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0442 `JPanel` \u0438 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 `paintComponent`, \u0433\u0434\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0430.\n  - \u041c\u0435\u0442\u043e\u0434 `drawPath` \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 `Path2D.Double` \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b `moveTo` \u0438 `curveTo` \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0432\u0430\u0448\u0438\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c.\n  - \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0446\u0432\u0435\u0442 \u043b\u0438\u043d\u0438\u0438 \u0438 \u0435\u0435 \u0442\u043e\u043b\u0449\u0438\u043d\u0430 \u0434\u043b\u044f \u043b\u0443\u0447\u0448\u0435\u0439 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438.\n\n- **\u041c\u0435\u0442\u043e\u0434 `main`:**\n  - \u0421\u043e\u0437\u0434\u0430\u0435\u0442 \u0438 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.\n  - \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 `PathDrawing` \u0432 \u043e\u043a\u043d\u043e \u0438 \u0434\u0435\u043b\u0430\u0435\u0442 \u0435\u0433\u043e \u0432\u0438\u0434\u0438\u043c\u044b\u043c.\n\n3. **\u0417\u0430\u043f\u0443\u0441\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:**\n   \n   \u0421\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0439\u0442\u0435 \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u043a\u043e\u0434. \u0412\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u043e\u043a\u043d\u043e \u0441 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043f\u0443\u0442\u0435\u043c, \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043f\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c.\n\n4. **\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438:**\n\n   - **\u041c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435:**\n     \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442, \u0432\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043b\u0438 \u0441\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043f\u0443\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u043b\u0441\u044f \u0432 \u043e\u043a\u043d\u0435. \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439 `AffineTransform`.\n\n   - **\u0417\u0430\u043b\u0438\u0432\u043a\u0430 \u0444\u043e\u0440\u043c\u044b:**\n     \u0415\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043d\u0442\u0443\u0440, \u043d\u043e \u0438 \u0437\u0430\u043b\u0438\u0432\u043a\u0443, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043c\u0435\u0442\u043e\u0434\u044b `g2d.fill(path)` \u0432\u043c\u0435\u0441\u0442\u043e \u0438\u043b\u0438 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 `g2d.draw(path)`.\n\n   - **\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439:**\n     \u0414\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043c\u044b\u0448\u0438 \u0438\u043b\u0438 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b.\n\n5. **\u041f\u043e\u043b\u043d\u044b\u0439 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:**\n\n   \u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0434\u043b\u044f \u0432\u0430\u0448\u0435\u0433\u043e \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430:\n\n```java\nimport javax.swing.JFrame;\nimport javax.swing.JPanel;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.BasicStroke;\nimport java.awt.Color;\nimport java.awt.geom.Path2D;\n\npublic class PathDrawing extends JPanel {\n\n    @Override\n    protected void paintComponent(Graphics g) {\n        super.paintComponent(g);\n        drawPath((Graphics2D) g);\n    }\n\n    private void drawPath(Graphics2D g2d) {\n        // \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0442\u043e\u043b\u0449\u0438\u043d\u044b \u043b\u0438\u043d\u0438\u0438 \u0438 \u0446\u0432\u0435\u0442\u0430\n        g2d.setStroke(new BasicStroke(2));\n        g2d.setColor(Color.BLUE);\n\n        // \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043f\u0443\u0442\u0438\n        Path2D.Double path = new Path2D.Double();\n\n        // \u041d\u0430\u0447\u0430\u043b\u044c\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 (M297 21)\n        path.moveTo(297, 21);\n\n        // \u041f\u0435\u0440\u0432\u0430\u044f \u043a\u0440\u0438\u0432\u0430\u044f \u0411\u0435\u0437\u044c\u0435 (C293 208 304 210 292 209)\n        path.curveTo(293, 208, 304, 210, 292, 209);\n\n        // \u0412\u0442\u043e\u0440\u0430\u044f \u043a\u0440\u0438\u0432\u0430\u044f \u0411\u0435\u0437\u044c\u0435 (C281 209 218 218 211 206)\n        path.curveTo(281, 209, 218, 218, 211, 206);\n\n        // \u0422\u0440\u0435\u0442\u044c\u044f \u043a\u0440\u0438\u0432\u0430\u044f \u0411\u0435\u0437\u044c\u0435 (C120 45 55 33 176 27)\n        path.curveTo(120, 45, 55, 33, 176, 27);\n\n        // \u041e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0430 \u043f\u0443\u0442\u0438\n        g2d.draw(path);\n    }\n\n    public static void main(String[] args) {\n        JFrame frame = new JFrame(\"\u0420\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0443\u0442\u0438\");\n        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n        frame.add(new PathDrawing());\n        frame.setSize(400, 300);\n        frame.setLocationRelativeTo(null); // \u0426\u0435\u043d\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u043a\u043d\u0430\n        frame.setVisible(true);\n    }\n}\n```\n\n6. **\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u0438 \u0437\u0430\u043f\u0443\u0441\u043a:**\n\n   - \u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u0435 \u043a\u043e\u0434 \u0432 \u0444\u0430\u0439\u043b \u0441 \u0438\u043c\u0435\u043d\u0435\u043c `PathDrawing.java`.\n   - \u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b \u0438\u043b\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0438 \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0441 \u0444\u0430\u0439\u043b\u043e\u043c.\n   - \u0421\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0439\u0442\u0435 \u043a\u043e\u0434:\n\n     ```bash\n     javac PathDrawing.java\n     ```\n\n   - \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443:\n\n     ```bash\n     java PathDrawing\n     ```\n\n\u0412\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u043e\u043a\u043d\u043e \u0441 \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043f\u0443\u0442\u0435\u043c \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u043e\u043a\u043d\u0430, \u0446\u0432\u0435\u0442, \u0442\u043e\u043b\u0449\u0438\u043d\u0443 \u043b\u0438\u043d\u0438\u0438 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e \u0441\u0432\u043e\u0435\u043c\u0443 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044e.\n\n\u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u0438\u043b\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u043d\u0435 \u0441\u0442\u0435\u0441\u043d\u044f\u0439\u0442\u0435\u0441\u044c \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f!","behavior":"degenerate_repetition","conversation_hash":"512d62a55d5e34f8c1fee3a1ec3e87a7","conversation_redacted":false,"conversation_toxic":false,"country":"Moldova","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"Russian","model":"o1-mini-2024-09-12","n_chars":5446,"n_turns_in_conversation":1,"n_words":625,"source_row_offset":12475,"source_shard":"turns-00035.parquet","timestamp":"Wed, 16 Oct 2024 09:23:45 GMT","turn_id":"e68d021d3ede753c4b002242","turn_index":0,"user_text":"\u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u0432 java, \u0437\u043d\u0430\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b M297 21C293 208 304 210 292 209 281 209 218 218 211 206 120 45 55 33 176 27"},{"assistant_initiates":false,"asst_text":"\u0417\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439\u0442\u0435!\n\n\u041e\u0448\u0438\u0431\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0435:\n\n```\nSyntaxError: expected 'except' or 'finally' block\n```\n\n\u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0431\u043b\u043e\u043a `try:`, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0431\u043b\u043e\u043a\u043e\u0432 `except:` \u0438\u043b\u0438 `finally:`. \u0412 \u0432\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 `handle_callback`. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c.\n\n### \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0438\n\n\u0412 \u0432\u0430\u0448\u0435\u043c \u043a\u043e\u0434\u0435 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 `handle_callback` \u0435\u0441\u0442\u044c \u0431\u043b\u043e\u043a `try:`, \u043d\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0431\u043b\u043e\u043a\u0438 `except:` \u0438\u043b\u0438 `finally:`, \u0447\u0442\u043e \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443. \u0412 Python \u043f\u043e\u0441\u043b\u0435 \u0431\u043b\u043e\u043a\u0430 `try:` \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c `except:`, `finally:` \u0438\u043b\u0438 \u043e\u0431\u0430 \u044d\u0442\u0438\u0445 \u0431\u043b\u043e\u043a\u0430.\n\n### \u041a\u0430\u043a \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c\n\n\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0431\u043b\u043e\u043a\u0438 `except:` \u0438 `finally:` \u043f\u043e\u0441\u043b\u0435 \u0431\u043b\u043e\u043a\u0430 `try:`. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0442\u043e\u0433\u043e, \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u043d\u0435\u0442.\n\n\u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 `handle_callback` \u0441 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u0431\u043b\u043e\u043a\u0430\u043c\u0438 `except:` \u0438 `finally:`:\n\n```python\nasync def handle_callback(update: Update, context: CallbackContext):\n    query = update.callback_query\n    user_id = query.from_user.id\n    data = query.data\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n\n    try:\n        if data == 'change_course':\n            c.execute(\"SELECT course FROM users WHERE id = ?\", (user_id,))\n            result = c.fetchone()\n            if result:\n                current_course = result[0]\n                new_course = 1 if current_course == 4 else current_course + 1\n                c.execute(\"UPDATE users SET course = ? WHERE id = ?\", (new_course, user_id))\n                conn.commit()\n                await query.answer(f\"\u2705 \u041a\u0443\u0440\u0441 \u0438\u0437\u043c\u0435\u043d\u0451\u043d \u043d\u0430 {new_course}\")\n                await personal_cabinet(update, context)\n            else:\n                await query.answer(\"\u274c \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d.\")\n\n        elif data == 'change_direction':\n            c.execute(\"SELECT direction FROM users WHERE id = ?\", (user_id,))\n            result = c.fetchone()\n            if result:\n                current_direction = result[0]\n                directions = ['\u0424', '\u0423', '\u0424\u041c', '\u0413\u041c\u0423', '\u0411\u0418']\n                try:\n                    new_direction_index = (directions.index(current_direction) + 1) % len(directions)\n                    new_direction = directions[new_direction_index]\n                    c.execute(\"UPDATE users SET direction = ? WHERE id = ?\", (new_direction, user_id))\n                    conn.commit()\n                    await query.answer(f\"\u2705 \u0413\u0440\u0443\u043f\u043f\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0430 \u043d\u0430 {new_direction}\")\n                    await personal_cabinet(update, context)\n                except ValueError:\n                    await query.answer(\"\u274c \u041d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u0430\u044f \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0430.\")\n            else:\n                await query.answer(\"\u274c \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d.\")\n\n        elif data.startswith(\"toggle_\"):\n            notification_type = data.split(\"_\")[1]\n            await toggle_notification(update, user_id, notification_type)\n\n        elif data == 'manage_notifications':\n            await manage_notifications(update, user_id)\n\n        elif data == 'admin_panel':\n            await admin_panel(update, context)\n\n        elif data == 'show_statistics' and is_teacher_user(user_id):\n            await show_statistics(update, context)\n\n        # \u041c\u0435\u043d\u044e \u0440\u0430\u0441\u0441\u044b\u043b\u043e\u043a\n        elif data == 'announcements_menu' and is_teacher_user(user_id):\n            # \u041c\u0435\u043d\u044e \u0440\u0430\u0441\u0441\u044b\u043b\u043e\u043a\n            buttons = [\n                [InlineKeyboardButton(\"\ud83d\udce4 \u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0443\", callback_data='send_announcement')],\n                [InlineKeyboardButton(\"\ud83d\uddc2 \u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0430\u044f \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0430\", callback_data='send_global_announcement')],\n                [InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='admin_panel')]\n            ]\n            reply_markup = InlineKeyboardMarkup(buttons)\n            await query.edit_message_text(text=\"\ud83d\udce2 **\u041c\u0435\u043d\u044e \u0440\u0430\u0441\u0441\u044b\u043b\u043e\u043a:**\", reply_markup=reply_markup, parse_mode='Markdown')\n\n        # \u041d\u0430\u0447\u0430\u043b\u043e \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n        elif data == 'send_announcement' and is_teacher_user(user_id):\n            # \u0412\u044b\u0431\u043e\u0440 \u0442\u0438\u043f\u0430 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n            buttons = [\n                [InlineKeyboardButton(\"\ud83d\udcda \u0414\u043e\u043c\u0430\u0448\u043d\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435\", callback_data='mailing_homework')],\n                [InlineKeyboardButton(\"\ud83d\udd04 \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0438\", callback_data='mailing_changes')],\n                [InlineKeyboardButton(\"\ud83d\udce2 \u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b\", callback_data='mailing_announcements')],\n                [InlineKeyboardButton(\"\ud83c\udfeb \u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442\u0430\", callback_data='mailing_university')],\n                [InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='announcements_menu')]\n            ]\n            reply_markup = InlineKeyboardMarkup(buttons)\n            await query.edit_message_text(text=\"\ud83d\udce4 **\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0438\u043f \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438:**\", reply_markup=reply_markup, parse_mode='Markdown')\n\n        # \u0412\u044b\u0431\u043e\u0440 \u0442\u0438\u043f\u0430 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u0434\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u043e\u0432\u043e\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438\n        elif data.startswith('mailing_') and not data.startswith('mailing_target'):\n            mailing_type = data.split('_')[1]\n            context.user_data['mailing_type'] = mailing_type\n            # \u0412\u044b\u0431\u043e\u0440 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0438\n            buttons = [\n                [InlineKeyboardButton(\"\ud83d\udcc6 \u041f\u043e \u043a\u0443\u0440\u0441\u0443 \u0438 \u0433\u0440\u0443\u043f\u043f\u0435\", callback_data='mailing_target_group')],\n                [InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='send_announcement')]\n            ]\n            reply_markup = InlineKeyboardMarkup(buttons)\n            await query.edit_message_text(text=f\"\ud83d\udce4 **\u0412\u044b\u0431\u0440\u0430\u043d\u043e: {mailing_type.capitalize()}**\\n\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0446\u0435\u043b\u0435\u0432\u0443\u044e \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u044e \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438:\", reply_markup=reply_markup, parse_mode='Markdown')\n\n        elif data == 'mailing_target_group' and is_teacher_user(user_id):\n            # \u0417\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n            await query.edit_message_text(\"\ud83d\udcdd **\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u0432\u0430\u0448\u0435\u0439 \u0433\u0440\u0443\u043f\u043f\u0435:**\")\n            context.user_data['awaiting_mailing_message'] = True\n\n        elif data == 'send_global_announcement' and is_teacher_user(user_id):\n            # \u0412\u044b\u0431\u043e\u0440 \u0442\u0438\u043f\u0430 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n            buttons = [\n                [InlineKeyboardButton(\"\ud83d\udcda \u0414\u043e\u043c\u0430\u0448\u043d\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435\", callback_data='global_mailing_homework')],\n                [InlineKeyboardButton(\"\ud83d\udd04 \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0438\", callback_data='global_mailing_changes')],\n                [InlineKeyboardButton(\"\ud83d\udce2 \u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b\", callback_data='global_mailing_announcements')],\n                [InlineKeyboardButton(\"\ud83c\udfeb \u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442\u0430\", callback_data='global_mailing_university')],\n                [InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='announcements_menu')]\n            ]\n            reply_markup = InlineKeyboardMarkup(buttons)\n            await query.edit_message_text(text=\"\ud83d\uddc2 **\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0438\u043f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438:**\", reply_markup=reply_markup, parse_mode='Markdown')\n\n        # \u0412\u044b\u0431\u043e\u0440 \u0442\u0438\u043f\u0430 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u0434\u043b\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438\n        elif data.startswith('global_mailing_') and is_teacher_user(user_id):\n            mailing_type = data.split('_')[2]\n            context.user_data['mailing_type'] = mailing_type\n            context.user_data['mailing_target'] = 'global'\n            # \u0417\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n            await query.edit_message_text(\"\ud83d\udcdd **\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438:**\")\n            context.user_data['awaiting_mailing_message'] = True\n\n        # \u041c\u0435\u043d\u044e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a\n        elif data == 'blocking_menu' and is_teacher_user(user_id):\n            # \u041c\u0435\u043d\u044e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a\n            buttons = [\n                [InlineKeyboardButton(\"\ud83d\udd12 \u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\", callback_data='block_user')],\n                [InlineKeyboardButton(\"\ud83d\udd13 \u0420\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\", callback_data='unblock_user')],\n                [InlineKeyboardButton(\"\ud83d\udc64 \u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439\", callback_data='view_blocked_users')],\n                [InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='admin_panel')]\n            ]\n            reply_markup = InlineKeyboardMarkup(buttons)\n            await query.edit_message_text(text=\"\ud83d\udd12 **\u041c\u0435\u043d\u044e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a:**\", reply_markup=reply_markup, parse_mode='Markdown')\n\n        # \u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439\n        elif data == 'view_blocked_users' and is_teacher_user(user_id):\n            await view_blocked_users(update, context)\n\n        elif data.startswith('page-') and is_teacher_user(user_id):\n            # \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0438 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439\n            try:\n                page_number = int(data.split('-')[1])\n                await view_blocked_users(update, context, page_number=page_number)\n            except (IndexError, ValueError):\n                await query.answer(\"\u274c \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043d\u043e\u043c\u0435\u0440 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.\", show_alert=True)\n\n        elif data == 'personal_cabinet' or data == 'back_to_admin':\n            await personal_cabinet(update, context)\n\n        else:\n            await query.answer(\"\u2753 \u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430.\", show_alert=True)\n\n    except sqlite3.Error as e:\n        logger.error(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445: {e}\")\n        await query.answer(\"\u274c \u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430.\", show_alert=True)\n\n    finally:\n        conn.close()\n```\n\n### \u041f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u044f \u043a \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c\n\n1. **\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0431\u043b\u043e\u043a\u0438 `except` \u0438 `finally`:**\n   - **`except sqlite3.Error as e:`** - \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043b\u043e\u0432\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0438, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 SQLite \u0438 \u043b\u043e\u0433\u0438\u0440\u0443\u0435\u043c \u0438\u0445. \u0422\u0430\u043a\u0436\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435.\n   - **`finally:`** - \u0412 \u044d\u0442\u043e\u043c \u0431\u043b\u043e\u043a\u0435 \u043c\u044b \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u043c, \u0447\u0442\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043a\u0440\u044b\u0442\u043e \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0442\u043e\u0433\u043e, \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u043d\u0435\u0442.\n\n2. **\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439:**\n   - \u0412\u043d\u0443\u0442\u0440\u0438 \u0431\u043b\u043e\u043a\u0430 `except` \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043b\u044e\u0431\u0443\u044e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043e\u0448\u0438\u0431\u043e\u043a, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430 \u0438\u043b\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0443 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f.\n\n3. **\u041b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435:**\n   - \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 `logger.error` \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u0430\u043c \u0432\u0435\u0441\u0442\u0438 \u0436\u0443\u0440\u043d\u0430\u043b \u043e\u0448\u0438\u0431\u043e\u043a, \u0447\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0438 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0431\u043e\u0442\u0430.\n\n### \u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438\n\n1. **\u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0445 \u0431\u043b\u043e\u043a\u043e\u0432 `try`:**\n   \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0432\u0441\u0435 \u0431\u043b\u043e\u043a\u0438 `try:` \u0432 \u0432\u0430\u0448\u0435\u043c \u043a\u043e\u0434\u0435 \u0438\u043c\u0435\u044e\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0431\u043b\u043e\u043a\u0438 `except:` \u0438/\u0438\u043b\u0438 `finally:`.\n\n2. **\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439:**\n   \u0412 \u0432\u0430\u0448\u0435\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0431\u043b\u043e\u043a\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0435\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u0443\u0441\u043b\u043e\u0432\u0438\u044f:\n   ```python\n   application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))\n   application.add_handler(MessageHandler(filters.TEXT & filters.Regex('^.*$'), collect_mailing_message))\n   ```\n   \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0443\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e. \u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u044b\u0435 \u0444\u0438\u043b\u044c\u0442\u0440\u044b \u0438\u043b\u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u0432 \u043e\u0434\u043d\u043e\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0435.\n\n3. **\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435:**\n   \u041f\u043e\u0441\u043b\u0435 \u0432\u043d\u0435\u0441\u0435\u043d\u0438\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0442\u0449\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u0431\u043e\u0442\u0430, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0432\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0438 \u0447\u0442\u043e \u0431\u043b\u043e\u043a\u0438 `try-except` \u043e\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u044e\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0443\u0447\u0430\u0441\u0442\u043a\u0438 \u043a\u043e\u0434\u0430.\n\n### \u041f\u043e\u043b\u043d\u044b\u0439 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434\n\n\u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u043f\u043e\u043b\u043d\u044b\u0439 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0441 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u0431\u043b\u043e\u043a\u0430\u043c\u0438 `except` \u0438 `finally` \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 `handle_callback`. \u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441 \u0431\u043b\u043e\u043a\u0430\u043c\u0438 `try:`, \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u043e\u043d\u0438 \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u044b.\n\n```python\nimport pytz\nimport sqlite3\nfrom datetime import datetime, timedelta\nfrom telegram import Update, ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton\nfrom telegram.ext import (\n    ApplicationBuilder,\n    CommandHandler,\n    CallbackContext,\n    MessageHandler,\n    filters,\n    CallbackQueryHandler,\n)\nimport configparser\nimport os\nimport logging\n\n# \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f\nlogging.basicConfig(\n    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO\n)\nlogger = logging.getLogger(__name__)\n\n# \u0427\u0442\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430\nconfig = configparser.ConfigParser()\nconfig.read('config.ini')\n\n# \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u0430 \u0438\u0437 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430\nTOKEN = config.get('Telegram', 'Token')\n\n# ID \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430\nMAIN_ADMIN_ID = 1108429314\n\ndef create_config_file():\n    config['Telegram'] = {'Token': 'your_bot_token_here'}\n    with open('config.ini', 'w') as configfile:\n        config.write(configfile)\n\ndef init_db():\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n\n    # \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b schedule\n    c.execute('''CREATE TABLE IF NOT EXISTS schedule\n                 (course INTEGER, direction TEXT, week_type TEXT, day TEXT, slot INTEGER, time TEXT, details TEXT)''')\n\n    # \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b users \u0441 \u043a\u043e\u043b\u043e\u043d\u043a\u043e\u0439 created_at\n    c.execute('''\n        CREATE TABLE IF NOT EXISTS users (\n            id INTEGER PRIMARY KEY,\n            username TEXT,\n            course INTEGER,\n            direction TEXT, \n            subscribed INTEGER DEFAULT 1, \n            notifications TEXT DEFAULT 'homework,changes,announcements,university',\n            blocked_until TEXT DEFAULT NULL,\n            created_at TEXT DEFAULT (datetime('now','localtime'))\n        )\n    ''')\n\n    # \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b teachers\n    c.execute('''CREATE TABLE IF NOT EXISTS teachers\n                 (id INTEGER PRIMARY KEY)''')\n\n    # \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u043f\u0440\u0435\u043f\u043e\u0434\u0430\u0432\u0430\u0442\u0435\u043b\u0435\u0439\n    c.execute(\"INSERT OR IGNORE INTO teachers (id) VALUES (?)\", (MAIN_ADMIN_ID,))\n\n    # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 created_at, \u0435\u0441\u043b\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0431\u0435\u0437 \u043d\u0435\u0451\n    c.execute(\"PRAGMA table_info(users)\")\n    columns = [info[1] for info in c.fetchall()]\n    if 'created_at' not in columns:\n        try:\n            c.execute(\"ALTER TABLE users ADD COLUMN created_at TEXT DEFAULT (datetime('now','localtime'))\")\n            conn.commit()\n            print(\"\u041a\u043e\u043b\u043e\u043d\u043a\u0430 'created_at' \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 'users'.\")\n        except sqlite3.OperationalError as e:\n            print(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 'created_at': {e}\")\n\n    # \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044f\n    c.execute(\"DELETE FROM schedule\")\n    times = [\"8:30 - 10:00\", \"10:10 - 11:40\", \"12:30 - 14:00\", \"14:10 - 15:40\", \"15:50 - 17:20\", \"17:30 - 19:00\"]\n    directions = ['\u0424', '\u0423', '\u0424\u041c', '\u0413\u041c\u0423', '\u0411\u0418']\n\n    schedule_bi = {\n        \"\u0447\u0451\u0442\u043d\u0430\u044f\": {\n            \"\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a\": [\"\u041c\u0430\u0442\u0435\u043c (\u043b) (222)\", \"\u041c\u0430\u0442\u0435\u043c (\u0441) (222)\", \"\u0424\u0438\u0437-\u0440\u0430\", \"\u0410\u043d\u0433\u043b (209)\", \"\", \"\"],\n            \"\u0412\u0442\u043e\u0440\u043d\u0438\u043a\": [\"\u0418\u0441\u0442\u043e\u0440\u0438\u044f (\u0441) (108)\", \"\u0418\u0441\u0442\u043e\u0440\u0438\u044f (\u043b) (108)\", \"\u0418\u0422\u041f\u0414 (\u0441) (217)\", \"\", \"\", \"\"],\n            \"\u0421\u0440\u0435\u0434\u0430\": [\"\", \"\", \"\", \"\u0418\u0422\u041f\u0414 (\u0441) (217)\", \"Phython (\u043b) (111)\", \"Phython (\u043b) (111)\"],\n            \"\u0427\u0435\u0442\u0432\u0435\u0440\u0433\": [\"\", \"\u0418\u0441\u0442\u043e\u0440\u0438\u044f (\u0441) (204)\", \"\u041c\u0435\u043d\u0435\u0434\u0436\u043c\u0435\u043d\u0442 (\u043b) (209)\", \"\", \"\", \"\"],\n            \"\u041f\u044f\u0442\u043d\u0438\u0446\u0430\": [\"\", \"\", \"\", \"\u0411\u0416\u0414 (\u043b) (304)\", \"\u041c\u0435\u043d\u0435\u0434\u0436\u043c\u0435\u043d\u0442 (\u0441) (108)\", \"\u0424\u0438\u0437-\u0440\u0430\"]\n        },\n        \"\u043d\u0435\u0447\u0451\u0442\u043d\u0430\u044f\": {\n            \"\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a\": [\"\u041c\u0430\u0442\u0435\u043c (\u043b) (222)\", \"\u041c\u0430\u0442\u0435\u043c (\u0441) (222)\", \"\u0424\u0438\u0437-\u0440\u0430\", \"\u0410\u043d\u0433\u043b (209)\", \"\", \"\"],\n            \"\u0412\u0442\u043e\u0440\u043d\u0438\u043a\": [\"\u0410\u043d\u0433\u043b (209)\", \"\u0418\u0441\u0442\u043e\u0440\u0438\u044f (\u043b) (108)\", \"\u0418\u0422\u041f\u0414 (\u0441) (217)\", \"\u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0424\u0423 (\u043b) (211)\", \"\", \"\"],\n            \"\u0421\u0440\u0435\u0434\u0430\": [\"\", \"\", \"\", \"\u0418\u0422\u041f\u0414 (\u0441) (217)\", \"\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 \u0441\u043f\u0435\u0446 (\u043b) (111)\", \"Phython (\u0441) (111)\"],\n            \"\u0427\u0435\u0442\u0432\u0435\u0440\u0433\": [\"\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 \u0441\u043f\u0435\u0446 (\u0441) (213)\", \"\u041c\u0430\u0442\u0435\u043c (\u0441) (204)\", \"\u0418\u0441\u0442\u043e\u0440\u0438\u044f (\u0441) (209)\", \"\", \"\", \"\"],\n            \"\u041f\u044f\u0442\u043d\u0438\u0446\u0430\": [\"\", \"\", \"\", \"\u0411\u0416\u0414 (\u0441) (304)\", \"\u041c\u0435\u043d\u0435\u0434\u0436\u043c\u0435\u043d\u0442 (\u0441) (108)\", \"\u0424\u0438\u0437-\u0440\u0430\"]\n        }\n    }\n\n    for course in range(1, 5):\n        for direction in directions:\n            schedule_data = {\n                \"\u0447\u0451\u0442\u043d\u0430\u044f\": {day: [\"\"] * 6 for day in [\"\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a\", \"\u0412\u0442\u043e\u0440\u043d\u0438\u043a\", \"\u0421\u0440\u0435\u0434\u0430\", \"\u0427\u0435\u0442\u0432\u0435\u0440\u0433\", \"\u041f\u044f\u0442\u043d\u0438\u0446\u0430\", \"\u0421\u0443\u0431\u0431\u043e\u0442\u0430\"]},\n                \"\u043d\u0435\u0447\u0451\u0442\u043d\u0430\u044f\": {day: [\"\"] * 6 for day in [\"\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a\", \"\u0412\u0442\u043e\u0440\u043d\u0438\u043a\", \"\u0421\u0440\u0435\u0434\u0430\", \"\u0427\u0435\u0442\u0432\u0435\u0440\u0433\", \"\u041f\u044f\u0442\u043d\u0438\u0446\u0430\", \"\u0421\u0443\u0431\u0431\u043e\u0442\u0430\"]}\n            }\n\n            if direction == '\u0411\u0418' and course == 1:\n                schedule_data = schedule_bi\n            else:\n                for week_type, days in schedule_data.items():\n                    for day in days:\n                        days[day][0] = f\"\u041a\u0443\u0440\u0441 {course}, \u0413\u0440\u0443\u043f\u043f\u0430 {direction}\"\n\n            for week_type, days in schedule_data.items():\n                for day, slots in days.items():\n                    for slot in range(6):\n                        time = times[slot]\n                        detail = slots[slot]\n                        c.execute(\n                            \"INSERT INTO schedule (course, direction, week_type, day, slot, time, details) VALUES (?, ?, ?, ?, ?, ?, ?)\",\n                            (course, direction, week_type, day, slot + 1, time, detail)\n                        )\n\n    conn.commit()\n    conn.close()\n\ndef get_day_name(index):\n    days_rus = [\n        \"\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a\",\n        \"\u0412\u0442\u043e\u0440\u043d\u0438\u043a\",\n        \"\u0421\u0440\u0435\u0434\u0430\",\n        \"\u0427\u0435\u0442\u0432\u0435\u0440\u0433\",\n        \"\u041f\u044f\u0442\u043d\u0438\u0446\u0430\",\n        \"\u0421\u0443\u0431\u0431\u043e\u0442\u0430\",\n        \"\u0412\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435\"\n    ]\n    return days_rus[index]\n\ndef is_even_week(date):\n    week_number = date.isocalendar()[1]\n    return week_number % 2 == 0\n\ndef get_week_type(date):\n    return '\u0447\u0451\u0442\u043d\u0430\u044f' if is_even_week(date) else '\u043d\u0435\u0447\u0451\u0442\u043d\u0430\u044f'\n\ndef get_week_type_short(date):\n    return '\u0447\u0451\u0442' if is_even_week(date) else '\u043d\u0435\u0447\u0451\u0442'\n\ndef get_schedule_for_day(course, direction, day_name, date):\n    week_type = get_week_type(date)\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n\n    c.execute(\n        \"SELECT slot, time, details FROM schedule WHERE course = ? AND direction = ? AND week_type = ? AND day = ? ORDER BY slot\",\n        (course, direction, week_type, day_name)\n    )\n    results = c.fetchall()\n    conn.close()\n\n    if not results:\n        return \"\u274c \u041d\u0435\u0442 \u0437\u0430\u043d\u044f\u0442\u0438\u0439\"\n\n    day_schedule = \"\"\n    for slot, time, details in results:\n        if details:\n            day_schedule += f\"{slot}. {time}\\n{details}\\n\\n\"\n\n    return day_schedule.strip() if day_schedule else \"\u274c \u041d\u0435\u0442 \u0437\u0430\u043d\u044f\u0442\u0438\u0439\"\n\nasync def start(update: Update, context: CallbackContext) -> None:\n    user_id = update.effective_user.id\n\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n    c.execute(\"SELECT blocked_until FROM users WHERE id=?\", (user_id,))\n    blocked_until = c.fetchone()\n\n    if blocked_until and blocked_until[0]:\n        blocked_until_date = datetime.fromisoformat(blocked_until[0])\n        if blocked_until_date > datetime.now():\n            await update.message.reply_text(f\"\u274c \u0412\u044b \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u044b! \u0414\u043e \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 {blocked_until_date}.\")\n            conn.close()\n            return\n\n    conn.close()\n\n    # \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043c\u0435\u043d\u044e\n    keyboard = [\n        [\"\ud83d\uddd3 \u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0434\u0430\u0442\u0443 \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044f\", \"\ud83d\udcc5 \u0420\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043d\u0430 \u0437\u0430\u0432\u0442\u0440\u0430\", \"\ud83d\udcc5 \u0420\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\"],\n        [\"\ud83d\udcc6 \u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a\", \"\ud83d\udcc6 \u0412\u0442\u043e\u0440\u043d\u0438\u043a\", \"\ud83d\udcc6 \u0421\u0440\u0435\u0434\u0430\"],\n        [\"\ud83d\udcc6 \u0427\u0435\u0442\u0432\u0435\u0440\u0433\", \"\ud83d\udcc6 \u041f\u044f\u0442\u043d\u0438\u0446\u0430\", \"\ud83d\udcc6 \u0421\u0443\u0431\u0431\u043e\u0442\u0430\"],\n        [\"\ud83d\udc64 \u041b\u0438\u0447\u043d\u044b\u0439 \u043a\u0430\u0431\u0438\u043d\u0435\u0442\"]\n    ]\n    reply_markup = ReplyKeyboardMarkup(keyboard, one_time_keyboard=True, resize_keyboard=True)\n    \n    # \u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u043c\u0435\u043d\u044e\n    await update.message.reply_text(\n        '\ud83d\udc4b \u041f\u0440\u0438\u0432\u0435\u0442! \u041f\u043e\u043c\u0435\u043d\u044f\u0439 \u0433\u0440\u0443\u043f\u043f\u0443 \u0438 \u043a\u0443\u0440\u0441 \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0432 \u0441\u0432\u043e\u0451\u043c \u043b\u0438\u0447\u043d\u043e\u043c \u043a\u0430\u0431\u0438\u043d\u0435\u0442\u0435.',\n        reply_markup=reply_markup\n    )\n    \n    # \u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043b\u0438\u0447\u043d\u043e\u0433\u043e \u043a\u0430\u0431\u0438\u043d\u0435\u0442\u0430\n    await personal_cabinet(update, context)\n\nasync def handle_message(update: Update, context: CallbackContext) -> None:\n    user_id = update.message.from_user.id\n    user_message = update.message.text.strip().lower()\n\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n    c.execute(\"SELECT blocked_until FROM users WHERE id=?\", (user_id,))\n    blocked_until = c.fetchone()\n\n    if blocked_until and blocked_until[0]:\n        blocked_until_date = datetime.fromisoformat(blocked_until[0])\n        if blocked_until_date > datetime.now():\n            await update.message.reply_text(f\"\u274c \u0412\u044b \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u044b! \u0414\u043e \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 {blocked_until_date}.\")\n            conn.close()\n            return\n\n    # \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439\n    if context.user_data.get('action') == 'promote_admin':\n        try:\n            promote_id = int(user_message)\n            c.execute(\"SELECT id FROM users WHERE id = ?\", (promote_id,))\n            if not c.fetchone():\n                await update.message.reply_text(\"\u274c \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0442\u0430\u043a\u0438\u043c ID \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d.\")\n            else:\n                c.execute(\"INSERT OR IGNORE INTO teachers (id) VALUES (?)\", (promote_id,))\n                conn.commit()\n                await update.message.reply_text(f\"\u2705 \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 ID {promote_id} \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u043c.\")\n        except ValueError:\n            await update.message.reply_text(\"\u274c \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 ID. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 ID \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.\")\n        except sqlite3.Error as e:\n            logger.error(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430: {e}\")\n            await update.message.reply_text(\"\u274c \u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430.\")\n        finally:\n            conn.close()\n            context.user_data['action'] = None\n        return\n\n    if context.user_data.get('action') == 'demote_admin':\n        try:\n            demote_id = int(user_message)\n            if demote_id == MAIN_ADMIN_ID:\n                await update.message.reply_text(\"\u274c \u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430.\")\n            else:\n                c.execute(\"SELECT id FROM teachers WHERE id = ?\", (demote_id,))\n                if not c.fetchone():\n                    await update.message.reply_text(\"\u274c \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0442\u0430\u043a\u0438\u043c ID \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u043c.\")\n                else:\n                    c.execute(\"DELETE FROM teachers WHERE id = ?\", (demote_id,))\n                    conn.commit()\n                    await update.message.reply_text(f\"\u2705 \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 ID {demote_id} \u0443\u0434\u0430\u043b\u0435\u043d \u0438\u0437 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u0432.\")\n        except ValueError:\n            await update.message.reply_text(\"\u274c \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 ID. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 ID \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.\")\n        except sqlite3.Error as e:\n            logger.error(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430: {e}\")\n            await update.message.reply_text(\"\u274c \u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430.\")\n        finally:\n            conn.close()\n            context.user_data['action'] = None\n        return\n\n    if context.user_data.get('action') == 'block_user':\n        try:\n            block_id = int(user_message)\n            c.execute(\"SELECT id FROM users WHERE id = ?\", (block_id,))\n            if not c.fetchone():\n                await update.message.reply_text(\"\u274c \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0442\u0430\u043a\u0438\u043c ID \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d.\")\n            else:\n                # \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u043d\u0430 24 \u0447\u0430\u0441\u0430\n                block_until = datetime.now() + timedelta(hours=24)\n                c.execute(\"UPDATE users SET blocked_until = ? WHERE id = ?\", (block_until.isoformat(), block_id))\n                conn.commit()\n                await update.message.reply_text(f\"\ud83d\udd12 \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 ID {block_id} \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d \u0434\u043e {block_until}.\")\n        except ValueError:\n            await update.message.reply_text(\"\u274c \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 ID. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 ID \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.\")\n        except sqlite3.Error as e:\n            logger.error(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f: {e}\")\n            await update.message.reply_text(\"\u274c \u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.\")\n        finally:\n            conn.close()\n            context.user_data['action'] = None\n        return\n\n    if context.user_data.get('action') == 'unblock_user':\n        try:\n            unblock_id = int(user_message)\n            if unblock_id == MAIN_ADMIN_ID:\n                await update.message.reply_text(\"\u274c \u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430.\")\n                conn.close()\n                context.user_data['action'] = None\n                return\n\n            c.execute(\"SELECT id FROM users WHERE id = ? AND blocked_until IS NOT NULL\", (unblock_id,))\n            if not c.fetchone():\n                await update.message.reply_text(\"\u274c \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0442\u0430\u043a\u0438\u043c ID \u043d\u0435 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d.\")\n            else:\n                c.execute(\"UPDATE users SET blocked_until = NULL WHERE id = ?\", (unblock_id,))\n                conn.commit()\n                await update.message.reply_text(f\"\ud83d\udd13 \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 ID {unblock_id} \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d.\")\n        except ValueError:\n            await update.message.reply_text(\"\u274c \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 ID. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 ID \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.\")\n        except sqlite3.Error as e:\n            logger.error(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f: {e}\")\n            await update.message.reply_text(\"\u274c \u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.\")\n        finally:\n            conn.close()\n            context.user_data['action'] = None\n        return\n\n    conn.close()\n\n    # \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439\n    logger.info(f\"Received message: {user_message}\")\n\n    if context.user_data.get('awaiting_date', False):\n        if user_message.isdigit():\n            day = int(user_message)\n            current_month = datetime.now(pytz.timezone('Asia/Omsk')).month\n            current_year = datetime.now(pytz.timezone('Asia/Omsk')).year\n            try:\n                date_obj = datetime(current_year, current_month, day, tzinfo=pytz.timezone('Asia/Omsk'))\n                if date_obj.month != current_month:\n                    raise ValueError\n                await show_schedule_by_date(update, context, date_obj)\n            except ValueError:\n                await update.message.reply_text('\u274c \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0434\u0435\u043d\u044c. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438 \u0447\u0438\u0441\u043b\u043e \u043e\u0442 1 \u0434\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0434\u043d\u044f \u043c\u0435\u0441\u044f\u0446\u0430.')\n            finally:\n                context.user_data['awaiting_date'] = False\n        else:\n            await update.message.reply_text('\u274c \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438 \u0447\u0438\u0441\u043b\u043e \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044f.')\n        return\n\n    if user_message in [\"\u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\", \"\u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043d\u0430 \u0437\u0430\u0432\u0442\u0440\u0430\", \"\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a\", \"\u0432\u0442\u043e\u0440\u043d\u0438\u043a\", \"\u0441\u0440\u0435\u0434\u0430\", \"\u0447\u0435\u0442\u0432\u0435\u0440\u0433\", \"\u043f\u044f\u0442\u043d\u0438\u0446\u0430\", \"\u0441\u0443\u0431\u0431\u043e\u0442\u0430\"]:\n        await show_schedule(update, context, user_message)\n    elif user_message == \"\u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0434\u0430\u0442\u0443 \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044f\":\n        logger.info(\"User chose to select a specific date for schedule\")\n        context.user_data['awaiting_date'] = True\n        await update.message.reply_text(\"\ud83d\uddd3 \u0412\u0432\u0435\u0434\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0441\u044f\u0446\u0430:\")\n    elif user_message == \"\u043b\u0438\u0447\u043d\u044b\u0439 \u043a\u0430\u0431\u0438\u043d\u0435\u0442\":\n        logger.info(\"User accessing personal cabinet\")\n        await personal_cabinet(update, context)\n    else:\n        logger.warning(f\"Unrecognized menu option: {user_message}\")\n        await update.message.reply_text('\u2753 \u0412\u044b\u0431\u0435\u0440\u0438 \u043e\u043f\u0446\u0438\u044e \u0438\u0437 \u043c\u0435\u043d\u044e.')\n\nasync def personal_cabinet(update: Update, context: CallbackContext):\n    user_id = update.effective_user.id\n    username = update.effective_user.username or \"\"\n    first_name = update.effective_user.first_name or \"\"\n    last_name = update.effective_user.last_name or \"\"\n\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n\n    # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445\n    c.execute(\n        \"SELECT username, course, direction, subscribed, notifications FROM users WHERE id = ?\",\n        (user_id,)\n    )\n    user = c.fetchone()\n\n    # \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0435\u0441\u043b\u0438 \u043e\u043d \u0435\u0449\u0451 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442\n    if not user:\n        current_time = datetime.now(pytz.timezone('Asia/Omsk')).isoformat()\n        c.execute(\n            \"INSERT INTO users (id, username, course, direction, created_at) VALUES (?, ?, ?, ?, ?)\",\n            (user_id, username, 1, \"\u0424\", current_time)\n        )\n        conn.commit()\n        user = (username, 1, \"\u0424\", 1, 'homework,changes,announcements,university')\n\n    # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f ID \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 teachers, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0435\u0433\u043e \u0442\u0430\u043c \u043d\u0435\u0442\n    c.execute(\"SELECT 1 FROM teachers WHERE id = ?\", (user_id,))\n    is_teacher = c.fetchone() is not None\n\n    if user_id == MAIN_ADMIN_ID and not is_teacher:\n        c.execute(\"INSERT INTO teachers (id) VALUES (?)\", (user_id,))\n        conn.commit()\n        is_teacher = True\n\n    conn.close()\n\n    current_date = datetime.now(pytz.timezone('Asia/Omsk'))\n    week_number = current_date.isocalendar()[1]\n    week_type = get_week_type(current_date)\n    week_status = f\"{week_number} {week_type}\"\n\n    role = \"\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\" if is_teacher else \"\u0421\u0442\u0443\u0434\u0435\u043d\u0442\"\n\n    message_text = (\n        f\"\ud83d\udc64 **\u041b\u0438\u0447\u043d\u044b\u0439 \u043a\u0430\u0431\u0438\u043d\u0435\u0442**\\n\\n\"\n        f\"**\u0418\u043c\u044f:** {first_name} {last_name}\\n\"\n        f\"**\u041d\u0438\u043a:** @{user[0]}\\n\"\n        f\"**ID:** `{user_id}`\\n\\n\"\n        f\"**\u0420\u043e\u043b\u044c:** {role}\\n\"\n        f\"**\u0413\u0440\u0443\u043f\u043f\u0430:** {user[2]}\\n\"\n        f\"**\u041a\u0443\u0440\u0441:** {user[1]}\\n\\n\"\n        f\"**\u041d\u0435\u0434\u0435\u043b\u044f:** {week_status}\\n\"\n        f\"**\u0414\u0430\u0442\u0430:** {current_date.strftime('%d.%m.%Y')}\\n\"\n        f\"**\u0412\u0440\u0435\u043c\u044f:** {current_date.strftime('%H:%M:%S')}\\n\"\n    )\n\n    buttons = [\n        [\n            InlineKeyboardButton(\"\ud83d\udd04 \u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0433\u0440\u0443\u043f\u043f\u0443\", callback_data='change_direction'),\n            InlineKeyboardButton(\"\ud83d\udd04 \u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043a\u0443\u0440\u0441\", callback_data='change_course')\n        ],\n        [InlineKeyboardButton(\"\ud83d\udd14 \u0423\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f\", callback_data='manage_notifications')]\n    ]\n\n    if is_teacher:\n        buttons.append([InlineKeyboardButton(\"\ud83d\udd27 \u0414\u043b\u044f \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u0432\", callback_data='admin_panel')])\n\n    reply_markup = InlineKeyboardMarkup(buttons)\n\n    if update.callback_query:\n        await update.callback_query.edit_message_text(\n            text=message_text,\n            reply_markup=reply_markup,\n            parse_mode='Markdown'\n        )\n    else:\n        await update.message.reply_text(\n            text=message_text,\n            reply_markup=reply_markup,\n            parse_mode='Markdown'\n        )\n\nasync def admin_panel(update: Update, context: CallbackContext):\n    query = update.callback_query\n    user_id = query.from_user.id\n\n    logger.info(f\"Accessing admin panel - User ID: {user_id}\")\n\n    if not is_teacher_user(user_id):\n        await query.answer(\"\u274c \u041d\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0430!\", show_alert=True)\n        return\n\n    buttons = [\n        [InlineKeyboardButton(\"\ud83d\udcc8 \u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430\", callback_data='show_statistics')],\n        [InlineKeyboardButton(\"\ud83d\udce2 \u0420\u0430\u0441\u0441\u044b\u043b\u043a\u0438\", callback_data='announcements_menu')],\n        [InlineKeyboardButton(\"\ud83d\udd12 \u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438\", callback_data='blocking_menu')]\n    ]\n\n    if user_id == MAIN_ADMIN_ID:\n        buttons.append([InlineKeyboardButton(\"\u2795 \u041d\u0430\u0437\u043d\u0430\u0447\u0438\u0442\u044c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430\", callback_data='promote_admin')])\n        buttons.append([InlineKeyboardButton(\"\u2796 \u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430\", callback_data='demote_admin')])\n\n    # \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u043d\u043e\u043f\u043a\u0443 \"\u041d\u0430\u0437\u0430\u0434\" \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0432 \u043b\u0438\u0447\u043d\u044b\u0439 \u043a\u0430\u0431\u0438\u043d\u0435\u0442\n    buttons.append([InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='personal_cabinet')])\n\n    reply_markup = InlineKeyboardMarkup(buttons)\n    await query.edit_message_text(text=\"\ud83d\udd27 **\u0414\u043b\u044f \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u0432:**\", reply_markup=reply_markup, parse_mode='Markdown')\n\nasync def handle_callback(update: Update, context: CallbackContext):\n    query = update.callback_query\n    user_id = query.from_user.id\n    data = query.data\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n\n    try:\n        if data == 'change_course':\n            c.execute(\"SELECT course FROM users WHERE id = ?\", (user_id,))\n            result = c.fetchone()\n            if result:\n                current_course = result[0]\n                new_course = 1 if current_course == 4 else current_course + 1\n                c.execute(\"UPDATE users SET course = ? WHERE id = ?\", (new_course, user_id))\n                conn.commit()\n                await query.answer(f\"\u2705 \u041a\u0443\u0440\u0441 \u0438\u0437\u043c\u0435\u043d\u0451\u043d \u043d\u0430 {new_course}\")\n                await personal_cabinet(update, context)\n            else:\n                await query.answer(\"\u274c \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d.\")\n\n        elif data == 'change_direction':\n            c.execute(\"SELECT direction FROM users WHERE id = ?\", (user_id,))\n            result = c.fetchone()\n            if result:\n                current_direction = result[0]\n                directions = ['\u0424', '\u0423', '\u0424\u041c', '\u0413\u041c\u0423', '\u0411\u0418']\n                try:\n                    new_direction_index = (directions.index(current_direction) + 1) % len(directions)\n                    new_direction = directions[new_direction_index]\n                    c.execute(\"UPDATE users SET direction = ? WHERE id = ?\", (new_direction, user_id))\n                    conn.commit()\n                    await query.answer(f\"\u2705 \u0413\u0440\u0443\u043f\u043f\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0430 \u043d\u0430 {new_direction}\")\n                    await personal_cabinet(update, context)\n                except ValueError:\n                    await query.answer(\"\u274c \u041d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u0430\u044f \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0430.\")\n            else:\n                await query.answer(\"\u274c \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d.\")\n\n        elif data.startswith(\"toggle_\"):\n            notification_type = data.split(\"_\")[1]\n            await toggle_notification(update, user_id, notification_type)\n\n        elif data == 'manage_notifications':\n            await manage_notifications(update, user_id)\n\n        elif data == 'admin_panel':\n            await admin_panel(update, context)\n\n        elif data == 'show_statistics' and is_teacher_user(user_id):\n            await show_statistics(update, context)\n\n        # \u041c\u0435\u043d\u044e \u0440\u0430\u0441\u0441\u044b\u043b\u043e\u043a\n        elif data == 'announcements_menu' and is_teacher_user(user_id):\n            # \u041c\u0435\u043d\u044e \u0440\u0430\u0441\u0441\u044b\u043b\u043e\u043a\n            buttons = [\n                [InlineKeyboardButton(\"\ud83d\udce4 \u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0443\", callback_data='send_announcement')],\n                [InlineKeyboardButton(\"\ud83d\uddc2 \u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0430\u044f \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0430\", callback_data='send_global_announcement')],\n                [InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='admin_panel')]\n            ]\n            reply_markup = InlineKeyboardMarkup(buttons)\n            await query.edit_message_text(text=\"\ud83d\udce2 **\u041c\u0435\u043d\u044e \u0440\u0430\u0441\u0441\u044b\u043b\u043e\u043a:**\", reply_markup=reply_markup, parse_mode='Markdown')\n\n        # \u041d\u0430\u0447\u0430\u043b\u043e \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n        elif data == 'send_announcement' and is_teacher_user(user_id):\n            # \u0412\u044b\u0431\u043e\u0440 \u0442\u0438\u043f\u0430 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n            buttons = [\n                [InlineKeyboardButton(\"\ud83d\udcda \u0414\u043e\u043c\u0430\u0448\u043d\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435\", callback_data='mailing_homework')],\n                [InlineKeyboardButton(\"\ud83d\udd04 \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0438\", callback_data='mailing_changes')],\n                [InlineKeyboardButton(\"\ud83d\udce2 \u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b\", callback_data='mailing_announcements')],\n                [InlineKeyboardButton(\"\ud83c\udfeb \u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442\u0430\", callback_data='mailing_university')],\n                [InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='announcements_menu')]\n            ]\n            reply_markup = InlineKeyboardMarkup(buttons)\n            await query.edit_message_text(text=\"\ud83d\udce4 **\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0438\u043f \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438:**\", reply_markup=reply_markup, parse_mode='Markdown')\n\n        # \u0412\u044b\u0431\u043e\u0440 \u0442\u0438\u043f\u0430 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u0434\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u043e\u0432\u043e\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438\n        elif data.startswith('mailing_') and not data.startswith('mailing_target'):\n            mailing_type = data.split('_')[1]\n            context.user_data['mailing_type'] = mailing_type\n            # \u0412\u044b\u0431\u043e\u0440 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0438\n            buttons = [\n                [InlineKeyboardButton(\"\ud83d\udcc6 \u041f\u043e \u043a\u0443\u0440\u0441\u0443 \u0438 \u0433\u0440\u0443\u043f\u043f\u0435\", callback_data='mailing_target_group')],\n                [InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='send_announcement')]\n            ]\n            reply_markup = InlineKeyboardMarkup(buttons)\n            await query.edit_message_text(text=f\"\ud83d\udce4 **\u0412\u044b\u0431\u0440\u0430\u043d\u043e: {mailing_type.capitalize()}**\\n\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0446\u0435\u043b\u0435\u0432\u0443\u044e \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u044e \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438:\", reply_markup=reply_markup, parse_mode='Markdown')\n\n        elif data == 'mailing_target_group' and is_teacher_user(user_id):\n            # \u0417\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n            await query.edit_message_text(\"\ud83d\udcdd **\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u0432\u0430\u0448\u0435\u0439 \u0433\u0440\u0443\u043f\u043f\u0435:**\")\n            context.user_data['awaiting_mailing_message'] = True\n\n        elif data == 'send_global_announcement' and is_teacher_user(user_id):\n            # \u0412\u044b\u0431\u043e\u0440 \u0442\u0438\u043f\u0430 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n            buttons = [\n                [InlineKeyboardButton(\"\ud83d\udcda \u0414\u043e\u043c\u0430\u0448\u043d\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435\", callback_data='global_mailing_homework')],\n                [InlineKeyboardButton(\"\ud83d\udd04 \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0438\", callback_data='global_mailing_changes')],\n                [InlineKeyboardButton(\"\ud83d\udce2 \u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b\", callback_data='global_mailing_announcements')],\n                [InlineKeyboardButton(\"\ud83c\udfeb \u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442\u0430\", callback_data='global_mailing_university')],\n                [InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='announcements_menu')]\n            ]\n            reply_markup = InlineKeyboardMarkup(buttons)\n            await query.edit_message_text(text=\"\ud83d\uddc2 **\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0438\u043f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438:**\", reply_markup=reply_markup, parse_mode='Markdown')\n\n        # \u0412\u044b\u0431\u043e\u0440 \u0442\u0438\u043f\u0430 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u0434\u043b\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438\n        elif data.startswith('global_mailing_') and is_teacher_user(user_id):\n            mailing_type = data.split('_')[2]\n            context.user_data['mailing_type'] = mailing_type\n            context.user_data['mailing_target'] = 'global'\n            # \u0417\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n            await query.edit_message_text(\"\ud83d\udcdd **\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438:**\")\n            context.user_data['awaiting_mailing_message'] = True\n\n        # \u041c\u0435\u043d\u044e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a\n        elif data == 'blocking_menu' and is_teacher_user(user_id):\n            # \u041c\u0435\u043d\u044e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a\n            buttons = [\n                [InlineKeyboardButton(\"\ud83d\udd12 \u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\", callback_data='block_user')],\n                [InlineKeyboardButton(\"\ud83d\udd13 \u0420\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\", callback_data='unblock_user')],\n                [InlineKeyboardButton(\"\ud83d\udc64 \u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439\", callback_data='view_blocked_users')],\n                [InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='admin_panel')]\n            ]\n            reply_markup = InlineKeyboardMarkup(buttons)\n            await query.edit_message_text(text=\"\ud83d\udd12 **\u041c\u0435\u043d\u044e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a:**\", reply_markup=reply_markup, parse_mode='Markdown')\n\n        # \u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439\n        elif data == 'view_blocked_users' and is_teacher_user(user_id):\n            await view_blocked_users(update, context)\n\n        elif data.startswith('page-') and is_teacher_user(user_id):\n            # \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0438 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439\n            try:\n                page_number = int(data.split('-')[1])\n                await view_blocked_users(update, context, page_number=page_number)\n            except (IndexError, ValueError):\n                await query.answer(\"\u274c \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043d\u043e\u043c\u0435\u0440 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.\", show_alert=True)\n\n        elif data == 'personal_cabinet' or data == 'back_to_admin':\n            await personal_cabinet(update, context)\n\n        else:\n            await query.answer(\"\u2753 \u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430.\", show_alert=True)\n\n    except sqlite3.Error as e:\n        logger.error(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445: {e}\")\n        await query.answer(\"\u274c \u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430.\", show_alert=True)\n\n    finally:\n        conn.close()\n\nasync def collect_mailing_message(update: Update, context: CallbackContext) -> None:\n    user_id = update.message.from_user.id\n    if not is_teacher_user(user_id) or not context.user_data.get('awaiting_mailing_message', False):\n        return\n\n    mailing_type = context.user_data.get('mailing_type')\n    mailing_target = context.user_data.get('mailing_target', 'group')\n    message_text = update.message.text\n\n    if not message_text:\n        await update.message.reply_text(\"\u274c \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c.\")\n        return\n\n    context.user_data['message_text'] = message_text\n    context.user_data['awaiting_mailing_message'] = False\n\n    confirm_message = f\"\ud83d\udcdd **\u0412\u043e\u0442 \u0432\u0430\u0448 \u0442\u0435\u043a\u0441\u0442:**\\n\\n{message_text}\\n\\n\ud83d\udce4 \u0425\u043e\u0442\u0438\u0442\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c?\"\n    buttons = [\n        [\n            InlineKeyboardButton(\"\u2705 \u0414\u0430\", callback_data='confirm_send_mailing'),\n            InlineKeyboardButton(\"\u274c \u041d\u0435\u0442\", callback_data='cancel_send_mailing')\n        ]\n    ]\n    reply_markup = InlineKeyboardMarkup(buttons)\n\n    await update.message.reply_text(confirm_message, reply_markup=reply_markup, parse_mode='Markdown')\n\nasync def handle_mailing_confirm(update: Update, context: CallbackContext) -> None:\n    query = update.callback_query\n    user_id = query.from_user.id\n    data = query.data\n\n    if data == 'confirm_send_mailing':\n        await send_mailing(update, context)\n        await query.edit_message_text(\"\u2705 \u0420\u0430\u0441\u0441\u044b\u043b\u043a\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430.\")\n    elif data == 'cancel_send_mailing':\n        await query.edit_message_text(\"\u274c \u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u0430.\")\n    else:\n        await query.answer(\"\u2753 \u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430.\")\n\nasync def send_mailing(update: Update, context: CallbackContext) -> None:\n    mailing_type = context.user_data.get('mailing_type')\n    mailing_target = context.user_data.get('mailing_target', 'group')\n    message_text = context.user_data.get('message_text')\n\n    if not mailing_type or not message_text:\n        return\n\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n\n    try:\n        if mailing_target == 'global':\n            # \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u0442\u0438\u043f \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n            c.execute(\"SELECT id FROM users WHERE subscribed = 1 AND notifications LIKE ?\", (f'%{mailing_type}%',))\n            users = c.fetchall()\n            # \u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u0432\n            c.execute(\"SELECT id FROM teachers\")\n            admins = c.fetchall()\n            recipients = set(users) | set(admins)\n        elif mailing_target == 'group':\n            # \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043a\u0443\u0440\u0441 \u0438 \u0433\u0440\u0443\u043f\u043f\u0443 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044f\n            c.execute(\"SELECT course, direction FROM users WHERE id = ?\", (update.effective_user.id,))\n            user_info = c.fetchone()\n            if not user_info:\n                logger.error(\"\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u0434\u043b\u044f \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u043f\u043e \u0433\u0440\u0443\u043f\u043f\u0435.\")\n                return\n            course, direction = user_info\n            c.execute(\"SELECT id FROM users WHERE course = ? AND direction = ? AND subscribed = 1 AND notifications LIKE ?\", \n                      (course, direction, f'%{mailing_type}%'))\n            users = c.fetchall()\n            # \u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u0432\n            c.execute(\"SELECT id FROM teachers\")\n            admins = c.fetchall()\n            recipients = set(users) | set(admins)\n        else:\n            logger.error(f\"\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u0442\u0438\u043f \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0438 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438: {mailing_target}\")\n            return\n\n    except sqlite3.Error as e:\n        logger.error(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u0435\u0439 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438: {e}\")\n        return\n    finally:\n        conn.close()\n\n    # \u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439\n    for recipient in recipients:\n        try:\n            await context.bot.send_message(chat_id=recipient[0], text=message_text)\n        except Exception as e:\n            logger.error(f\"\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e {recipient[0]}: {e}\")\n\n    # \u041e\u0447\u0438\u0441\u0442\u043a\u0430 context\n    context.user_data['mailing_type'] = None\n    context.user_data['mailing_target'] = None\n    context.user_data['message_text'] = None\n\nasync def manage_notifications(update: Update, user_id):\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n    try:\n        c.execute(\"SELECT notifications FROM users WHERE id = ?\", (user_id,))\n        result = c.fetchone()\n        if result:\n            current_notifications = result[0].split(',')\n        else:\n            current_notifications = []\n\n        notification_map = {\n            'homework': '\ud83d\udcda \u0414\u043e\u043c\u0430\u0448\u043d\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435',\n            'changes': '\ud83d\udd04 \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0438',\n            'announcements': '\ud83d\udce2 \u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b',\n            'university': '\ud83c\udfeb \u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442\u0430'\n        }\n\n        buttons = []\n\n        for n_type, label in notification_map.items():\n            enabled = n_type in current_notifications\n            text = f\"{label}: {'\u2705' if enabled else '\u274c'}\"\n            buttons.append([InlineKeyboardButton(text, callback_data=f\"toggle_{n_type}\")])\n\n        buttons.append([InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data=\"personal_cabinet\")])\n\n        reply_markup = InlineKeyboardMarkup(buttons)\n        await update.callback_query.edit_message_text(\"\ud83d\udccc **\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0438\u043f\u044b \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439:**\", reply_markup=reply_markup, parse_mode='Markdown')\n    except sqlite3.Error as e:\n        logger.error(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f\u043c\u0438: {e}\")\n        await update.callback_query.edit_message_text(\"\u274c \u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f\u043c\u0438.\")\n    finally:\n        conn.close()\n\nasync def toggle_notification(update: Update, user_id, notification_type):\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n    try:\n        c.execute(\"SELECT notifications FROM users WHERE id = ?\", (user_id,))\n        result = c.fetchone()\n        if result:\n            current_notifications = result[0].split(',')\n        else:\n            current_notifications = []\n\n        if notification_type in current_notifications:\n            current_notifications.remove(notification_type)\n        else:\n            current_notifications.append(notification_type)\n\n        updated_notifications = ','.join(current_notifications)\n        c.execute(\"UPDATE users SET notifications = ? WHERE id = ?\", (updated_notifications, user_id))\n        conn.commit()\n    except sqlite3.Error as e:\n        logger.error(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f '{notification_type}': {e}\")\n        await update.callback_query.answer(\"\u274c \u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439.\", show_alert=True)\n        return\n    finally:\n        conn.close()\n    \n    await manage_notifications(update, user_id)\n\nasync def view_blocked_users(update: Update, context: CallbackContext, page_number=0):\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n    try:\n        c.execute(\n            \"SELECT username, id, blocked_until FROM users WHERE blocked_until IS NOT NULL AND blocked_until > datetime('now','localtime')\"\n        )\n        blocked_users = c.fetchall()\n    except sqlite3.Error as e:\n        logger.error(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439: {e}\")\n        await update.callback_query.edit_message_text(\"\u274c \u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.\")\n        return\n    finally:\n        conn.close()\n\n    items_per_page = 10\n    total_pages = (len(blocked_users) + items_per_page - 1) // items_per_page\n\n    if total_pages == 0:\n        await update.callback_query.edit_message_text(\"\ud83d\udd12 **\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442.**\")\n        return\n\n    if page_number < 0 or page_number >= total_pages:\n        await update.callback_query.edit_message_text(\"\u2757 \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043d\u043e\u043c\u0435\u0440 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.\")\n        return\n\n    start_index = page_number * items_per_page\n    end_index = min(start_index + items_per_page, len(blocked_users))\n\n    blocked_list = blocked_users[start_index:end_index]\n\n    message_text = f\"\ud83d\udd12 **\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 (\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 {page_number + 1}/{total_pages}):**\\n\\n\"\n    for i, user in enumerate(blocked_list, start=start_index + 1):\n        blocked_until = datetime.fromisoformat(user[2])\n        time_left = str(blocked_until - datetime.now()).split('.')[0]\n        message_text += f\"{i}. {user[0]} (@{user[1]})\\n\u0414\u043e \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438: {time_left}\\n\\n\"\n\n    buttons = [\n        [\n            InlineKeyboardButton(\"\u2b05\ufe0f \u041d\u0430\u0437\u0430\u0434\", callback_data=f\"page-{page_number - 1}\") if page_number > 0 else InlineKeyboardButton(\"\u2b05\ufe0f \u041d\u0430\u0437\u0430\u0434\", callback_data='noop'),\n            InlineKeyboardButton(f\"\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 {page_number + 1} \u0438\u0437 {total_pages}\", callback_data='noop'),\n            InlineKeyboardButton(\"\u0412\u043f\u0435\u0440\u0451\u0434 \u27a1\ufe0f\", callback_data=f\"page-{page_number + 1}\") if page_number + 1 < total_pages else InlineKeyboardButton(\"\u0412\u043f\u0435\u0440\u0451\u0434 \u27a1\ufe0f\", callback_data='noop'),\n        ],\n        [InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='blocking_menu')]\n    ]\n\n    reply_markup = InlineKeyboardMarkup(buttons)\n    await update.callback_query.edit_message_text(message_text.strip(), reply_markup=reply_markup, parse_mode='Markdown')\n\ndef is_teacher_user(user_id):\n    if user_id == MAIN_ADMIN_ID:\n        return True\n\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n    c.execute(\"SELECT 1 FROM teachers WHERE id = ?\", (user_id,))\n    result = c.fetchone()\n    conn.close()\n    return result is not None\n\nif __name__ == '__main__':\n    # \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430, \u0435\u0441\u043b\u0438 \u043e\u043d \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442\n    if not os.path.exists('config.ini'):\n        create_config_file()\n        print(\"\ud83d\udcc4 \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0439\u0442\u0435 config.ini \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u0442\u043e\u043a\u0435\u043d \u0431\u043e\u0442\u0430.\")\n        exit(1)\n\n    init_db()\n\n    # \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 application\n    application = ApplicationBuilder().token(TOKEN).build()\n\n    # \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043a\u043e\u043c\u0430\u043d\u0434 \u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439\n    application.add_handler(CommandHandler(\"start\", start))\n    application.add_handler(CallbackQueryHandler(handle_callback, pattern='^.*$'))\n    application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))\n    application.add_handler(MessageHandler(filters.TEXT & filters.Regex('^.*$'), collect_mailing_message))\n    application.add_handler(MessageHandler(filters.PHOTO, collect_mailing_message))\n    # \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n    application.add_handler(CallbackQueryHandler(handle_mailing_confirm, pattern='^(confirm_send_mailing|cancel_send_mailing)$'))\n    \n    # \u0417\u0430\u043f\u0443\u0441\u043a \u0431\u043e\u0442\u0430\n    application.run_polling()\n```\n\n### \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438\n\n1. **\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u0431\u043b\u043e\u043a\u043e\u0432 `try:`:**\n   \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0432\u0435\u0441\u044c \u0432\u0430\u0448 \u043a\u043e\u0434 \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0434\u0440\u0443\u0433\u0438\u0445 \u0431\u043b\u043e\u043a\u043e\u0432 `try:`, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0438\u043c\u0435\u044e\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 `except:` \u0438\u043b\u0438 `finally:`. \u0412\u0441\u0435 \u0431\u043b\u043e\u043a\u0438 `try:` \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u044b \u044d\u0442\u0438\u043c\u0438 \u0431\u043b\u043e\u043a\u0430\u043c\u0438.\n\n2. **\u041b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u0442\u043b\u0430\u0434\u043a\u0430:**\n   \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043b\u043e\u0433\u0438\u0440\u0443\u044e\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043b\u0435\u0433\u0447\u0438\u0442\u044c \u043e\u0442\u043b\u0430\u0434\u043a\u0443 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c.\n\n3. **\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435:**\n   \u041f\u043e\u0441\u043b\u0435 \u0432\u043d\u0435\u0441\u0435\u043d\u0438\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u0431\u043e\u0442\u0430 \u0432 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f\u0445, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0432\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0438 \u043e\u0448\u0438\u0431\u043a\u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e.\n\n4. **\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432:**\n   \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0438\u0437\u0431\u0435\u0436\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0442\u0438\u044f \u0438 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.\n\n\u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u0438\u043b\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u043c\u043e\u0449\u044c \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0447\u0430\u0441\u0442\u044f\u043c\u0438 \u043a\u043e\u0434\u0430, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0434\u0430\u0439\u0442\u0435 \u0437\u043d\u0430\u0442\u044c!","behavior":"degenerate_repetition","conversation_hash":"9ec3dd3c6056d280046687ddc6432dde","conversation_redacted":false,"conversation_toxic":false,"country":"Russia","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"o1-mini-2024-09-12","n_chars":85467,"n_turns_in_conversation":1,"n_words":6980,"source_row_offset":12476,"source_shard":"turns-00035.parquet","timestamp":"Wed, 16 Oct 2024 09:24:41 GMT","turn_id":"1b516f5c0bf130fdfcbda3e4","turn_index":0,"user_text":"\u0412\u043e\u0442 \u043e\u0448\u0438\u0431\u043a\u0430: Traceback (most recent call last):\n  File \"/data/user/0/ru.iiec.pydroid3/files/accomp_files/iiec_run/iiec_run.py\", line 31, in <module>    start(fakepyfile,mainpyfile)\n  File \"/data/user/0/ru.iiec.pydroid3/files/accomp_files/iiec_run/iiec_run.py\", line 30, in start\n    exec(open(mainpyfile).read(),  __main__.__dict__)\n  File \"<string>\", line 603\n    async def collect_mailing_message(update: Update, context: CallbackContext) -> None:\nSyntaxError: expected 'except' or 'finally' block\n\n[Program finished]. \u0412\u043e\u0442 \u043c\u043e\u0439 \u043a\u043e\u0434: import pytz\nimport sqlite3\nfrom datetime import datetime, timedelta\nfrom telegram import Update, ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton\nfrom telegram.ext import (\n    ApplicationBuilder,\n    CommandHandler,\n    CallbackContext,\n    MessageHandler,\n    filters,\n    CallbackQueryHandler,\n)\nimport configparser\nimport os\nimport logging\n\n# \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f\nlogging.basicConfig(\n    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO\n)\nlogger = logging.getLogger(__name__)\n\n# \u0427\u0442\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430\nconfig = configparser.ConfigParser()\nconfig.read('config.ini')\n\n# \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u0430 \u0438\u0437 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430\nTOKEN = config.get('Telegram', 'Token')\n\n# ID \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430\nMAIN_ADMIN_ID = 1108429314\n\ndef create_config_file():\n    config['Telegram'] = {'Token': 'your_bot_token_here'}\n    with open('config.ini', 'w') as configfile:\n        config.write(configfile)\n\ndef init_db():\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n\n    # \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b schedule\n    c.execute('''CREATE TABLE IF NOT EXISTS schedule\n                 (course INTEGER, direction TEXT, week_type TEXT, day TEXT, slot INTEGER, time TEXT, details TEXT)''')\n\n    # \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b users \u0441 \u043a\u043e\u043b\u043e\u043d\u043a\u043e\u0439 created_at\n    c.execute('''\n        CREATE TABLE IF NOT EXISTS users (\n            id INTEGER PRIMARY KEY,\n            username TEXT,\n            course INTEGER,\n            direction TEXT, \n            subscribed INTEGER DEFAULT 1, \n            notifications TEXT DEFAULT 'homework,changes,announcements,university',\n            blocked_until TEXT DEFAULT NULL,\n            created_at TEXT DEFAULT (datetime('now','localtime'))\n        )\n    ''')\n\n    # \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b teachers\n    c.execute('''CREATE TABLE IF NOT EXISTS teachers\n                 (id INTEGER PRIMARY KEY)''')\n\n    # \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u043f\u0440\u0435\u043f\u043e\u0434\u0430\u0432\u0430\u0442\u0435\u043b\u0435\u0439\n    c.execute(\"INSERT OR IGNORE INTO teachers (id) VALUES (?)\", (MAIN_ADMIN_ID,))\n\n    # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 created_at, \u0435\u0441\u043b\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0431\u0435\u0437 \u043d\u0435\u0451\n    c.execute(\"PRAGMA table_info(users)\")\n    columns = [info[1] for info in c.fetchall()]\n    if 'created_at' not in columns:\n        try:\n            c.execute(\"ALTER TABLE users ADD COLUMN created_at TEXT DEFAULT (datetime('now','localtime'))\")\n            conn.commit()\n            print(\"\u041a\u043e\u043b\u043e\u043d\u043a\u0430 'created_at' \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 'users'.\")\n        except sqlite3.OperationalError as e:\n            print(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 'created_at': {e}\")\n\n    # \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044f\n    c.execute(\"DELETE FROM schedule\")\n    times = [\"8:30 - 10:00\", \"10:10 - 11:40\", \"12:30 - 14:00\", \"14:10 - 15:40\", \"15:50 - 17:20\", \"17:30 - 19:00\"]\n    directions = ['\u0424', '\u0423', '\u0424\u041c', '\u0413\u041c\u0423', '\u0411\u0418']\n\n    schedule_bi = {\n        \"\u0447\u0451\u0442\u043d\u0430\u044f\": {\n            \"\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a\": [\"\u041c\u0430\u0442\u0435\u043c (\u043b) (222)\", \"\u041c\u0430\u0442\u0435\u043c (\u0441) (222)\", \"\u0424\u0438\u0437-\u0440\u0430\", \"\u0410\u043d\u0433\u043b (209)\", \"\", \"\"],\n            \"\u0412\u0442\u043e\u0440\u043d\u0438\u043a\": [\"\u0418\u0441\u0442\u043e\u0440\u0438\u044f (\u0441) (108)\", \"\u0418\u0441\u0442\u043e\u0440\u0438\u044f (\u043b) (108)\", \"\u0418\u0422\u041f\u0414 (\u0441) (217)\", \"\", \"\", \"\"],\n            \"\u0421\u0440\u0435\u0434\u0430\": [\"\", \"\", \"\", \"\u0418\u0422\u041f\u0414 (\u0441) (217)\", \"Phython (\u043b) (111)\", \"Phython (\u043b) (111)\"],\n            \"\u0427\u0435\u0442\u0432\u0435\u0440\u0433\": [\"\", \"\u0418\u0441\u0442\u043e\u0440\u0438\u044f (\u0441) (204)\", \"\u041c\u0435\u043d\u0435\u0434\u0436\u043c\u0435\u043d\u0442 (\u043b) (209)\", \"\", \"\", \"\"],\n            \"\u041f\u044f\u0442\u043d\u0438\u0446\u0430\": [\"\", \"\", \"\", \"\u0411\u0416\u0414 (\u043b) (304)\", \"\u041c\u0435\u043d\u0435\u0434\u0436\u043c\u0435\u043d\u0442 (\u0441) (108)\", \"\u0424\u0438\u0437-\u0440\u0430\"]\n        },\n        \"\u043d\u0435\u0447\u0451\u0442\u043d\u0430\u044f\": {\n            \"\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a\": [\"\u041c\u0430\u0442\u0435\u043c (\u043b) (222)\", \"\u041c\u0430\u0442\u0435\u043c (\u0441) (222)\", \"\u0424\u0438\u0437-\u0440\u0430\", \"\u0410\u043d\u0433\u043b (209)\", \"\", \"\"],\n            \"\u0412\u0442\u043e\u0440\u043d\u0438\u043a\": [\"\u0410\u043d\u0433\u043b (209)\", \"\u0418\u0441\u0442\u043e\u0440\u0438\u044f (\u043b) (108)\", \"\u0418\u0422\u041f\u0414 (\u0441) (217)\", \"\u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0424\u0423 (\u043b) (211)\", \"\", \"\"],\n            \"\u0421\u0440\u0435\u0434\u0430\": [\"\", \"\", \"\", \"\u0418\u0422\u041f\u0414 (\u0441) (217)\", \"\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 \u0441\u043f\u0435\u0446 (\u043b) (111)\", \"Phython (\u0441) (111)\"],\n            \"\u0427\u0435\u0442\u0432\u0435\u0440\u0433\": [\"\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 \u0441\u043f\u0435\u0446 (\u0441) (213)\", \"\u041c\u0430\u0442\u0435\u043c (\u0441) (204)\", \"\u0418\u0441\u0442\u043e\u0440\u0438\u044f (\u0441) (209)\", \"\", \"\", \"\"],\n            \"\u041f\u044f\u0442\u043d\u0438\u0446\u0430\": [\"\", \"\", \"\", \"\u0411\u0416\u0414 (\u0441) (304)\", \"\u041c\u0435\u043d\u0435\u0434\u0436\u043c\u0435\u043d\u0442 (\u0441) (108)\", \"\u0424\u0438\u0437-\u0440\u0430\"]\n        }\n    }\n\n    for course in range(1, 5):\n        for direction in directions:\n            schedule_data = {\n                \"\u0447\u0451\u0442\u043d\u0430\u044f\": {day: [\"\"] * 6 for day in [\"\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a\", \"\u0412\u0442\u043e\u0440\u043d\u0438\u043a\", \"\u0421\u0440\u0435\u0434\u0430\", \"\u0427\u0435\u0442\u0432\u0435\u0440\u0433\", \"\u041f\u044f\u0442\u043d\u0438\u0446\u0430\", \"\u0421\u0443\u0431\u0431\u043e\u0442\u0430\"]},\n                \"\u043d\u0435\u0447\u0451\u0442\u043d\u0430\u044f\": {day: [\"\"] * 6 for day in [\"\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a\", \"\u0412\u0442\u043e\u0440\u043d\u0438\u043a\", \"\u0421\u0440\u0435\u0434\u0430\", \"\u0427\u0435\u0442\u0432\u0435\u0440\u0433\", \"\u041f\u044f\u0442\u043d\u0438\u0446\u0430\", \"\u0421\u0443\u0431\u0431\u043e\u0442\u0430\"]}\n            }\n\n            if direction == '\u0411\u0418' and course == 1:\n                schedule_data = schedule_bi\n            else:\n                for week_type, days in schedule_data.items():\n                    for day in days:\n                        days[day][0] = f\"\u041a\u0443\u0440\u0441 {course}, \u0413\u0440\u0443\u043f\u043f\u0430 {direction}\"\n\n            for week_type, days in schedule_data.items():\n                for day, slots in days.items():\n                    for slot in range(6):\n                        time = times[slot]\n                        detail = slots[slot]\n                        c.execute(\n                            \"INSERT INTO schedule (course, direction, week_type, day, slot, time, details) VALUES (?, ?, ?, ?, ?, ?, ?)\",\n                            (course, direction, week_type, day, slot + 1, time, detail)\n                        )\n\n    conn.commit()\n    conn.close()\n\ndef get_day_name(index):\n    days_rus = [\n        \"\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a\",\n        \"\u0412\u0442\u043e\u0440\u043d\u0438\u043a\",\n        \"\u0421\u0440\u0435\u0434\u0430\",\n        \"\u0427\u0435\u0442\u0432\u0435\u0440\u0433\",\n        \"\u041f\u044f\u0442\u043d\u0438\u0446\u0430\",\n        \"\u0421\u0443\u0431\u0431\u043e\u0442\u0430\",\n        \"\u0412\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435\"\n    ]\n    return days_rus[index]\n\ndef is_even_week(date):\n    week_number = date.isocalendar()[1]\n    return week_number % 2 == 0\n\ndef get_week_type(date):\n    return '\u0447\u0451\u0442\u043d\u0430\u044f' if is_even_week(date) else '\u043d\u0435\u0447\u0451\u0442\u043d\u0430\u044f'\n\ndef get_week_type_short(date):\n    return '\u0447\u0451\u0442' if is_even_week(date) else '\u043d\u0435\u0447\u0451\u0442'\n\ndef get_schedule_for_day(course, direction, day_name, date):\n    week_type = get_week_type(date)\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n\n    c.execute(\n        \"SELECT slot, time, details FROM schedule WHERE course = ? AND direction = ? AND week_type = ? AND day = ? ORDER BY slot\",\n        (course, direction, week_type, day_name)\n    )\n    results = c.fetchall()\n    conn.close()\n\n    if not results:\n        return \"\u274c \u041d\u0435\u0442 \u0437\u0430\u043d\u044f\u0442\u0438\u0439\"\n\n    day_schedule = \"\"\n    for slot, time, details in results:\n        if details:\n            day_schedule += f\"{slot}. {time}\\n{details}\\n\\n\"\n\n    return day_schedule.strip() if day_schedule else \"\u274c \u041d\u0435\u0442 \u0437\u0430\u043d\u044f\u0442\u0438\u0439\"\n\nasync def start(update: Update, context: CallbackContext) -> None:\n    user_id = update.effective_user.id\n\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n    c.execute(\"SELECT blocked_until FROM users WHERE id=?\", (user_id,))\n    blocked_until = c.fetchone()\n\n    if blocked_until and blocked_until[0]:\n        blocked_until_date = datetime.fromisoformat(blocked_until[0])\n        if blocked_until_date > datetime.now():\n            await update.message.reply_text(f\"\u274c \u0412\u044b \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u044b! \u0414\u043e \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 {blocked_until_date}.\")\n            conn.close()\n            return\n\n    conn.close()\n\n    # \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043c\u0435\u043d\u044e\n    keyboard = [\n        [\"\ud83d\uddd3 \u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0434\u0430\u0442\u0443 \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044f\", \"\ud83d\udcc5 \u0420\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043d\u0430 \u0437\u0430\u0432\u0442\u0440\u0430\", \"\ud83d\udcc5 \u0420\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\"],\n        [\"\ud83d\udcc6 \u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a\", \"\ud83d\udcc6 \u0412\u0442\u043e\u0440\u043d\u0438\u043a\", \"\ud83d\udcc6 \u0421\u0440\u0435\u0434\u0430\"],\n        [\"\ud83d\udcc6 \u0427\u0435\u0442\u0432\u0435\u0440\u0433\", \"\ud83d\udcc6 \u041f\u044f\u0442\u043d\u0438\u0446\u0430\", \"\ud83d\udcc6 \u0421\u0443\u0431\u0431\u043e\u0442\u0430\"],\n        [\"\ud83d\udc64 \u041b\u0438\u0447\u043d\u044b\u0439 \u043a\u0430\u0431\u0438\u043d\u0435\u0442\"]\n    ]\n    reply_markup = ReplyKeyboardMarkup(keyboard, one_time_keyboard=True, resize_keyboard=True)\n    \n    # \u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u043c\u0435\u043d\u044e\n    await update.message.reply_text(\n        '\ud83d\udc4b \u041f\u0440\u0438\u0432\u0435\u0442! \u041f\u043e\u043c\u0435\u043d\u044f\u0439 \u0433\u0440\u0443\u043f\u043f\u0443 \u0438 \u043a\u0443\u0440\u0441 \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0432 \u0441\u0432\u043e\u0451\u043c \u043b\u0438\u0447\u043d\u043e\u043c \u043a\u0430\u0431\u0438\u043d\u0435\u0442\u0435.',\n        reply_markup=reply_markup\n    )\n    \n    # \u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043b\u0438\u0447\u043d\u043e\u0433\u043e \u043a\u0430\u0431\u0438\u043d\u0435\u0442\u0430\n    await personal_cabinet(update, context)\n\nasync def handle_message(update: Update, context: CallbackContext) -> None:\n    user_id = update.message.from_user.id\n    user_message = update.message.text.strip().lower()\n\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n    c.execute(\"SELECT blocked_until FROM users WHERE id=?\", (user_id,))\n    blocked_until = c.fetchone()\n\n    if blocked_until and blocked_until[0]:\n        blocked_until_date = datetime.fromisoformat(blocked_until[0])\n        if blocked_until_date > datetime.now():\n            await update.message.reply_text(f\"\u274c \u0412\u044b \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u044b! \u0414\u043e \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 {blocked_until_date}.\")\n            conn.close()\n            return\n\n    # \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439\n    if context.user_data.get('action') == 'promote_admin':\n        try:\n            promote_id = int(user_message)\n            c.execute(\"SELECT id FROM users WHERE id = ?\", (promote_id,))\n            if not c.fetchone():\n                await update.message.reply_text(\"\u274c \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0442\u0430\u043a\u0438\u043c ID \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d.\")\n            else:\n                c.execute(\"INSERT OR IGNORE INTO teachers (id) VALUES (?)\", (promote_id,))\n                conn.commit()\n                await update.message.reply_text(f\"\u2705 \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 ID {promote_id} \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u043c.\")\n        except ValueError:\n            await update.message.reply_text(\"\u274c \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 ID. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 ID \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.\")\n        except sqlite3.Error as e:\n            logger.error(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430: {e}\")\n            await update.message.reply_text(\"\u274c \u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430.\")\n        finally:\n            conn.close()\n            context.user_data['action'] = None\n        return\n\n    if context.user_data.get('action') == 'demote_admin':\n        try:\n            demote_id = int(user_message)\n            if demote_id == MAIN_ADMIN_ID:\n                await update.message.reply_text(\"\u274c \u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430.\")\n            else:\n                c.execute(\"SELECT id FROM teachers WHERE id = ?\", (demote_id,))\n                if not c.fetchone():\n                    await update.message.reply_text(\"\u274c \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0442\u0430\u043a\u0438\u043c ID \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u043c.\")\n                else:\n                    c.execute(\"DELETE FROM teachers WHERE id = ?\", (demote_id,))\n                    conn.commit()\n                    await update.message.reply_text(f\"\u2705 \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 ID {demote_id} \u0443\u0434\u0430\u043b\u0435\u043d \u0438\u0437 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u0432.\")\n        except ValueError:\n            await update.message.reply_text(\"\u274c \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 ID. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 ID \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.\")\n        except sqlite3.Error as e:\n            logger.error(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430: {e}\")\n            await update.message.reply_text(\"\u274c \u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430.\")\n        finally:\n            conn.close()\n            context.user_data['action'] = None\n        return\n\n    if context.user_data.get('action') == 'block_user':\n        try:\n            block_id = int(user_message)\n            c.execute(\"SELECT id FROM users WHERE id = ?\", (block_id,))\n            if not c.fetchone():\n                await update.message.reply_text(\"\u274c \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0442\u0430\u043a\u0438\u043c ID \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d.\")\n            else:\n                # \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u043d\u0430 24 \u0447\u0430\u0441\u0430\n                block_until = datetime.now() + timedelta(hours=24)\n                c.execute(\"UPDATE users SET blocked_until = ? WHERE id = ?\", (block_until.isoformat(), block_id))\n                conn.commit()\n                await update.message.reply_text(f\"\ud83d\udd12 \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 ID {block_id} \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d \u0434\u043e {block_until}.\")\n        except ValueError:\n            await update.message.reply_text(\"\u274c \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 ID. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 ID \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.\")\n        except sqlite3.Error as e:\n            logger.error(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f: {e}\")\n            await update.message.reply_text(\"\u274c \u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.\")\n        finally:\n            conn.close()\n            context.user_data['action'] = None\n        return\n\n    if context.user_data.get('action') == 'unblock_user':\n        try:\n            unblock_id = int(user_message)\n            if unblock_id == MAIN_ADMIN_ID:\n                await update.message.reply_text(\"\u274c \u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430.\")\n                conn.close()\n                context.user_data['action'] = None\n                return\n\n            c.execute(\"SELECT id FROM users WHERE id = ? AND blocked_until IS NOT NULL\", (unblock_id,))\n            if not c.fetchone():\n                await update.message.reply_text(\"\u274c \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0442\u0430\u043a\u0438\u043c ID \u043d\u0435 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d.\")\n            else:\n                c.execute(\"UPDATE users SET blocked_until = NULL WHERE id = ?\", (unblock_id,))\n                conn.commit()\n                await update.message.reply_text(f\"\ud83d\udd13 \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 ID {unblock_id} \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d.\")\n        except ValueError:\n            await update.message.reply_text(\"\u274c \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 ID. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 ID \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.\")\n        except sqlite3.Error as e:\n            logger.error(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f: {e}\")\n            await update.message.reply_text(\"\u274c \u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.\")\n        finally:\n            conn.close()\n            context.user_data['action'] = None\n        return\n\n    conn.close()\n\n    # \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439\n    logger.info(f\"Received message: {user_message}\")\n\n    if context.user_data.get('awaiting_date', False):\n        if user_message.isdigit():\n            day = int(user_message)\n            current_month = datetime.now(pytz.timezone('Asia/Omsk')).month\n            current_year = datetime.now(pytz.timezone('Asia/Omsk')).year\n            try:\n                date_obj = datetime(current_year, current_month, day, tzinfo=pytz.timezone('Asia/Omsk'))\n                if date_obj.month != current_month:\n                    raise ValueError\n                await show_schedule_by_date(update, context, date_obj)\n            except ValueError:\n                await update.message.reply_text('\u274c \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0434\u0435\u043d\u044c. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438 \u0447\u0438\u0441\u043b\u043e \u043e\u0442 1 \u0434\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0434\u043d\u044f \u043c\u0435\u0441\u044f\u0446\u0430.')\n            finally:\n                context.user_data['awaiting_date'] = False\n        else:\n            await update.message.reply_text('\u274c \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438 \u0447\u0438\u0441\u043b\u043e \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044f.')\n        return\n\n    if user_message in [\"\u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\", \"\u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043d\u0430 \u0437\u0430\u0432\u0442\u0440\u0430\", \"\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a\", \"\u0432\u0442\u043e\u0440\u043d\u0438\u043a\", \"\u0441\u0440\u0435\u0434\u0430\", \"\u0447\u0435\u0442\u0432\u0435\u0440\u0433\", \"\u043f\u044f\u0442\u043d\u0438\u0446\u0430\", \"\u0441\u0443\u0431\u0431\u043e\u0442\u0430\"]:\n        await show_schedule(update, context, user_message)\n    elif user_message == \"\u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0434\u0430\u0442\u0443 \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044f\":\n        logger.info(\"User chose to select a specific date for schedule\")\n        context.user_data['awaiting_date'] = True\n        await update.message.reply_text(\"\ud83d\uddd3 \u0412\u0432\u0435\u0434\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0441\u044f\u0446\u0430:\")\n    elif user_message == \"\u043b\u0438\u0447\u043d\u044b\u0439 \u043a\u0430\u0431\u0438\u043d\u0435\u0442\":\n        logger.info(\"User accessing personal cabinet\")\n        await personal_cabinet(update, context)\n    else:\n        logger.warning(f\"Unrecognized menu option: {user_message}\")\n        await update.message.reply_text('\u2753 \u0412\u044b\u0431\u0435\u0440\u0438 \u043e\u043f\u0446\u0438\u044e \u0438\u0437 \u043c\u0435\u043d\u044e.')\n\nasync def personal_cabinet(update: Update, context: CallbackContext):\n    user_id = update.effective_user.id\n    username = update.effective_user.username or \"\"\n    first_name = update.effective_user.first_name or \"\"\n    last_name = update.effective_user.last_name or \"\"\n\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n\n    # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445\n    c.execute(\n        \"SELECT username, course, direction, subscribed, notifications FROM users WHERE id = ?\",\n        (user_id,)\n    )\n    user = c.fetchone()\n\n    # \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0435\u0441\u043b\u0438 \u043e\u043d \u0435\u0449\u0451 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442\n    if not user:\n        current_time = datetime.now(pytz.timezone('Asia/Omsk')).isoformat()\n        c.execute(\n            \"INSERT INTO users (id, username, course, direction, created_at) VALUES (?, ?, ?, ?, ?)\",\n            (user_id, username, 1, \"\u0424\", current_time)\n        )\n        conn.commit()\n        user = (username, 1, \"\u0424\", 1, 'homework,changes,announcements,university')\n\n    # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f ID \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 teachers, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0435\u0433\u043e \u0442\u0430\u043c \u043d\u0435\u0442\n    c.execute(\"SELECT 1 FROM teachers WHERE id = ?\", (user_id,))\n    is_teacher = c.fetchone() is not None\n\n    if user_id == MAIN_ADMIN_ID and not is_teacher:\n        c.execute(\"INSERT INTO teachers (id) VALUES (?)\", (user_id,))\n        conn.commit()\n        is_teacher = True\n\n    conn.close()\n\n    current_date = datetime.now(pytz.timezone('Asia/Omsk'))\n    week_number = current_date.isocalendar()[1]\n    week_type = get_week_type(current_date)\n    week_status = f\"{week_number} {week_type}\"\n\n    role = \"\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\" if is_teacher else \"\u0421\u0442\u0443\u0434\u0435\u043d\u0442\"\n\n    message_text = (\n        f\"\ud83d\udc64 **\u041b\u0438\u0447\u043d\u044b\u0439 \u043a\u0430\u0431\u0438\u043d\u0435\u0442**\\n\\n\"\n        f\"**\u0418\u043c\u044f:** {first_name} {last_name}\\n\"\n        f\"**\u041d\u0438\u043a:** @{user[0]}\\n\"\n        f\"**ID:** `{user_id}`\\n\\n\"\n        f\"**\u0420\u043e\u043b\u044c:** {role}\\n\"\n        f\"**\u0413\u0440\u0443\u043f\u043f\u0430:** {user[2]}\\n\"\n        f\"**\u041a\u0443\u0440\u0441:** {user[1]}\\n\\n\"\n        f\"**\u041d\u0435\u0434\u0435\u043b\u044f:** {week_status}\\n\"\n        f\"**\u0414\u0430\u0442\u0430:** {current_date.strftime('%d.%m.%Y')}\\n\"\n        f\"**\u0412\u0440\u0435\u043c\u044f:** {current_date.strftime('%H:%M:%S')}\\n\"\n    )\n\n    buttons = [\n        [\n            InlineKeyboardButton(\"\ud83d\udd04 \u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0433\u0440\u0443\u043f\u043f\u0443\", callback_data='change_direction'),\n            InlineKeyboardButton(\"\ud83d\udd04 \u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043a\u0443\u0440\u0441\", callback_data='change_course')\n        ],\n        [InlineKeyboardButton(\"\ud83d\udd14 \u0423\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f\", callback_data='manage_notifications')]\n    ]\n\n    if is_teacher:\n        buttons.append([InlineKeyboardButton(\"\ud83d\udd27 \u0414\u043b\u044f \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u0432\", callback_data='admin_panel')])\n\n    reply_markup = InlineKeyboardMarkup(buttons)\n\n    if update.callback_query:\n        await update.callback_query.edit_message_text(\n            text=message_text,\n            reply_markup=reply_markup,\n            parse_mode='Markdown'\n        )\n    else:\n        await update.message.reply_text(\n            text=message_text,\n            reply_markup=reply_markup,\n            parse_mode='Markdown'\n        )\n\nasync def admin_panel(update: Update, context: CallbackContext):\n    query = update.callback_query\n    user_id = query.from_user.id\n\n    logger.info(f\"Accessing admin panel - User ID: {user_id}\")\n\n    if not is_teacher_user(user_id):\n        await query.answer(\"\u274c \u041d\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0430!\", show_alert=True)\n        return\n\n    buttons = [\n        [InlineKeyboardButton(\"\ud83d\udcc8 \u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430\", callback_data='show_statistics')],\n        [InlineKeyboardButton(\"\ud83d\udce2 \u0420\u0430\u0441\u0441\u044b\u043b\u043a\u0438\", callback_data='announcements_menu')],\n        [InlineKeyboardButton(\"\ud83d\udd12 \u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438\", callback_data='blocking_menu')]\n    ]\n\n    if user_id == MAIN_ADMIN_ID:\n        buttons.append([InlineKeyboardButton(\"\u2795 \u041d\u0430\u0437\u043d\u0430\u0447\u0438\u0442\u044c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430\", callback_data='promote_admin')])\n        buttons.append([InlineKeyboardButton(\"\u2796 \u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430\", callback_data='demote_admin')])\n\n    # \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u043d\u043e\u043f\u043a\u0443 \"\u041d\u0430\u0437\u0430\u0434\" \u0434\u043b\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0432 \u043b\u0438\u0447\u043d\u044b\u0439 \u043a\u0430\u0431\u0438\u043d\u0435\u0442\n    buttons.append([InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='personal_cabinet')])\n\n    reply_markup = InlineKeyboardMarkup(buttons)\n    await query.edit_message_text(text=\"\ud83d\udd27 **\u0414\u043b\u044f \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u0432:**\", reply_markup=reply_markup, parse_mode='Markdown')\n\nasync def handle_callback(update: Update, context: CallbackContext):\n    query = update.callback_query\n    user_id = query.from_user.id\n    data = query.data\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n\n    try:\n        if data == 'change_course':\n            c.execute(\"SELECT course FROM users WHERE id = ?\", (user_id,))\n            result = c.fetchone()\n            if result:\n                current_course = result[0]\n                new_course = 1 if current_course == 4 else current_course + 1\n                c.execute(\"UPDATE users SET course = ? WHERE id = ?\", (new_course, user_id))\n                conn.commit()\n                await query.answer(f\"\u2705 \u041a\u0443\u0440\u0441 \u0438\u0437\u043c\u0435\u043d\u0451\u043d \u043d\u0430 {new_course}\")\n                await personal_cabinet(update, context)\n            else:\n                await query.answer(\"\u274c \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d.\")\n\n        elif data == 'change_direction':\n            c.execute(\"SELECT direction FROM users WHERE id = ?\", (user_id,))\n            result = c.fetchone()\n            if result:\n                current_direction = result[0]\n                directions = ['\u0424', '\u0423', '\u0424\u041c', '\u0413\u041c\u0423', '\u0411\u0418']\n                try:\n                    new_direction_index = (directions.index(current_direction) + 1) % len(directions)\n                    new_direction = directions[new_direction_index]\n                    c.execute(\"UPDATE users SET direction = ? WHERE id = ?\", (new_direction, user_id))\n                    conn.commit()\n                    await query.answer(f\"\u2705 \u0413\u0440\u0443\u043f\u043f\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0430 \u043d\u0430 {new_direction}\")\n                    await personal_cabinet(update, context)\n                except ValueError:\n                    await query.answer(\"\u274c \u041d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u0430\u044f \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0430.\")\n            else:\n                await query.answer(\"\u274c \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d.\")\n\n        elif data.startswith(\"toggle_\"):\n            notification_type = data.split(\"_\")[1]\n            await toggle_notification(update, user_id, notification_type)\n\n        elif data == 'manage_notifications':\n            await manage_notifications(update, user_id)\n\n        elif data == 'admin_panel':\n            await admin_panel(update, context)\n\n        elif data == 'show_statistics' and is_teacher_user(user_id):\n            await show_statistics(update, context)\n\n        # \u041c\u0435\u043d\u044e \u0440\u0430\u0441\u0441\u044b\u043b\u043e\u043a\n        elif data == 'announcements_menu' and is_teacher_user(user_id):\n            # \u041c\u0435\u043d\u044e \u0440\u0430\u0441\u0441\u044b\u043b\u043e\u043a\n            buttons = [\n                [InlineKeyboardButton(\"\ud83d\udce4 \u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0443\", callback_data='send_announcement')],\n                [InlineKeyboardButton(\"\ud83d\uddc2 \u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0430\u044f \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0430\", callback_data='send_global_announcement')],\n                [InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='admin_panel')]\n            ]\n            reply_markup = InlineKeyboardMarkup(buttons)\n            await query.edit_message_text(text=\"\ud83d\udce2 **\u041c\u0435\u043d\u044e \u0440\u0430\u0441\u0441\u044b\u043b\u043e\u043a:**\", reply_markup=reply_markup, parse_mode='Markdown')\n\n        # \u041d\u0430\u0447\u0430\u043b\u043e \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n        elif data == 'send_announcement' and is_teacher_user(user_id):\n            # \u0412\u044b\u0431\u043e\u0440 \u0442\u0438\u043f\u0430 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n            buttons = [\n                [InlineKeyboardButton(\"\ud83d\udcda \u0414\u043e\u043c\u0430\u0448\u043d\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435\", callback_data='mailing_homework')],\n                [InlineKeyboardButton(\"\ud83d\udd04 \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0438\", callback_data='mailing_changes')],\n                [InlineKeyboardButton(\"\ud83d\udce2 \u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b\", callback_data='mailing_announcements')],\n                [InlineKeyboardButton(\"\ud83c\udfeb \u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442\u0430\", callback_data='mailing_university')],\n                [InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='announcements_menu')]\n            ]\n            reply_markup = InlineKeyboardMarkup(buttons)\n            await query.edit_message_text(text=\"\ud83d\udce4 **\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0438\u043f \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438:**\", reply_markup=reply_markup, parse_mode='Markdown')\n\n        # \u0412\u044b\u0431\u043e\u0440 \u0442\u0438\u043f\u0430 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u0434\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u043e\u0432\u043e\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438\n        elif data.startswith('mailing_') and not data.startswith('mailing_target'):\n            mailing_type = data.split('_')[1]\n            context.user_data['mailing_type'] = mailing_type\n            # \u0412\u044b\u0431\u043e\u0440 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0438\n            buttons = [\n                [InlineKeyboardButton(\"\ud83d\udcc6 \u041f\u043e \u043a\u0443\u0440\u0441\u0443 \u0438 \u0433\u0440\u0443\u043f\u043f\u0435\", callback_data='mailing_target_group')],\n                [InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='send_announcement')]\n            ]\n            reply_markup = InlineKeyboardMarkup(buttons)\n            await query.edit_message_text(text=f\"\ud83d\udce4 **\u0412\u044b\u0431\u0440\u0430\u043d\u043e: {mailing_type.capitalize()}**\\n\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0446\u0435\u043b\u0435\u0432\u0443\u044e \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u044e \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438:\", reply_markup=reply_markup, parse_mode='Markdown')\n\n        elif data == 'mailing_target_group' and is_teacher_user(user_id):\n            # \u0417\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n            await query.edit_message_text(\"\ud83d\udcdd **\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u0432\u0430\u0448\u0435\u0439 \u0433\u0440\u0443\u043f\u043f\u0435:**\")\n            context.user_data['awaiting_mailing_message'] = True\n\n        elif data == 'send_global_announcement' and is_teacher_user(user_id):\n            # \u0412\u044b\u0431\u043e\u0440 \u0442\u0438\u043f\u0430 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n            buttons = [\n                [InlineKeyboardButton(\"\ud83d\udcda \u0414\u043e\u043c\u0430\u0448\u043d\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435\", callback_data='global_mailing_homework')],\n                [InlineKeyboardButton(\"\ud83d\udd04 \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0438\", callback_data='global_mailing_changes')],\n                [InlineKeyboardButton(\"\ud83d\udce2 \u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b\", callback_data='global_mailing_announcements')],\n                [InlineKeyboardButton(\"\ud83c\udfeb \u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442\u0430\", callback_data='global_mailing_university')],\n                [InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='announcements_menu')]\n            ]\n            reply_markup = InlineKeyboardMarkup(buttons)\n            await query.edit_message_text(text=\"\ud83d\uddc2 **\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0438\u043f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438:**\", reply_markup=reply_markup, parse_mode='Markdown')\n\n        # \u0412\u044b\u0431\u043e\u0440 \u0442\u0438\u043f\u0430 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u0434\u043b\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438\n        elif data.startswith('global_mailing_') and is_teacher_user(user_id):\n            mailing_type = data.split('_')[2]\n            context.user_data['mailing_type'] = mailing_type\n            context.user_data['mailing_target'] = 'global'\n            # \u0417\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n            await query.edit_message_text(\"\ud83d\udcdd **\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438:**\")\n            context.user_data['awaiting_mailing_message'] = True\n\n        # \u041c\u0435\u043d\u044e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a\n        elif data == 'blocking_menu' and is_teacher_user(user_id):\n            # \u041c\u0435\u043d\u044e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a\n            buttons = [\n                [InlineKeyboardButton(\"\ud83d\udd12 \u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\", callback_data='block_user')],\n                [InlineKeyboardButton(\"\ud83d\udd13 \u0420\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\", callback_data='unblock_user')],\n                [InlineKeyboardButton(\"\ud83d\udc64 \u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439\", callback_data='view_blocked_users')],\n                [InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='admin_panel')]\n            ]\n            reply_markup = InlineKeyboardMarkup(buttons)\n            await query.edit_message_text(text=\"\ud83d\udd12 **\u041c\u0435\u043d\u044e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043e\u043a:**\", reply_markup=reply_markup, parse_mode='Markdown')\n\n        # \u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439\n        elif data == 'view_blocked_users' and is_teacher_user(user_id):\n            await view_blocked_users(update, context)\n\n        elif data.startswith('page-') and is_teacher_user(user_id):\n            # \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0438 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439\n            try:\n                page_number = int(data.split('-')[1])\n                await view_blocked_users(update, context, page_number=page_number)\n            except (IndexError, ValueError):\n                await query.answer(\"\u274c \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043d\u043e\u043c\u0435\u0440 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.\", show_alert=True)\n\n        elif data == 'personal_cabinet' or data == 'back_to_admin':\n            await personal_cabinet(update, context)\n\n        else:\n            await query.answer(\"\u2753 \u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430.\", show_alert=True)\n\nasync def collect_mailing_message(update: Update, context: CallbackContext) -> None:\n    user_id = update.message.from_user.id\n    if not is_teacher_user(user_id) or not context.user_data.get('awaiting_mailing_message', False):\n        return\n\n    mailing_type = context.user_data.get('mailing_type')\n    mailing_target = context.user_data.get('mailing_target', 'group')\n    message_text = update.message.text\n\n    if not message_text:\n        await update.message.reply_text(\"\u274c \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c.\")\n        return\n\n    context.user_data['message_text'] = message_text\n    context.user_data['awaiting_mailing_message'] = False\n\n    confirm_message = f\"\ud83d\udcdd **\u0412\u043e\u0442 \u0432\u0430\u0448 \u0442\u0435\u043a\u0441\u0442:**\\n\\n{message_text}\\n\\n\ud83d\udce4 \u0425\u043e\u0442\u0438\u0442\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c?\"\n    buttons = [\n        [\n            InlineKeyboardButton(\"\u2705 \u0414\u0430\", callback_data='confirm_send_mailing'),\n            InlineKeyboardButton(\"\u274c \u041d\u0435\u0442\", callback_data='cancel_send_mailing')\n        ]\n    ]\n    reply_markup = InlineKeyboardMarkup(buttons)\n\n    await update.message.reply_text(confirm_message, reply_markup=reply_markup, parse_mode='Markdown')\n\nasync def handle_mailing_confirm(update: Update, context: CallbackContext) -> None:\n    query = update.callback_query\n    user_id = query.from_user.id\n    data = query.data\n\n    if data == 'confirm_send_mailing':\n        await send_mailing(update, context)\n        await query.edit_message_text(\"\u2705 \u0420\u0430\u0441\u0441\u044b\u043b\u043a\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430.\")\n    elif data == 'cancel_send_mailing':\n        await query.edit_message_text(\"\u274c \u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u0430.\")\n    else:\n        await query.answer(\"\u2753 \u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430.\")\n\nasync def send_mailing(update: Update, context: CallbackContext) -> None:\n    mailing_type = context.user_data.get('mailing_type')\n    mailing_target = context.user_data.get('mailing_target', 'group')\n    message_text = context.user_data.get('message_text')\n\n    if not mailing_type or not message_text:\n        return\n\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n\n    try:\n        if mailing_target == 'global':\n            # \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u0442\u0438\u043f \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n            c.execute(\"SELECT id FROM users WHERE subscribed = 1 AND notifications LIKE ?\", (f'%{mailing_type}%',))\n            users = c.fetchall()\n            # \u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u0432\n            c.execute(\"SELECT id FROM teachers\")\n            admins = c.fetchall()\n            recipients = set(users) | set(admins)\n        elif mailing_target == 'group':\n            # \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043a\u0443\u0440\u0441 \u0438 \u0433\u0440\u0443\u043f\u043f\u0443 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044f\n            c.execute(\"SELECT course, direction FROM users WHERE id = ?\", (update.effective_user.id,))\n            user_info = c.fetchone()\n            if not user_info:\n                logger.error(\"\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u0434\u043b\u044f \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u043f\u043e \u0433\u0440\u0443\u043f\u043f\u0435.\")\n                return\n            course, direction = user_info\n            c.execute(\"SELECT id FROM users WHERE course = ? AND direction = ? AND subscribed = 1 AND notifications LIKE ?\", \n                      (course, direction, f'%{mailing_type}%'))\n            users = c.fetchall()\n            # \u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u0432\n            c.execute(\"SELECT id FROM teachers\")\n            admins = c.fetchall()\n            recipients = set(users) | set(admins)\n        else:\n            logger.error(f\"\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u0442\u0438\u043f \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0438 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438: {mailing_target}\")\n            return\n\n    except sqlite3.Error as e:\n        logger.error(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u0435\u0439 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438: {e}\")\n        return\n    finally:\n        conn.close()\n\n    # \u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439\n    for recipient in recipients:\n        try:\n            await context.bot.send_message(chat_id=recipient[0], text=message_text)\n        except Exception as e:\n            logger.error(f\"\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e {recipient[0]}: {e}\")\n\n    # \u041e\u0447\u0438\u0441\u0442\u043a\u0430 context\n    context.user_data['mailing_type'] = None\n    context.user_data['mailing_target'] = None\n    context.user_data['message_text'] = None\n\nasync def manage_notifications(update: Update, user_id):\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n    try:\n        c.execute(\"SELECT notifications FROM users WHERE id = ?\", (user_id,))\n        result = c.fetchone()\n        if result:\n            current_notifications = result[0].split(',')\n        else:\n            current_notifications = []\n\n        notification_map = {\n            'homework': '\ud83d\udcda \u0414\u043e\u043c\u0430\u0448\u043d\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435',\n            'changes': '\ud83d\udd04 \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0438',\n            'announcements': '\ud83d\udce2 \u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b',\n            'university': '\ud83c\udfeb \u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442\u0430'\n        }\n\n        buttons = []\n\n        for n_type, label in notification_map.items():\n            enabled = n_type in current_notifications\n            text = f\"{label}: {'\u2705' if enabled else '\u274c'}\"\n            buttons.append([InlineKeyboardButton(text, callback_data=f\"toggle_{n_type}\")])\n\n        buttons.append([InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data=\"personal_cabinet\")])\n\n        reply_markup = InlineKeyboardMarkup(buttons)\n        await update.callback_query.edit_message_text(\"\ud83d\udccc **\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0438\u043f\u044b \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439:**\", reply_markup=reply_markup, parse_mode='Markdown')\n    except sqlite3.Error as e:\n        logger.error(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f\u043c\u0438: {e}\")\n        await update.callback_query.edit_message_text(\"\u274c \u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f\u043c\u0438.\")\n    finally:\n        conn.close()\n\nasync def toggle_notification(update: Update, user_id, notification_type):\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n    try:\n        c.execute(\"SELECT notifications FROM users WHERE id = ?\", (user_id,))\n        result = c.fetchone()\n        if result:\n            current_notifications = result[0].split(',')\n        else:\n            current_notifications = []\n\n        if notification_type in current_notifications:\n            current_notifications.remove(notification_type)\n        else:\n            current_notifications.append(notification_type)\n\n        updated_notifications = ','.join(current_notifications)\n        c.execute(\"UPDATE users SET notifications = ? WHERE id = ?\", (updated_notifications, user_id))\n        conn.commit()\n    except sqlite3.Error as e:\n        logger.error(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f '{notification_type}': {e}\")\n        await update.callback_query.answer(\"\u274c \u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439.\", show_alert=True)\n        return\n    finally:\n        conn.close()\n    \n    await manage_notifications(update, user_id)\n\nasync def view_blocked_users(update: Update, context: CallbackContext, page_number=0):\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n    try:\n        c.execute(\n            \"SELECT username, id, blocked_until FROM users WHERE blocked_until IS NOT NULL AND blocked_until > datetime('now','localtime')\"\n        )\n        blocked_users = c.fetchall()\n    except sqlite3.Error as e:\n        logger.error(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439: {e}\")\n        await update.callback_query.edit_message_text(\"\u274c \u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.\")\n        return\n    finally:\n        conn.close()\n\n    items_per_page = 10\n    total_pages = (len(blocked_users) + items_per_page - 1) // items_per_page\n\n    if total_pages == 0:\n        await update.callback_query.edit_message_text(\"\ud83d\udd12 **\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442.**\")\n        return\n\n    if page_number < 0 or page_number >= total_pages:\n        await update.callback_query.edit_message_text(\"\u2757 \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043d\u043e\u043c\u0435\u0440 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.\")\n        return\n\n    start_index = page_number * items_per_page\n    end_index = min(start_index + items_per_page, len(blocked_users))\n\n    blocked_list = blocked_users[start_index:end_index]\n\n    message_text = f\"\ud83d\udd12 **\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 (\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 {page_number + 1}/{total_pages}):**\\n\\n\"\n    for i, user in enumerate(blocked_list, start=start_index + 1):\n        blocked_until = datetime.fromisoformat(user[2])\n        time_left = str(blocked_until - datetime.now()).split('.')[0]\n        message_text += f\"{i}. {user[0]} (@{user[1]})\\n\u0414\u043e \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438: {time_left}\\n\\n\"\n\n    buttons = [\n        [\n            InlineKeyboardButton(\"\u2b05\ufe0f \u041d\u0430\u0437\u0430\u0434\", callback_data=f\"page-{page_number - 1}\") if page_number > 0 else InlineKeyboardButton(\"\u2b05\ufe0f \u041d\u0430\u0437\u0430\u0434\", callback_data='noop'),\n            InlineKeyboardButton(f\"\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 {page_number + 1} \u0438\u0437 {total_pages}\", callback_data='noop'),\n            InlineKeyboardButton(\"\u0412\u043f\u0435\u0440\u0451\u0434 \u27a1\ufe0f\", callback_data=f\"page-{page_number + 1}\") if page_number + 1 < total_pages else InlineKeyboardButton(\"\u0412\u043f\u0435\u0440\u0451\u0434 \u27a1\ufe0f\", callback_data='noop'),\n        ],\n        [InlineKeyboardButton(\"\ud83d\udd19 \u041d\u0430\u0437\u0430\u0434\", callback_data='blocking_menu')]\n    ]\n\n    reply_markup = InlineKeyboardMarkup(buttons)\n    await update.callback_query.edit_message_text(message_text.strip(), reply_markup=reply_markup, parse_mode='Markdown')\n\ndef is_teacher_user(user_id):\n    if user_id == MAIN_ADMIN_ID:\n        return True\n\n    conn = sqlite3.connect('university.db')\n    c = conn.cursor()\n    c.execute(\"SELECT 1 FROM teachers WHERE id = ?\", (user_id,))\n    result = c.fetchone()\n    conn.close()\n    return result is not None\n\nif __name__ == '__main__':\n    # \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430, \u0435\u0441\u043b\u0438 \u043e\u043d \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442\n    if not os.path.exists('config.ini'):\n        create_config_file()\n        print(\"\ud83d\udcc4 \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0439\u0442\u0435 config.ini \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u0442\u043e\u043a\u0435\u043d \u0431\u043e\u0442\u0430.\")\n        exit(1)\n\n    init_db()\n\n    # \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 application\n    application = ApplicationBuilder().token(TOKEN).build()\n\n    # \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043a\u043e\u043c\u0430\u043d\u0434 \u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439\n    application.add_handler(CommandHandler(\"start\", start))\n    application.add_handler(CallbackQueryHandler(handle_callback, pattern='^.*$'))\n    application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))\n    application.add_handler(MessageHandler(filters.TEXT & filters.Regex('^.*$'), collect_mailing_message))\n    application.add_handler(MessageHandler(filters.PHOTO, collect_mailing_message))\n    # \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043b\u044f \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438\n    application.add_handler(CallbackQueryHandler(handle_mailing_confirm, pattern='^(confirm_send_mailing|cancel_send_mailing)$'))\n    \n    # \u0417\u0430\u043f\u0443\u0441\u043a \u0431\u043e\u0442\u0430\n    application.run_polling(). \u041f\u043e\u043c\u043e\u0433\u0438 \u043c\u043d\u0435 \u0438 \u0440\u0435\u0448\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439. \u0412\u044b\u0448\u043b\u0438 \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434"}],"shard":{"index":35,"name":"turns-00035.parquet","rows":56995}}
