docs: добавь поясняющие комментарии к модулям и инструментам
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
# Входная точка пакета altera_logic. Определяет доступные при импорте имена; подробные
|
||||
# контракты находятся в специализированных модулях пакета. Изменение реэкспортов влияет на
|
||||
# существующие import у потребителей.
|
||||
|
||||
"""Portable Altera analyzer client. Wire protocol and sequencing live in C99."""
|
||||
from .native import Capture, NativeAnalyzer
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Состояние измерительных маркеров и линеек графика. Маркер относится к координатам
|
||||
# отображаемого сигнала; его перемещение не изменяет полученные выборки или настройки
|
||||
# транспорта.
|
||||
|
||||
"""Presentation state for waveform rulers; no transport or wire processing."""
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
# Автомат UART-клиента логического анализатора Altera: запрос, накопление ответа и контроль
|
||||
# времени. Одновременно выполняется одна операция; ARM нельзя безусловно повторять, поскольку
|
||||
# повторный запуск меняет состояние захвата. Здесь только ctypes-привязка: протокольного
|
||||
# fallback на Python нет.
|
||||
|
||||
"""ctypes binding only: no Python packet codec or protocol fallback."""
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Qt-прокрутка области графика анализатора: колесо перемещает X, Ctrl с колесом — Y.
|
||||
# Обработчик меняет область просмотра, сохраняя масштаб и исходный массив захвата.
|
||||
|
||||
"""Qt presentation port: wheel pans X; Ctrl+wheel pans Y, never zooms."""
|
||||
from PySide6.QtCore import Qt, Signal
|
||||
from PySide6.QtWidgets import QScrollArea
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Последовательный Qt-порт анализатора Altera. Порт обслуживает соединение, таймеры и события,
|
||||
# а решения о запросах, ответах и таймаутах принимает автомат C99.
|
||||
|
||||
"""Qt serial/lifecycle port. Protocol decisions are exclusively in C99."""
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Клиентский приём потока SETCAN логического анализатора. CAN-события или UART-оболочка
|
||||
# передаются общему приёмнику; накопление выборок и частота перерисовки разделены, чтобы поток
|
||||
# пакетов не перегружал GUI.
|
||||
|
||||
"""SETCAN streaming FFI and immutable display/export models. No wire codec."""
|
||||
from __future__ import annotations
|
||||
import csv
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Клиентский приём потока SETCAN логического анализатора. CAN-события или UART-оболочка
|
||||
# передаются общему приёмнику; накопление выборок и частота перерисовки разделены, чтобы поток
|
||||
# пакетов не перегружал GUI.
|
||||
|
||||
"""Qt transport/lifecycle port for the C SETCAN stream receiver.
|
||||
|
||||
CAN ingress accepts canonical RX events from an existing bus connection.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Контракт обработки снимков графика: входные ряды, запрос расчёта и результирующие кривые.
|
||||
# Вычисленные данные отделены от исходных измерений; численная обработка делегируется общему
|
||||
# ядру C99.
|
||||
|
||||
"""Sparse sine reconstruction using the public contract, independent of a GUI."""
|
||||
import argparse
|
||||
import math
|
||||
|
||||
@@ -1,2 +1,6 @@
|
||||
# Входная точка пакета firmware_image. Определяет доступные при импорте имена; подробные
|
||||
# контракты находятся в специализированных модулях пакета. Изменение реэкспортов влияет на
|
||||
# существующие import у потребителей.
|
||||
|
||||
"""Shared firmware images and flash layout plans."""
|
||||
from .core import *
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Проверка Intel HEX и подготовка адресованного образа прошивки. Контрольные суммы записей,
|
||||
# расширенные адреса и пересечения проверяются до использования результата; рабочая память
|
||||
# C-парсера принадлежит вызывающему.
|
||||
|
||||
"""Переносимое ядро проверки образа прошивки STM32.
|
||||
|
||||
Модуль не знает ни про HTTP, ни про Modbus, ни про файловую систему, ни про
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
# Проверка Intel HEX и подготовка адресованного образа прошивки. Контрольные суммы записей,
|
||||
# расширенные адреса и пересечения проверяются до использования результата; рабочая память
|
||||
# C-парсера принадлежит вызывающему. Python-слой предоставляет модели и ctypes-вызовы без
|
||||
# резервного парсера на Python.
|
||||
|
||||
"""Models for the C99 Intel HEX parser. No Python parser fallback."""
|
||||
import ctypes as ct
|
||||
from functools import lru_cache
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
# Входная точка пакета logic_analyzer. Определяет доступные при импорте имена; подробные
|
||||
# контракты находятся в специализированных модулях пакета. Изменение реэкспортов влияет на
|
||||
# существующие import у потребителей.
|
||||
|
||||
"""Reusable device libraries from setcorp/templates."""
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Офлайн-анализ логических фронтов с временными метками. Интервалы считаются по переходам, без
|
||||
# разворачивания в массив каждой выборки; аппаратное подключение для анализа уже сохранённого
|
||||
# захвата не требуется.
|
||||
|
||||
"""Offline analysis of timestamped edges; no resampling or hardware access."""
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Преобразование цифровых захватов между CSV, JSON, SAL и DSL. Используются общие читатели
|
||||
# фронтов; аналоговые данные и настройки анализатора не переносятся как цифровые сигналы.
|
||||
|
||||
"""Digital CSV/JSON/SAL/DSL conversion using the shared capture readers.
|
||||
|
||||
SAL v3 encoding follows DSLogic_Logic_2/dslogic_script/tests/generate_test_sal.py.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Потоковый импорт цифрового CSV в захват DSView v3. Интервалы между переходами сохраняются
|
||||
# явно, поэтому длинный неизменный уровень не требует хранения каждой отдельной выборки.
|
||||
|
||||
"""Stream digital CSV into DSView v3, preserving intervals between transitions."""
|
||||
from contextlib import contextmanager
|
||||
import csv
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Нормализация настраиваемого CSV-ввода: временная колонка, цифровые каналы и правила чтения
|
||||
# строк. Преобразование выполняется потоково, чтобы размер исходного файла не определял объём
|
||||
# оперативной памяти.
|
||||
|
||||
"""Streaming normalization of configurable digital CSV input."""
|
||||
import csv
|
||||
from decimal import Decimal, InvalidOperation
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
# Входная точка пакета logic_analyzer.decoders. Определяет доступные при импорте имена;
|
||||
# подробные контракты находятся в специализированных модулях пакета. Изменение реэкспортов
|
||||
# влияет на существующие import у потребителей.
|
||||
|
||||
"""Reusable device libraries from setcorp/templates."""
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Проверка временных характеристик драйвера затвора по цифровым фронтам. Параметры профилей
|
||||
# задаются в наносекундах; типичная задержка ACK используется для предупреждения, а
|
||||
# нормированная длительность импульса — для PASS/FAIL.
|
||||
|
||||
"""Pure timing checker used by the DSView decoder and unit tests.
|
||||
|
||||
All time values in profiles are nanoseconds. The ACK delay in the vendor
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Декодирование UART-обмена ПМ35 с командами Modbus 03/06. Учитывается исторический ответ на
|
||||
# 128 слов с нулевым полем числа байтов; универсальный Modbus-parser без этого правила
|
||||
# потеряет границу сообщения.
|
||||
|
||||
"""PM35 MODBUS 03/06, including the legacy 128-word/zero-byte-count reply."""
|
||||
from .set_uart import crc16, number
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Офлайн-интерпретация CAN-захвата для ProtoCAN, BALZAM и SET v2. Выбранный формат определяет
|
||||
# разбор адреса и данных; сегментированные SET-пакеты требуют сборки до интерпретации полезной
|
||||
# нагрузки.
|
||||
|
||||
"""ProtoCAN, Balsam and SET v2 classic CAN binding."""
|
||||
from .set_uart import number, parse_frame
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Декодирование потоков UART протоколов SET по накопленным байтам. Поиск сигнатуры и проверка
|
||||
# сообщения должны переживать границу входного фрагмента; неверная контрольная сумма не
|
||||
# выдаётся как успешный пакет.
|
||||
|
||||
"""Portable wire readers based on templates/c/set-protocol (no native DLL)."""
|
||||
import binascii
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Анализ двух комплементарных входов транзисторной пары. Совместное включение, паузы и
|
||||
# интервалы определяются только по этим входам; ACK/Vstat драйвера не участвуют в данной
|
||||
# модели.
|
||||
|
||||
"""Independent complementary transistor input timing; no ACK/Vstat dependency."""
|
||||
import math
|
||||
from .gate_timing import InputTimingChecker, format_ns
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Онлайн-захват DSLogic через отдельный процесс DSView/libsigrok4DSL. Изоляция оставляет
|
||||
# нативные зависимости драйвера вне основного Qt-приложения; результат процесса затем
|
||||
# преобразуется в клиентскую модель.
|
||||
|
||||
"""DSLogic ONLINE through an isolated DSView/libsigrok4DSL host."""
|
||||
from array import array
|
||||
from dataclasses import dataclass, asdict
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Проверка и настройка условий запуска DSView без зависимости от Qt/cffi. Представление
|
||||
# условия проверяется до программирования API, чтобы неверные каналы или комбинации не попали
|
||||
# в аппаратный захват.
|
||||
|
||||
"""DSView trigger validation and API programming, independent of Qt/cffi."""
|
||||
import math
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Изолированный процесс драйвера DSView с JSON-запросом и результатом. Ссылки на нативные
|
||||
# callbacks сохраняются до выхода процесса; сырые CROSS_DATA выгружаются отдельно от
|
||||
# управляющих метаданных.
|
||||
|
||||
"""Isolated DSView driver host. JSON request/result files, raw CROSS_DATA spool.
|
||||
|
||||
Native callbacks and their references live until process exit. Never import
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Управление отдельным процессом и окном модифицированного DSView по host protocol 1. Qt,
|
||||
# Python и libusb DSView остаются внутри дочернего процесса; владелец управляет только своим
|
||||
# запущенным экземпляром.
|
||||
|
||||
"""Process boundary for the patched DSView GUI (host protocol 1, Windows).
|
||||
|
||||
The host owns only its child process/window. Qt 5, Python and libusb remain
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Чтение цифровых захватов с хранением фронтов вместо массива всех выборок. Версия бинарного
|
||||
# формата проверяется явно; неизвестную раскладку нельзя угадывать по похожему заголовку.
|
||||
|
||||
"""Digital capture readers. Store edges, never expand captures to sample arrays.
|
||||
|
||||
DSView layout: DreamSourceLab/DSView libsigrok4DSL/session_driver.c.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Шаблон метаданных Logic 2 для цифрового SAL-захвата, schema 22. Метаданные описывают
|
||||
# контейнер и не заменяют массивы цифровых переходов; версия должна соответствовать формату
|
||||
# записываемого архива.
|
||||
|
||||
"""Empty Logic 2 metadata based on the DSLogic_Logic_2 SAL fixture (schema 22)."""
|
||||
from copy import deepcopy
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Захват через локальную Logic 2 Automation API. Зависимость от API опциональна; настройка
|
||||
# сеанса и получение результата отделены от последующего офлайн-разбора цифровых сигналов.
|
||||
|
||||
"""Local Logic 2 acquisition through the optional Saleae Automation API."""
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Входная точка пакета protocan. Определяет доступные при импорте имена; подробные контракты
|
||||
# находятся в специализированных модулях пакета. Изменение реэкспортов влияет на существующие
|
||||
# import у потребителей.
|
||||
|
||||
"""Переносимые модули и тонкая Python-обёртка SETProtocol."""
|
||||
|
||||
# Consumers may supply additional platform ports from their pinned templates
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Python-привязка исторического CAN-протокола Balsam к общему C99-ядру. Модуль представляет
|
||||
# результат в объектах Python; двоичный контракт регистров остаётся в balsam_can.
|
||||
|
||||
"""Balsam 167 legacy CAN register decoder backed by the shared C99 core."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Клиент A/B-загрузчика ProtoCAN с оконной передачей блоков по восемь байт. Ответы принимаются
|
||||
# только для целевого адреса и текущей сессии; продвижение по этапам зависит от подтверждения,
|
||||
# а не от факта отправки.
|
||||
|
||||
"""Legacy ProtoCAN Boot client ported from Gui_Android CanFirmwareProtocol.kt."""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -66,6 +70,8 @@ class CanBootTransfer:
|
||||
and p.msg_type == 12 and p.pm == 1 and p.device_type == t.device_type
|
||||
and p.device == t.device and p.body >> 8 == t.session_id and len(frame.data) == 8)
|
||||
|
||||
# Окно содержит до 16 блоков. Последний неполный блок заполняется 0xFF,
|
||||
# но метаданные образа сохраняют исходную длину без этого дополнения.
|
||||
def _window(self):
|
||||
total = (len(self.image.data) + 7) // 8
|
||||
self._window_end = min(total, self.next_block + 16)
|
||||
@@ -78,6 +84,8 @@ class CanBootTransfer:
|
||||
command = ProtoCanId.parse(frame.can_id).body & 255
|
||||
expected_command = {"enter": 2, "image": 3, "compat": 4, "erase": 5,
|
||||
"data": 0, "verify": 6, "commit": 7, "reboot": 9}.get(self.stage)
|
||||
# Позднее подтверждение предыдущего этапа нельзя применять к новому:
|
||||
# оно не продвигает автомат и не считается ошибкой текущего запроса.
|
||||
if command != expected_command:
|
||||
return [], ""
|
||||
status, slot, expected = struct.unpack_from("<BBH", frame.data)
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Команды и кадры USB-моста CAN485 DevBoard_V1. Преобразование между представлением адаптера и
|
||||
# CAN отделено от последовательного порта, чтобы один контракт использовался в GUI и проверках
|
||||
# без устройства.
|
||||
|
||||
"""CAN485 DevBoard_V1 USB command and frame helpers (no GUI/serial dependency)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Описание объектов общего адресного пространства и подписок на значения. Каталог задаёт
|
||||
# адреса, типы и имена, а пакеты наблюдения несут текущие данные; сборка частей каталога
|
||||
# должна завершиться до использования всей схемы.
|
||||
|
||||
"""Каталог общего адресного пространства и поток выбранных значений.
|
||||
|
||||
Прибор объявляет, какие регистры у него есть и как они называются, GUI
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Общая модель исторического CAN_terminal и его каталога проектов. Выбор проекта определяет
|
||||
# интерпретацию регистров; транспорт и отображение подключаются отдельно, без переноса таблиц
|
||||
# протокола в каждый GUI.
|
||||
|
||||
"""UI-independent model of the historical CAN_terminal protocol.
|
||||
|
||||
The catalog is migrated from ``CAN_terminal/Projects.ini``. Both desktop
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
# Стабильная C-граница для ctypes, JNI и других языков. Фиксированные типы и явные размеры
|
||||
# буферов отделяют бинарный контракт от внутренних структур; изменения сигнатур требуют
|
||||
# согласованного обновления привязок. Поиск DLL/SO учитывает явный путь окружения и варианты
|
||||
# имён библиотеки.
|
||||
|
||||
"""ctypes port for the shared C99 SETProtocol core.
|
||||
|
||||
The protocol implementation lives in ``c/set-protocol``. This module
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Протокол периферийного контроллера ПМ35/TMS320F28335: регистры, команды и разбор ответов.
|
||||
# Этот профиль имеет собственную адресацию и не должен подменяться протоколом основного
|
||||
# TMS320F2812.
|
||||
|
||||
"""Thin Python port of the shared C99 PM35/TMS320F28335 protocol."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Адаптер общей математики графика из set_plot.c. Область просмотра и координатные
|
||||
# преобразования рассчитываются ядром; приложение отвечает за единицы, получение измерений и
|
||||
# отрисовку.
|
||||
|
||||
"""Plot interaction port. All numerical operations use templates' set_plot.c.
|
||||
|
||||
This module has no Qt dependency. The application supplies its SETProtocol CDLL.
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Явная упаковка полей в 29-битный идентификатор ProtoCAN и их извлечение. Маски и сдвиги
|
||||
# задают переносимый wire-формат без зависимости от расположения битовых полей компилятора.
|
||||
|
||||
"""Разбор и сборка сообщений ProtoCAN — прикладного уровня шины CAN.
|
||||
|
||||
Раскладка полей повторяет ``ProtoCanId_t`` из SETCAN/Inc/protocan.h:
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Кадрирование исторического GUI protocol v1. Parser накапливает части входного потока и
|
||||
# проверяет сообщение до выдачи результата; этот формат следует выбирать по профилю
|
||||
# соединения, а не только по сигнатуре.
|
||||
|
||||
"""Совместимое с ``lib/gui_transport`` кадрирование GUI protocol v1."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Клиент обновления SETProtocol v2 через сегментированный classic CAN. Состояние передачи
|
||||
# связывает запросы и подтверждения; сегментация транспорта отделена от команд начала, данных
|
||||
# и завершения обновления.
|
||||
|
||||
"""SETProtocol v2 firmware client over segmented classic CAN."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Привязка общего расчёта спектра C99 к клиенту. Входные временные метки задаются в секундах;
|
||||
# частота дискретизации и нормировка определяются ядром, поэтому отображение не должно
|
||||
# повторно нормировать амплитуды.
|
||||
|
||||
"""Shared FFT adapter for desktop GUIs; no numpy/Qt dependency or duplicated DSP.
|
||||
|
||||
Pass NativeProtocol.lib (rebuilt with set_spectrum.c). Timestamp inputs are seconds.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Пакеты системного UART-загрузчика STM32 по AN3155. Команды этого режима отличаются от
|
||||
# SETProtocol; переход в ROM bootloader и физический обмен обслуживает внешний клиент.
|
||||
|
||||
"""Packets and constants for the STM32 system-memory UART bootloader (AN3155)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Исторический протокол основного контроллера ПМ67/TMS320F2812. Формирование команд и проверка
|
||||
# ответов находятся в общем ядре; адреса памяти C28x считаются словами, тогда как длины
|
||||
# передачи могут задаваться байтами.
|
||||
|
||||
"""Thin Python adapter for the shared C99 PM67/TMS320F2812 protocol."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Последовательность обновления BALZAM/ПМ67 через команды TMS. Адрес задаётся в 16-битных
|
||||
# словах, а размер передаваемого блока — в байтах; смешение этих единиц смещает запись даже
|
||||
# при корректной контрольной сумме.
|
||||
|
||||
"""BALZAM/PM67 firmware protocol, ported from Gui_Android Tms2812Protocol.
|
||||
|
||||
Addresses count 16-bit words; transfer lengths count bytes.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Обмен с историческим терминалом TMS. Формат обычных ответов и телеметрии зависит от
|
||||
# используемого адаптера; состояние parser сохраняется между фрагментами, а профиль
|
||||
# контроллера выбирается вызывающим приложением.
|
||||
|
||||
"""Thin host binding for legacy TMS2812 requests and ordinary responses.
|
||||
|
||||
The wire implementation is c/set-protocol/src/tms2812.c, also used by JNI.
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Потоковый транспорт моста CAN/RS485 с сигнатурой AA 55 и CRC16. Приём может доставлять
|
||||
# произвольные фрагменты; parser сохраняет незавершённый кадр и отделяет CAN-идентификатор от
|
||||
# служебных флагов моста.
|
||||
|
||||
"""Транспортный кадр моста CAN <-> RS485.
|
||||
|
||||
Это не протокол SETGUI (``A5 5A``) из ``protocol.py``, а кадр полевого
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Модели источников и настроек трендов, используемые клиентскими приложениями. Идентификатор
|
||||
# сигнала связывает историю с источником независимо от имени и порядка; визуальное
|
||||
# переименование не должно менять физический источник.
|
||||
|
||||
"""Portable trend configuration shared by SETGUI and Android (no Qt/Android).
|
||||
|
||||
Numeric CAN decoding uses set_trends.c through NativeTrends. JSON adapters
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
# Входная точка пакета set_devices. Определяет доступные при импорте имена; подробные
|
||||
# контракты находятся в специализированных модулях пакета. Изменение реэкспортов влияет на
|
||||
# существующие import у потребителей.
|
||||
|
||||
"""Reusable device libraries from setcorp/templates."""
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Исторический регистровый CAN-протокол BALZAM/TMS2812. Формат идентификаторов и порядок слов
|
||||
# относятся именно к этому профилю; общий физический CAN не делает его совместимым с SET v2
|
||||
# или протоколом ПМ35.
|
||||
|
||||
"""GUI-neutral adapter for the shared templates Balsam 167 CAN decoder."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user