оптемезируй стили и код,убери все эелементы  оставь только конструктор 
<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="UTF-8">
  <title>Визуальный Конструктор Скриптов на Python</title>
  <style>
      /* Общие стили */
    body {
      margin: 0;
      display: flex;
      flex-direction: column;
      height: 100vh;
      font-family: Arial, sans-serif;
    }

    /* Верхнее меню */
    #menu {
      background: #f1f1f1;
      padding: 10px;
      display: flex;
      border-bottom: 1px solid #ccc;
    }

    #menu button {
      margin-right: 10px;
      padding: 8px 15px;
      background-color: #337ab7;
      color: #fff;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      transition: background 0.3s;
    }

    #menu button:hover {
      background-color: #286090;
    }

    /* Основная часть */
    #content {
      display: flex;
      flex-grow: 1;
    }

    /* Левая панель (элементы) */
    #sidebar {
      width: 200px;
      background: #f7f7f7;
      padding: 10px;
      overflow-y: auto;
      border-right: 1px solid #ccc;
      box-sizing: border-box;
    }

    #sidebar h3,
    #sidebar h4 {
      margin-top: 0;
    }

    #custom-elements {
      margin-top: 20px;
    }

    /* Правая панель (свойства) */
    #properties {
      width: 250px;
      background: #f7f7f7;
      padding: 10px;
      overflow-y: auto;
      border-left: 1px solid #ccc;
      box-sizing: border-box;
    }

    #properties h3 {
      margin-top: 0;
    }

    #properties-content {
      margin-top: 10px;
    }

    .element-properties {
      margin-bottom: 20px;
      border-bottom: 1px solid #ccc;
      padding-bottom: 10px;
    }

    .element-properties h4 {
      margin: 0 0 10px 0;
    }

    /* Центральная часть */
    #main-content {
      flex-grow: 1;
      display: flex;
    }

    /* Рабочая область */
    #workspace-container {
      flex-grow: 1;
      display: flex;
      flex-direction: column;
    }

    #workspace {
      position: relative;
      background: #fff;
      overflow: auto;
      flex-grow: 1;
    }

    /* Прямоугольник выделения */
    #selection-rectangle {
      position: absolute;
      border: 1px dashed #5bc0de;
      background: rgba(91, 192, 222, 0.1);
      display: none;
      pointer-events: none;
    }

    /* Консоль (снизу) */
    #console {
      background: #232323;
      color: #eaeaea;
      font-family: monospace;
      padding: 10px;
      overflow-y: auto;
      box-sizing: border-box;
      height: 150px;
    }

    #console h3 {
      margin-top: 0;
    }

    #console pre {
      white-space: pre-wrap;
    }

    /* Элементы */
    .element {
      background: #d9edf7;
      margin: 5px 0;
      padding: 8px;
      border: 1px solid #bce8f1;
      border-radius: 4px;
      cursor: grab;
      user-select: none;
      transition: background 0.3s, transform 0.3s;
    }

    .element:hover {
      background: #c4e3f3;
      transform: scale(1.05);
    }

    .workspace-element {
      position: absolute;
      background: #fefefe;
      padding: 10px;
      border: 1px solid #ddd;
      border-radius: 4px;
      cursor: move;
      user-select: none;
      min-width: 150px;
      text-align: center;
      transition: box-shadow 0.2s, transform 0.3s;
      animation: fadeIn 0.5s;
    }

    .workspace-element:hover {
      box-shadow: 0 0 5px rgba(0,0,0,0.3);
      transform: scale(1.05);
    }

    .workspace-element.selected {
      border-color: #5cb85c;
      box-shadow: 0 0 10px rgba(92, 184, 92, 0.5);
    }

    /* Анимация появления элемента */
    @keyframes fadeIn {
      from { opacity: 0; transform: scale(0.8); }
      to { opacity: 1; transform: scale(1); }
    }

    /* Точки соединения */
    .connector {
      width: 12px;
      height: 12px;
      background: #5bc0de;
      border: 1px solid #46b8da;
      border-radius: 50%;
      position: absolute;
      cursor: pointer;
      transition: background 0.2s;
    }

    .connector:hover {
      background: #31b0d5;
    }

    .connector.connecting {
      background: #d9534f;
    }

    .connector.active {
      background: #5cb85c;
    }

    /* Левая точка (Вход) */
    .connector.input {
      left: -6px;
      top: 50%;
      transform: translateY(-50%);
    }

    /* Правая точка (Выход) */
    .connector.output {
      right: -6px;
      top: 50%;
      transform: translateY(-50%);
    }

    /* Подсказки */
    .connector::after {
      content: attr(data-tooltip);
      position: absolute;
      left: 50%;
      bottom: 140%;
      transform: translateX(-50%);
      background: #333;
      color: #fff;
      padding: 2px 5px;
      border-radius: 3px;
      opacity: 0;
      white-space: nowrap;
      pointer-events: none;
      transition: opacity 0.2s;
      font-size: 12px;
      z-index: 10;
    }

    .connector:hover::after {
      opacity: 1;
    }

    /* Соединения */
    #connections {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      pointer-events: none;
    }

    .line {
      stroke: #337ab7;
      stroke-width: 2;
      transition: stroke 0.2s;
    }

    .line:hover {
      stroke: #d9534f;
    }

    .line.active {
      stroke: #5cb85c;
    }

    /* Временная линия при соединении */
    #temp-line {
      stroke: #5bc0de;
      stroke-width: 2;
      stroke-dasharray: 5,5;
    }

    /* Стрелки на линиях */
    .marker {
      stroke: none;
      fill: #337ab7;
    }

    /* Форма в окне свойств */
    #properties-content form {
      display: flex;
      flex-direction: column;
    }

    #properties-content label {
      margin-bottom: 10px;
      display: flex;
      flex-direction: column;
    }

    #properties-content input[type="text"],
    #properties-content textarea {
      width: 100%;
      padding: 5px;
      box-sizing: border-box;
    }

    #properties-content textarea {
      height: 60px;
    }

    #properties-content select {
      width: 100%;
      padding: 5px;
      box-sizing: border-box;
    }

    #properties-content button {
      padding: 8px 15px;
      background-color: #5cb85c;
      color: #fff;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      margin-top: 10px;
      transition: background 0.3s;
    }

    #properties-content button:hover {
      background-color: #4cae4c;
    }

    .element-properties {
      margin-bottom: 20px;
      border-bottom: 1px solid #ccc;
      padding-bottom: 10px;
    }

    .element-properties h4 {
      margin: 0 0 10px 0;
    }

    /* Модальное окно */
    #modal-overlay,
    #manage-elements-modal-overlay {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(0, 0, 0, 0.5);
      z-index: 100;
      display: none;
    }

    #modal,
    #manage-elements-modal {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background: #fff;
      padding: 20px;
      border-radius: 4px;
      z-index: 101;
      width: 400px;
      max-width: 90%;
    }

    #modal h3,
    #manage-elements-modal h3 {
      margin-top: 0;
    }

    #modal form,
    #manage-elements-modal form {
      display: flex;
      flex-direction: column;
    }

    #modal label,
    #manage-elements-modal label {
      margin-bottom: 10px;
    }

    #modal input[type="text"],
    #modal textarea,
    #modal select,
    #manage-elements-modal input[type="text"],
    #manage-elements-modal textarea,
    #manage-elements-modal select {
      width: 100%;
      padding: 5px;
      box-sizing: border-box;
    }

    #modal textarea,
    #manage-elements-modal textarea {
      height: 80px;
    }

    #modal button,
    #manage-elements-modal button {
      padding: 8px 15px;
      background-color: #337ab7;
      color: #fff;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      margin-top: 10px;
      transition: background 0.3s;
    }

    #modal button:hover,
    #manage-elements-modal button:hover {
      background-color: #286090;
    }

    #close-modal,
    #close-manage-modal {
      background-color: #d9534f;
    }

    #close-modal:hover,
    #close-manage-modal:hover {
      background-color: #c9302c;
    }

    /* Стили для списка пользовательских элементов в модальном окне */
    #custom-elements-list {
      list-style: none;
      padding: 0;
      margin: 0;
      max-height: 300px;
      overflow-y: auto;
    }

    #custom-elements-list li {
      padding: 10px;
      border-bottom: 1px solid #ccc;
      position: relative;
    }

    #custom-elements-list li:hover {
      background-color: #f1f1f1;
    }

    .edit-button,
    .delete-button {
      position: absolute;
      top: 10px;
      right: 70px;
      padding: 5px 10px;
      background-color: #5bc0de;
      color: #fff;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      margin-right: 5px;
    }

    .delete-button {
      right: 10px;
      background-color: #d9534f;
    }

    .edit-button:hover {
      background-color: #31b0d5;
    }

    .delete-button:hover {
      background-color: #c9302c;
    }

    /* Кнопка копирования кода */
    #copy-code {
      padding: 8px 15px;
      background-color: #5bc0de;
      color: #fff;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      margin: 10px;
      transition: background 0.3s;
    }

    #copy-code:hover {
      background-color: #31b0d5;
    }
    :root {
      --primary-color: #337ab7;
      --secondary-color: #286090;
      --highlight-color: #5bc0de;
      --error-color: #d9534f;
      --success-color: #5cb85c;
      --neutral-color: #f1f1f1;
      --border-color: #ccc;
      --font-color: #fff;
    }

    body {
      margin: 0;
      display: flex;
      flex-direction: column;
      height: 100vh;
      font-family: Arial, sans-serif;
    }

    #menu {
      background: var(--neutral-color);
      padding: 10px;
      display: flex;
      border-bottom: 1px solid var(--border-color);
    }
    #menu button {
      margin-right: 10px;
      padding: 8px 15px;
      background-color: var(--primary-color);
      color: var(--font-color);
      border: none;
      border-radius: 4px;
      cursor: pointer;
      transition: background 0.3s;
    }
    #menu button:hover {
      background-color: var(--secondary-color);
    }

    #content {
      display: flex;
      flex-grow: 1;
    }

    #sidebar, #properties {
      width: 250px;
      background: var(--neutral-color);
      padding: 10px;
      overflow-y: auto;
      border-right: 1px solid var(--border-color);
      box-sizing: border-box;
    }
    #sidebar h3, #sidebar h4, #properties h3 {
      margin-top: 0;
    }

    #main-content {
      flex-grow: 1;
      display: flex;
      position: relative;
    }

    #workspace-container {
      flex-grow: 1;
      display: flex;
      flex-direction: column;
    }
    
    #workspace {
      position: relative;
      background: #fff;
      overflow: auto;
      flex-grow: 1;
      border: 1px solid var(--border-color);
    }

    #console {
      background: #2d2d2d;
      color: #f1f1f1;
      padding: 10px;
      height: 150px;
      overflow-y: auto;
      border-top: 1px solid var(--border-color);
    }

    #selection-rectangle {
      position: absolute;
      border: 1px dashed var(--highlight-color);
      background: rgba(91, 192, 222, 0.1);
      display: none;
      pointer-events: none;
      z-index: 1000;
    }

    .element {
      background: #d9edf7;
      margin: 5px 0;
      padding: 8px;
      border: 1px solid #bce8f1;
      border-radius: 4px;
      cursor: grab;
      user-select: none;
      transition: background 0.3s, transform 0.3s;
    }
    .element:hover {
      background: #c4e3f3;
      transform: scale(1.05);
    }

    .workspace-element {
      position: absolute;
      background: #fefefe;
      padding: 10px;
      border: 1px solid #ddd;
      border-radius: 4px;
      cursor: move;
      user-select: none;
      min-width: 150px;
      text-align: center;
      transition: box-shadow 0.2s, transform 0.3s, opacity 0.5s;
      animation: fadeIn 0.5s;
      z-index: 500;
    }
    .workspace-element:hover {
      box-shadow: 0 0 5px rgba(0,0,0,0.3);
      transform: scale(1.05);
    }
    .workspace-element.selected {
      border-color: var(--success-color);
      box-shadow: 0 0 10px rgba(92, 184, 92, 0.5);
    }

    @keyframes fadeIn {
      from { opacity: 0; transform: scale(0.8); }
      to { opacity: 1; transform: scale(1); }
    }

    .connector {
      width: 12px;
      height: 12px;
      background: var(--highlight-color);
      border: 1px solid #46b8da;
      border-radius: 50%;
      position: absolute;
      cursor: pointer;
      transition: background 0.2s;
    }
    .connector:hover {
      background: #31b0d5;
    }

    .connector.input {
      left: -6px;
      top: 50%;
      transform: translateY(-50%);
    }
    .connector.output {
      right: -6px;
      top: 50%;
      transform: translateY(-50%);
    }

    .connector::after {
      content: attr(data-tooltip);
      position: absolute;
      left: 50%;
      bottom: 140%;
      transform: translateX(-50%);
      background: #333;
      color: #fff;
      padding: 2px 5px;
      border-radius: 3px;
      opacity: 0;
      pointer-events: none;
      transition: opacity 0.2s;
      font-size: 12px;
      z-index: 10;
      white-space: nowrap;
    }
    .connector:hover::after {
      opacity: 1;
    }

    #connections {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      pointer-events: none;
      z-index: 1;
    }

    .line {
      stroke: var(--primary-color);
      stroke-width: 2;
      transition: stroke 0.2s;
      cursor: pointer;
    }
    .line:hover {
      stroke: var(--error-color);
    }

    .marker {
      stroke: none;
      fill: var(--primary-color);
    }

    #properties-content form {
      display: flex;
      flex-direction: column;
    }
    #properties-content label {
      margin-bottom: 10px;
      display: flex;
      flex-direction: column;
    }
    #properties-content input[type="text"],
    #properties-content textarea,
    #properties-content select {
      width: 100%;
      padding: 5px;
      box-sizing: border-box;
    }
    #properties-content textarea {
      height: 60px;
    }
    #properties-content button {
      padding: 8px 15px;
      background-color: var(--success-color);
      color: var(--font-color);
      border: none;
      border-radius: 4px;
      cursor: pointer;
      margin-top: 10px;
      transition: background 0.3s;
    }
    #properties-content button:hover {
      background-color: #4cae4c;
    }

    #modal-overlay {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(0, 0, 0, 0.5);
      z-index: 100;
      display: none;
    }
    #modal {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background: #fff;
      padding: 20px;
      border-radius: 4px;
      z-index: 101;
      width: 400px;
      max-width: 90%;
      box-shadow: 0 2px 10px rgba(0,0,0,0.3);
    }
    #modal form {
      display: flex;
      flex-direction: column;
    }
    #modal label {
      margin-bottom: 10px;
    }
    #modal input[type="text"],
    #modal textarea,
    #modal select {
      width: 100%;
      padding: 5px;
      box-sizing: border-box;
    }
    #modal textarea {
      height: 80px;
    }
    #modal button {
      padding: 8px 15px;
      background-color: var(--primary-color);
      color: var(--font-color);
      border: none;
      border-radius: 4px;
      cursor: pointer;
      margin-top: 10px;
      transition: background 0.3s;
    }
    #modal button:hover {
      background-color: var(--secondary-color);
    }

    #close-modal {
      background-color: var(--error-color);
    }
    #close-modal:hover {
      background-color: #c9302c;
    }

    #copy-code {
      margin: 10px;
    }
  </style>
