Skip to content

Latest commit

 

History

History
779 lines (626 loc) · 40.4 KB

File metadata and controls

779 lines (626 loc) · 40.4 KB

Platform License GitHub release GitHub downloads GitHub issues GitHub stars Donate

SwitchShuttle Logo

SwitchShuttle

🚀 Кроссплатформенный менеджер терминальных команд с глобальными горячими клавишами

SwitchShuttle Demo

✨ Что такое SwitchShuttle?

SwitchShuttle — это мощное кроссплатформенное приложение для системного трея, которое революционизирует способ управления и выполнения терминальных команд. Построенное на современных технологиях (Rust + Tauri + Vue.js), оно предоставляет элегантный интерфейс для организации, настройки и быстрого доступа к наиболее часто используемым терминальным операциям.

🎯 Ключевые возможности

  • 🖥️ Мультиплатформенная поддержка - Работает на macOS, Windows и Linux
  • ⚡ Глобальные горячие клавиши - Выполняйте команды мгновенно из любого места
  • 🎨 Поддержка множества терминалов - iTerm, Terminal, Warp, Alacritty, Hyper и другие
  • 📁 Умная организация - Создавайте вложенные подменю для лучшей организации команд
  • 🔧 Динамические входные данные - Интерактивные запросы для команд, требующих ввода пользователя
  • 🔄 Множественные режимы выполнения - Запуск в текущем окне, новой вкладке или новом окне
  • 🚀 Автозапуск - Запуск при старте системы для мгновенного доступа
  • 🎨 Современный интерфейс - Красивый, интуитивный интерфейс на Vue.js
  • 💻 Командная строка - Выполняйте команды напрямую из терминала с CLI
  • ⚙️ Управление конфигурациями - Включайте/выключайте конфигурации без удаления
  • 🔄 Команды-переключатели - Переключайте системные функции с фоновым выполнением
  • 📊 Команды мониторинга - Мониторинг системных ресурсов в реальном времени с визуальными индикаторами
  • 📅 Запланированные команды - Автоматизация задач с помощью cron выражений
  • 🎯 Система шаблонов - Готовые шаблоны команд для распространенных рабочих процессов

🖥️ Обзор пользовательского интерфейса

SwitchShuttle предоставляет современный, интуитивный интерфейс с несколькими ключевыми компонентами:

🎛️ Основные компоненты интерфейса

1. Редактор конфигураций

  • Визуальный JSON редактор - Редактирование конфигураций с подсветкой синтаксиса и валидацией
  • Система шаблонов - Импорт готовых шаблонов команд для распространенных рабочих процессов
  • Валидация в реальном времени - Мгновенная обратная связь об ошибках конфигурации
  • Автосохранение - Изменения автоматически сохраняются при вводе
  • Управление конфигурациями - Включение/выключение конфигураций без удаления
  • Поиск и фильтрация - Быстрый поиск конкретных конфигураций
  • Дублирование конфигураций - Создание копий существующих конфигураций для тестирования

2. Управление командами

  • Конструктор команд - Создание команд с помощью визуального интерфейса форм
  • Настройка горячих клавиш - Установка глобальных сокращений для мгновенного выполнения команд
  • Выбор иконок - Выбор эмодзи иконок для лучшей визуальной организации
  • Поля ввода - Настройка динамических запросов ввода для интерактивных команд
  • Вложенные подменю - Организация команд в иерархические структуры
  • Валидация команд - Валидация синтаксиса команд в реальном времени

3. Панель настроек

  • Выбор терминала - Выбор предпочитаемого терминального приложения
  • Режим запуска - Настройка способа выполнения команд (текущее/новая вкладка/новое окно)
  • Настройки темы - Настройка внешнего вида приложения
  • Конфигурация автозапуска - Включение/выключение запуска при старте системы
  • Настройки глобальных горячих клавиш - Настройка системных сокращений для меню

4. Меню системного трея

  • Быстрый доступ - Щелчок правой кнопкой по иконке трея для мгновенного доступа к командам
  • Индикаторы статуса - Визуальная обратная связь для команд-переключателей и мониторинга
  • Вложенные меню - Организованная иерархия команд для легкой навигации
  • Глобальные горячие клавиши - Сочетания клавиш для немедленного выполнения команд
  • Мониторинг в реальном времени - Живые индикаторы системных ресурсов

