Импорт, происхождение и распространение

Импорт: что записывается, а что — никогда

Импорт матча, позиции или другой базы добавляет то, чего не хватает; он не заменяет того, что уже есть.

  • Позиция никогда не дублируется. Её узнаёт её идентичность — шашки, куб, кости, счёт, — а не файл, из которого она пришла: одна и та же позиция, встреченная в двух матчах, остаётся одной строкой.

  • Импорт базы считывает всё, что записывает экспорт. Позиции с их анализами и комментариями, а также матчи (включая партии и ходы), турниры с их Руководством и Встречей, черновики транскрипций, псевдонимы, коллекции, уроки и колоды Anki: см. Объединение базы данных. Ничто не перезаписывается: уже имеющийся матч повторно не копируется, одноимённый турнир получает матчи без смены даты события (дата его последнего изменения сдвигается вперёд, так как он получает новые матчи), турнир, у которого уже есть Руководство, сохраняет его и остаётся вне импортированной Встречи, матч, уже размещённый в другом турнире или на другом месте таблицы, остаётся там, а то, что база уже решила, остаётся за её решением. Турниры, Руководства, Встречи, черновики транскрипций и псевдонимы, создаваемые импортом, сохраняют свои исходные даты; создаваемые коллекции, уроки и колоды Anki их не сохраняют.

  • По одному анализу на движок. eXtreme Gammon, GNUbg, BGBlitz и встроенный оценщик уживаются на одной и той же позиции, и панель Анализа указывает происхождение каждого из них. Импорт одного не стирает другой.

  • Импортированный анализ никогда не пересчитывается. blunderDB хранит его как есть, с меткой уровня («3-ply», «XG Roller++», «Book»), эквити, ошибками, вероятностями и удачей броска. Правило гласит: «оценка лишь заполняет пробел»: автоматический анализ после импорта посещает только позиции без какого-либо анализа, а повторный анализ устаревших анализов gammonNet оставляет нетронутой любую позицию, несущую импортированный анализ (см. Конфигурация).

  • Повторный импорт уже сохранённого матча приносит только более глубокое. Матч распознаётся по игре (игроки, длина, кости, ходы, куб), а не по анализу: ни матч, ни партия, ни ход не перезаписываются. Пометки, поставленные в исходной программе, добавляются, а анализ глубже сохранённого заменяет его, позиция за позицией — версия Roller++ того же матча заменяет версию 3-ply независимо от порядка импорта; при равной или меньшей глубине сохранённый анализ остаётся. Поэтому повторный импорт того же файла ничего не перезаписывает. Отчёт об импорте отличает дубликаты, не принёсшие ничего, от тех, что углубили анализы. В командной строке --skip-duplicates пропускает дубликат, не беря из него ничего, кроме пометок. Матч, оборванный и позже дополненный (больше партий), — это не тот же матч: он импортируется как второй матч.

  • Нечитаемый анализ не мешает импорту матча. Решение, анализ которого содержит значение, не являющееся конечным числом (NaN или бесконечность, встречающиеся в некоторых файлах XG), импортируется без этого анализа; остальная часть матча импортируется как обычно, а отчёт об импорте подсчитывает затронутые решения.

  • Матч, уже имеющийся под другими именами, отмечается, но никогда не объединяется. Два отпечатка матча содержат имена игроков: «Martin A.» и «Alice Martin» дают два матча. Импорт также сравнивает кости (длина, начальный счёт, кости каждой партии) и сообщает под строкой файла и в отчёте о матче, уже имеющемся в базе под другими именами, чьи кости он содержит. blunderdb repair --duplicates перечисляет эти пары в существующей базе, а также обрезанные матчи и их более длинную версию.

  • Имя, известное под другим написанием, записывается под своим каноническим именем. Псевдоним означает, что «Martin A.» — другое написание «Alice Martin» (или что название события — другое написание другого). При импорте имена игроков и события заменяются их каноническим именем, а матч помещается в турнир канонического события. Отпечатки матча сохраняют имена из файла: файл, импортированный до появления его псевдонима, поэтому всегда распознаётся. Матч, кубики которого совпадают с кубиками матча в базе, а имена различаются лишь известными псевдонимами, не является вторым матчем: его анализы обогащают уже сохранённый.

