{"id":7393,"date":"2025-12-17T23:26:50","date_gmt":"2025-12-17T20:26:50","guid":{"rendered":"https:\/\/1.cbm.ua\/?page_id=7393"},"modified":"2026-01-29T18:11:56","modified_gmt":"2026-01-29T15:11:56","slug":"%d0%b2%d0%b2%d0%be%d0%b4-%d1%86%d0%b8%d1%84%d1%80-%d0%b6%d0%b5%d1%81%d1%82%d0%b0%d0%bc%d0%b8-2","status":"publish","type":"page","link":"https:\/\/1.cbm.ua\/?page_id=7393","title":{"rendered":"_v2 \u0412\u0432\u043e\u0434 \u0446\u0438\u0444\u0440 \u0436\u0435\u0441\u0442\u0430\u043c\u0438."},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"ru\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>\u0414\u043e\u0441\u043a\u0430 \u0434\u043b\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u043b\u0438\u043d\u0438\u0439 \u0441\u043e \u0441\u043b\u043e\u044f\u043c\u0438<\/title>\n    <style>\n        body {\n            margin: 0;\n            padding: 20px;\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            font-family: Arial, sans-serif;\n            background: #f0f0f0;\n        }\n        #canvas {\n            border: 2px solid #333;\n            background: white;\n            cursor: crosshair;\n            box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n        }\n        .controls {\n            margin-bottom: 15px;\n            display: flex;\n            gap: 15px;\n            align-items: center;\n            flex-wrap: wrap;\n        }\n        button {\n            padding: 8px 16px;\n            font-size: 14px;\n            cursor: pointer;\n            border: none;\n            background: #4CAF50;\n            color: white;\n            border-radius: 4px;\n        }\n        button:hover {\n            background: #45a049;\n        }\n        button:disabled {\n            background: #ccc;\n            cursor: not-allowed;\n        }\n        .layer-btn {\n            background: #2196F3;\n        }\n        .layer-btn:hover:not(:disabled) {\n            background: #0b7dda;\n        }\n        .menu-btn {\n            background: #FF9800;\n        }\n        .menu-btn:hover {\n            background: #e68900;\n        }\n        label {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n        }\n        input[type=\"color\"] {\n            cursor: pointer;\n            width: 40px;\n            height: 30px;\n            border: none;\n        }\n        input[type=\"range\"], input[type=\"number\"] {\n            cursor: pointer;\n        }\n        input[type=\"number\"] {\n            width: 60px;\n            padding: 4px;\n            border: 1px solid #ccc;\n            border-radius: 4px;\n        }\n        .layer-controls {\n            display: flex;\n            gap: 10px;\n            align-items: center;\n            padding: 10px;\n            background: #e0e0e0;\n            border-radius: 4px;\n        }\n        .layer-info {\n            font-weight: bold;\n            min-width: 100px;\n        }\n        .shortcut {\n            font-size: 11px;\n            color: #666;\n            margin-left: 5px;\n        }\n        .arrow-btn {\n            font-size: 18px;\n            padding: 8px 12px;\n            min-width: 40px;\n        }\n        \/* \u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0431\u043b\u043e\u043a *\/\n        .info-panel {\n            margin-top: 15px;\n            padding: 15px;\n            background: #fff;\n            border: 2px solid #2196F3;\n            border-radius: 8px;\n            width: 800px;\n            box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n        }\n        .info-header {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            margin-bottom: 10px;\n        }\n        .info-title {\n            font-weight: bold;\n            font-size: 16px;\n            color: #2196F3;\n        }\n        .clear-sequence-btn {\n            background: #f44336;\n            padding: 6px 14px;\n            font-size: 13px;\n        }\n        .clear-sequence-btn:hover {\n            background: #d32f2f;\n        }\n        .sequence-container {\n            border: 1px solid #ddd;\n            border-radius: 4px;\n            background: #f9f9f9;\n            max-height: 200px;\n            overflow-y: auto;\n            font-family: 'Courier New', monospace;\n            font-size: 13px;\n        }\n        .sequence-header {\n            display: grid;\n            grid-template-columns: 100px 80px 100px 150px 150px;\n            gap: 10px;\n            padding: 8px 10px;\n            background: #2196F3;\n            color: white;\n            font-weight: bold;\n            position: sticky;\n            top: 0;\n            border-bottom: 2px solid #1976D2;\n        }\n        .sequence-row {\n            display: grid;\n            grid-template-columns: 100px 80px 100px 150px 150px;\n            gap: 10px;\n            padding: 8px 10px;\n            border-bottom: 1px solid #eee;\n        }\n        .sequence-row:hover {\n            background: #f0f0f0;\n        }\n        .sequence-row:last-child {\n            border-bottom: none;\n        }\n        .sequence-empty {\n            padding: 20px;\n            text-align: center;\n            color: #999;\n            font-style: italic;\n        }\n        .sequence-highlight {\n            background: #e3f2fd;\n            font-weight: bold;\n        }\n        \/* \u041c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e *\/\n        .modal {\n            display: none;\n            position: fixed;\n            z-index: 1000;\n            left: 0;\n            top: 0;\n            width: 100%;\n            height: 100%;\n            background-color: rgba(0, 0, 0, 0.5);\n            animation: fadeIn 0.3s;\n        }\n        @keyframes fadeIn {\n            from { opacity: 0; }\n            to { opacity: 1; }\n        }\n        .modal-content {\n            position: relative;\n            background-color: #fff;\n            margin: 10% auto;\n            padding: 30px;\n            border-radius: 8px;\n            width: 500px;\n            max-width: 90%;\n            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);\n            animation: slideDown 0.3s;\n        }\n        @keyframes slideDown {\n            from {\n                transform: translateY(-50px);\n                opacity: 0;\n            }\n            to {\n                transform: translateY(0);\n                opacity: 1;\n            }\n        }\n        .modal-header {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            margin-bottom: 20px;\n            padding-bottom: 15px;\n            border-bottom: 2px solid #e0e0e0;\n        }\n        .modal-title {\n            font-size: 20px;\n            font-weight: bold;\n            color: #333;\n        }\n        .close-btn {\n            background: #f44336;\n            color: white;\n            border: none;\n            width: 30px;\n            height: 30px;\n            border-radius: 50%;\n            font-size: 18px;\n            cursor: pointer;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            padding: 0;\n        }\n        .close-btn:hover {\n            background: #d32f2f;\n        }\n        .settings-options {\n            display: flex;\n            flex-direction: column;\n            gap: 15px;\n        }\n        .checkbox-label {\n            display: flex;\n            align-items: center;\n            gap: 10px;\n            cursor: pointer;\n            padding: 10px;\n            border-radius: 4px;\n            transition: background 0.2s;\n        }\n        .checkbox-label:hover {\n            background: #f5f5f5;\n        }\n        .checkbox-label input[type=\"checkbox\"] {\n            cursor: pointer;\n            width: 20px;\n            height: 20px;\n        }\n        .checkbox-label span {\n            font-size: 15px;\n        }\n        .setting-group {\n            display: flex;\n            align-items: center;\n            gap: 10px;\n            padding: 10px;\n            border-radius: 4px;\n        }\n        .setting-group:hover {\n            background: #f5f5f5;\n        }\n        .menu-dropdown {\n            position: relative;\n            display: inline-block;\n        }\n        .menu-content {\n            display: none;\n            position: absolute;\n            background-color: white;\n            min-width: 200px;\n            box-shadow: 0 4px 8px rgba(0,0,0,0.2);\n            z-index: 100;\n            border-radius: 4px;\n            overflow: hidden;\n        }\n        .menu-content.show {\n            display: block;\n        }\n        .menu-item {\n            padding: 12px 16px;\n            cursor: pointer;\n            border: none;\n            background: white;\n            color: #333;\n            text-align: left;\n            width: 100%;\n            font-size: 14px;\n        }\n        .menu-item:hover {\n            background: #f0f0f0;\n        }\n    <\/style>\n<\/head>\n<body>\n    <div class=\"controls\">\n        <div class=\"menu-dropdown\">\n            <button id=\"menuBtn\" class=\"menu-btn\">\u2630 \u041c\u0435\u043d\u044e<\/button>\n            <div id=\"menuContent\" class=\"menu-content\">\n                <button class=\"menu-item\" id=\"settingsMenuItem\">\u2699\ufe0f \u0424\u043e\u0440\u043c\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438<\/button>\n            <\/div>\n        <\/div>\n        <label>\n            \u0426\u0432\u0435\u0442:\n            <input type=\"color\" id=\"colorPicker\" value=\"#000000\">\n        <\/label>\n        <label>\n            \u0422\u043e\u043b\u0449\u0438\u043d\u0430:\n            <input type=\"range\" id=\"lineWidth\" min=\"1\" max=\"20\" value=\"2\">\n            <span id=\"widthValue\">2<\/span>px\n        <\/label>\n        <button id=\"clearBtn\">\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0441\u043b\u043e\u0439<\/button>\n    <\/div>\n    <div class=\"layer-controls\">\n        <button id=\"newLayerBtn\" class=\"layer-btn\">\n            \u041d\u043e\u0432\u044b\u0439 \u0441\u043b\u043e\u0439 <span class=\"shortcut\">(Q)<\/span>\n        <\/button>\n        <button id=\"prevLayerBtn\" class=\"layer-btn arrow-btn\">\u2190<\/button>\n        <button id=\"nextLayerBtn\" class=\"layer-btn arrow-btn\">\u2192<\/button>\n        <div class=\"layer-info\">\n            \u0421\u043b\u043e\u0439: <span id=\"currentLayer\">1<\/span> \/ <span id=\"totalLayers\">1<\/span>\n        <\/div>\n        <button id=\"deleteLayerBtn\" style=\"background: #f44336;\">\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u043b\u043e\u0439<\/button>\n    <\/div>\n    <canvas id=\"canvas\" width=\"800\" height=\"600\"><\/canvas>\n    <!-- \u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0431\u043b\u043e\u043a -->\n    <div class=\"info-panel\">\n        <div class=\"info-header\">\n            <div class=\"info-title\">\ud83d\udcca \u041f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043b\u0438\u043d\u0438\u0439<\/div>\n            <button class=\"clear-sequence-btn\" onclick=\"clearDirectionSequence()\">\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c<\/button>\n        <\/div>\n        <div class=\"sequence-container\" id=\"sequenceContainer\">\n            <div class=\"sequence-header\">\n                <div>\u041d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435<\/div>\n                <div>\u0414\u043b\u0438\u043d\u0430<\/div>\n                <div>\u0423\u0433\u043e\u043b<\/div>\n                <div>\u041d\u0430\u0447\u0430\u043b\u043e<\/div>\n                <div>\u041a\u043e\u043d\u0435\u0446<\/div>\n            <\/div>\n            <div id=\"sequenceContent\">\n                <div class=\"sequence-empty\">\u041d\u0430\u0447\u043d\u0438\u0442\u0435 \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u043b\u0438\u043d\u0438\u0438&#8230;<\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n    <!-- \u041c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a -->\n    <div id=\"settingsModal\" class=\"modal\">\n        <div class=\"modal-content\">\n            <div class=\"modal-header\">\n                <div class=\"modal-title\">\u2699\ufe0f \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438<\/div>\n                <button id=\"closeModalBtn\" class=\"close-btn\">\u2715<\/button>\n            <\/div>\n            <div class=\"settings-options\">\n                <label class=\"checkbox-label\">\n                    <input type=\"checkbox\" id=\"copyContentCheckbox\">\n                    <span>\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043d\u0430 \u043d\u043e\u0432\u044b\u0439 \u0441\u043b\u043e\u0439<\/span>\n                <\/label>\n                <label class=\"checkbox-label\">\n                    <input type=\"checkbox\" id=\"newLineNewLayerCheckbox\">\n                    <span>\u041d\u043e\u0432\u0430\u044f \u043b\u0438\u043d\u0438\u044f &#8212; \u043d\u043e\u0432\u044b\u0439 \u0441\u043b\u043e\u0439<\/span>\n                <\/label>\n                <label class=\"checkbox-label\">\n                    <input type=\"checkbox\" id=\"showGridCheckbox\" checked>\n                    <span>\u0412\u044b\u0432\u0435\u0441\u0442\u0438 \u0441\u0435\u0442\u043a\u0443<\/span>\n                <\/label>\n                <div class=\"setting-group\">\n                    <label>\n                        <span>\u0428\u0430\u0433 \u0441\u0435\u0442\u043a\u0438:<\/span>\n                        <input type=\"number\" id=\"gridStepInput\" min=\"50\" max=\"300\" value=\"50\">\n                        <span>px<\/span>\n                    <\/label>\n                <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n    <script>\n        const canvas = document.getElementById('canvas');\n        const ctx = canvas.getContext('2d');\n        const colorPicker = document.getElementById('colorPicker');\n        const lineWidthSlider = document.getElementById('lineWidth');\n        const widthValue = document.getElementById('widthValue');\n        const clearBtn = document.getElementById('clearBtn');\n        const newLayerBtn = document.getElementById('newLayerBtn');\n        const prevLayerBtn = document.getElementById('prevLayerBtn');\n        const nextLayerBtn = document.getElementById('nextLayerBtn');\n        const deleteLayerBtn = document.getElementById('deleteLayerBtn');\n        const currentLayerSpan = document.getElementById('currentLayer');\n        const totalLayersSpan = document.getElementById('totalLayers');\n        const copyContentCheckbox = document.getElementById('copyContentCheckbox');\n        const newLineNewLayerCheckbox = document.getElementById('newLineNewLayerCheckbox');\n        const showGridCheckbox = document.getElementById('showGridCheckbox');\n        const gridStepInput = document.getElementById('gridStepInput');\n        const menuBtn = document.getElementById('menuBtn');\n        const menuContent = document.getElementById('menuContent');\n        const settingsMenuItem = document.getElementById('settingsMenuItem');\n        const settingsModal = document.getElementById('settingsModal');\n        const closeModalBtn = document.getElementById('closeModalBtn');\n        const sequenceContent = document.getElementById('sequenceContent');\n        const sequenceContainer = document.getElementById('sequenceContainer');\n        \n        let activeTouches = {}; \/\/ \u041e\u0431\u044a\u0435\u043a\u0442 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043a\u0430\u0436\u0434\u043e\u043c \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c \u043a\u0430\u0441\u0430\u043d\u0438\u0438\n        let isDrawing = false;\n        let lastX = 0;\n        let lastY = 0;\n        let startX = 0;\n        let startY = 0;\n        let currentLineSegments = [];\n        let currentLineInfo = null;\n        let lineSequence = []; \/\/ \u041c\u0430\u0441\u0441\u0438\u0432 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e \u043b\u0438\u043d\u0438\u044f\u0445\n        \n        \/\/ \u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u0441\u043b\u043e\u0435\u0432\n        let layers = [[]];\n        let currentLayerIndex = 0;\n        \n        \/\/ \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f\n        ctx.lineCap = 'round';\n        ctx.lineJoin = 'round';\n\n        \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0441\u0435\u0442\u043a\u0438\n        function drawGrid() {\n            if (!showGridCheckbox.checked) return;\n            \n            const step = parseInt(gridStepInput.value) || 50;\n            const width = canvas.width;\n            const height = canvas.height;\n            \n            ctx.strokeStyle = '#cccccc';\n            ctx.lineWidth = 0.5;\n            ctx.setLineDash([2, 2]);\n            \n            \/\/ \u0412\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043b\u0438\u043d\u0438\u0438\n            for (let x = 0; x <= width; x += step) {\n                ctx.beginPath();\n                ctx.moveTo(x, 0);\n                ctx.lineTo(x, height);\n                ctx.stroke();\n            }\n            \n            \/\/ \u0413\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043b\u0438\u043d\u0438\u0438\n            for (let y = 0; y <= height; y += step) {\n                ctx.beginPath();\n                ctx.moveTo(0, y);\n                ctx.lineTo(width, y);\n                ctx.stroke();\n            }\n            \n            \/\/ \u0414\u0438\u0430\u0433\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043b\u0438\u043d\u0438\u0438 (\u043e\u0442 \u0432\u0435\u0440\u0445\u043d\u0435\u0433\u043e \u043b\u0435\u0432\u043e\u0433\u043e \u0443\u0433\u043b\u0430 \u0432\u043f\u0440\u0430\u0432\u043e-\u0432\u043d\u0438\u0437)\n            for (let start = 0; start <= width + height; start += step) {\n                ctx.beginPath();\n                if (start <= width) {\n                    ctx.moveTo(start, 0);\n                    const endX = Math.min(width, start + height);\n                    const endY = endX - start;\n                    ctx.lineTo(endX, endY);\n                } else {\n                    const startY = start - width;\n                    ctx.moveTo(width, startY);\n                    ctx.lineTo(width - (height - startY), height);\n                }\n                ctx.stroke();\n            }\n            \n            \/\/ \u0414\u0438\u0430\u0433\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043b\u0438\u043d\u0438\u0438 (\u043e\u0442 \u0432\u0435\u0440\u0445\u043d\u0435\u0433\u043e \u043f\u0440\u0430\u0432\u043e\u0433\u043e \u0443\u0433\u043b\u0430 \u0432\u043b\u0435\u0432\u043e-\u0432\u043d\u0438\u0437)\n            for (let start = 0; start <= width + height; start += step) {\n                ctx.beginPath();\n                if (start <= width) {\n                    ctx.moveTo(width - start, 0);\n                    const endX = Math.max(0, width - start - height);\n                    const endY = width - start - endX;\n                    ctx.lineTo(endX, endY);\n                } else {\n                    const startY = start - width;\n                    ctx.moveTo(0, startY);\n                    ctx.lineTo(Math.min(width, height - startY), height);\n                }\n                ctx.stroke();\n            }\n            \n            ctx.setLineDash([]);\n        }\n\n        \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0441\u0435\u0442\u043a\u0438\n        showGridCheckbox.addEventListener('change', redrawCanvas);\n        gridStepInput.addEventListener('input', redrawCanvas);\n\n        \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043a\u0440\u0443\u0436\u043e\u0447\u043a\u0430 \u043d\u0430 \u043a\u043e\u043d\u0446\u0435 \u043b\u0438\u043d\u0438\u0438\n        function drawEndCircle(x, y, color, width) {\n            ctx.fillStyle = color;\n            ctx.beginPath();\n            ctx.arc(x, y, width * 1.5, 0, Math.PI * 2);\n            ctx.fill();\n        }\n        \n        \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043b\u0438\u043d\u0438\u0438 \u0431\u0435\u0437 \u043a\u0440\u0443\u0436\u043e\u0447\u043a\u0430\n        function drawLine(x1, y1, x2, y2, color, width) {\n            ctx.strokeStyle = color;\n            ctx.lineWidth = width;\n            ctx.beginPath();\n            ctx.moveTo(x1, y1);\n            ctx.lineTo(x2, y2);\n            ctx.stroke();\n        }\n        \n        \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e \u0443\u0433\u043b\u0443\n        function getDirectionFromAngle(angle) {\n            const \u0448\u0430\u0433 = 45\/2;\n            let \u0433\u0440\u0430\u0434\u0443\u0441, \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442;\n            \n            \u0433\u0440\u0430\u0434\u0443\u0441 = -135; \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 = 7; if (angle > \u0433\u0440\u0430\u0434\u0443\u0441-\u0448\u0430\u0433 && angle <= \u0433\u0440\u0430\u0434\u0443\u0441+\u0448\u0430\u0433) return \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442;\n            \u0433\u0440\u0430\u0434\u0443\u0441 = -90;  \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 = 0; if (angle > \u0433\u0440\u0430\u0434\u0443\u0441-\u0448\u0430\u0433 && angle <= \u0433\u0440\u0430\u0434\u0443\u0441+\u0448\u0430\u0433) return \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442;\n            \u0433\u0440\u0430\u0434\u0443\u0441 = -45;  \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 = 1; if (angle > \u0433\u0440\u0430\u0434\u0443\u0441-\u0448\u0430\u0433 && angle <= \u0433\u0440\u0430\u0434\u0443\u0441+\u0448\u0430\u0433) return \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442;\n            \u0433\u0440\u0430\u0434\u0443\u0441 = 0;    \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 = 2; if (angle > \u0433\u0440\u0430\u0434\u0443\u0441-\u0448\u0430\u0433 && angle <= \u0433\u0440\u0430\u0434\u0443\u0441+\u0448\u0430\u0433) return \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442;\n            \u0433\u0440\u0430\u0434\u0443\u0441 = 45;   \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 = 3; if (angle > \u0433\u0440\u0430\u0434\u0443\u0441-\u0448\u0430\u0433 && angle <= \u0433\u0440\u0430\u0434\u0443\u0441+\u0448\u0430\u0433) return \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442;\n            \u0433\u0440\u0430\u0434\u0443\u0441 = 90;   \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 = 4; if (angle > \u0433\u0440\u0430\u0434\u0443\u0441-\u0448\u0430\u0433 && angle <= \u0433\u0440\u0430\u0434\u0443\u0441+\u0448\u0430\u0433) return \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442;\n            \u0433\u0440\u0430\u0434\u0443\u0441 = 135;  \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 = 5; if (angle > \u0433\u0440\u0430\u0434\u0443\u0441-\u0448\u0430\u0433 && angle <= \u0433\u0440\u0430\u0434\u0443\u0441+\u0448\u0430\u0433) return \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442;\n            \u0433\u0440\u0430\u0434\u0443\u0441 = 180;  \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 = 6; if (angle > \u0433\u0440\u0430\u0434\u0443\u0441-\u0448\u0430\u0433 && angle <= \u0433\u0440\u0430\u0434\u0443\u0441) return \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442;\n            \u0433\u0440\u0430\u0434\u0443\u0441 = -180; \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 = 6; if (angle >= \u0433\u0440\u0430\u0434\u0443\u0441 && angle <= \u0433\u0440\u0430\u0434\u0443\u0441+\u0448\u0430\u0433) return \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442;\n            return 0;\n        }\n        \n        \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438\n        function updateSequence() {\n            if (lineSequence.length === 0) {\n                sequenceContent.innerHTML = '<div class=\"sequence-empty\">\u041d\u0430\u0447\u043d\u0438\u0442\u0435 \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u043b\u0438\u043d\u0438\u0438...<\/div>';\n                return;\n            }\n            \n            let html = '';\n            lineSequence.forEach((line, index) => {\n                const isLast = index === lineSequence.length - 1;\n                html += `\n                    <div class=\"sequence-row ${isLast ? 'sequence-highlight' : ''}\">\n                        <div>${line.direction}<\/div>\n                        <div>${line.length} px<\/div>\n                        <div>${line.angle}\u00b0<\/div>\n                        <div>${line.start}<\/div>\n                        <div>${line.end}<\/div>\n                    <\/div>\n                `;\n            });\n            \n            sequenceContent.innerHTML = html;\n            \n            \/\/ \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043f\u0440\u043e\u043a\u0440\u0443\u0442\u043a\u0430 \u043a \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0441\u0442\u0440\u043e\u043a\u0435\n            sequenceContainer.scrollTop = sequenceContainer.scrollHeight;\n        }\n        \n        \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043b\u0438\u043d\u0438\u0438 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\n        function addLineToSequence(x1, y1, x2, y2) {\n            const length = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));\n            const angle = Math.atan2(y2 - y1, x2 - x1) * (180 \/ Math.PI);\n            const direction = getDirectionFromAngle(angle);\n            \n            lineSequence.push({\n                direction: direction,\n                length: Math.round(length),\n                angle: angle.toFixed(1),\n                start: `X:${Math.round(x1)}, Y:${Math.round(y1)}`,\n                end: `X:${Math.round(x2)}, Y:${Math.round(y2)}`\n            });\n            \n            updateSequence();\n        }\n        \n        \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438\n        function clearDirectionSequence() {\n            lineSequence = [];\n            updateSequence();\n        }\n        \n        \/\/ \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043c\u0435\u043d\u044e\n        menuBtn.addEventListener('click', (e) => {\n            e.stopPropagation();\n            menuContent.classList.toggle('show');\n        });\n        document.addEventListener('click', () => {\n            menuContent.classList.remove('show');\n        });\n        settingsMenuItem.addEventListener('click', () => {\n            settingsModal.style.display = 'block';\n            menuContent.classList.remove('show');\n        });\n        closeModalBtn.addEventListener('click', () => {\n            settingsModal.style.display = 'none';\n        });\n        settingsModal.addEventListener('click', (e) => {\n            if (e.target === settingsModal) {\n                settingsModal.style.display = 'none';\n            }\n        });\n        \n        function redrawCanvas() {\n            ctx.clearRect(0, 0, canvas.width, canvas.height);\n            \n            \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u0441\u0435\u0442\u043a\u0443 \u043f\u0435\u0440\u0432\u043e\u0439 (\u043d\u0430 \u0437\u0430\u0434\u043d\u0435\u043c \u043f\u043b\u0430\u043d\u0435)\n            drawGrid();\n            \n            const currentLayer = layers[currentLayerIndex];\n            \n            \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u0432\u0441\u0435 \u043b\u0438\u043d\u0438\u0438 \u0441 \u043a\u0440\u0443\u0436\u043e\u0447\u043a\u0430\u043c\u0438 \u043d\u0430 \u043a\u043e\u043d\u0446\u0430\u0445\n            currentLayer.forEach(lineGroup => {\n                \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u0432\u0441\u0435 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b \u043b\u0438\u043d\u0438\u0438\n                lineGroup.segments.forEach(segment => {\n                    drawLine(segment.x1, segment.y1, segment.x2, segment.y2, lineGroup.color, lineGroup.width);\n                });\n                \n                \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u043a\u0440\u0443\u0436\u043e\u0447\u0435\u043a \u043d\u0430 \u043a\u043e\u043d\u0446\u0435 \u043b\u0438\u043d\u0438\u0438\n                drawEndCircle(lineGroup.endX, lineGroup.endY, lineGroup.color, lineGroup.width);\n            });\n        }\n        \n        function updateLayerInfo() {\n            currentLayerSpan.textContent = currentLayerIndex + 1;\n            totalLayersSpan.textContent = layers.length;\n            \n            prevLayerBtn.disabled = currentLayerIndex === 0;\n            nextLayerBtn.disabled = currentLayerIndex === layers.length - 1;\n            deleteLayerBtn.disabled = layers.length === 1;\n        }\n        \n        function createNewLayer() {\n            let newLayerContent = [];\n            \n            if (copyContentCheckbox.checked) {\n                newLayerContent = JSON.parse(JSON.stringify(layers[currentLayerIndex]));\n            }\n            \n            layers.push(newLayerContent);\n            currentLayerIndex = layers.length - 1;\n            redrawCanvas();\n            updateLayerInfo();\n        }\n        \n        function goToPreviousLayer() {\n            if (currentLayerIndex > 0) {\n                currentLayerIndex--;\n                redrawCanvas();\n                updateLayerInfo();\n            }\n        }\n        \n        function goToNextLayer() {\n            if (currentLayerIndex < layers.length - 1) {\n                currentLayerIndex++;\n                redrawCanvas();\n                updateLayerInfo();\n            }\n        }\n        \n        function deleteCurrentLayer() {\n            if (layers.length > 1) {\n                layers.splice(currentLayerIndex, 1);\n                if (currentLayerIndex >= layers.length) {\n                    currentLayerIndex = layers.length - 1;\n                }\n                redrawCanvas();\n                updateLayerInfo();\n            }\n        }\n        \n        lineWidthSlider.addEventListener('input', (e) => {\n            widthValue.textContent = e.target.value;\n        });\n        \n        canvas.addEventListener('mousedown', (e) => {\n            isDrawing = true;\n            const rect = canvas.getBoundingClientRect();\n            lastX = e.clientX - rect.left;\n            lastY = e.clientY - rect.top;\n            startX = lastX;\n            startY = lastY;\n            currentLineSegments = [];\n            \n            \/\/ \u041d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u043b\u0438\u043d\u0438\u044e\n            currentLineInfo = {\n                segments: [],\n                color: colorPicker.value,\n                width: lineWidthSlider.value,\n                endX: lastX,\n                endY: lastY\n            };\n        });\n        \n        canvas.addEventListener('mousemove', (e) => {\n            if (!isDrawing) return;\n            const rect = canvas.getBoundingClientRect();\n            let currentX = e.clientX - rect.left;\n            let currentY = e.clientY - rect.top;\n            \n            const color = colorPicker.value;\n            const width = lineWidthSlider.value;\n            const segment = {\n                x1: lastX,\n                y1: lastY,\n                x2: currentX,\n                y2: currentY\n            };\n            \n            currentLineInfo.segments.push(segment);\n            currentLineInfo.endX = currentX;\n            currentLineInfo.endY = currentY;\n            currentLineInfo.color = color;\n            currentLineInfo.width = width;\n            \n            \/\/ \u041f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0432\u0441\u0435\n            ctx.clearRect(0, 0, canvas.width, canvas.height);\n            drawGrid();\n            \n            \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u0432\u0441\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044b\u0435 \u043b\u0438\u043d\u0438\u0438\n            const currentLayer = layers[currentLayerIndex];\n            currentLayer.forEach(lineGroup => {\n                lineGroup.segments.forEach(segment => {\n                    drawLine(segment.x1, segment.y1, segment.x2, segment.y2, lineGroup.color, lineGroup.width);\n                });\n                drawEndCircle(lineGroup.endX, lineGroup.endY, lineGroup.color, lineGroup.width);\n            });\n            \n            \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043b\u0438\u043d\u0438\u044e\n            currentLineInfo.segments.forEach(segment => {\n                drawLine(segment.x1, segment.y1, segment.x2, segment.y2, color, width);\n            });\n            drawEndCircle(currentX, currentY, color, width);\n            \n            lastX = currentX;\n            lastY = currentY;\n        });\n        \n        canvas.addEventListener('mouseup', () => {\n            if (isDrawing && currentLineInfo && currentLineInfo.segments.length > 0) {\n                \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u0443\u044e \u043b\u0438\u043d\u0438\u044e\n                layers[currentLayerIndex].push(currentLineInfo);\n                \n                \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043b\u0438\u043d\u0438\u044e \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\n                addLineToSequence(startX, startY, currentLineInfo.endX, currentLineInfo.endY);\n                \n                currentLineInfo = null;\n                \n                \/\/ \u0415\u0441\u043b\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u043e\u043f\u0446\u0438\u044f \"\u041d\u043e\u0432\u0430\u044f \u043b\u0438\u043d\u0438\u044f - \u043d\u043e\u0432\u044b\u0439 \u0441\u043b\u043e\u0439\", \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0441\u043b\u043e\u0439\n                if (newLineNewLayerCheckbox.checked) {\n                    createNewLayer();\n                }\n            }\n            isDrawing = false;\n            currentLineSegments = [];\n        });\n        \n        canvas.addEventListener('mouseleave', () => {\n            if (isDrawing && currentLineInfo && currentLineInfo.segments.length > 0) {\n                layers[currentLayerIndex].push(currentLineInfo);\n                addLineToSequence(startX, startY, currentLineInfo.endX, currentLineInfo.endY);\n                currentLineInfo = null;\n                \n                if (newLineNewLayerCheckbox.checked) {\n                    createNewLayer();\n                }\n            }\n            isDrawing = false;\n            currentLineSegments = [];\n        });\n        \n        canvas.addEventListener('touchstart', (e) => {\n            e.preventDefault();\n            const rect = canvas.getBoundingClientRect();\n            \n            \/\/ \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043a\u0430\u0436\u0434\u043e\u0435 \u043d\u043e\u0432\u043e\u0435 \u043a\u0430\u0441\u0430\u043d\u0438\u0435\n            for (let i = 0; i < e.changedTouches.length; i++) {\n                const touch = e.changedTouches[i];\n                const touchId = touch.identifier;\n                const touchX = touch.clientX - rect.left;\n                const touchY = touch.clientY - rect.top;\n                \n                \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043a\u0430\u0441\u0430\u043d\u0438\u044f\n                activeTouches[touchId] = {\n                    lastX: touchX,\n                    lastY: touchY,\n                    startX: touchX,\n                    startY: touchY,\n                    lineInfo: {\n                        segments: [],\n                        color: colorPicker.value,\n                        width: lineWidthSlider.value,\n                        endX: touchX,\n                        endY: touchY\n                    }\n                };\n            }\n        });\n        \n        canvas.addEventListener('touchmove', (e) => {\n            e.preventDefault();\n            if (Object.keys(activeTouches).length === 0) return;\n            \n            const rect = canvas.getBoundingClientRect();\n            \n            \/\/ \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043a\u0430\u0436\u0434\u043e\u0435 \u0434\u0432\u0438\u0436\u0443\u0449\u0435\u0435\u0441\u044f \u043a\u0430\u0441\u0430\u043d\u0438\u0435\n            for (let i = 0; i < e.changedTouches.length; i++) {\n                const touch = e.changedTouches[i];\n                const touchId = touch.identifier;\n                \n                \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u043a\u0430\u0441\u0430\u043d\u0438\u0435 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f\n                if (!activeTouches[touchId]) continue;\n                \n                const currentX = touch.clientX - rect.left;\n                const currentY = touch.clientY - rect.top;\n                const touchData = activeTouches[touchId];\n                \n                const color = colorPicker.value;\n                const width = lineWidthSlider.value;\n                const segment = {\n                    x1: touchData.lastX,\n                    y1: touchData.lastY,\n                    x2: currentX,\n                    y2: currentY\n                };\n                \n                touchData.lineInfo.segments.push(segment);\n                touchData.lineInfo.endX = currentX;\n                touchData.lineInfo.endY = currentY;\n                touchData.lineInfo.color = color;\n                touchData.lineInfo.width = width;\n                \n                touchData.lastX = currentX;\n                touchData.lastY = currentY;\n            }\n            \n            \/\/ \u041f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u043c canvas \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u0430\u0441\u0430\u043d\u0438\u0439\n            ctx.clearRect(0, 0, canvas.width, canvas.height);\n            drawGrid();\n            \n            \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u0432\u0441\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044b\u0435 \u043b\u0438\u043d\u0438\u0438\n            const currentLayer = layers[currentLayerIndex];\n            currentLayer.forEach(lineGroup => {\n                lineGroup.segments.forEach(segment => {\n                    drawLine(segment.x1, segment.y1, segment.x2, segment.y2, lineGroup.color, lineGroup.width);\n                });\n                drawEndCircle(lineGroup.endX, lineGroup.endY, lineGroup.color, lineGroup.width);\n            });\n            \n            \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u0432\u0441\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043b\u0438\u043d\u0438\u0438 \u043e\u0442 \u043a\u0430\u0441\u0430\u043d\u0438\u0439\n            Object.values(activeTouches).forEach(touchData => {\n                touchData.lineInfo.segments.forEach(segment => {\n                    drawLine(segment.x1, segment.y1, segment.x2, segment.y2, touchData.lineInfo.color, touchData.lineInfo.width);\n                });\n                drawEndCircle(touchData.lineInfo.endX, touchData.lineInfo.endY, touchData.lineInfo.color, touchData.lineInfo.width);\n            });\n        });\n        \n        canvas.addEventListener('touchend', (e) => {\n            e.preventDefault();\n            \n            \/\/ \u0424\u043b\u0430\u0433 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f, \u043d\u0443\u0436\u043d\u043e \u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0441\u043b\u043e\u0439 \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438\n            let shouldCreateNewLayer = false;\n            \n            \/\/ \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043a\u0430\u0436\u0434\u043e\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u0435 \u043a\u0430\u0441\u0430\u043d\u0438\u0435\n            for (let i = 0; i < e.changedTouches.length; i++) {\n                const touch = e.changedTouches[i];\n                const touchId = touch.identifier;\n                \n                \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u043a\u0430\u0441\u0430\u043d\u0438\u0435 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f\n                if (!activeTouches[touchId]) continue;\n                \n                const touchData = activeTouches[touchId];\n                \n                \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u0443\u044e \u043b\u0438\u043d\u0438\u044e \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b\n                if (touchData.lineInfo.segments.length > 0) {\n                    layers[currentLayerIndex].push(touchData.lineInfo);\n                    addLineToSequence(touchData.startX, touchData.startY, touchData.lineInfo.endX, touchData.lineInfo.endY);\n                    shouldCreateNewLayer = true;\n                }\n                \n                \/\/ \u0423\u0434\u0430\u043b\u044f\u0435\u043c \u043a\u0430\u0441\u0430\u043d\u0438\u0435 \u0438\u0437 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445\n                delete activeTouches[touchId];\n            }\n            \n            \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0441\u043b\u043e\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u0433\u0434\u0430 \u0412\u0421\u0415 \u043f\u0430\u043b\u044c\u0446\u044b \u043e\u0442\u043e\u0440\u0432\u0430\u043b\u0438\u0441\u044c \u043e\u0442 \u044d\u043a\u0440\u0430\u043d\u0430 \u0438 \u0431\u044b\u043b\u0438 \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u044b \u043b\u0438\u043d\u0438\u0438\n            if (Object.keys(activeTouches).length === 0 && shouldCreateNewLayer && newLineNewLayerCheckbox.checked) {\n                createNewLayer();\n            }\n        });\n        \n        \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f \u043a\u0430\u0441\u0430\u043d\u0438\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439\n        canvas.addEventListener('touchcancel', (e) => {\n            e.preventDefault();\n            \n            \/\/ \u0424\u043b\u0430\u0433 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f, \u043d\u0443\u0436\u043d\u043e \u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0441\u043b\u043e\u0439 \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438\n            let shouldCreateNewLayer = false;\n            \n            \/\/ \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043a\u0430\u0436\u0434\u043e\u0435 \u043f\u0440\u0435\u0440\u0432\u0430\u043d\u043d\u043e\u0435 \u043a\u0430\u0441\u0430\u043d\u0438\u0435\n            for (let i = 0; i < e.changedTouches.length; i++) {\n                const touch = e.changedTouches[i];\n                const touchId = touch.identifier;\n                \n                \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u043a\u0430\u0441\u0430\u043d\u0438\u0435 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f\n                if (!activeTouches[touchId]) continue;\n                \n                const touchData = activeTouches[touchId];\n                \n                \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043f\u0440\u0435\u0440\u0432\u0430\u043d\u043d\u0443\u044e \u043b\u0438\u043d\u0438\u044e \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b\n                if (touchData.lineInfo.segments.length > 0) {\n                    layers[currentLayerIndex].push(touchData.lineInfo);\n                    addLineToSequence(touchData.startX, touchData.startY, touchData.lineInfo.endX, touchData.lineInfo.endY);\n                    shouldCreateNewLayer = true;\n                }\n                \n                \/\/ \u0423\u0434\u0430\u043b\u044f\u0435\u043c \u043a\u0430\u0441\u0430\u043d\u0438\u0435 \u0438\u0437 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445\n                delete activeTouches[touchId];\n            }\n            \n            \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0441\u043b\u043e\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u0433\u0434\u0430 \u0412\u0421\u0415 \u043f\u0430\u043b\u044c\u0446\u044b \u043e\u0442\u043e\u0440\u0432\u0430\u043b\u0438\u0441\u044c \u043e\u0442 \u044d\u043a\u0440\u0430\u043d\u0430 \u0438 \u0431\u044b\u043b\u0438 \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u044b \u043b\u0438\u043d\u0438\u0438\n            if (Object.keys(activeTouches).length === 0 && shouldCreateNewLayer && newLineNewLayerCheckbox.checked) {\n                createNewLayer();\n            }\n        });\n        \n        clearBtn.addEventListener('click', () => {\n            layers[currentLayerIndex] = [];\n            redrawCanvas();\n        });\n        \n        newLayerBtn.addEventListener('click', createNewLayer);\n        prevLayerBtn.addEventListener('click', goToPreviousLayer);\n        nextLayerBtn.addEventListener('click', goToNextLayer);\n        deleteLayerBtn.addEventListener('click', deleteCurrentLayer);\n        \n        document.addEventListener('keydown', (e) => {\n            if (e.key === 'q' || e.key === 'Q' || e.key === '\u0439' || e.key === '\u0419') {\n                e.preventDefault();\n                createNewLayer();\n            } else if (e.key === 'ArrowLeft') {\n                e.preventDefault();\n                goToPreviousLayer();\n            } else if (e.key === 'ArrowRight') {\n                e.preventDefault();\n                goToNextLayer();\n            }\n        });\n        \n        \/\/ \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f\n        updateLayerInfo();\n        redrawCanvas();\n    <\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>\u0414\u043e\u0441\u043a\u0430 \u0434\u043b\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u043b\u0438\u043d\u0438\u0439 \u0441\u043e \u0441\u043b\u043e\u044f\u043c\u0438 \u2630 \u041c\u0435\u043d\u044e \u2699\ufe0f \u0424\u043e\u0440\u043c\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0426\u0432\u0435\u0442: \u0422\u043e\u043b\u0449\u0438\u043d\u0430: 2px \u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0441\u043b\u043e\u0439 \u041d\u043e\u0432\u044b\u0439 \u0441\u043b\u043e\u0439 (Q) \u2190 \u2192 \u0421\u043b\u043e\u0439: 1 \/ 1 \u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u043b\u043e\u0439 \ud83d\udcca \u041f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043b\u0438\u043d\u0438\u0439 \u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u041d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0414\u043b\u0438\u043d\u0430 \u0423\u0433\u043e\u043b \u041d\u0430\u0447\u0430\u043b\u043e \u041a\u043e\u043d\u0435\u0446 \u041d\u0430\u0447\u043d\u0438\u0442\u0435 \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u043b\u0438\u043d\u0438\u0438&#8230; \u2699\ufe0f \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u2715 \u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043d\u0430 \u043d\u043e\u0432\u044b\u0439 \u0441\u043b\u043e\u0439 \u041d\u043e\u0432\u0430\u044f \u043b\u0438\u043d\u0438\u044f &#8212; \u043d\u043e\u0432\u044b\u0439 \u0441\u043b\u043e\u0439 \u0412\u044b\u0432\u0435\u0441\u0442\u0438 \u0441\u0435\u0442\u043a\u0443 \u0428\u0430\u0433&hellip;&nbsp;<a href=\"https:\/\/1.cbm.ua\/?page_id=7393\" rel=\"bookmark\">\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 &raquo;<span class=\"screen-reader-text\">_v2 \u0412\u0432\u043e\u0434 \u0446\u0438\u0444\u0440 \u0436\u0435\u0441\u0442\u0430\u043c\u0438.<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"page-templates\/template-pagebuilder-full-width.php","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"class_list":["post-7393","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/1.cbm.ua\/index.php?rest_route=\/wp\/v2\/pages\/7393","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/1.cbm.ua\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/1.cbm.ua\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/1.cbm.ua\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/1.cbm.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7393"}],"version-history":[{"count":4,"href":"https:\/\/1.cbm.ua\/index.php?rest_route=\/wp\/v2\/pages\/7393\/revisions"}],"predecessor-version":[{"id":8499,"href":"https:\/\/1.cbm.ua\/index.php?rest_route=\/wp\/v2\/pages\/7393\/revisions\/8499"}],"wp:attachment":[{"href":"https:\/\/1.cbm.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7393"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}