🎨 Возможности интерфейса

Визуальный конструктор команд

{
  "name": "🚀 Запустить сервер разработки",
  "command": "npm run dev",
  "hotkey": "Ctrl+Shift+D",
  "icon": "🚀",
  "background": false,
  "inputs": {
    "port": "3000",
    "host": "localhost"
  }
}

Система шаблонов

SwitchShuttle включает готовые шаблоны для распространенных рабочих процессов разработки:

  • Разработка - Операции Git, инструменты сборки, тестирование
  • DevOps - Docker, Kubernetes, управление серверами
  • База данных - Операции MySQL, PostgreSQL, MongoDB
  • Облачные сервисы - Команды AWS, Azure, Google Cloud
  • Безопасность - Сканирование сети, оценка уязвимостей
  • Мониторинг - Системные ресурсы, логи, метрики
  • Утилиты - Операции с файлами, системные инструменты
  • Планировщик - Cron задачи и автоматизированные задачи

Умная организация

  • Вложенные подменю - Организация команд в логические группы
  • Поддержка иконок - Визуальная идентификация с помощью эмодзи иконок
  • Управление горячими клавишами - Глобальные сокращения для мгновенного доступа
  • Индикаторы статуса - Обратная связь в реальном времени для команд-переключателей
  • Функция поиска - Быстрое обнаружение команд

🔒 Менеджер безопасности

SwitchShuttle включает комплексный Менеджер безопасности, который защищает вашу систему от потенциально вредоносных команд и предоставляет детальный контроль над выполнением команд.

🛡️ Функции безопасности

Валидация команд

  • Ограничения длины: Максимальная длина команды (1000 символов) и длина ввода (500 символов) предотвращают слишком длинные команды
  • Заблокированные команды: Определите список опасных команд, которые никогда не должны выполняться
  • Подозрительные паттерны: Используйте regex паттерны для обнаружения и блокировки потенциально вредоносных паттернов команд
  • Валидация в реальном времени: Команды проверяются во время редактирования для обеспечения безопасности

Настройки безопасности

  • Включение/выключение безопасности: Переключайте функции безопасности по необходимости
  • Пользовательские списки блокировки: Добавляйте конкретные команды в список заблокированных команд
  • Сопоставление паттернов: Определяйте regex паттерны для обнаружения подозрительных структур команд
  • Ограничения длины: Настройте максимальные длины для команд и пользовательских вводов

Как это работает

  1. Валидация в редакторе: SecurityManager проверяет команды в редакторе конфигураций перед сохранением
  2. Сопоставление паттернов: Команды проверяются на соответствие заблокированным паттернам и подозрительным regex паттернам
  3. Валидация длины: Команды и вводы проверяются на соответствие максимальным ограничениям длины
  4. Проверка списка блокировки: Команды сравниваются с пользовательским списком заблокированных команд
  5. Безопасная конфигурация: Только проверенные конфигурации разрешены к сохранению и использованию

🚀 Быстрый старт

Скачивание и установка

Вариант 1: Homebrew (macOS - Рекомендуется)

# Установка через Homebrew
brew tap s00d/switchshuttle
brew install --cask switchshuttle

Вариант 2: Ручное скачивание

  1. Скачайте последний релиз для вашей платформы с GitHub Releases
  2. Установите приложение
  3. Запустите SwitchShuttle - он появится в системном трее
  4. Щелкните правой кнопкой по иконке трея для доступа к меню

Первая настройка

  1. Откройте редактор конфигураций - Нажмите "Редактировать конфигурацию" в меню системного трея
  2. Выберите терминал - Выберите предпочитаемое терминальное приложение
  3. Добавьте команды - Используйте визуальный редактор или импортируйте шаблоны
  4. Настройте горячие клавиши - Настройте глобальные сокращения для быстрого доступа
  5. Сохраните и перезапустите - Ваши команды теперь доступны в меню трея

Пошаговое руководство по интерфейсу

Шаг 1: Редактор конфигураций

  • Откройте SwitchShuttle и перейдите на вкладку "Редактор"
  • Выберите терминальное приложение (iTerm, Terminal, Warp и т.д.)
  • Установите режим запуска (текущее окно, новая вкладка или новое окно)
  • Настройте глобальные горячие клавиши для доступа к меню