</head>
<body>
  <div id="menu">
    <button id="save-project">Сохранить проект</button>
    <button id="load-project">Загрузить проект</button>
    <button id="create-element">Создать элемент</button>
    <button id="copy-code">Копировать код</button>
  </div>

  <div id="content">
    <div id="sidebar">
      <h3>Элементы</h3>
      <div class="element" data-type="variable" draggable="true">Переменная</div>
      <div class="element" data-type="condition" draggable="true">Условие</div>
      <div class="element" data-type="action" draggable="true">Действие</div>
      <div class="element" data-type="input" draggable="true">Логический Вход</div>
      <div class="element" data-type="output" draggable="true">Логический Выход</div>
      <div class="element" data-type="loop" draggable="true">Цикл</div>
      <div class="element" data-type="function" draggable="true">Функция</div>
      <div class="element" data-type="array" draggable="true">Массив</div>
      <div class="element" data-type="class" draggable="true">Класс</div>
      <div class="element" data-type="file" draggable="true">Файл</div>
      <div class="element" data-type="comment" draggable="true">Комментарий</div>
      <div class="element" data-type="exception" draggable="true">Исключение</div>
      <div id="custom-elements">
        <h4>Пользовательские элементы</h4>
      </div>
    </div>

    <div id="main-content">
      <div id="workspace-container">
        <div id="workspace">
          <svg id="connections"></svg>
          <div id="selection-rectangle"></div>
        </div>
        <div id="console">
          <h3>Результат Кода</h3>
          <pre id="console-output"></pre>
        </div>
      </div>
      <div id="properties">
        <h3>Свойства</h3>
        <div id="properties-content">
          <p>Выберите элемент, чтобы изменить его свойства.</p>
        </div>
      </div>
    </div>
  </div>

  <div id="modal-overlay">
    <div id="modal">
      <h3 id="modal-title">Создать новый элемент</h3>
      <form id="create-element-form">
        <label>
          Имя элемента:
          <input type="text" id="custom-element-name" required>
        </label>
        <label>
          Параметры элемента (в формате JSON):
          <textarea id="custom-element-params" placeholder='{"param1": "value1", "param2": "value2"}' required></textarea>
        </label>
        <label>
          Шаблон кода:
          <textarea id="custom-element-code-template" placeholder='код шаблона с параметрами типа {param1}, {param2}' required></textarea>
        </label>
        <label>
          Точки соединения:
          <select id="custom-element-connectors">
            <option value="input-output">Вход и Выход</option>
            <option value="input">Только Вход</option>
            <option value="output">Только Выход</option>
            <option value="none">Без точек</option>
          </select>
        </label>
        <button type="submit" id="create-element-button">Создать</button>
        <button type="button" id="close-modal">Отмена</button>
      </form>
    </div>
  </div>

  <script>
    // DOM Elements
    const saveProjectBtn = document.getElementById('save-project');
    const loadProjectBtn = document.getElementById('load-project');
    const createElementBtn = document.getElementById('create-element');
    const copyCodeBtn = document.getElementById('copy-code');
    const sidebar = document.getElementById('sidebar');
    const workspace = document.getElementById('workspace');
    const consoleOutput = document.getElementById('console-output');
    const connectionsSvg = document.getElementById('connections');
    const propertiesPanel = document.getElementById('properties-content');
    const selectionRectangle = document.getElementById('selection-rectangle');
    const customElementsContainer = document.getElementById('custom-elements');
    const modalOverlay = document.getElementById('modal-overlay');
    const modal = document.getElementById('modal');
    const modalTitle = document.getElementById('modal-title');
    const createElementForm = document.getElementById('create-element-form');
    const createElementButton = document.getElementById('create-element-button');
    const closeModalBtn = document.getElementById('close-modal');

    // Data Structures
    let elements = []; // Array of element objects
    let connections = []; // Array of connection objects
    let selectedElements = []; // Array of selected DOM elements
    let customElements = []; // Array of custom element definitions
    let editingElementIndex = null; // Index of the element being edited

    // Temporary Line for connections
    const tempLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');
    tempLine.setAttribute('id', 'temp-line');
    tempLine.setAttribute('stroke', '#5bc0de');
    tempLine.setAttribute('stroke-width', '2');
    connectionsSvg.appendChild(tempLine);

    // Define Arrowhead Marker
    const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
    const markerElem = document.createElementNS('http://www.w3.org/2000/svg', 'marker');
    markerElem.setAttribute('id', 'arrowhead');
    markerElem.setAttribute('markerWidth', '10');
    markerElem.setAttribute('markerHeight', '7');
    markerElem.setAttribute('refX', '10');
    markerElem.setAttribute('refY', '3.5');
    markerElem.setAttribute('orient', 'auto');

    const arrowPath = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
    arrowPath.setAttribute('points', '0 0, 10 3.5, 0 7');
    arrowPath.setAttribute('class', 'marker');

    markerElem.appendChild(arrowPath);
    defs.appendChild(markerElem);
    connectionsSvg.appendChild(defs);

    // Event Listeners for Menu Buttons
    saveProjectBtn.addEventListener('click', saveProject);
    loadProjectBtn.addEventListener('click', loadProject);
    createElementBtn.addEventListener('click', openCreateElementModal);
    copyCodeBtn.addEventListener('click', copyCodeToClipboard);

    // Save Project to Local Storage
    function saveProject() {
      const projectData = {
        elements: elements.map(el => ({
          id: el.id,
          type: el.type,
          x: el.x,
          y: el.y,
          properties: el.properties,
          custom: el.custom || false,
        })),
        connections,
        customElements,
      };
      localStorage.setItem('visualScriptProject', JSON.stringify(projectData));
      alert('Проект сохранен!');
    }

    // Load Project from Local Storage
    function loadProject() {
      const projectData = JSON.parse(localStorage.getItem('visualScriptProject') || "{}");
      if (projectData.elements && Array.isArray(projectData.elements)) {
        clearWorkspace();
        customElements = projectData.customElements || [];
        saveCustomElementsToLocalStorage();
        customElementsContainer.innerHTML = '<h4>Пользовательские элементы</h4>';
        customElements.forEach(customEl => addCustomElementToSidebar(customEl));
        projectData.elements.forEach(elData => {
          createWorkspaceElement(elData.type, elData.x, elData.y, elData.id, elData.custom);
        });

        connections = projectData.connections || [];
        drawConnections();
        alert('Проект загружен!');
        generateCode();
      } else {
        alert('Нет сохраненного проекта.');
      }
    }

    // Clear Workspace
    function clearWorkspace() {
      elements.forEach(el => {
        el.domElement.remove();
      });
      elements = [];
      connections = [];
      drawConnections();
      generateCode();
    }

    // Open Modal to Create Custom Element
    function openCreateElementModal() {
      editingElementIndex = null;
      modalTitle.textContent = 'Создать новый элемент';
      createElementButton.textContent = 'Создать';
      modalOverlay.style.display = 'block';
      createElementForm.reset();
    }

    // Close Modal
    closeModalBtn.addEventListener('click', () => {
      modalOverlay.style.display = 'none';
      createElementForm.reset();
    });

    // Save Custom Elements to Local Storage
    function saveCustomElementsToLocalStorage() {
      localStorage.setItem('customElements', JSON.stringify(customElements));
    }

    // Load Custom Elements from Local Storage
    function loadCustomElementsFromLocalStorage() {
      const storedElements = JSON.parse(localStorage.getItem('customElements'));
      if (storedElements && Array.isArray(storedElements)) {
        customElements = storedElements;
        customElementsContainer.innerHTML = '<h4>Пользовательские элементы</h4>';
        customElements.forEach(customEl => addCustomElementToSidebar(customEl));
      }
    }

    // Add Custom Element to Sidebar
    function addCustomElementToSidebar(customElement) {
      const customElementDiv = document.createElement('div');
      customElementDiv.classList.add('element');
      customElementDiv.textContent = customElement.name;
      customElementDiv.dataset.type = customElement.name;
      customElementDiv.dataset.custom = 'true';
      customElementDiv.draggable = true;
      customElementsContainer.appendChild(customElementDiv);

      customElementDiv.addEventListener('dragstart', (e) => {
        e.dataTransfer.setData('custom-element', JSON.stringify(customElement));
      });
    }

    // Drag and Drop from Sidebar to Workspace
    sidebar.addEventListener('dragstart', (e) => {
      if (e.target.classList.contains('element')) {
        if (e.target.dataset.custom === 'true') {
          const customEl = customElements.find(el => el.name === e.target.dataset.type);
          if (customEl) {
            e.dataTransfer.setData('custom-element', JSON.stringify(customEl));
          }
        } else {
          e.dataTransfer.setData('text/plain', e.target.dataset.type);
        }
      }
    });

    workspace.addEventListener('dragover', (e) => {
      e.preventDefault();
    });

    workspace.addEventListener('drop', (e) => {
      e.preventDefault();
      const rect = workspace.getBoundingClientRect();
      const x = e.clientX - rect.left + workspace.scrollLeft;
      const y = e.clientY - rect.top + workspace.scrollTop;
      const customElementData = e.dataTransfer.getData('custom-element');
      if (customElementData) {
        const customElement = JSON.parse(customElementData);
        createWorkspaceElement(customElement.name, x, y, null, true);
      } else {
        const elementType = e.dataTransfer.getData('text/plain');
        if (elementType) {
          createWorkspaceElement(elementType, x, y);
        }
      }
    });

    // Create Workspace Element
    function createWorkspaceElement(type, x, y, id = null, isCustom = false) {
      const elem = document.createElement('div');
      elem.classList.add('workspace-element');
      elem.dataset.type = type;
      elem.dataset.custom = isCustom;
      elem.style.left = x + 'px';
      elem.style.top = y + 'px';
      const content = document.createElement('div');
      content.textContent = type;
      elem.appendChild(content);
      
      const connectorsType = isCustom ? (customElements.find(el => el.name === type)?.connectors || 'input-output') : 'input-output';
      addConnectors(elem, connectorsType);
      const elementId = id || 'elem-' + Date.now() + '-' + Math.floor(Math.random() * 1000);
      elem.dataset.id = elementId;

      const elementData = {
        id: elementId,
        type: type,
        x: x,
        y: y,
        properties: {},
        domElement: elem,
        tempProperties: {},
        custom: isCustom,
      };

      if (isCustom) {
        const customElData = customElements.find(el => el.name === type);
        if (customElData) {
          elementData.properties = { ...customElData.params, codeTemplate: customElData.codeTemplate };
        }
      }

      elements.push(elementData);
      workspace.appendChild(elem);
      makeElementDraggable(elem);

      elem.addEventListener('click', (e) => {
        e.stopPropagation();
        if (!e.shiftKey && !e.ctrlKey) {
          clearSelection();
        }
        selectElement(elem);
      });

      // Add event listeners to connectors
      const connectors = elem.querySelectorAll('.connector');
      connectors.forEach(connector => {
        connector.addEventListener('mousedown', (e) => {
          e.preventDefault();
          connectorMouseDown(e, connector);
        });
      });

      generateCode();
      return elementData;
    }

    // Add Connectors to Element
    function addConnectors(elem, connectorsType) {
      // Remove existing connectors
      const existingConnectors = elem.querySelectorAll('.connector');
      existingConnectors.forEach(connector => connector.remove());

      // Add Input Connector
      if (connectorsType === 'input' || connectorsType === 'input-output') {
        const inputConnector = document.createElement('div');
        inputConnector.classList.add('connector', 'input');
        inputConnector.dataset.type = 'input';
        inputConnector.dataset.tooltip = 'Входная точка';
        elem.appendChild(inputConnector);
      }

      // Add Output Connector
      if (connectorsType === 'output' || connectorsType === 'input-output') {
        const outputConnector = document.createElement('div');
        outputConnector.classList.add('connector', 'output');
        outputConnector.dataset.type = 'output';
        outputConnector.dataset.tooltip = 'Выходная точка';
        elem.appendChild(outputConnector);
      }
    }

    // Make Element Draggable
    function makeElementDraggable(elem) {
      let offsetX, offsetY;

      elem.addEventListener('mousedown', (e) => {
        if (e.target.classList.contains('connector')) {
          return;
        }
        if (!selectedElements.includes(elem)) {
          if (!e.shiftKey && !e.ctrlKey) {
            clearSelection();
          }
          selectElement(elem);
        }
        offsetX = e.clientX;
        offsetY = e.clientY;

        const initialPositions = selectedElements.map((el) => {
          return {
            el: el,
            x: parseInt(el.style.left),
            y: parseInt(el.style.top),
          };
        });

        function mouseMove(eMove) {
          const dx = eMove.clientX - offsetX;
          const dy = eMove.clientY - offsetY;

          initialPositions.forEach((pos) => {
            pos.el.style.left = pos.x + dx + 'px';
            pos.el.style.top = pos.y + dy + 'px';
            const elementData = elements.find((elData) => elData.id === pos.el.dataset.id);
            if (elementData) {
              elementData.x = parseInt(pos.el.style.left);
              elementData.y = parseInt(pos.el.style.top);
            }
          });

          drawConnections();
        }

        function mouseUp() {
          document.removeEventListener('mousemove', mouseMove);
          document.removeEventListener('mouseup', mouseUp);
          generateCode();
        }

        document.addEventListener('mousemove', mouseMove);
        document.addEventListener('mouseup', mouseUp);
      });
    }

    // Select Element
    function selectElement(elem) {
      if (!selectedElements.includes(elem)) {
        selectedElements.push(elem);
        elem.classList.add('selected');
        showProperties();
      }
    }

    // Clear Selection
    function clearSelection() {
      selectedElements.forEach((el) => el.classList.remove('selected'));
      selectedElements = [];
      showProperties();
    }

    // Selection Rectangle Variables
    let isSelecting = false;
    let selectionStart = { x: 0, y: 0 };
    let justSelected = false;

    // Workspace Mouse Events for Selection Rectangle
    workspace.addEventListener('mousedown', (e) => {
      if (e.target === workspace) {
        isSelecting = true;
        const rect = workspace.getBoundingClientRect();
        selectionStart.x = e.clientX - rect.left + workspace.scrollLeft;
        selectionStart.y = e.clientY - rect.top + workspace.scrollTop;

        selectionRectangle.style.display = 'block';
        selectionRectangle.style.left = selectionStart.x + 'px';
        selectionRectangle.style.top = selectionStart.y + 'px';
        selectionRectangle.style.width = '0px';
        selectionRectangle.style.height = '0px';
      }
    });

    workspace.addEventListener('mousemove', (e) => {
      if (isSelecting) {
        const rect = workspace.getBoundingClientRect();
        const x = e.clientX - rect.left + workspace.scrollLeft;
        const y = e.clientY - rect.top + workspace.scrollTop;
        const rectX = Math.min(x, selectionStart.x);
        const rectY = Math.min(y, selectionStart.y);
        const rectWidth = Math.abs(x - selectionStart.x);
        const rectHeight = Math.abs(y - selectionStart.y);

        selectionRectangle.style.left = rectX + 'px';
        selectionRectangle.style.top = rectY + 'px';
        selectionRectangle.style.width = rectWidth + 'px';
        selectionRectangle.style.height = rectHeight + 'px';

        clearSelection();

        elements.forEach((elData) => {
          const el = elData.domElement;
          const elRect = el.getBoundingClientRect();
          const workspaceRect = workspace.getBoundingClientRect();

          const elementRect = {
            left: elRect.left - workspaceRect.left + workspace.scrollLeft,
            top: elRect.top - workspaceRect.top + workspace.scrollTop,
            right: elRect.right - workspaceRect.left + workspace.scrollLeft,
            bottom: elRect.bottom - workspaceRect.top + workspace.scrollTop,
          };

          if (rectsIntersect({
            left: rectX,
            top: rectY,
            right: rectX + rectWidth,
            bottom: rectY + rectHeight,
          }, elementRect)) {
            selectElement(el);
          }
        });
      }
    });

    workspace.addEventListener('mouseup', (e) => {
      if (isSelecting) {
        isSelecting = false;
        selectionRectangle.style.display = 'none';
        justSelected = true;
        showProperties();
      }
    });

    workspace.addEventListener('click', (e) => {
      if (e.target === workspace) {
        if (!justSelected) {
          clearSelection();
        }
        justSelected = false;
      }
    });

    // Check Rectangle Intersection
    function rectsIntersect(rect1, rect2) {
      return !(
        rect2.left > rect1.right ||
        rect2.right < rect1.left ||
        rect2.top > rect1.bottom ||
        rect2.bottom < rect1.top
      );
    }

    // Show Properties Panel
    function showProperties() {
      propertiesPanel.innerHTML = '';
      if (selectedElements.length === 0) {
        propertiesPanel.innerHTML = '<p>Выберите элемент, чтобы изменить его свойства.</p>';
        return;
      }

      selectedElements.forEach((el) => {
        const elementId = el.dataset.id;
        const elementData = elements.find((elData) => elData.id === elementId);

        if (elementData) {
          const container = document.createElement('div');
          container.classList.add('element-properties');

          const title = document.createElement('h4');
          title.textContent = `${capitalizeFirstLetter(elementData.type)} (${elementId})`;
          container.appendChild(title);

          const form = document.createElement('form');
          form.addEventListener('input', (e) => {
            const target = e.target;
            elementData.tempProperties[target.name] = target.type === 'checkbox' ? target.checked : target.value;
            if (target.name === 'declareEarly' && target.type === 'checkbox') {
              showProperties();
            }
          });

          form.addEventListener('submit', (e) => {
            e.preventDefault();
            if (Object.keys(elementData.tempProperties).length > 0) {
              Object.assign(elementData.properties, elementData.tempProperties);
              updateElementContent(el, elementData);
              generateCode();
              elementData.tempProperties = {};
            }
          });

          container.appendChild(form);
          propertiesPanel.appendChild(container);

          if (elementData.custom) {
            for (let paramName in elementData.properties) {
              if (paramName !== 'codeTemplate') {
                createInputField(form, `${capitalizeFirstLetter(paramName)}:`, paramName, elementData.properties[paramName] || '');
              }
            }
          } else {
            mapPropertiesToForm(elementData.type, elementData.properties, form, elementData);
          }

          const applyButton = document.createElement('button');
          applyButton.textContent = 'Применить';
          form.appendChild(applyButton);
        }
      });
    }

    // Map Properties to Form Fields
    function mapPropertiesToForm(type, properties, form, elementData) {
      const mappings = {
        variable: () => {
          createInputField(form, 'Имя переменной:', 'name', properties.name || 'var');
          createSelectField(form, 'Тип переменной:', 'type', properties.type || 'string', ['string', 'int', 'bool', 'real']);
          createInputFieldWithTypeCheck(form, 'Значение переменной:', 'value', properties.value || '', properties.type);
          createCheckboxField(form, 'Объявить переменную заранее:', 'declareEarly', properties.declareEarly || false);
          if (properties.declareEarly) {
            createInputFieldWithTypeCheck(form, 'Начальное значение:', 'initialValue', properties.initialValue || '', properties.type);
          }
        },
        condition: () => createInputField(form, 'Условие:', 'condition', properties.condition || ''),
        action: () => createInputField(form, 'Действие:', 'action', properties.action || ''),
        input: () => createInputField(form, 'Имя входа:', 'name', properties.name || ''),
        output: () => createInputField(form, 'Имя выхода:', 'name', properties.name || ''),
        loop: () => {
          createInputField(form, 'Количество итераций:', 'iterations', properties.iterations || '10');
          createInputField(form, 'Действие внутри цикла:', 'action', properties.action || '');
        },
        function: () => {
          createInputField(form, 'Имя функции:', 'name', properties.name || 'my_function');
          createInputField(form, 'Параметры функции:', 'params', properties.params || '');
          createInputField(form, 'Тело функции:', 'body', properties.body || '');
        },
        array: () => {
          createInputField(form, 'Имя массива:', 'name', properties.name || 'array');
          createInputField(form, 'Элементы:', 'elements', properties.elements || '1,2,3');
        },
        class: () => {
          createInputField(form, 'Имя класса:', 'name', properties.name || 'MyClass');
          createInputField(form, 'Атрибуты:', 'attributes', properties.attributes || 'attr1,attr2');
        },
        file: () => {
          createInputField(form, 'Имя файла:', 'name', properties.name || 'file.txt');
          createInputField(form, 'Режим:', 'mode', properties.mode || 'r');
        },
        comment: () => createInputField(form, 'Текст комментария:', 'text', properties.text || 'Something important'),
        exception: () => {
          createInputField(form, 'Исключение:', 'exception', properties.exception || 'Exception');
          createInputField(form, 'Сообщение:', 'message', properties.message || 'An error occurred');
        }
      };
     
      if (mappings[type]) {
        mappings[type]();
      }
    }

    // Create Input Field
    function createInputField(form, labelText, propertyName, value) {
      const label = document.createElement('label');
      label.textContent = labelText;
      const input = document.createElement('input');
      input.type = 'text';
      input.name = propertyName;
      input.value = value;
      label.appendChild(input);
      form.appendChild(label);
    }

    // Create Select Field
    function createSelectField(form, labelText, propertyName, selectedValue, options) {
      const label = document.createElement('label');
      label.textContent = labelText;
      const select = document.createElement('select');
      select.name = propertyName;
      options.forEach(optionValue => {
        const option = document.createElement('option');
        option.value = optionValue;
        option.textContent = optionValue;
        if (optionValue === selectedValue) {
          option.selected = true;
        }
        select.appendChild(option);
      });
      label.appendChild(select);
      form.appendChild(label);
    }

    // Create Checkbox Field
    function createCheckboxField(form, labelText, propertyName, isChecked) {
      const label = document.createElement('label');
      label.textContent = labelText;
      const input = document.createElement('input');
      input.type = 'checkbox';
      input.name = propertyName;
      input.checked = isChecked;
      label.appendChild(input);
      form.appendChild(label);
    }

    // Create Input Field with Type Check
    function createInputFieldWithTypeCheck(form, labelText, propertyName, value, type) {
      const label = document.createElement('label');
      label.textContent = labelText;
      const input = document.createElement('input');
      input.type = 'text';
      input.name = propertyName;
      input.value = value;
      label.appendChild(input);
      form.appendChild(label);

      input.addEventListener('input', () => {
        if (type === 'string') {
          if (!input.value.startsWith('"') || !input.value.endsWith('"')) {
            input.value = `"${input.value.replace(/"/g, '')}"`;
          }
        } else if (type === 'int' || type === 'real') {
          // Allow only numbers and one decimal point for 'real'
          if (type === 'int') {
            input.value = input.value.replace(/[^0-9\-]/g, '');
          } else {
            input.value = input.value.replace(/[^0-9.\-]/g, '').replace(/(\..*)\./g, '$1');
          }
        } else if (type === 'bool') {
          const val = input.value.toLowerCase();
          if (val !== 'true' && val !== 'false') {
            input.setCustomValidity('Введите true или false');
          } else {
            input.setCustomValidity('');
          }
        }
      });
    }

    // Update Element Content Based on Properties
    function updateElementContent(elem, elementData) {
      const content = elem.querySelector('div');
      if (elementData.custom) {
        content.textContent = elementData.type;
      } else {
        mapContentToElement(elementData.type, elementData.properties, content);
      }
    }

    // Map Content to Element Display
    function mapContentToElement(type, properties, content) {
      const contentMap = {
        variable: () => `${properties.name} = ${formatValue(properties.value, properties.type)}`,
        condition: () => `if ${properties.condition}:`,
        action: () => `${properties.action}`,
        input: () => `${properties.name} = input()`,
        output: () => `print(${properties.name})`,
        loop: () => `for i in range(${properties.iterations}):`,
        function: () => `def ${properties.name}(${properties.params}):`,
        array: () => `${properties.name} = [${properties.elements}]`,
        class: () => `class ${properties.name}:`,
        file: () => `open('${properties.name}', '${properties.mode}')`,
        comment: () => `# ${properties.text}`,
        exception: () => `raise ${properties.exception}("${properties.message}")`
      };

      if (contentMap[type]) {
        content.textContent = contentMap[type]();
      }
    }

    // Handle Connector Mouse Down (Start Connection)
    let isConnecting = false;
    let startConnector = null;

    function connectorMouseDown(e, connector) {
      e.preventDefault();
      isConnecting = true;
      startConnector = connector;
      startConnector.classList.add('connecting');
      const startPos = getConnectorPosition(startConnector);
      tempLine.setAttribute('x1', startPos.x);
      tempLine.setAttribute('y1', startPos.y);
      tempLine.setAttribute('x2', startPos.x);
      tempLine.setAttribute('y2', startPos.y);
      tempLine.style.display = 'block';
      workspace.addEventListener('mousemove', connectorMouseMove);
      document.addEventListener('mouseup', connectorMouseUp);
    }

    // Handle Connector Mouse Move (Draw Temporary Line)
    function connectorMouseMove(e) {
      const rect = workspace.getBoundingClientRect();
      const x = e.clientX - rect.left + workspace.scrollLeft;
      const y = e.clientY - rect.top + workspace.scrollTop;
      tempLine.setAttribute('x2', x);
      tempLine.setAttribute('y2', y);
    }

    // Handle Connector Mouse Up (Finalize Connection)
    function connectorMouseUp(e) {
      workspace.removeEventListener('mousemove', connectorMouseMove);
      document.removeEventListener('mouseup', connectorMouseUp);

      tempLine.style.display = 'none';
      startConnector.classList.remove('connecting');

      if (e.target.classList.contains('connector') && e.target !== startConnector) {
        createConnection(startConnector, e.target);
      }

      isConnecting = false;
      startConnector = null;
    }

    // Create Connection Between Two Connectors
    function createConnection(fromConnector, toConnector) {
      if (fromConnector.dataset.type !== toConnector.dataset.type) {
        const fromElementId = fromConnector.parentElement.dataset.id;
        const toElementId = toConnector.parentElement.dataset.id;

        // Prevent connecting an element to itself
        if (fromElementId === toElementId) {
          alert('Невозможно соединить элемент с самим собой.');
          return;
        }

        let sourceId, targetId;
        let sourceConnectorType = fromConnector.dataset.type;
        let targetConnectorType = toConnector.dataset.type;

        if (fromConnector.dataset.type === 'output') {
          sourceId = fromElementId;
          targetId = toElementId;
        } else {
          // If starting from input, invert the connection
          sourceId = toElementId;
          targetId = fromElementId;
          sourceConnectorType = toConnector.dataset.type;
          targetConnectorType = fromConnector.dataset.type;
        }

        // Check if the connection already exists
        const existingConnection = connections.find(
          (conn) =>
            conn.from === sourceId &&
            conn.to === targetId &&
            conn.fromConnectorType === sourceConnectorType &&
            conn.toConnectorType === targetConnectorType
        );

        if (!existingConnection) {
          connections.push({
            from: sourceId,
            to: targetId,
            fromConnectorType: sourceConnectorType,
            toConnectorType: targetConnectorType,
          });

          drawConnections();
          generateCode();
        } else {
          alert('Соединение уже существует.');
        }
      } else {
        alert('Неверное соединение. Соединяйте выход с входом.');
      }
    }

    // Draw All Connections
    function drawConnections() {
      // Remove existing lines except the temporary one
      connectionsSvg.querySelectorAll('.line').forEach((line) => line.remove());

      connections.forEach((conn) => {
        drawSingleConnection(conn);
      });
    }

    // Draw a Single Connection Line
    function drawSingleConnection(conn) {
      const fromElem = document.querySelector(`.workspace-element[data-id="${conn.from}"]`);
      const toElem = document.querySelector(`.workspace-element[data-id="${conn.to}"]`);

      if (!fromElem || !toElem) return;

      const fromConnector = fromElem.querySelector(`.connector.output`);
      const toConnector = toElem.querySelector(`.connector.input`);

      if (fromConnector && toConnector) {
        const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
        const fromPos = getConnectorPosition(fromConnector);
        const toPos = getConnectorPosition(toConnector);

        line.setAttribute('x1', fromPos.x);
        line.setAttribute('y1', fromPos.y);
        line.setAttribute('x2', toPos.x);
        line.setAttribute('y2', toPos.y);
        line.classList.add('line');
        line.setAttribute('marker-end', 'url(#arrowhead)');

        line.addEventListener('click', (e) => {
          e.stopPropagation();
          removeConnectionIfConfirmed(conn, line);
        });

        connectionsSvg.appendChild(line);
      }
    }

    // Remove Connection After Confirmation
    function removeConnectionIfConfirmed(conn, line) {
      if (confirm('Удалить соединение?')) {
        const index = connections.findIndex(
          (c) =>
            c.from === conn.from &&
            c.to === conn.to &&
            c.fromConnectorType === conn.fromConnectorType &&
            c.toConnectorType === conn.toConnectorType
        );
        if (index !== -1) {
          connections.splice(index, 1);
        }

        line.remove();
        generateCode();
      }
    }

    // Get Connector Position Relative to Workspace
    function getConnectorPosition(connector) {
      const rect = connector.getBoundingClientRect();
      const parentRect = workspace.getBoundingClientRect();

      return {
        x: rect.left - parentRect.left + rect.width / 2 + workspace.scrollLeft,
        y: rect.top - parentRect.top + rect.height / 2 + workspace.scrollTop,
      };
    }

    // Generate Python Code from Elements and Connections
    function generateCode() {
      const variableDefinitions = [];
      const codeLines = [];
      const processedVariables = new Set();
      const processedElements = new Set();

      // Collect Early Declarations
      elements.forEach(element => {
        if (element.type === 'variable' && !processedVariables.has(element.id)) {
          processedVariables.add(element.id);
          if (element.properties.declareEarly && element.properties.name) {
            variableDefinitions.push(`${element.properties.name} = ${formatValue(element.properties.initialValue, element.properties.type)}`);
          }
        }
      });

      // Get Root Elements (No Incoming Connections)
      getRoots().forEach(root => {
        generateElementCodePython(root, codeLines, 0, processedElements);
      });

      // Combine Variable Definitions and Code Lines
      consoleOutput.textContent = [...variableDefinitions, ...codeLines].join('\n');
    }

    // Get Root Elements
    function getRoots() {
      return elements.filter(el => connections.every(conn => conn.to !== el.id));
    }

    // Get Child Elements Connected from a Given Element
    function getChildren(elementId) {
      return connections
        .filter(conn => conn.from === elementId)
        .map(conn => elements.find(el => el.id === conn.to))
        .filter(el => el);
    }

    // Recursively Generate Code for Each Element
    function generateElementCodePython(element, codeLines, indentLevel, processedElements) {
      if (processedElements.has(element.id)) return;
      processedElements.add(element.id);

      const indent = '  '.repeat(indentLevel);
      const codeGenerators = {
        variable: () => {
          if (!element.properties.declareEarly && element.properties.name) {
            codeLines.push(`${indent}${element.properties.name} = ${formatValue(element.properties.value, element.properties.type)}`);
          }
        },
        condition: () => {
          if (element.properties.condition) {
            codeLines.push(`${indent}if ${element.properties.condition}:`);
            const children = getChildren(element.id);
            if (children.length === 0) {
              codeLines.push(`${indent}  pass`);
            } else {
              children.forEach(child => generateElementCodePython(child, codeLines, indentLevel + 1, processedElements));
            }
          }
        },
        action: () => {
          if (element.properties.action) {
            codeLines.push(`${indent}${element.properties.action}`);
          }
        },
        input: () => {
          if (element.properties.name) {
            codeLines.push(`${indent}${element.properties.name} = input()`);
          }
        },
        output: () => {
          if (element.properties.name) {
            codeLines.push(`${indent}print(${element.properties.name})`);
          }
        },
        loop: () => {
          if (element.properties.iterations) {
            codeLines.push(`${indent}for i in range(${element.properties.iterations}):`);
            const loopChildren = getChildren(element.id);
            if (loopChildren.length === 0) {
              codeLines.push(`${indent}  pass`);
            } else {
              loopChildren.forEach(child => generateElementCodePython(child, codeLines, indentLevel + 1, processedElements));
            }
          }
        },
        function: () => {
          if (element.properties.name) {
            const params = element.properties.params || '';
            const body = element.properties.body || 'pass';
            codeLines.push(`${indent}def ${element.properties.name}(${params}):`);
            if (body.trim() === '') {
              codeLines.push(`${indent}  pass`);
            } else {
              // Handle multi-line body
              const bodyLines = body.split('\n');
              bodyLines.forEach(line => {
                codeLines.push(`${indent}  ${line.trim()}`);
              });
            }
          }
        },
        array: () => {
          if (element.properties.name) {
            const elementsList = element.properties.elements || '';
            codeLines.push(`${indent}${element.properties.name} = [${elementsList}]`);
          }
        },
        class: () => {
          if (element.properties.name) {
            const attributes = element.properties.attributes || '';
            codeLines.push(`${indent}class ${element.properties.name}:`);
            if (attributes.trim() === '') {
              codeLines.push(`${indent}  pass`);
            } else {
              const attrs = attributes.split(',').map(attr => attr.trim()).filter(attr => attr !== '');
              codeLines.push(`${indent}  def __init__(self, ${attrs.join(', ')}):`);
              attrs.forEach(attr => {
                codeLines.push(`${indent}    self.${attr} = ${attr}`);
              });
            }
          }
        },
        file: () => {
          if (element.properties.name && element.properties.mode) {
            codeLines.push(`${indent}with open('${element.properties.name}', '${element.properties.mode}') as file:`);
            codeLines.push(`${indent}  pass  # работа с файлом`);
          }
        },
        comment: () => {
          if (element.properties.text) {
            codeLines.push(`${indent}# ${element.properties.text}`);
          }
        },
        exception: () => {
          if (element.properties.exception) {
            const message = element.properties.message || '';
            codeLines.push(`${indent}raise ${element.properties.exception}("${message}")`);
          }
        }
      };

      // Handle Custom Elements
      const customElementCode = () => {
        const codeTemplate = element.properties.codeTemplate;
        if (codeTemplate) {
          let code = codeTemplate;
          for (const param in element.properties) {
            if (param !== 'codeTemplate') {
              const regex = new RegExp(`{${param}}`, 'g');
              code = code.replace(regex, element.properties[param]);
            }
          }
          codeLines.push(`${indent}${code}`);
        }
      };

      // Execute the appropriate code generator
      if (codeGenerators[element.type]) {
        codeGenerators[element.type]();
      } else if (element.custom) {
        customElementCode();
      }
    }

    // Format Value Based on Type
    function formatValue(value, type) {
      if (type === 'string') {
        return `"${value.replace(/"/g, '')}"`;
      } else if (type === 'bool') {
        return value.toLowerCase() === 'true' ? 'True' : 'False';
      }
      return value;
    }

    // Capitalize First Letter Utility
    function capitalizeFirstLetter(string) {
      return string.charAt(0).toUpperCase() + string.slice(1);
    }

    // Context Menu for Deleting Elements
    workspace.addEventListener('contextmenu', (e) => {
      e.preventDefault();
      let targetElem = null;
      if (e.target.classList.contains('workspace-element')) {
        targetElem = e.target;
      } else if (e.target.parentElement.classList.contains('workspace-element')) {
        targetElem = e.target.parentElement;
      }

      if (targetElem) {
        const elementId = targetElem.dataset.id;
        removeElementIfConfirmed(targetElem, elementId);
      }
    });

    // Remove Element and Its Connections After Confirmation
    function removeElementIfConfirmed(targetElem, elementId) {
      if (confirm('Удалить элемент и все связанные с ним соединения?')) {
        targetElem.style.transition = 'opacity 0.5s, transform 0.5s';
        targetElem.style.opacity = '0';
        targetElem.style.transform = 'scale(0.5)';

        setTimeout(() => {
          const elementIndex = elements.findIndex((el) => el.id === elementId);
          if (elementIndex !== -1) {
            elements.splice(elementIndex, 1);
          }

          connections = connections.filter(conn => conn.from !== elementId && conn.to !== elementId);
          targetElem.remove();

          if (selectedElements.includes(targetElem)) {
            selectedElements = selectedElements.filter((el) => el !== targetElem);
            showProperties();
          }

          drawConnections();
          generateCode();
        }, 500);
      }
    }

    // Handle Custom Element Form Submission
    createElementForm.addEventListener('submit', handleCreateElementSubmit);

    function handleCreateElementSubmit(e) {
      e.preventDefault();
      const name = document.getElementById('custom-element-name').value.trim();
      const paramsText = document.getElementById('custom-element-params').value.trim();
      const codeTemplate = document.getElementById('custom-element-code-template').value.trim();
      const connectors = document.getElementById('custom-element-connectors').value;

      if (!name || !paramsText || !codeTemplate) {
        alert('Пожалуйста, заполните все поля.');
        return;
      }

      let params;
      try {
        params = JSON.parse(paramsText);
      } catch (error) {
        alert('Ошибка в формате параметров. Используйте корректный JSON.');
        return;
      }

      manageCustomElement(name, params, codeTemplate, connectors);
    }

    // Manage Custom Elements (Create or Update)
    function manageCustomElement(name, params, codeTemplate, connectors) {
      if (editingElementIndex !== null) {
        updateCustomElement(name, params, codeTemplate, connectors);
      } else {
        if (!customElements.some(el => el.name === name)) {
          const customElement = {
            name,
            params,
            codeTemplate,
            connectors,
          };

          customElements.push(customElement);
          saveCustomElementsToLocalStorage();
          addCustomElementToSidebar(customElement);
        } else {
          alert('Элемент с таким именем уже существует.');
          return;
        }

        modalOverlay.style.display = 'none';
        createElementForm.reset();
      }
    }

    // Update Existing Custom Element
    function updateCustomElement(name, params, codeTemplate, connectors) {
      if (customElements.some((el, idx) => el.name === name && idx !== editingElementIndex)) {
        alert('Элемент с таким именем уже существует.');
        return;
      }

      customElements[editingElementIndex] = {
        name,
        params,
        codeTemplate,
        connectors,
      };
      saveCustomElementsToLocalStorage();

      customElementsContainer.innerHTML = '<h4>Пользовательские элементы</h4>';
      customElements.forEach(customEl => addCustomElementToSidebar(customEl));

      elements.forEach((elData) => {
        if (elData.custom && elData.type === name) {
          elData.properties = { ...params, codeTemplate: elData.codeTemplate };
          addConnectors(elData.domElement, connectors);
          updateElementContent(elData.domElement, elData);
        }
      });

      drawConnections();
      generateCode();

      editingElementIndex = null;
      modalTitle.textContent = 'Создать новый элемент';
      createElementButton.textContent = 'Создать';

      modalOverlay.style.display = 'none';
      createElementForm.reset();
    }

    // Copy Generated Code to Clipboard
    function copyCodeToClipboard() {
      const code = consoleOutput.textContent;
      if (code.trim() === '') {
        alert('Нет кода для копирования.');
        return;
      }
      navigator.clipboard.writeText(code).then(() => {
        alert('Код скопирован в буфер обмена!');
      }).catch(err => {
        alert('Ошибка при копировании: ' + err);
      });
    }

    // Load Custom Elements on Page Load
    loadCustomElementsFromLocalStorage();
  </script>
</body>
</html>