Псевдонимы управляются на вкладке Корпус настроек: выбрать Игроки или События, ввести псевдоним и каноническое имя или удалить псевдоним из списка. Предложить перечисляет имена, различающиеся только регистром, диакритикой, пунктуацией или порядком слов; ничего не применяется без щелчка по Применить. Та же вкладка содержит флажок Пропускать дубликаты при импорте (эквивалент --skip-duplicates, на время сеанса) и поиск вероятных дубликатов существующей базы, тот же, что у blunderdb repair --duplicates: каждая пара указывается номерами матчей, ничего не объединяется. Под парой с одинаковыми костями Создать эти псевдонимы одним щелчком записывает псевдонимы игроков, после которых оба матча называли бы одних и тех же игроков, причём написание более нового матча становится псевдонимом: одно предложение, когда имя общее для обоих, иначе два — место за местом, затем крест-накрест, — из которых выбирают то, что говорит, кто есть кто. В командной строке: blunderdb players alias и blunderdb events alias.

  • Папка импортируется параллельно. Файлы читаются сразу на нескольких ядрах и записываются группами, всегда в порядке папки: номера матчей не зависят от машины. Файл, побайтно совпадающий с уже прочитанным файлом той же папки, не читается повторно: он считается дубликатом. Отмена останавливает импорт на текущей группе; уже записанное остаётся.

  • Прогресс измеряется в позициях в секунду. Окно импорта показывает прочитанный процент, скорость, оценку оставшегося времени и текущие счётчики (импортировано, дубликаты, с ошибкой). Свернуть убирает его в строку состояния, откуда значок открывает его снова: импорт продолжается, пока вы работаете, а окно само возвращается с отчётом в конце. Первые сто ошибок перечислены; остальные подсчитаны, и журнал приложения называет их все. В командной строке blunderdb import --type batch показывает тот же прогресс в стандартном потоке ошибок, а --format json возвращает его в итоговом объекте (progress).

  • Каждый файл импорта записывается в журнал, а прерванный импорт можно возобновить. Для каждого файла журнал пакета хранит путь, размер, дату изменения, отпечаток SHA-256 и результат: новая партия (с её номером), дубликат (с партией, которая его покрывает), дополненная партия или ошибка (с сообщением). Отменённый или оборванный импорт продолжается без повторения уже решённого: файл с тем же путём, размером и датой пропускается без чтения; файл с тем же содержимым читается, но не анализируется; файл с ошибкой повторяется. В приложении окно завершения импорта перечисляет журнал (один файл на строку, с его результатом и сообщением об ошибке; повторно обработанный файл показывает последний исход), а строка, давшая партию, открывает её. Отменённый импорт оставляет окно открытым с кнопкой Продолжить. В командной строке blunderdb import --type batch --dir <папка> --resume <пакет> возобновляет пакет, номер которого был показан в начале импорта, а --format json возвращает журнал в итоговом объекте (journal). Сервер принимает resume в запросе imports.batch и возвращает журнал через imports.files. Журнал — данные импорта: открытие или чтение базы ничего в него не пишет.

  • Импорт, прерванный остановкой приложения, возобновляется из окна. Команда :resume перечисляет импорты, которые ничто не завершило; выберите нужный, затем снова укажите папку или файлы, как --dir в командной строке. Журнал пакета решает, что не читается повторно.

  • Большая папка импортируется в пакетном режиме. Начиная с 200 файлов, blunderDB пишет с увеличенным кешем и реже делает контрольные точки. Если в базе ещё нет ни одной позиции, он идёт дальше: поисковые индексы перестраиваются только в конце, а запись больше не синхронизируется с диском. Отключение питания во время такого импорта может тогда повредить базу: её нужно создать заново и повторить импорт. Аварийное завершение программы, напротив, оставляет лишь отсутствующие индексы, которые перестраиваются при следующем открытии (журнал сообщает об этом).

  • Что blunderDB никогда не записывает: пересчитанное везение — оно читается из исходного файла или остаётся неизвестным — и роллаут, который он не запускал сам: данные роллаута из файла .xg не открываются. Сохраняются только роллауты, которые создаёт сам blunderDB (Роллауты), рядом с анализом.