Шаг 2: Добавление команд

  • Нажмите "Добавить команду" для создания новой команды
  • Заполните детали команды:
    • Имя: Отображаемое имя команды
    • Команда: Фактическая терминальная команда для выполнения
    • Горячая клавиша: Глобальное сокращение (необязательно)
    • Иконка: Эмодзи иконка для визуальной идентификации
    • Фон: Запускать ли в фоновом режиме
    • Входные данные: Динамические поля ввода для интерактивных команд

Шаг 3: Использование шаблонов

  • Нажмите "Импортировать шаблон" для доступа к готовым коллекциям команд
  • Просмотрите категории, такие как Разработка, DevOps, База данных и т.д.
  • Выберите и импортируйте нужные шаблоны
  • Настройте импортированные команды по необходимости

Шаг 4: Доступ через системный трей

  • Щелкните правой кнопкой по иконке SwitchShuttle в трее
  • Просмотрите организованное меню команд
  • Используйте глобальные горячие клавиши для мгновенного выполнения команд
  • Отслеживайте статус системы с помощью индикаторов в реальном времени

Шаг 5: Расширенные возможности

  • Команды-переключатели: Переключение системных функций с визуальными индикаторами статуса
  • Команды мониторинга: Мониторинг системных ресурсов в реальном времени
  • Запланированные команды: Автоматизация задач с помощью cron выражений
  • Вложенные меню: Организация команд в иерархические структуры

💻 Командная строка (CLI)

SwitchShuttle также предоставляет мощный интерфейс командной строки для быстрого выполнения команд без открытия GUI.

Использование CLI

Выполнение команд

# Выполнение по ID команды
switch-shuttle cmd_8

# Выполнение по имени команды (без учета регистра)
switch-shuttle "Пример команды"

Список всех команд

# Показать все доступные команды с их ID
switch-shuttle --list
# или
switch-shuttle -l

Поиск команд

# Поиск команд, содержащих определенный текст
switch-shuttle --search "git"
# или
switch-shuttle -s "docker"

Запуск CLI на разных операционных системах

macOS

# Если установлено через Homebrew
switch-shuttle --list

# Если установлено вручную
/Applications/switch-shuttle.app/Contents/MacOS/SwitchShuttle --list

# Создать алиас для более легкого доступа
echo 'alias switch-shuttle="/Applications/switch-shuttle.app/Contents/MacOS/SwitchShuttle"' >> ~/.zshrc
source ~/.zshrc

Windows

# Если установлено через установщик
"C:\Program Files\SwitchShuttle\switch-shuttle.exe" --list

# Если установлено через winget или chocolatey
switch-shuttle --list

# Добавить в PATH для более легкого доступа
# Добавьте "C:\Program Files\SwitchShuttle" в системный PATH

Linux

# Если установлено через менеджер пакетов
switch-shuttle --list

# Если установлено вручную
./switch-shuttle --list

# Сделать исполняемым и добавить в PATH
chmod +x switch-shuttle
sudo mv switch-shuttle /usr/local/bin/

Примеры CLI

# Быстрые операции Git
switch-shuttle "git status"
switch-shuttle "git pull"

# Рабочие процессы разработки
switch-shuttle "npm run dev"
switch-shuttle "docker-compose up"

# Список всех доступных команд
switch-shuttle --list

# Найти команды, связанные с базой данных
switch-shuttle --search "database"

Возможности CLI

  • 🚀 Быстрое выполнение - Запуск команд мгновенно из терминала
  • 🔍 Умный поиск - Поиск команд по ID или имени
  • 📋 Список команд - Просмотр всех доступных команд
  • ⚡ Без GUI - Идеально для автоматизации и скриптов
  • 🔄 Выход после выполнения - Чистый опыт работы с терминалом

📋 Руководство по конфигурации

Базовая структура

SwitchShuttle использует JSON файлы конфигурации, хранящиеся в:

  • macOS/Linux: ~/.config/switch-shuttle/
  • Windows: C:\Users\<Username>\AppData\Roaming\switch-shuttle\

Простой пример

