Meridian Open Package — раскладка пакета
Спецификация контейнера — docs/04-file-formats.md §2;
форматы приложений — §3. Здесь — дерево пакета с пояснениями.
1. Общий каркас (любое приложение)
<документ>.m?x ZIP (PKWARE 6.3, ZIP64 при необходимости), записи в указанном порядке
├─ mimetype 1-я запись, stored, без extra-полей: "application/vnd.meridian.<app>" (байты 38+ файла)
├─ manifest.xml m:manifest — версия формата, части (путь, MIME, роль, размер, SHA-256), возможности, история
├─ meta.xml m:meta — Dublin Core + m:* (авторы, статистика, происхождение, пользовательские свойства)
├─ settings.xml m:settings — группы пар «имя—значение» (вид, печать, совместимость, история, язык)
├─ styles.xml m:styles — умолчания, тема (цвета/шрифты), стили всех видов, стили списков, m:fonts
├─ <содержимое> content.xml или части приложения (см. §2)
├─ comments.xml m:comments — комментарии и ответы; цели — маркеры в тексте или @target=UUID объекта
├─ media/ медиа и шрифты; имя = <вид>-<uuid7>.<ext>; дедупликация по SHA-256
│ ├─ image-<uuid7>.png stored (уже сжат)
│ ├─ image-<uuid7>.svg deflate; санитизированный SVG (без скриптов и внешних ссылок)
│ ├─ font-<uuid7>-subset.woff2 встроенный субсет шрифта (режим embed-mode=subset|full)
│ └─ profile-<uuid7>.icc цветовой профиль (Paint)
├─ objects/ встроенные объекты
│ ├─ chart-<uuid7>.xml ch:chart (Meridian Chart)
│ ├─ sheet-<uuid7>.msx вложенный пакет другого приложения (stored; единственный разрешённый ZIP-в-ZIP)
│ ├─ formula-<uuid7>.meq формула как объект (обычно t:math встроен прямо в текст)
│ └─ ole-<uuid7>.bin чужой OLE-объект (CFB) как оригинал; превью обязательно в media/
├─ foreign/ «мешок неизвестного»: части исходного чужого файла для round-trip
│ └─ <source>/ source = ooxml | odf | iwork | …
│ ├─ index.xml типы содержимого, связи (rels), хэши исходных частей, essential-флаги
│ └─ <исходный путь> например foreign/ooxml/customXml/item1.xml, foreign/ooxml/word/vbaProject.bin
├─ history/ журнал операций CRDT (опционально; settings/history.enabled)
│ ├─ index.xml m:history-index — сегменты, снапшоты, вехи, отметки усечения, state-hash
│ ├─ log-<NNNNNN>.mhl сегмент журнала: "MHL1" + doc-id + first-seq + zstd(кадры CBOR); stored
│ ├─ snapshot-<NNNNNN>.mhs снимок состояния Yrs (state vector + update v2, zstd); stored
│ └─ versions/<NNNNNN>.content.xml.zst материализованное содержимое вехи (просмотр версии без CRDT)
├─ scripts/ скрипты документа (не исполняются без разрешения; расширение файла не меняется)
│ ├─ manifest.json точки входа, события, требуемые разрешения, версия API
│ ├─ main.ts
│ ├─ lib/…
│ └─ converted/… результат транслятора VBA → MeridianScript (origin="vba")
├─ thumbnail.png 256×256 (вписано), sRGB, без альфа; отсутствует в шифрованных пакетах
└─ signatures/
└─ sig-<n>.xml ds:Signature (XMLDSig + XAdES baseline); покрывает все части, кроме signatures/, history/, thumbnail.png
Правила записей ZIP: UTF-8 имена, прямой слэш, без каталогов-записей,
без ..; deflate уровень 6 для XML/текста,
stored для PNG/JPEG/WebP/WOFF2/zstd-сегментов/вложенных
пакетов; время всех записей одинаково (UTC сохранения); никакого
ZIP-шифрования.
2. Содержимое по приложениям
Write — .mwx (шаблон
.mwt)
content.xml w:document → w:body (w:section* → блоки) · w:notes (сноски/концевые) · w:lists (экземпляры списков)
comments.xml
media/, objects/
Один файл содержимого: колонтитулы — внутри w:section,
сноски — в w:notes, списки — в w:lists. Нет
rels и отдельных частей header/footer/footnotes.
Sheets — .msx (шаблон
.mst)
workbook.xml s:workbook — листы (@src), именованные диапазоны, внешние ссылки, свойства вычислений
sheets/sheet-<n>.xml s:sheet — столбцы, строки/ячейки, объединения, усл. форматирование, валидации, таблицы, печать, рисунки
strings.xml s:strings — общие строки (повторяющиеся или длинные); остальные — inline в ячейках
styles.xml + стили kind="cell" и kind="cell-diff"
pivots/pivot-<n>.xml s:pivot — определение сводной
pivots/cache-<n>.bin кэш сводной (колонки + словари, zstd); опционально
objects/chart-<uuid7>.xml диаграммы
external/x<n>.xml кэш внешних книг
comments.xml потоковые комментарии (threaded); заметки (s:notes) — внутри листа
Порядок записей: workbook.xml и strings.xml
раньше листов (листы читаются параллельно после них).
Slides — .mpx (шаблон
.mpt)
presentation.xml p:presentation — размер, мастера, порядок слайдов, секции, параметры показа
masters/master-<n>.xml p:master — фон, общие фигуры, текстовые стили уровней, список макетов, (своя m:theme при импорте pptx)
layouts/layout-<n>.xml p:layout — тип и плейсхолдеры
slides/slide-<n>.xml p:slide — фигуры, переход, анимации (плоский список), заметки докладчика
notes/notes-master.xml мастер страницы заметок (опционально)
objects/chart-<uuid7>.xml, media/
comments.xml @target = id слайда или фигуры
Draw — .mvx (шаблон
.mvt)
content.xml d:drawing → d:page* (слои, g:shape/g:connector/g:group/g:image), направляющие
stencils/<name>.xml мастер-фигуры (экземпляры ссылаются @master="stencils/<name>.xml#<id>")
objects/, media/
Paint — .mpi
mimetype application/vnd.meridian.paint
manifest.xml, meta.xml
image.xml pt:image — размер, dpi, режим, профиль, стек слоёв (сверху вниз), направляющие, пути
layers/<uuid7>.png слои 8/16 бит (stored)
layers/<uuid7>.exr слои 32-бит float (линейный scRGB)
layers/<uuid7>/tile-<x>-<y>.png тайлы для слоёв > 16 384 px по стороне
masks/<uuid7>.png маски слоёв (серый 8/16 бит)
merged.png сведённое изображение (обязательно)
selection.png текущее выделение (опционально)
thumbnail.png
media/profile-<uuid7>.icc
Без styles.xml/settings.xml. Структура
зеркальна OpenRaster: экспорт в .ora без потерь растровых
слоёв и групп.
Notes — .mnx
notebook.xml n:notebook → n:section* → n:page-ref* (порядок, заголовки, цвета, теги)
pages/<uuid7>.xml n:page — холст: n:outline (t:p, tb:table), n:ink, n:clip, n:attachment, n:audio
ink/<uuid7>.bin штрихи: дельта-кодированные точки (x, y, давление, время), zstd
media/
Forms — .mfx (шаблон
.mft)
form.xml f:form — секции, вопросы, ветвления, настройки сбора, ссылка на книгу ответов
themes/<name>.xml оформление
media/
Ответы в пакет не входят (f:responses/@target → книга
Sheets или CSV).
Math — .meq
content.xml mq:formula — mq:source (LaTeX/UnicodeMath), Presentation MathML, mq:layout
media/preview-<uuid7>.png растровое превью (опционально)
Mail — .mmx (архив)
mimetype application/vnd.meridian.mail
manifest.xml, meta.xml
folders.xml mm:folder* — иерархия, типы (inbox/sent/…/calendar/contacts/tasks), счётчики
mail/<folder-uuid7>/<uuid7>.eml письма RFC 5322 как есть
attachments/<sha256> вынесенные крупные вложения (ссылка из .eml через X-Meridian-Attachment)
calendar/<uuid7>.ics календари (VCALENDAR)
contacts/<uuid7>.vcf контакты (vCard 4.0)
tasks/<uuid7>.ics задачи (VTODO)
index.sqlite кэш: flags, labels, threads, FTS5-индекс; восстанавливается из файлов
Base — .mbx
Не ZIP: файл SQLite 3 (application_id = 0x4D524442),
пользовательские таблицы + служебные meridian_meta,
meridian_objects, meridian_table_props,
meridian_relations, meridian_lookups,
meridian_connections, meridian_history,
meridian_media (схема —
docs/04-file-formats.md §3.7).
3. Плоский вариант —
.mwxf, .msxf, .mpxf,
.mvxf
Один XML-файл, MIME
application/vnd.meridian.<app>+xml:
m:flat (@version @app @units="emu|pretty" xml:space="preserve")
├─ m:manifest без m:part для вложенных ниже частей
├─ m:meta
├─ m:settings
├─ m:styles
├─ <содержимое> w:document | (s:workbook, s:strings?, s:sheet*) | (p:presentation, p:master*, p:layout*, p:slide*) | d:drawing
├─ m:comments
└─ m:media m:file @path @type (@encoding="base64" + содержимое | @href="<имя>.media/…" внешняя папка)
Не включаются: history/, signatures/,
foreign/, thumbnail.png. Сериализация
детерминирована (атрибуты по схеме, затем по алфавиту; отступ 2 пробела;
LF) — для чистых диффов в системах контроля версий.
4. Зашифрованный пакет
<документ>.m?x расширение не меняется
├─ mimetype application/vnd.meridian.encrypted (stored, первый)
├─ encryption.xml m:encryption — параметры AES-256-GCM (чанки 4 МиБ), обёрнутые ключи: пароль (Argon2id),
│ сертификат (RSA-OAEP / X25519-HPKE), корпоративное восстановление; inner-mime
└─ package.bin шифротекст обычного пакета целиком (чанк || тег GCM)*
Внутри package.bin — обычный пакет из §1 (включая
meta.xml и thumbnail.png, если был). Снаружи —
ничего, кроме параметров.
5. Порядок чтения
- Первые 64 байта:
mimetype→ тип приложения / зашифрованный пакет. manifest.xml→ версия (@version,@min-reader), список частей, возможности, зависимости.meta.xml,settings.xml,styles.xml→ контекст (авторы, профиль совместимости, стили/тема/шрифты).- Содержимое — потоково; для Sheets/Slides — части параллельно.
comments.xml,objects/,media/— лениво, по ссылкам.history/— только при включённой истории и совпаденииstate-hash.signatures/— проверка после загрузки всех частей (статус в UI).