Панель метаданных

Панель Метаданные (CTRL-M) показывает общие сведения о текущей базе данных: Пользователь, дату создания (Создано), Версию схемы и Описание. Пользователь, дата и описание изменяются на месте и сохраняются при выходе из поля; версия доступна только для чтения. Доступна также командой meta.

Она также показывает, если она есть, происхождение базы — см. Распространение базы: происхождение и пароль. У обычной базы этот раздел не отображается.

Распространение базы: происхождение и пароль

У преподавателя, раздающего базу позиций, есть два независимых друг от друга механизма, оба необязательные и выбираемые в момент экспорта: пометить файл его происхождением и защитить его паролем.

Примечание

Ни один из них не отслеживает дальнейшую судьбу файла. blunderDB ничего не записывает на стороне получателя базы: открыть помеченную базу — то же самое, что открыть любую другую, и нигде не фиксируется, кто её открыл, когда и откуда взялось её содержимое.

Пометить базу её происхождением

Окно экспорта умещается на одном экране: полоса заголовка — число экспортируемых позиций, Отмена и Экспорт… — затем сетка, по одной строке на семейство с его количеством. Эти количества точны: они читаются с сервера при каждом изменении флажка, на том же отборе, что и экспорт, и это именно то, что будет в файле. Файл выбирается последним, после Экспорт…; если закрыть этот выбор без имени, происходит возврат к сетке. На время записи поверх появляется индикатор хода, окно закрывается само, а результат отображается в строке состояния.

Девять пунктов заслуживают внимания:

  • Охват: из списка — поиска, коллекции — строка Охват выбирает между Текущий список и Вся библиотека. Текущий список экспортирует свои позиции, а строка Матчи предлагает только те матчи, в которых эти позиции были сыграны; каждый отмеченный матч уходит со всеми своими позициями. Из библиотеки охват — это библиотека.

  • Вся библиотека — это экспорт сервера и export --type database: все семейства отмечены изначально, колоды Anki с их историей повторений, а текущие транскрипции уходят вместе с остальным.

  • Синхронизация: при выборе Вся библиотека строка Синхронизация предлагает Только новое с последнего экспорта в эту папку и кнопку Выбрать папку…. Файл тогда больше не запрашивается: он записывается в эту папку под новым именем, а счётчики относятся к новому (см. Синхронизация двух компьютеров).

  • Матч уходит со своим черновиком записи — под флажком Транскрипции строки Матчи, отмеченным изначально; так же уходят матчи, которые уносит и турнир. Черновик, который ещё не дал матча, уходит только со всей библиотекой. Матч или транскрипция, связанные с локальным видео, уносят только имя файла, без его папки, которую получатель заново указывает на своей копии; веб-ссылка уходит как есть. Файл, из которого был импортирован матч, также уходит только по имени.

  • Матч уходит с псевдонимами своих игроков и своего события: флажок Псевдонимы, отмеченный изначально, заставляет слияние игроков следовать за матчем, и получатель читает объединённого игрока как одного. Псевдоним, который не называет никого из экспортируемых матчей, остаётся у вас.

  • Коллекция, чьи позиции не все входят в список, приходит усечённой. Список коллекций показывает для каждой охваченную долю («12/40») и отмечает её красным, когда она неполная. Флажок + их позиции уносит позиции отмеченных коллекций: позиции списка, составленного вручную, и те, что выбирает запрос живой коллекции. Живая коллекция, чей запрос называет строки, которых нет в файле, уходит замороженной: она приходит списком того, что запрос выбирает сегодня, а список отмечает её красным как «заморожена» с примечанием; флажок + их позиции оставляет её живой.

  • Турнир всегда уходит вместе со своими матчами: без них связи турнир–матч не существует, и турнир пришёл бы пустым. Отметка турнира забирает его матчи, даже если флажок матчей снят или ограничен другими. Он уходит и со своим Руководством — журнал, пары, столы и привязка экспортируемых матчей, — а его Встреча уходит, как только уходит один из её турниров; выходная папка Руководства остаётся у вас. Руководство находится при открытии файла или при его импорте в другую базу.

  • Колода Anki уходит со своими позициями — как новая учебная копия. Флажок с моей историей уносит дополнительно состояние каждой карточки и журнал её повторений: резервная копия или ваши колоды, перенесённые на другую машину. Для списка он снят, для библиотеки отмечен.

  • Сохранённые фильтры экспортируют не содержимое, а ваши собственные поиски, бесполезные в чужой базе; для списка флажок снят. Фильтр, указывающий позицию, матч или турнир по его номеру, перенумеровывается для файла; если он указывает на то, что не уходит, он остаётся у вас.