{
  "terminal": "iterm",
  "launch_in": "new_tab",
  "title": "Мои команды",
  "commands": [
    {
      "name": "🚀 Запустить сервер разработки",
      "command": "npm run dev",
      "hotkey": "Ctrl+Shift+D"
    },
    {
      "name": "📦 Установить зависимости",
      "command": "npm install",
      "hotkey": "Ctrl+Shift+I"
    },
    {
      "name": "🔧 Инструменты разработки",
      "submenu": [
        {
          "name": "🧪 Запустить тесты",
          "command": "npm test",
          "hotkey": "Ctrl+Shift+T"
        },
        {
          "name": "📊 Собрать проект",
          "command": "npm run build",
          "hotkey": "Ctrl+Shift+B"
        }
      ]
    }
  ]
}

Расширенные возможности

🔧 Динамические входные данные

Создавайте интерактивные команды, которые запрашивают ввод пользователя:

{
  "name": "📝 Создать новый компонент",
  "inputs": {
    "componentName": "MyComponent",
    "componentType": "functional"
  },
  "commands": [
    "mkdir -p src/components/[componentName]",
    "touch src/components/[componentName]/index.tsx",
    "echo 'import React from \"react\";' > src/components/[componentName]/index.tsx",
    "echo 'export const [componentName] = () => <div>[componentName]</div>;' >> src/components/[componentName]/index.tsx"
  ],
  "hotkey": "Ctrl+Shift+N"
}

🔄 Множественные команды

Выполнение последовательности команд:

{
  "name": "🔄 Полный цикл разработки",
  "commands": [
    "git pull origin main",
    "npm install",
    "npm run lint",
    "npm run test",
    "npm run build"
  ],
  "background": true,
  "hotkey": "Ctrl+Shift+F"
}

⏰ Запланированные команды (Cron)

Планируйте команды для автоматического выполнения с помощью cron выражений:

{
  "name": "🔄 Автоматическое резервное копирование",
  "commands": [
    "rsync -av /source/ /backup/"
  ],
  "scheduler": "0 2 * * *",
  "background": true,
  "hotkey": "Ctrl+Shift+B"
}

Формат Cron выражений: Планировщик использует стандартные cron выражения с 6 полями: секунда минута час день месяц день_недели

Распространенные примеры Cron:

  • "0 0 * * * *" - Каждый час в минуту 0
  • "0 0 2 * * *" - Каждый день в 2:00 утра
  • "0 30 9 * * 1-5" - В рабочие дни в 9:30 утра
  • "0 0 12 * * 1" - Каждый понедельник в полдень
  • "0 0 0 1 * *" - Первый день каждого месяца
  • "0 */15 * * * *" - Каждые 15 минут
  • "0 0 0 * * 0" - Каждое воскресенье в полночь

Возможности планировщика:

  • Фоновое выполнение - Команды выполняются тихо без открытия терминала
  • Поддержка Cron - Полный парсинг и выполнение cron выражений
  • Обработка ошибок - Graceful fallback при ошибках парсинга cron
  • Кроссплатформенность - Работает на macOS, Windows и Linux

🖥️ Фоновое выполнение

Контролируйте способ выполнения команд - в фоне с помощью ConsolePool или обычное выполнение в терминале:

{
  "name": "🚀 Запустить сервер",
  "commands": [
    "npm run dev"
  ],
  "background": true,
  "hotkey": "Ctrl+Shift+S"
}

Варианты фонового выполнения:

  • "background": true - Выполнение с помощью ConsolePool (фон)
  • "background": false - Выполнение с помощью обычного терминала
  • "background": null или пропуск - Автоопределение на основе типа команды

📁 Вложенные подменю

Организуйте команды в иерархические меню:

{
  "name": "🐳 Операции Docker",
  "submenu": [
    {
      "name": "🚀 Запустить сервисы",
      "submenu": [
        {
          "name": "🏗️ Разработка",
          "command": "docker-compose -f docker-compose.dev.yml up -d"
        },
        {
          "name": "🏭 Продакшн",
          "command": "docker-compose -f docker-compose.prod.yml up -d"
        }
      ]
    },
    {
      "name": "🛑 Остановить все",
      "command": "docker-compose down"
    }
  ]
}

🔄 Команды-переключатели

Переключайте системные функции с фоновым выполнением:

{
  "name": "🔧 Системные элементы управления",
  "submenu": [
    {
      "name": "📶 Переключить WiFi",
      "command": "networksetup -setairportpower en0 toggle",
      "switch": "networksetup -getairportpower en0 | grep -q 'On' && echo 'true' || echo 'false'"
    },
    {
      "name": "🔊 Переключить Bluetooth",
      "command": "blueutil -p toggle",
      "switch": "blueutil -p | grep -q '1' && echo 'true' || echo 'false'"
    },
    {
      "name": "🌙 Переключить темный режим",
      "command": "osascript -e 'tell app \"System Events\" to tell appearance preferences to set dark mode to not dark mode'",
      "switch": "osascript -e 'tell app \"System Events\" to tell appearance preferences to get dark mode'"
    }
  ]
}

Возможности команд-переключателей:

  • Фоновое выполнение - Команды выполняются тихо без открытия терминала
  • Проверка статуса - Автоматически определяет текущее состояние
  • Визуальная обратная связь - Показывает статус включено/выключено в меню
  • Кроссплатформенность - Работает на macOS, Windows и Linux

📊 Команды мониторинга

Мониторьте системные ресурсы и сервисы с информацией в реальном времени:

{
  "name": "📊 Системный мониторинг",
  "submenu": [
    {
      "name": "💾 Использование памяти",
      "command": "top -l 1 | head -n 10",
      "monitor": "memory",
      "icon": "🧠"
    },
    {
      "name": "💻 Загрузка CPU",
      "command": "top -l 1 | grep 'CPU usage'",
      "monitor": "cpu",
      "icon": ""
    },
    {
      "name": "💾 Свободное место на диске",
      "command": "df -h | grep '/dev/'",
      "monitor": "disk",
      "icon": "💾"
    },
    {
      "name": "🌐 Статус сети",
      "command": "ifconfig | grep -E 'inet |status:'",
      "monitor": "network",
      "icon": "🌐"
    }
  ]
}

Возможности команд мониторинга:

  • Интеграция с меню - Добавление кнопок мониторинга в меню системного трея
  • Выполнение команд - Выполнение команд мониторинга при открытии меню
  • Отображение данных - Показ вывода команд прямо в интерфейсе меню
  • Визуальные индикаторы - Иконки и индикаторы статуса в меню
  • Кроссплатформенность - Работает на macOS, Windows и Linux

⚙️ Справочник по конфигурации

Основная конфигурация

Параметр Тип Описание По умолчанию
terminal String Терминальное приложение для использования "terminal"
launch_in String Где запускать команды "current"
theme String Тема терминала (если поддерживается) -
title String Заголовок окна/вкладки -
menu_hotkey String Глобальная горячая клавиша для открытия меню -
commands Array Список конфигураций команд []
enabled Boolean Должна ли эта конфигурация загружаться true

Варианты терминалов

Терминал macOS Windows Linux
iterm
terminal
warp
alacritty
hyper

Режимы запуска

Режим Описание
current Выполнение в текущем окне терминала
new_tab Открыть новую вкладку и выполнить
new_window Открыть новое окно и выполнить

Конфигурация команд

Параметр Тип Обязательный Описание
name String Отображаемое имя команды
commands Array Множественные команды для выполнения
submenu Array Вложенные подкоманды
switch String Команда для проверки состояния переключателя (возвращает true/false)
monitor String Команда для получения значения отображения для мониторинга
inputs Object Динамические поля ввода
hotkey String Глобальная горячая клавиша
icon String Эмодзи иконка для визуальной идентификации
background Boolean Выполнение в фоне (ConsolePool) или обычный терминал
scheduler String Cron выражение для запланированного выполнения

Управление конфигурациями

Включение/выключение конфигураций

Вы можете включать или выключать отдельные файлы конфигурации для контроля того, какие команды доступны в меню системного трея. Это полезно для:

  • Временного отключения - Отключение конфигураций без удаления
  • Тестирования - Включение/отключение конфигураций во время разработки
  • Организации - Хранение множественных конфигураций, но использование только конкретных

В визуальном редакторе:

  • Откройте редактор конфигураций
  • Используйте переключатель в разделе "Статус конфигурации"
  • Включенные конфигурации будут загружены и доступны в меню
  • Отключенные конфигурации будут проигнорированы

В JSON конфигурации:

{
  "terminal": "iterm",
  "launch_in": "current",
  "title": "Мои команды",
  "enabled": true,
  "commands": [
    {
      "name": "Пример команды",
      "command": "echo Hello World"
    }
  ]
}
Параметр Тип По умолчанию Описание
enabled Boolean true Должна ли эта конфигурация загружаться и быть доступной в меню