Коллекции, уроки, транскрипции, колоды Anki, псевдонимы и турниры уходят с теми датами создания и добавления, которые они имеют у вас, а не с датой экспорта.

Поля Пользователь, Описание и Дата создания описывают создаваемый файл; они предзаполнены из исходной базы.

Если отметить Водяной знак, появятся два поля:

  • Происхождение — что это за файл и откуда он, вашими словами: «Курс Жана Дюпона — 12 марта 2026 года». Это поле обязательное: пока оно пусто, оно обведено красным, а кнопка экспорта остаётся неактивной.

  • Примечание, необязательное — условия использования, контактный адрес, просьба не распространять дальше.

Отметка подписана вашей идентичностью автора. Поэтому она неизменяема и неподделываема: никто не может её изменить или изготовить от вашего имени. Зато она не является неудаляемой — распространяемый файл представляет собой обычную базу SQLite, а blunderDB — свободная программа. Она ничему не препятствует: она говорит, откуда файл.

Написанные вами комментарии подписываются той же идентичностью: получатель видит, что они от вас и не были ли изменены по дороге (см. Панель комментариев). Комментарий, уже несущий подпись другого отправителя, сохраняет её. Строка состояния сообщает в конце экспорта, сколько ваших комментариев подписано; экспорт без отметки не подписывает ни одного.

Идентичность автора

Отметки подписываются вашей идентичностью автора, которая создаётся сама при первой пометке файла; настраивать ничего не нужно. Она принадлежит человеку, а не базе: все ваши файлы несут один и тот же публичный отпечаток вида A3F1-9C24-7B05-E1D8.

Вы можете сообщить этот отпечаток получателям, чтобы они убедились, что файл действительно от вас. Идентичность переносится с одного компьютера на другой одним файлом (расширение .bdbid), при желании защищённым парольной фразой. Этот файл позволяет подписывать от вашего имени: не передавайте его.

В настройках (значок шестерёнки на панели инструментов) вкладка Идентичность автора показывает ваше имя и отпечаток и предлагает Сохранить идентичность…, Загрузить идентичность… и Создать заново….

Предупреждение

Создание заново ничего не отзывает. Отметка несёт в себе публичный ключ, которым она подписана, поэтому проверяется сама по себе и всегда. Если ваш файл идентичности утёк, тот, у кого он есть, сможет и дальше подписывать под вашим прежним отпечатком, и такие отметки останутся действительными.

После утечки вас защищает не программа: нужно опубликовать новый отпечаток и объявить прежний недействительным перед вашими получателями.