Примечание: Когда enabled установлен в false или пропущен, конфигурация будет проигнорирована и её команды не появятся в меню системного трея.

🎯 Случаи использования

👨‍💻 Разработчики

  • Быстрая навигация по проектам - Мгновенный переход к разным проектам
  • Рабочие процессы сборки и тестирования - Однонажатные циклы разработки
  • Управление Docker - Запуск/остановка контейнеров с горячими клавишами
  • Операции Git - Общие git команды под рукой
  • Управление серверами разработки - Запуск/остановка серверов разработки
  • Инструменты качества кода - Запуск линтеров, форматтеров и тестов

🛠️ DevOps инженеры

  • Управление серверами - SSH соединения и серверные команды
  • Инструменты мониторинга - Быстрый доступ к логам и метрикам
  • Скрипты развертывания - Автоматизированные рабочие процессы развертывания
  • Операции с базой данных - Общие команды базы данных
  • Оркестрация контейнеров - Управление Docker и Kubernetes
  • Мониторинг инфраструктуры - Отслеживание системных ресурсов

🎨 Дизайнеры

  • Оптимизация ресурсов - Обработка и оптимизация изображений
  • Инструменты дизайн-системы - Генерация и обновление компонентов
  • Серверы прототипов - Быстрый запуск серверов дизайна
  • Автоматизация инструментов дизайна - Пакетная обработка и рабочие процессы

🔧 Системные администраторы

  • Системный мониторинг - Мониторинг ресурсов в реальном времени
  • Управление сервисами - Запуск/остановка системных сервисов
  • Автоматизация резервного копирования - Запланированные операции резервного копирования
  • Сетевые инструменты - Диагностика и конфигурация сети
  • Инструменты безопасности - Сканирование уязвимостей и оценка
  • Задачи обслуживания - Очистка и оптимизация системы

🔧 Сборка из исходного кода

Предварительные требования

  • Rust (последняя стабильная версия)
  • Node.js (v16 или выше)
  • pnpm (рекомендуемый менеджер пакетов)
  • Tauri CLI

Шаги сборки

# Клонировать репозиторий
git clone https://github.com/s00d/switchshuttle.git
cd switchshuttle

# Установить зависимости
pnpm install

# Режим разработки
pnpm run tauri dev

# Сборка для продакшена
pnpm run tauri build

Заметки для конкретных платформ

macOS

# Если у вас проблемы с подписью
chmod +x /Applications/switch-shuttle.app
xattr -cr /Applications/switch-shuttle.app
codesign --force --deep --sign - /Applications/switch-shuttle.app

Windows

# Установить Rust и Node.js
# Затем следуйте шагам сборки выше

Linux

# Установить системные зависимости
sudo apt-get update
sudo apt-get install libwebkit2gtk-4.0-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev

# Затем следуйте шагам сборки выше

🤝 Участие в разработке

Мы приветствуем вклад! Вот как вы можете помочь:

  1. Форкните репозиторий
  2. Создайте ветку функции (git checkout -b feature/amazing-feature)
  3. Зафиксируйте ваши изменения (git commit -m 'Add amazing feature')
  4. Отправьте в ветку (git push origin feature/amazing-feature)
  5. Откройте Pull Request

Рекомендации по разработке

  • Следуйте существующему стилю кода
  • Добавляйте тесты для новых функций
  • Обновляйте документацию по мере необходимости
  • Обеспечивайте кроссплатформенную совместимость
  • Используйте pnpm для управления пакетами

Настройка разработки

# Установить зависимости
pnpm install

# Запустить сервер разработки
pnpm run tauri dev

# Запустить проверку типов
pnpm run type-check

# Собрать для продакшена
pnpm run tauri build

📄 Лицензия

Этот проект лицензирован под MIT License - см. файл LICENSE для деталей.

🙏 Благодарности

  • Вдохновлен оригинальным проектом Shuttle
  • Построен с помощью Tauri для кроссплатформенных десктопных приложений
  • UI работает на Vue.js
  • Стилизован с помощью Tailwind CSS

📞 Поддержка


Создано с ❤️ сообществом SwitchShuttle

⭐ Поставьте звезду этому репозиторию, если он вам полезен!