Создание заново перезаписывает текущий ключ; blunderDB предлагает сохранить его перед заменой.

Защита базы паролем

Пароль вводится скрытым — и здесь, и при открытии защищённого файла; значок в виде глаза показывает его, пока его удерживают нажатым, и снова скрывает, как только его отпускают.

Если отметить Пароль, будет создан файл с расширением .dbx — даже если имя, выбранное в окне сохранения, оканчивается на .db. Чтобы открыть его, используйте обычное открытие базы: окно выбора принимает и .db, и .dbx. Затем blunderDB запрашивает пароль и устанавливает рядом обычную базу; после этого больше ничего не спрашивается.

Окно предлагает удалить защищённый файл после открытия: иначе одно и то же содержимое останется у вас под двумя именами. По умолчанию флажок снят — защищённый файл остаётся у вас, если вы собираетесь его передать, — а удаление происходит только после успешного открытия.

Предупреждение

Пароль защищает файл при передаче, а не саму базу. Он мешает постороннему открыть файл, забытый в папке загрузок, или вложение, пересланное по ошибке. Он не защищает от того, кому вы сообщили пароль.

Пароль проверяется при каждом открытии, в том числе если файл уже открывали на этом компьютере ранее.

Технически база шифруется алгоритмом AES-256 в режиме GCM, ключ выводится из пароля функцией Argon2id (64 МиБ памяти, 3 прохода, 4 потока), соль случайна и своя для каждого файла. Режим GCM аутентифицирует всё целиком: неверный пароль распознаётся как таковой, равно как и любое изменение зашифрованного файла — молча испорченной базы не получится никогда.

Заголовок защищённого файла остаётся открытым: его происхождение читается и без пароля.

Как прочитать происхождение файла

В приложении откройте файл и покажите панель Метаданные (команда meta). В верхней части панели появится раздел Происхождение, доступный только для чтения; он сообщает, что было записано, кем, когда и в каком состоянии подпись:

  • «✓ помечено вами»: файл несёт вашу отметку в целости;

  • «✓ подпись проверена»: отметка нетронута и сделана другим ключом — сравните её отпечаток с тем, который сообщил вам автор;

  • «⚠ подпись недействительна»: документ был изменён или подделан.

У обычной базы этот раздел не появляется.

В командной строке blunderdb info --db файл.db показывает происхождение и состояние подписи, никогда не записывая в файл. Команда работает и с защищённым файлом, без пароля. См. CLI_USAGE.md про параметры --watermark и --password команды export, а также про identity и open.

Публикация базы для других

Помеченная база распространяется как любой файл — по почте, с личного сайта, на флешке. blunderDB не предоставляет никакой службы: ни хранилища, ни размещённого каталога, ни учётной записи. Это прямое следствие его устройства: на стороне того, кто получает файл, никогда ничего не записывается, и сообщать службе было бы нечего, даже если бы она существовала.

То, что делает опубликованную базу пригодной для другого, сводится к четырём полям, и все они уже есть:

  • Пользователь — кто её собрал, под тем именем, которое вы хотите видеть указанным.

  • Описание — что база содержит, одной фразой, помещающейся в список: «240 решений по кубу при счёте, с комментариями, средний уровень».

  • Происхождение (водяного знака) — что это за файл и для кого он был сделан. Это первое, что получатель читает в панели Метаданные.

  • Отпечаток издателя — публикуйте его рядом с файлом, а не внутри: сравнивая его, получатель убеждается, что файл пришёл от вас, а не от того, кто взял ваше имя.

База, опубликованная без водяного знака, остаётся вполне пригодной; она просто анонимна, и панель Метаданные не показывает тогда раздела Происхождение.

Чтобы о базе узнали, категория Show and tell обсуждений репозитория служит указателем: это список, который ведут сами публикующие, а не служба, оказываемая blunderDB. Чтобы объявить там базу, нужны ссылка, четыре поля выше и отпечаток.