Открытый код для форматов, Sheets и данных (Codecs, meridian-calc, Base)
Отчёт исследования, 2026-10-04. Область: чтение/запись форматов, CFB и шифрование Office, движок таблиц и функций, числовые форматы, потоки данных, поиск решения, статистика, даты, десятичные; MOffice Base. Правила и классы лицензий —
docs/research/BRIEF.md,docs/12-license-policy.md.
1. Выводы
Главное. Для Sheets и кодеков есть готовая основа
классов 0–1 почти на всё, кроме OneNote, Visio/Publisher/iWork (там
только MPL-библиотеки — решение владельца — или своя работа по
спецификациям с разрешительными референсами). Три находки меняют
component-map.md: (1)
outlook-pst — эталонная реализация
[MS-PST] от самой Microsoft на Rust, MIT; (2)
jetdb — чтение .mdb/.accdb на
чистом Rust, MIT OR Apache-2.0; (3)
formualizer — второй движок таблиц на Rust
(MIT OR Apache-2.0) с инкрементальным графом зависимостей и
многопоточным пересчётом, то есть ровно с тем, чего нет у IronCalc. Ещё
одна поправка: formulajs и Univer почти не нужны как источник
функций. Скрипт сравнения показал, что IronCalc уже покрывает
492 из 518 имён каталога (§3.1–3.2), поэтому ценность этих двух проектов
— в тестах.
Базис для оценки экономии. В 08-roadmap.md трудоёмкость
по эпикам не разбита, поэтому база эпика = численность подкоманды ×
длительность эпика (инкремент = 6 недель). Получается так: E2.2 «Движок
формул» ≈ 21 чел.-мес. (2,5 Rust × I05–I10); E2.4 «Кодеки Sheets» ≈ 19
(2 × I05–I11); E1.4 «Кодеки Write» ≈ 21 (2,5 × I03–I08); E3.4 «Кодеки
Slides/Draw» ≈ 24 (2,5 × I09–I15); E5.6 «Кодеки PIM» ≈ 17 (2 × I17–I22);
E5.4 Base ≈ 24, из них Rust ≈ 10.
| # | Что берём | Лиц. / класс | Стратегия | Куда в MOffice | Экономия, чел.-мес. (эпик) |
|---|---|---|---|---|---|
| 1 | IronCalc: 492 работающие функции (P0 — 99,4 %), парсер A1/R1C1 с локалями, LET/LAMBDA, spill, структурированные ссылки, 2 768 тестов и 211 эталонных xlsx | MIT OR Apache-2.0 / 1 | fork → meridian-calc |
Kernel/формулы, Sheets | 11–13 (E2.2) |
| 2 | Apache POI: записи HSSF и PTG, модель HWPF и sprm, записи HSLF, DDF (OfficeArt), HPSF | Apache-2.0 / 1 | port | codec-msbinary (doc/xls/ppt) |
9–12 (E1.4, E2.4, E3.4) |
| 3 | Стек Base: rusqlite + SQLCipher, sqlparser-rs, tokio-postgres / mysql_async / tiberius / odbc-api; FastReport как референс полос отчёта | MIT, BSD-3, Apache / 1 | adopt + ref | meridian-db, meridian-base |
2–3 (E5.4; драйверы и sqlparser уже заложены в
base.md) |
| 4 | outlook-pst (Microsoft) — [MS-PST] на Rust | MIT / 1 | adopt | codec-mail/pst |
4–5 (E5.6) |
| 5 | onenote_parser (onenote.rs) | MPL-2.0 / 2 | adopt без правок, если разрешит владелец; без разрешения — своя реализация, pyOneNote (Apache) как референс | codec-onenote |
4–5 с разрешением / ≈1 без него (E5.6) |
| 6 | jetdb (чтение Jet3…ACE17, запросы, VBA, шифрование) + jackcess (сложные типы, выражения, свойства) | MIT OR Apache-2.0; Apache-2.0 / 1 | fork + port частей | codec-access |
3–4 (E5.6) |
| 7 | Polars, arrow/parquet, csv, encoding_rs, chardetng | MIT, Apache, Unlicense / 0–1 | adopt | потоки данных, мастер CSV, «большой режим» | 3–4 (E2.4, Sheets 1.6) |
| 8 | HiGHS + good_lp (без coin_cbc),
Clarabel, argmin |
MIT, Apache / 1 | adopt | Поиск решения | 2–3 (Sheets 1.6) |
| 9 | numbers-parser, iWorkFileFormat, litchi — референсы IWA | MIT, MIT, Apache-2.0 / 1 | ref / port схем | codec-iwork |
2–3 (E2.4, E3.4) |
| 10 | SheetJS SSF (+ ≈2,4 млн строк эталонов), office-crypto + ms-offcrypto-writer + msoffcrypto-tool, formualizer (граф), calamine | Apache, MIT / 1 | port / adopt / ref | meridian-numfmt, offcrypto, граф
meridian-calc, быстрый импорт |
4–6 вместе (E2.2, E1.4, E2.4) |
Итого ≈ 44–58 чел.-мес. против базиса roadmap (41–54, если владелец не разрешит MPL для OneNote); с мелочами из §2 — ≈ 47–62. Кроме того, снимается главный риск фазы 2: по оценке §3.1, 500 функций «с нуля» — это 28–35 чел.-мес., а в roadmap на весь E2.2 заложено ≈ 21. Высвобожденные 1–2 Rust FTE стоит отдать на сводные таблицы и Chart: это риск «сводные объёмнее оценки» из §3.2 roadmap.
2. Таблицы по подобластям
Данные о лицензиях, звёздах, загрузках и датах взяты из
oss-verified.tsv (проверка 2026-10-04); для того, чего там
нет, стоит пометка. Даты последнего коммита — по клонам
(git log -1) или по pushed_at. Сокращения: ★ —
звёзды GitHub, «загр.» — загрузки с crates.io; стратегии — по BRIEF.
2.1 OOXML, ODF и общий фундамент кодеков
| Кандидат | SPDX (кл.) | ★ / загр. | Коммит | Язык | Что даёт MOffice | Стр. | Что пишем сами, риски | Эк. |
|---|---|---|---|---|---|---|---|---|
| zip2, quick-xml, roxmltree | MIT; MIT; MIT OR Apache (1) | 287M; 447M; 80M | 2026-10 / 08 / 09 | Rust | codec-core: ZIP64, потоковый XML, мелкие DOM |
adopt | — | (в базе) |
| rust_xlsxwriter | MIT OR Apache-2.0 (1) | ★591 / 4,9M | 2026-09-14 | Rust | эталон XML, который принимает Excel: диаграммы, условное форматирование, таблицы, спарклайны, проверка данных | ref + fork модулей записи диаграмм и стилей | только запись, без чтения и round-trip; модель чужая | 1–1,5 |
| umya-spreadsheet | MIT (1) | ★483 / 1,2M | 2026-10-01 | Rust | готовые Rust-структуры сотен элементов SpreadsheetML (чтение и запись) | ref | медленный, модель не наша; брать только как донор схемы | 0,5 |
IronCalc xlsx |
MIT OR Apache-2.0 (1) | ★4,2k | 2026-10-02 | Rust | импорт и экспорт стилей, условного форматирования,
sharedStrings, метаданных dynamic arrays, префиксов
_xlfn. |
fork частей | нет диаграмм, сводных, проверки данных, изображений, защиты и round-trip (§3.1) | 1 |
| Open-XML-SDK | MIT (1) | ★4,6k | 2026-09-16 | C# | машиночитаемые схемы всех элементов OOXML → генератор Rust-типов и валидатор | ref (данные схем) | генератор пишем сами | 1 |
| spreadsheet-ods | MIT/Apache-2.0 (1) | ★37 / 118k | 2026-03-20 | Rust | чтение и запись ODS: стили, формулы строками | ref / fork | один автор; конвертер OpenFormula ↔︎ канон пишем сами | 0,5–1 |
Apache OpenOffice
(xmloff, oox, фильтры
ww8/excel/ppt/rtf) |
Apache-2.0 (1) | ★1,2k | 2026-09-22 | C++ | единственный полный класс-1 код фильтров doc/xls/ppt/rtf/ODF/OOXML-импорта | ref | C++ на внутренних API AOO — только как референс поведения | (в §3.4) |
| docx-rs, docx4j, python-docx, python-pptx, PptxGenJS, mammoth.js, ClosedXML, exceljs | MIT / Apache-2.0 / BSD-2 (1) | 0,5–15k | 2024–2026 | разные | референсы разметки docx/pptx/xlsx | ref | — | — |
2.2 Бинарные форматы MS Office, CFB, шифрование
| Кандидат | SPDX (кл.) | ★ / загр. | Коммит | Язык | Что даёт MOffice | Стр. | Что пишем сами, риски | Эк. |
|---|---|---|---|---|---|---|---|---|
| Apache POI | Apache-2.0 (1) | ★2,3k | 2026-10-03 | Java | HSSF (xls), HWPF (doc), HSLF (ppt), DDF, HPSF, PTG, HDGF, HPBF, XDGF, HSMF | port (§3.4) | HWPF и HSLF лежат в «scratchpad» — запись слабая | 9–12 |
| calamine | MIT (1) | ★2,4k / 14,1M | 2026-09-02 | Rust | быстрое чтение значений и формул xls/xlsx/xlsb/ods, извлечение VBA
(vba.rs) |
adopt (R-сценарии) + fork vba.rs |
стилей нет — для полного кодека Sheets не годится | 1–2 |
| cfb | MIT (1) | 68M | 2026-09-18 | Rust | чтение и запись CFB v3/v4 | adopt | — | 0,5 |
| office-crypto (проверено 2026-10-04) | MIT (1) | ★9 / 197k | 2026-09-13 | Rust | расшифровка Agile/Standard (OOXML), RC4 CryptoAPI для doc и ppt | adopt / fork | нет xls RC4, XOR, Agile на SHA-1/256 | 0,5 |
| ms-offcrypto-writer (проверено 2026-10-04) | MIT OR Apache-2.0 (1) | ★0 / 113k | 2025-09-05 | Rust | запись Agile (AES-256/SHA-512) | adopt | один автор, тихий проект | 0,3 |
| msoffcrypto-tool | MIT (1) | ★625 | 2026-01-12 | Python | полный набор: xls RC4/XOR, doc RC4, ppt, Agile/Standard; тестовые файлы | port недостающего (≈1,5 тыс. строк) | — | 0,5 |
| olefile, oletools | BSD-3; MIT+BSD (1) | ★274; ★3,4k | 2024 / 2026 | Python | разбор OLE, анализ VBA и макровирусов (для предупреждений о макросах) | ref | — | — |
| libxls, xlrd, npoi | BSD; BSD-3; Apache (1) | ★0,5–6k | 2026 | C / Python / C# | вторые референсы BIFF8: XF, форматы, кодировки | ref | — | — |
| litchi (проверено 2026-10-04) | Apache-2.0 (1) | ★38 / 6,6k | 2026-09-29 | Rust | doc/xls/ppt/IWA/ODF на Rust | ref | автор сам пишет «не для продакшена» | — |
2.3 RTF, Markdown, HTML, EPUB, FB2
| Кандидат | SPDX (кл.) | ★ / загр. | Коммит | Что даёт MOffice | Стр. | Что пишем сами, риски |
|---|---|---|---|---|---|---|
| rtf-parser | MIT (1) | 188k | 2026-06-11 | токенизатор RTF | ref | модель упрощённая; свой ридер и писатель по RTF 1.9.1 (§3.4) |
| comrak | BSD-2-Clause (1) | ★1,7k / 8,4M | 2026-09-23 | GFM с AST и CommonMark-выводом → импорт и экспорт
.md |
adopt | — |
| pulldown-cmark | MIT (1) | ★2,7k / 166M | 2026-09-30 | быстрый потоковый Markdown (предпросмотр, Notes) | adopt | брать только один из двух (comrak или pulldown-cmark) для импорта |
| html5ever, ammonia | MIT OR Apache (1) | 117M; 17M | 2026-09 / 10 | разбор и санитизация HTML (Write, Mail) | adopt | CSS-каскад свой; не cssparser /
lightningcss (MPL-2.0, см. §4) |
| epub-builder | MPL-2.0 (2) | 169k | 2026-04-10 | запись EPUB | замена | свой EPUB 3 R/W на zip + quick-xml (≈2 тыс. строк, 0,7 чел.-мес.) |
| epub (проверено 2026-10-04) | GPL-3.0 (3) | 268k | 2025-10-29 | чтение EPUB | avoid | см. §5 |
| FB2 | — | — | — | — | own | крейтов нет; XML-схема FB2 — quick-xml, ≈1 тыс. строк, 0,3 чел.-мес. |
2.4 PIM, Access, iWork, Visio, Publisher
| Кандидат | SPDX (кл.) | ★ / загр. | Коммит | Язык | Что даёт MOffice | Стр. | Риски | Эк. |
|---|---|---|---|---|---|---|---|---|
| outlook-pst (проверено 2026-10-04) | MIT (1) | ★36 / 175k | 2026-09-30 | Rust | [MS-PST] (NDB, LTP, Messaging), совместимость с
mspst32.dll |
adopt | полнота OST и записи не проверена | 4–5 |
| libpff | LGPL-3.0 (2) | ★368 | 2026-09-17 | C | PST/OST | avoid (есть MIT) | — | — |
| java-libpst (проверено 2026-10-04) | Apache-2.0 / LGPL — двойная, выбираем Apache (1) | ★274 | 2022-07-11 | Java | второй референс PST | ref | заброшен | — |
| msg_parser | MIT (1) | ★10 / 303k | 2026-05-24 | Rust | .msg → поля и вложения |
adopt / fork | один автор; лучше общий слой MAPI-свойств с PST | 0,5 |
| onenote_parser | MPL-2.0 (2) | ★86 / 23k | 2026-08-06 | Rust | .one/.onetoc2, FSSHTTPB (OneDrive),
чернила, формулы |
решение владельца (§3.6) | — | 4–5 |
| pyOneNote (проверено 2026-10-04) | Apache-2.0 (1) | ★153 | 2024-07-11 | Python | разбор [MS-ONESTORE] | ref | неполный, не обновляется | 1 |
| jetdb (проверено 2026-10-04) | MIT OR Apache-2.0 (1) | ★13 / 8,4k | 2026-10-03 | Rust | Jet3…ACE17: схема, строки, DDL, SQL запросов, VBA, свойства, расшифровка | fork (§3.5) | молодой (с 2026-02); все строки грузит в память | 3–4 вместе с jackcess |
| jackcess | Apache-2.0 (1) | ★120 | 2026-09-13 | Java | эталон Jet/ACE, 86 тестовых баз | port частей | — | (вместе с jetdb) |
| mdbtools | GPL-2.0 (3) | ★1,2k | 2026-09-29 | C | — | avoid | упомянут в base.md и 04-file-formats.md —
убрать (§7) |
— |
| numbers-parser (проверено 2026-10-04) | MIT (1) | ★257 | 2026-10-03 | Python | Numbers R/W, .proto-схемы IWA |
ref + port схем | схемы извлечены из приложений Apple — юридическая проверка | 2–3 вместе |
| iWorkFileFormat (проверено 2026-10-04) | MIT (1) | ★273 | 2016-06-08 | док. | описание контейнера IWA | ref | устарело (iWork 2013) | (вместе) |
| libetonyek | MPL-2.0 (2) | ★19 | 2026-09-23 | C++ | Pages/Numbers/Keynote, включая iWork '09 | замена | — | — |
| keynote-parser (проверено 2026-10-04) | лицензия не указана (9) | ★210 | 2026-08-09 | Python | Keynote | не брать | без лицензии — все права защищены | — |
| POI HDGF / XDGF | Apache-2.0 (1) | — | 2026-10-03 | Java | vsd: распаковка и чанки; vsdx: страницы, мастера, фигуры | port | VSD-геометрию дописываем сами (§3.7) | 1–1,5 |
| libvisio; libmspub | MPL-2.0 (2) | ★47; ★14 | 2026-09 | C++ | vsd; pub | решение владельца / замена | — | — |
| POI HPBF | Apache-2.0 (1) | — | 2026-10-03 | Java | извлечение текста .pub |
port | рамки и раскладку пишем сами | 0,5 |
| evernote2md | MIT (1) | ★1,1k | 2026-09-25 | Go | ENEX → Markdown | ref | — | 0,2 |
2.5 Движок таблиц, функции, числовые форматы
| Кандидат | SPDX (кл.) | ★ / загр. | Коммит | Язык | Что даёт MOffice | Стр. | Риски | Эк. |
|---|---|---|---|---|---|---|---|---|
| IronCalc | MIT OR Apache-2.0 (1) | ★4,2k / 124k (base) | 2026-10-02 | Rust | 496 функций, парсер, spill, LET/LAMBDA, таблицы, форматер, 5 языков | fork (§3.1) | полный однопоточный пересчёт; нет 3D-ссылок, объединения и пересечения, внешних ссылок | 11–13 |
| formualizer (проверено 2026-10-04) | MIT OR Apache-2.0 (1) | ★187 / 3,4k | 2026-09-30 | Rust | граф зависимостей, инкрементальный и параллельный (rayon) пересчёт, Arrow-хранилище, 418 функций + 19 алиасов, 4 263 теста | ref + port графа и 3 функций | движок 0.10 новый; хранение по столбцам Arrow ≠ наши чанки | 1,5–2 |
| Univer engine-formula | Apache-2.0 (1) | ★21,9k | 2026-10-02 | TS | 516 имён (+22 заглушки), 475 spec-файлов / 5 563 проверки, описания на 17 языках | ref (тесты) + port 4 функций | русские описания похожи на справку Microsoft — не брать (§3.2) | 1 |
| formulajs | MIT (1) | ★820 | 2026-10-01 | JS | 437 имён, 3 084 проверки | ref (тест-оракул) | семантика JS-массивов ≠ Excel | 0,5 |
| SheetJS SSF | Apache-2.0 (1) | ★161 | 2023-02-22 | JS | движок числовых форматов Excel + эталоны | port (§3.3) | репозиторий заморожен (апстрим ушёл в монорепо SheetJS) | 1–1,5 |
| Grist | Apache-2.0 (1) | ★11,9k | 2026-09-29 | TS / Python | формульные столбцы и их зависимости, trigger formulas, сводные таблицы | ref (Base) | формулы на Python — не наш язык | 0,5 |
| HyperFormula | GPL-3.0 / коммерч. (3) | ★2,8k | 2026-09-29 | TS | — | avoid | — | — |
| ixion / orcus | MPL-2.0 (2) | ★19 | — | C++ | — | не нужны | есть класс 1 | — |
2.6 Данные, поиск решения, статистика, даты, десятичные
| Кандидат | SPDX (кл.) | ★ / загр. | Коммит | Что даёт MOffice | Стр. | Риски / что пишем | Эк. |
|---|---|---|---|---|---|---|---|
| Polars | MIT (1) | ★39,9k / 15,2M | 2026-10-02 | шаги «потоков данных» как LazyFrame (фильтр, join, union, pivot/unpivot, group_by), многопоточный CSV/Parquet/JSON для «большого режима» | adopt (Sheets 1.6) | +25–40 МБ к бинарнику; API меняется | 2–3 |
| arrow / parquet | Apache-2.0 (1) | ★3,6k / 84M | 2026-09-29 | Parquet/Arrow R/W (§5.22 sheets.md), ленивые чанки
ChunkSource::Lazy |
adopt | — | 0,5 |
| DuckDB + duckdb-rs | MIT (1) | ★41,7k / 4,4M | 2026-09-30 | SQL над Parquet/CSV, связанные «аналитические» таблицы Base | adopt (опционально, плагин) | C++ около 20–30 МБ; не дублировать Polars в ядре | 0,5 |
| DataFusion | Apache-2.0 (1) | ★9,4k / 28M | 2026-09-29 | SQL-движок на Rust | ref / резерв | тяжёлый; выбрать что-то одно: DuckDB или DataFusion | — |
| csv | Unlicense/MIT (0) | ★2,0k / 258M | 2026-08-04 | RFC 4180, потоковый разбор | adopt | — | 0,3 |
| encoding_rs + chardetng | (Apache OR MIT) AND BSD-3; Apache OR MIT (1) | 554M; 14M | 2026-09 / 03 | кодировки WHATWG (cp1251, KOI8-R, IBM866) + детектор Firefox | adopt | заменяет свою «статистику байтов» из §5.21 sheets.md | 0,5 |
| HiGHS + highs | MIT (1) | ★1,9k / 1,1M | 2026-09-30 | LP/MIP: симплекс, IPM, ветви и отсечения; двойственные цены и диапазоны устойчивости | adopt | сборка C++ (cmake) | 1,5–2 |
| good_lp (проверено 2026-10-04) | MIT (1) | ★461 / 4,2M | 2026-09-03 | моделирование LP поверх HiGHS | adopt с default-features = false |
по умолчанию тянет coin_cbc
(EPL-2.0) |
0,3 |
| Clarabel | Apache-2.0 (1) | ★613 / 2,1M | 2026-04-13 | QP и конические задачи (выпуклый GRG-режим) | adopt | — | 0,3 |
| argmin | MIT OR Apache-2.0 (1) | ★1,3k / 5,2M | 2025-11-07 | L-BFGS, Нелдер–Мид, линейный поиск (GRG, FORECAST.ETS) | adopt | GRG с активными ограничениями и DE пишем сами | 0,5 |
| microlp / minilp | Apache-2.0 (1) | 1,5M / архив | 2026-07 / 2020 | чистый Rust LP для WASM-сборки | adopt (wasm) | слабее HiGHS | — |
| statrs, nalgebra | MIT; Apache-2.0 (1) | 41M; 93M | 2026-09 / 06 | распределения (IronCalc уже использует statrs), QR/LU для LINEST/MINVERSE | adopt | — | (в п. 1) |
| statsmodels (проверено 2026-10-04) | BSD-3-Clause (1) | ★11,7k | 2026-10-03 | Holt–Winters AAA — референс для FORECAST.ETS* | ref / port алгоритма | совпадение с Excel не гарантировано: Microsoft не публикует детали | 0,5 |
| jiff, chrono | Unlicense OR MIT (0); MIT/Apache (1) | 211M; 850M | 2026-09 | часовые пояса и календарная арифметика (Mail, NOW) | adopt | сериалы 1900/1904 и «ошибка 1900» — своя тонкая логика (есть в IronCalc) | — |
| rust_decimal | MIT (1) | ★1,3k / 153M | 2026-09-24 | DECIMAL/MONEY/NUMERIC в Base и коннекторах | adopt | для Sheets не нужен (f64 + Ryū) | — |
2.7 MOffice Base
| Кандидат | SPDX (кл.) | ★ / загр. | Коммит | Что даёт | Стр. | Риски / что пишем | Эк. |
|---|---|---|---|---|---|---|---|
| SQLite + rusqlite | blessing / PD (0); MIT (1) | ★10,6k; 117M | 2026-10-01 / 09-25 | .mbx, хранилища Mail/Notes/Hub |
adopt (bundled) |
— | (в базе) |
| SQLCipher Community (LICENSE.md проверен 2026-10-04) | BSD-3-Clause (1) | ★7,3k | 2026-09-15 | шифрование .mbx (AES-256, PBKDF2-HMAC-SHA512) |
adopt через rusqlite
bundled-sqlcipher |
криптопровайдер: OpenSSL 3 (Apache-2.0) или CommonCrypto; не NSS (MPL) | 0,5 |
| sqlparser-rs | Apache-2.0 (1) | ★3,5k / 81M | 2026-09-26 | AST для диалектов SQLite/PG/MySQL/MsSql/Generic; QBE ↔︎ SQL, перевод
Jet-SQL, разбор HSQLDB-скриптов .odb |
adopt | комментарии и форматирование не сохраняются — храним исходный текст | уже в плане (2–3 против «с нуля») |
| tokio-postgres, mysql_async, tiberius, odbc-api | MIT OR Apache / MIT (1) | 72M; 7,8M; 5,3M; 1,7M | 2026-06…09 | нативные коннекторы PG, MySQL, MS SQL (TDS) и ODBC | adopt за трейтом DbBackend |
ODBC на Linux/macOS загружает системный unixODBC (LGPL) — не поставлять | уже в плане |
| sqlx | MIT OR Apache (1) | ★17,5k / 157M | — | единый async-API (PG/MySQL/SQLite) | не брать в Base | MS SQL удалён; два стека драйверов не держим | — |
| FastReport Open Source (проверено 2026-10-04) | MIT (1) | ★3,1k | 2026-09-11 | эталон движка отчётов с полосами: группы, KeepTogether, CanGrow/CanShrink, двухпроходный «стр. N из M» | ref / port алгоритма | C#; раскладку и печать делаем через MOffice Print | 0,5–1 |
| JasperReports; BIRT | LGPL-3.0; EPL-2.0 (2) | ★1,4k; ★0,5k | 2026-09 | — | только ref по документации | заменены FastReport | — |
| dbeaver, Baserow | Apache-2.0; MIT (1) | ★51,9k; ★2,2k | 2026 | конструктор запросов и ER-схема; формульные поля | ref | — | — |
| NocoDB | собственная с 2026-01-29 (3) | ★65k | — | — | avoid | — | — |
3. Глубокие разборы
3.1 IronCalc как основа meridian-calc
Клон oss-src/ironcalc_IronCalc — коммит
9b1ae3f от 2026-10-02, workspace base,
xlsx, bindings/{wasm,python,nodejs}.
Зависимости base: serde, ryu, chrono(+tz), bitcode, csv,
statrs, rand, regex — все класса 1.
Структура и объём (строк Rust, без тестов):
base/src/functions — 35,3 тыс. (по категориям,
functions/mod.rs — enum Function на 496
вариантов и диспетчер evaluate_function);
expressions — 7,9 тыс. (лексер lexer/mod.rs в
режимах A1 и R1C1, lexer/structured_references.rs, парсер
parser/mod.rs — AST Node,
parser/static_analysis.rs — 2,2 тыс.,
stringify.rs с to_rc_format и
to_localized_string, move_formula.rs);
formatter — 2,3 тыс.; user_model (undo,
автозаполнение, буфер обмена) — 8,7 тыс.; model.rs — 3,9
тыс.; evaluation.rs — 1,1 тыс.;
xlsx/src/import — 4,8 тыс., export — 3,8 тыс.
Тесты: 288 файлов, 52 тыс. строк, 2 768
#[test], плюс 211 эталонных xlsx
в xlsx/tests/calc_tests/<КАТЕГОРИЯ>/ (значения,
вычисленные Excel).
Как это устроено и что из этого следует для нас.
| Аспект | IronCalc (файл) | MOffice (sheets.md) |
Решение |
|---|---|---|---|
| Хранение ячеек | sheet_data.rs: чанки по 1 024 строки, строка —
отсортированный Vec<(col, Cell)> |
чанки 256×256, разреженные или плотные (§4.2) | заменить на meridian-grid::CellStore; функции читают
через трейт CellSource |
| Ячейка | types.rs:367
enum Cell { Number, SharedString, CellFormula, ArrayFormula{r,kind}, SpillCell{a}, … }
+ s: i32 |
CellSlot { Value, StyleId, ExtraId } (§4.3) |
соответствие 1:1; SpillCell →
Extra::SpillChild |
| Формулы | shared_formulas: Vec<String> в R1C1 на лист +
parsed_formulas: Vec<Vec<(Arc<Node>, StaticResult)>>
(model.rs:199) |
общие формулы с base (§4.6) |
идея совпадает. FormulaStore хранит
Arc<Node>; байткод — после
бенчмарков |
| Пересчёт | evaluation.rs:486 evaluate(): полный рекурсивный проход
по всей книге, рестарты прохода для spill; графа зависимостей,
инкрементальности и потоков нет (rayon не
используется) |
граф + инкрементальный пересчёт + rayon по компонентам (§5.4–5.5) | граф и планировщик пишем свои (референс — formualizer); из IronCalc берём вычисление одной формулы |
| Состояние вычисления | variable_stack, lambdas,
evaluation лежат в Model
(&mut self) |
параллельные компоненты | вынести в EvalFrame на поток; функции переводятся с
&mut Model на EvalContext (механическая
замена в 35 тыс. строк) |
| Spill | порядок якорей + рестарты;
model.rs:1224 spill_dynamic_array,
functions/spill_functions.rs |
регистрация «пишущей» формулы в графе (§5.6) | логику блокеров и #SPILL! берём, порядок даёт наш
граф |
| Синтаксис | A1 и R1C1, структурированные ссылки, @,
A1#, LAMBDA-вызовы LAMBDA(..)(..);
нет 3D-ссылок Лист1:Лист3!A1, внешних
[Книга]Лист!A1, объединения , и пересечения
«пробел» (token.rs:219 — таких токенов нет) |
всё P0 (§2.4) | дописать: ≈2–3 тыс. строк, 1–1,5 чел.-мес. |
| Локали | имена функций: en/de/fr/es/it
(generate_language/src/languages.json); числовые локали:
en, en-GB, de, es, fr, it
(generate_locale/locales.json) |
ru и en — P0, ещё 16 языков — P1 | JSON → locale/*.toml; русские имена 518 функций — наша
таблица |
| Числовые форматы | formatter/ (упрощённый, автор сам пишет в комментарии,
что все правила Excel «практически невозможно» реализовать) |
§5.10 | заменить портом SSF (§3.3) |
| xlsx | импорт: стили, условное форматирование (0,9 тыс.), таблицы,
комментарии (только чтение), гиперссылки, объединения, закрепление,
имена, metadata dynamic arrays; нет
проверки данных, диаграмм, изображений, сводных, защиты, спарклайнов,
VBA, threadedComments, round-trip неизвестных частей |
полный round-trip (§7 sheets.md) |
кодек codec-ooxml/sml пишем свой; из IronCalc берём
модули стилей и условного форматирования |
Сравнение функций (скрипт fncov.py
лежит в scratchpad сессии и в репозиторий не кладётся: он разбирает
таблицы §5.23 sheets.md и сопоставляет их с
languages.json IronCalc, function-map.ts
Univer без закомментированных заглушек, экспортами src/*.js
formulajs и fn name() в builtins formualizer).
Каталог MOffice: 518 имён = P0 331 (317 + 14 алиасов) +
P1 171 (147 + 24) + P2 16. Все 496 функций IronCalc входят в каталог; 4
из них — FORECAST.ETS, .CONFINT,
.SEASONALITY, .STAT — заглушки
#N/IMPL!
(functions/statistical/forecast.rs:85).
| Категория | P0: всего / IronCalc | P1: всего / IronCalc | P2: всего / IronCalc | Недостаёт; где взять (U — Univer, F — formualizer, J — formulajs, «—» — нигде) |
|---|---|---|---|---|
| Математические | 57 / 56 | 24 / 24 | — | AGGREGATE (U, F, J) |
| Статистические | 63 / 63 | 48 / 44 | — | FORECAST.ETS* ×4 (—; алгоритм по statsmodels) |
| Совместимость (алиасы) | 14 / 14 | 24 / 24 | — | — |
| Текстовые | 33 / 33 | 15 / 11 | 2 / 0 | BAHTTEXT (U), DBCS (U), JIS (—), PHONETIC (—); TRANSLATE и DETECTLANGUAGE — через Assist |
| Логические, LAMBDA | 20 / 20 | — | — | — |
| Дата и время | 25 / 25 | — | — | — |
| Ссылки и поиск | 35 / 34 | 5 / 2 | 1 / 0 | GETPIVOTDATA (—, нужен наш PivotRender); IMAGE (U),
GROUPBY (U, F), PIVOTBY (F); RTD (—) |
| Финансовые | 27 / 27 | 24 / 24 | 4 / 4 | — |
| Инженерные | 24 / 24 | 30 / 30 | — | — |
| Информационные, БД, веб | 33 / 33 | 1 / 0 | 9 / 0 | FILTERXML (U); WEBSERVICE, EUROCONVERT (заглушки у Univer), CUBE* ×7 (—, значения из кэша файла) |
| Итого | 331 / 329 (99,4 %) | 171 / 159 (93,0 %) | 16 / 4 (25 %) | 492 / 518 = 95,0 %; с Univer и formualizer — 499 (96,3 %); остаются 19 своих (P0 — 1, P1 — 6, P2 — 12) |
Для сравнения покрытие каталога другими движками: formualizer — 428,
Univer — 493, formulajs — 403. Оговорка о качестве: «есть в IronCalc» ≠
«полностью как в Excel». В functions/ 33 места возвращают
#N/IMPL! для частных случаев. 18 из них — «Arrays not
supported yet»: массивы в аргументах AND/OR, COUNTIF-семейства,
D-функций, SUBTOTAL, текстовых и дат-функций. Остальные — LAMBDA в
аргументах, неявное пересечение в текстовых функциях и частичные
INFO, CELL, SHEETS
(functions/information/mod.rs:381–496). Закрыть этот список
— ≈1 чел.-мес.
Многопоточность и производительность. У IronCalc их
нет: однопоточный полный пересчёт. Для цели R1 из roadmap (1 млн формул
≤ 2 с, пересчёт после правки — мгновенный) нужен свой граф. Для
сравнения: formualizer заявляет 1 млн формул за 0,38 с и 52 мс на
пересчёт после правки одной ячейки (README, проверено 2026-10-04). Его
engine/ даёт референс класса 1:
interval_tree.rs — диапазонные слушатели,
csr_edges.rs/delta_edges.rs — рёбра графа,
scheduler.rs/topo/ — порядок,
lookup_index_cache.rs — хэш-индекс для VLOOKUP/MATCH (§5.24
sheets.md).
Стратегия fork →
kernel/crates/meridian-calc. (1) Снимок
9b1ae3f в ветку upstream/ironcalc; из двойной
лицензии выбираем MIT; копирайт «Nicolás Hatcher и авторы IronCalc» — в
NOTICE и в заголовках файлов. (2) I05, 3 недели: выделить
parse/ и functions/, ввести трейты
CellSource и EvalContext, прогнать 2 768
тестов и 211 xlsx на адаптере. (3) I05–I06: граф §5.4 и планировщик §5.5
с референсом formualizer. (4) I06–I07: 3D-ссылки, объединение,
пересечение, внешние ссылки; ru-локаль; AGGREGATE (порт
formualizer-eval/src/builtins/math/aggregate.rs); массивы в
аргументах. (5) I07–I08: GROUPBY и PIVOTBY
(builtins/lookup/dynamic.rs), IMAGE, FILTERXML, BAHTTEXT,
DBCS (Univer), FORECAST.ETS* (statsmodels), GETPIVOTDATA (после
сводных). (6) Раз в квартал переносить исправления из апстрима (≈0,25
чел.-мес.); для этого раскладка functions/ остаётся близкой
к оригиналу.
Альтернатива — formualizer как движок целиком.
Плюсы: граф и потоки уже есть. Минусы: покрытие каталога 428 против 492,
хранение по столбцам Arrow вместо наших чанков 256×256, движок 0.10
переписан в 2026 году, ★187. Рекомендация — спайк на 2 недели в
I05: прогнать 211 xlsx IronCalc и бенчмарк «1 млн формул» на
обоих; решение зафиксировать в 03-architecture.md.
Экономия. С нуля 492 функции — это 28–35 чел.-мес. (1,2–1,5 чел.-дня на функцию с тестами и сверкой с Excel), парсер с локалями — 3–4, тесты — 6–8; всего 35–45. Против базиса E2.2 (≈ 21) остаётся 8–10: адаптер 1,5; граф и пересчёт 3–4; синтаксис 1–1,5; 26 функций 1,5–2; массивы 1; ru 0,3. Экономия 11–13 чел.-мес., и цель «500 функций» сдвигается с I08 на I06.
3.2 Источники недостающих функций: formulajs и Univer
Главный результат сравнения: портировать из JS/TS почти нечего. Из 26 функций, которых нет у IronCalc, Univer даёт 6, formualizer (Rust) — 3, formulajs — только AGGREGATE, которая есть и у двух других.
Univer engine-formula (Apache-2.0,
oss-src/dream-num_univer/packages/engine-formula, коммит
2026-10-02):
- Функции:
src/functions/<категория>/<имя>/index.ts, регистрация в<категория>/function-map.ts, имена — вfunction-names.ts. Реализовано 516 имён: в это число входят 6 операторов изmeta, 2 изarrayи около 15 собственных функций Univer и Google Sheets (ISEMAIL, ISURL, REGEXMATCH, FLATTEN, ROUNDBANK, TO_DATE…). Ещё 22 заглушкиNotImplementedFunctionзакомментированы в картах: CUBE* ×7, FORECAST.ETS* ×4, GETPIVOTDATA, RTD, WEBSERVICE, EUROCONVERT, PHONETIC, CALL, REGISTER.ID, INFO, ISOMITTED, AMORDEGRC, ISO.CEILING. Объём: функции — 52 тыс. строк TS,engine/— 19,7 тыс. (лексер, AST, интерпретатор,engine/dependency/dependency-tree.ts),services/— 19,7 тыс. - Тесты: 475 файлов
__tests__/index.spec.ts, 5 563 проверкиexpect(; тесты есть почти у каждой функции. - Берём: (1) тесты как независимый оракул — скрипт-конвертер spec →
Rust-тест, ≈2 недели QA-автоматизации; (2) порт TS → Rust 4 функций:
web/filterxml(99 строк),lookup/image(162),text/bahttext(122),text/dbcs(72), плюсmath/aggregate(300) как второй референс. - Описания функций не берём.
src/locale/function-list/<кат>/ru-RU.ts(8,1 тыс. строк; всего 17 языков, 138 тыс. строк) содержит тексты в стиле справки Excel со ссылками наsupport.microsoft.com/ru-ru/…. Вероятное происхождение — справка Microsoft, поэтому лицензия Apache-2.0 на них не распространяется. Описания и имена параметров для «Мастера функций» пишем сами: 518 × ≈15 мин ≈ 3 чел.-недели на язык, это работа техписателей.
formulajs (MIT,
oss-src/formulajs_formulajs, v4.6.1, коммит 2026-10-01):
src/*.js — 12,3 тыс. строк, 437 имён (403 из каталога),
тесты test/*.js — 3 084 проверки,
зависимости jstat (MIT) и bessel (лицензия не
проверена). Уникальных для нас функций нет. Семантика JS: диапазоны —
это массивы, пустые ячейки и текст в диапазонах приводятся не как в
Excel. Поэтому ожидания из тестов прогоняем как третий
оракул с фильтром: расхождение с IronCalc → разбор вручную, а
не «истина».
Поправка в component-map.md. Было:
«formulajs (411), Univer (502) — port — полный каталог». Нужно:
«formualizer (AGGREGATE, GROUPBY, PIVOTBY) + Univer (IMAGE, FILTERXML,
BAHTTEXT, DBCS) — port 7 функций; Univer + formulajs — тест-оракулы
(≈8,6 тыс. проверок)». Экономия ≈1,5 чел.-мес.: 0,5 — функции, 1 —
эталоны для стенда формул E2.6.
3.3 Числовые форматы: SheetJS SSF → meridian-numfmt
oss-src/SheetJS_ssf: Apache-2.0, последний коммит
2023-02-22 — репозиторий заморожен, развитие идёт в монорепо SheetJS (не
проверено). Собранный ssf.js — 966 строк; исходники лежат в
bits/*.js (1 146 строк). Главная ценность —
эталоны, снятые с Excel: test/valid.tsv
(442 кода), general.json (516), implied.json
(756 — встроенные id), fraction.json (121),
oddities.json (180), is_date.json (447),
exp.tsv (46), dates.tsv (≈296 тыс. строк),
times.tsv и cal.tsv (по 1 048 576 строк).
Всего ≈2,4 млн проверок, 186 МБ — они лежат в тестовом репозитории, не в
продукте.
| Шаг порта | Источник (bits/) |
Модуль meridian-numfmt |
Строк Rust | Дней |
|---|---|---|---|---|
Лексер, секции ;, условия [<100],
цвета, [$-LCID] |
80_split, 82_eval (лексер),
88_cond |
lexer.rs, section.rs |
450 | 4 |
Компиляция в инструкции (грамматика §5.10.1
sheets.md) |
82_eval |
compile.rs |
400 | 4 |
Числа: группы, масштаб ,, %,
E±, выравнивание ?, дроби (цепные дроби) |
56_commaify…69_numfoot,
30_frac |
number.rs, fraction.rs |
600 | 6 |
Даты и время: сериал → части, «ошибка 1900», 1904, [h],
доли секунды, AM/PM, e/b, хиджра, тайские
цифры |
35_datecode, 50_date,
45_hijri, 49_thaidigits |
datetime.rs |
450 | 4 |
| «Общий» с подбором под ширину столбца (§5.10.4) | 40_general + своё |
general.rs |
250 | 3 |
| Встроенные форматы id 0–49 и локальные id 50–81 | 25_table, 26_defaults |
builtin.rs |
200 | 1 |
Локализация: разделители, месяцы и дни из ICU4X,
[$₽-419], LCID → локаль |
у SSF только en-US — пишем сами | locale.rs |
300 | 4 |
| Раннер эталонов (вне продукта) | test/* |
tests/ssf_corpus.rs |
300 | 3 |
Итого ≈3 тыс. строк и ≈29 рабочих дней, то есть 1,3–1,5 чел.-мес. С
нуля, вместе со сбором эталонов, — 2,5–3. Экономия 1–1,5
чел.-мес. Сами дописываем то, чего в SSF нет: *x
(заполнитель) и _x (отступ шириной символа) возвращаются
как fill и pad в DisplayString,
ширину считает рендер по метрике шрифта; [ColorN] — палитра
из 56 цветов; японские эры g/gg/ggg (P2).
meridian-numfmt заменяет formatter/ IronCalc и
становится единым механизмом для отображения, TEXT(),
экспорта CSV «как отображено», Base и Forms. В NOTICE: «SheetJS SSF, ©
SheetJS LLC, Apache-2.0»; в файлах — заголовок «основано на SheetJS
SSF».
3.4 Бинарные форматы: POI, calamine, cfb, шифрование, RTF
Apache POI (Apache-2.0, ★2,3k, коммит
12c3688 от 2026-10-03; частичный клон для подсчёта —
scratchpad/fmt-src/apache_poi). Объём модулей Java приведён
как «файлов / строк / строк кода без комментариев».
| Модуль POI (путь) | Формат | Java | Что портируем → куда | Rust, тыс. строк | Порт / с нуля, чел.-мес. |
|---|---|---|---|---|---|
poi/…/hssf/record (+ aggregates,
cf, chart, pivottable) |
xls BIFF8 | 248 / 45,2k / 28,8k | ≈250 записей: SST, XF, FORMULA, SHRFMLA, ARRAY, CF, DV, имена,
графика → codec-msbinary/xls |
18 | 4–5 / 8–10 |
poi/…/hssf/usermodel |
xls | 65 / 22,9k / 14,2k | не портируем (модель своя); логику сборки — выборочно | — | — |
poi/…/ss/formula/ptg |
формулы xls и xlsb | 68 / 6,0k / 4,3k | кодирование и декодирование PTG → codec-msbinary/ptg
(общий для xlsb) |
2,5 | 0,7 / 1,5 |
poi/…/ddf |
OfficeArt (Escher) | 38 / 6,8k / 4,2k | фигуры и BLIP для xls, doc, ppt, pub →
codec-msbinary/officeart |
3 | 0,8 / 1,5 |
poi/…/hpsf |
SummaryInformation | 46 / 9,2k / 4,4k | свойства документа → codec-msbinary/props |
2,5 | 0,5 / 1 |
poi-scratchpad/…/hwpf |
doc | 199 / 54,4k / 36,7k | model/ (FIB, TextPieceTable, CHP/PAP/SEP-таблицы,
StyleSheet, ListTables, FieldsTables, NotesTables, PicturesTable),
sprm/ → codec-msbinary/doc |
15–18 | 4–5 / 8–10 |
poi-scratchpad/…/hslf |
ppt | 169 / 34,7k / 21,3k | record/ (≈100 атомов и контейнеров),
model/textproperties → codec-msbinary/ppt |
12–14 | 3–4 / 6–7 |
poi-scratchpad/…/hdgf,
poi-ooxml/…/xdgf |
vsd; vsdx | 27 / 2,7k; 56 / 6,6k | распаковка VisioDocument, чанки; фигуры и наследование
мастеров vsdx → codec-vector |
4 | 1,1 / 3 |
poi-scratchpad/…/hpbf |
pub | 14 / 1,6k / 1,0k | текст QuillContents, EscherStm →
codec-publisher |
0,7 | 0,2 / 0,5 |
poi/…/poifs, poifs/crypt |
CFB; шифрование | 115 / 18,7k; 50 / 7,7k | не портируем: крейт cfb +
offcrypto (ниже) |
— | — |
poi-scratchpad/…/hsmf, hwmf,
hemf |
msg; wmf, emf | 25 / 5,7k; 68 / 23,7k | msg — референс; wmf/emf — кандидат для codec-vector
(вне этой области) |
— | — |
Итого порт ≈ 15–17 чел.-мес. против 30–37 по спецификациям [MS-DOC],
[MS-XLS], [MS-PPT] «с нуля». Экономия против базиса E1.4, E2.4 и
E3.4 — 9–12 чел.-мес.: doc 3–4, xls 3–4, ppt 2–3, vsd/vsdx
1–1,5. Порядок: фаза 1 — DDF, HPSF, HWPF (doc R — P0); фаза 2 — записи
HSSF и PTG (xls R — P0, W — P1; xlsb R через тот же PTG); фаза 3 — HSLF
(ppt R), HDGF/XDGF, HPBF. Приём порта: не копировать ООП-иерархию POI, а
описать записи декларативно (структуры плюс таблица «sid → декодер»).
Запись doc и ppt у POI слабая, поэтому писатели делаем свои (doc W — P1,
ppt W — P2). Вторым референсом поведения служат фильтры Apache
OpenOffice (Apache-2.0): ww8,
sc/source/filter/excel, sd/source/filter/ppt —
пути не проверены.
calamine (MIT, v0.36.1, коммит 2026-09-02, 17,3 тыс.
строк, scratchpad/fmt-src/tafia_calamine):
src/xls.rs (2,0k), src/xlsb/ (1,3k),
src/xlsx/ (5,2k), src/ods.rs (0,8k),
src/vba.rs (467 строк: распаковка [MS-OVBA] и извлечение
модулей), src/formats.rs (дата ли это по формату). Читает
значения, формулы (PTG → текст для xls и xlsb), объединения, имена, VBA
и изображения; стилей, условного форматирования, проверки данных
и диаграмм нет. Стратегия: adopt для лёгких сценариев
только-чтения (импорт в Base, источник «Excel» в потоках данных,
предпросмотр в Hub, Forms) и fork vba.rs в
meridian-script/vba, чтобы транслятор VBA получал исходники
модулей из xlsm, xls, doc и accdb. Кодек Sheets — свой. Экономия 1–2
чел.-мес.
CFB: adopt крейта cfb (MIT, 68 млн
загрузок, чтение и запись v3/v4). Шифрование — модуль
codec-core/offcrypto:
- adopt
office-crypto(MIT) для расшифровки Agile, Standard и RC4 CryptoAPI в doc и ppt иms-offcrypto-writer(MIT OR Apache-2.0) для записи Agile AES-256/SHA-512, как требует §4.104-file-formats.md; - порт из msoffcrypto-tool (MIT,
scratchpad/fmt-src/nolze_msoffcrypto-tool, 4,6 тыс. строк Python):method/xor_obfuscation.py(354),method/rc4.py(97),format/xls97.py(683 — расшифровка BIFF с открытыми записями BOF, FILEPASS…),format/doc97.py(501),format/ppt97.py(838), Agile на SHA-1/256/384 — всего ≈1,5 тыс. строк Rust; тестовые файлыtests/inputs/*— в корпус. Итого 1 чел.-мес. вместо 2–2,5, экономия 1–1,5.
RTF: своя реализация по спецификации Microsoft RTF
1.9.1. Ридер ≈4–5 тыс. строк: группы, ≈1 500 управляющих слов,
\trowd, \listtable, \field,
\pict, \uN, кодовые страницы через
encoding_rs. Писатель — 2–3 тыс. Всего 3–3,5 чел.-мес. Референсы класса
1: токенизатор rtf-parser (MIT) и RTF-фильтры Apache
OpenOffice (svtools/source/svrtf,
sw/source/filter/rtf; не проверено). Классы 2–3 не трогаем:
pandoc (GPL), writerfilter LibreOffice (MPL). Сжатый RTF (LZFu) из PST и
MSG — свой, ≈200 строк по [MS-OXRTFCP].
3.5 Access: jackcess → codec-access
jackcess (Apache-2.0, ★120, коммит 2026-09-13,
oss-src/jahlborn_jackcess): 194 файла в
src/main (≈56 тыс. строк) и 45 тестовых классов; 86
тестовых баз .mdb/.accdb (Apache-2.0) — их берём в
корпус. Карта кода
src/main/java/com/healthmarketscience/jackcess/:
impl/(65 файлов, 30,5 тыс. строк):- формат и страницы:
JetFormat(1 199 — константы Jet3/Jet4/ACE12–16),PageChannel(466 — страницы, маска заголовка, шифрование),UsageMap(1 112); - таблицы и значения:
TableImpl(3 739 — TDEF и строки),ColumnImpl(2 933 — MONEY, NUMERIC, DATETIME, сжатый Unicode),LongValueColumnImpl(547 — LVAL); - индексы:
IndexData/IndexImpl/IndexPageCache(≈5,3 тыс.),GeneralLegacyIndexCodes+resources/index_codes_*.txt(таблицы сортировки); - каталог и свойства:
DatabaseImpl(3 042 —MSysObjects, связи),PropertyMaps(559 — LvProp),OleUtil(838);
- формат и страницы:
impl/query/(1,8 тыс.) — SQL изMSysQueriesдля SELECT, UNION, CROSSTAB, APPEND, UPDATE, DELETE, MAKETABLE, DDL;impl/complex/(2,0 тыс.) — вложения, многозначные поля, история версий;impl/expr/(9,0 тыс.) — язык выражений Access: парсер и около 120 функций (Default*Functions).
jetdb (MIT OR Apache-2.0, crates.io 0.3.3, ★13,
коммит 2026-10-03; проверено 2026-10-04 по README) — то, что
base.md §6.2 собирался писать сам. Это чистый Rust, Access
97 (Jet3) … 2019 (ACE17): каталог, схема (столбцы, индексы, связи),
строки, генерация DDL для SQLite/PG/MySQL, восстановление SQL
сохранённых запросов, исходники VBA, макросы в виде текста SaveAsText,
LvProp, расшифровка (RC4 Jet, Agile, RC4 CryptoAPI, Standard AES),
сборка под wasm32. Ограничения: только чтение, полный скан без индексов,
все строки грузятся в память. Тестовые базы взяты из jackcess.
Юридическая оговорка: автор благодарит mdbtools за
HACKING.md — это документация формата, не код. Факты о
формате не охраняются, но перед fork нужна короткая проверка, что кода
mdbtools в jetdb нет; затем — запись в реестр.
План codec-access:
- Fork jetdb в
kernel/crates/codecs/codec-access, исправления по возможности отдаём в апстрим. 0,3 чел.-мес. - Доработки: потоковый итератор строк вместо
Vec, кодовая страница Jet3 из заголовка (cp1251 для русских баз через encoding_rs — проверить, есть ли она в jetdb), сопоставление типов Access → SQLite (§4.3base.md), пакетный импорт в.mbxтранзакциями по 10 тыс. строк. 0,5 чел.-мес. - Порт из jackcess по необходимости:
impl/complex/*→ вложения в дочерние таблицы, многозначные поля в JSON (0,3);impl/query/*— сверка с восстановлением SQL у jetdb (0,2). impl/expr/*не портируем. Список функцийDefault*Functionsслужит спецификацией для слоя совместимости «выражения Access» вmeridian-calc(IIf, Nz, Format, DateDiff, DLookup…), как предлагает вопрос 10.2base.md. 0,5 чел.-мес.- CI: сверка jetdb ↔︎ jackcess (Java как инструмент тестов, не в
продукте) на 86 базах + 100 реальных из §9
base.md.
Итого 1,8–2 чел.-мес. вместо 4–5. Экономия 3–4 чел.-мес.
(E5.6). Если jetdb не пройдёт проверку — порт чтения jackcess
(≈12–15 тыс. строк Java → 9–11 тыс. Rust, 2,5–3,5 чел.-мес.), экономия
1,5–2. mdbtools (GPL-2.0) и обёртку mdbsql
не используем ни как код, ни как «референс»: ссылки на mdbtools в
base.md (§6.2, §9) и 04-file-formats.md
(§4.10) нужно убрать (§7).
3.6 OneNote, PST, MSG
OneNote — onenote.rs / onenote_parser
(MPL-2.0, класс 2, v2.0.0, коммит 2026-08-06,
oss-src/msiemens_onenote.rs). Объём
crates/parser — 18,6 тыс. строк Rust:
src/onenote(4,6k) — модель: книжка, раздел, страница, outline, rich text, таблица, изображение, вложение, чернила, формулы;src/one/property_set(2,3k),src/one/property(1,8k) — объекты и свойства [MS-ONE];src/fsshttpb/*(1,9k) иsrc/onestore/fsshttpb(0,85k) — пакеты FSSHTTPB для книжек, скачанных из OneDrive;src/onestore/{shared,desktop}(1,1k) — revision store формата desktop;src/fs,src/shared(0,9k).
Тестов почти нет (276 строк); записи нет. Чернила и формулы разобраны реверсом — в спецификации их нет.
Своя реализация по [MS-ONESTORE] и [MS-ONE] (Open
Specification Promise). Хранилище ревизий (заголовок,
FileNodeList, ≈40 типов FileNode, манифесты
ObjectSpace и Revision, ExtendedGUID и CompactID, журнал транзакций,
FileDataStore) — 3–4 тыс. строк. Объекты jcid* (Page,
Outline, OutlineElement, RichText с TextRunFormatting,
Image, Table, EmbeddedFile) — 5–6 тыс. Отображение в
n:page/n:outline/t:p/tb:table
— 1–2 тыс. FSSHTTPB для OneDrive — 2–3 тыс. (P2). Итого 11–15 тыс.
строк, 4–6 чел.-мес., плюс 1 на чернила и формулы
реверсом. Референс класса 1 — pyOneNote (Apache-2.0, ★153, последний
коммит 2024-07-11, проверено 2026-10-04; полнота не проверена). Варианты
решения для владельца — §4.
PST — outlook-pst (MIT; crates.io
1.2.0, 175 тыс. загрузок; github microsoft/outlook-pst-rs,
★36, коммит 2026-09-30; проверено 2026-10-04). README называет его
«clean room»-реализацией [MS-PST] от Microsoft, совместимой с
mspst32.dll и переносимой между ОС. Adopt.
codec-mail/pst — тонкий адаптер по §4.9
04-file-formats.md: папки → mm:folder;
сообщения → .eml (MIME собирается из MAPI-свойств, RTF →
HTML с де-инкапсуляцией [MS-OXRTFEX] и распаковкой LZFu); встречи →
VEVENT (AppointmentRecurrencePattern → RRULE через
rust-rrule); контакты → vCard. Это 1–1,5 чел.-мес. вместо своих
NDB/LTP/Messaging (≈15–20 тыс. строк, 5–6 чел.-мес.). Экономия
4–5. Не проверено: OST, запись, потоковое чтение 50-гигабайтных
файлов — первая задача спайка в I17. Альтернативы не нужны: libpff
(LGPL-3), java-libpst (Apache/LGPL, заброшен с 2022), XstReader (MS-PL,
2021).
MSG ([MS-OXMSG]: CFB, потоки
__substg1.0_*, __properties_version1.0):
msg_parser (MIT, 303 тыс. загрузок, ★10) подходит для
быстрого старта; целевой вариант — своя реализация ≈1 тыс. строк на
крейте cfb с общим слоем MAPI-свойств вместе с PST.
Референс — POI HSMF. Экономия ≈0,5.
3.7 iWork, Visio, Publisher
iWork (IWA, iWork 2013 и новее). Устройство: ZIP или
папка-пакет с Index/*.iwa. Каждый .iwa — кадры
snappy в варианте Apple (без CRC), внутри — varint-длина,
TSP.ArchiveInfo и protobuf-сообщения объектов со ссылками
по идентификаторам. Рядом лежат Data/* (медиа) и
preview.jpg. Что есть класса 1:
obriensp/iWorkFileFormat(MIT, 2016) — описание контейнера и утилитаproto-dump, которая извлекает схемы;masaccio/numbers-parser(MIT, коммит 2026-10-03) — актуальные.proto-схемы TSP, TSK, TSD, TSS, TST (таблицы), TSCE (формулы), TN, а также логика тайлов ячеек v4/v5, таблиц строк и форматов, AST формул и записи;DevExzh/litchi(Apache-2.0) — IWA на Rust, пригоден как пример связки snappy + prost.
keynote-parser без лицензии — не берём. libetonyek
(MPL-2.0) нужен был бы только ради старых XML-форматов iWork '09 — их
предлагаем не поддерживать.
План codec-iwork: контейнер (snap +
prost) — 1,5 тыс. строк; Numbers — таблицы, формулы TSCE →
наш AST, стили — 4 тыс.; Pages — TSWP: текст, стили, списки, таблицы,
изображения — 4–5 тыс.; Keynote — слайды, мастера, фигуры, текст,
анимации в P2 — 4 тыс. Итого 13–15 тыс. строк, 5–6 чел.-мес. вместо 7–9
вслепую, экономия 2–3. Риск: схемы .proto
машинно извлечены из приложений Apple. Это функциональное описание
формата для совместимости, но нужно юридическое заключение в фазе 0
вместе с вопросом об OSP.
Visio. VSDX: спецификация [MS-VSDX] (OSP) плюс порт
POI XDGF (poi-ooxml/…/xdgf: 56 файлов, 4,5 тыс. строк кода
— страницы, мастера, наследование ячеек ShapeSheet, геометрия
MoveTo/LineTo/ArcTo/NURBSTo/PolylineTo…, текст). Порт ≈3 тыс. строк Rust
в codec-ooxml/vsdx — 0,8 чел.-мес. вместо 2; запись vsdx —
своя (≈2 чел.-мес.). VSD (бинарный) спецификации не имеет. POI HDGF (2,7
тыс. строк: распаковка HDGFLZW, потоки и чанки, таблица
разбора chunks_parse_cmds.tbl) даёт структуру и текст.
Ячейки ShapeSheet в VSD — те же, что в [MS-VSDX], поэтому остальное
восстанавливаем «чистой комнатой» по парам файлов, сохранённых из Visio
в VSD и VSDX, — 3–4 чел.-мес. Экономия 1–1,5. Фразу «R*
через портирование подхода libvisio» в §4.4
04-file-formats.md заменить (libvisio — класс 2, §4).
Publisher. Спецификации нет. POI HPBF (1,6 тыс.
строк: QuillContents — текст и гиперссылки,
EscherStm — фигуры) за 0,2 чел.-мес. даёт R* «только
текст»: поиск и индекс в Hub, импорт текста в Write. Полный R*
(страницы, рамки, связанные фреймы, стили) — 3–4 чел.-мес. своими силами
или libmspub (MPL-2.0) — решение владельца (§4). Рекомендация: в 1.x —
только текст через HPBF; полный импорт решить в фазе 7 по запросам
пользователей.
3.8 Base: SQLite, SQLCipher, sqlparser-rs, коннекторы, отчёты
Хранилище. SQLite (public domain, класс 0) через
rusqlite (MIT, 0.40.2). SQLCipher Community —
BSD-3-Clause, © Zetetic LLC (текст LICENSE.md проверен
2026-10-04), класс 1. Обязательство одно: уведомление в документации
бинарного дистрибутива, то есть в окне «О программе». Формат SQLCipher 4
(AES-256-CBC, HMAC-SHA512, PBKDF2 на 256 000 итераций) совпадает с §2.6
base.md. Ответ на вопрос 10.4 base.md:
статическая сборка через rusqlite
bundled-sqlcipher-vendored-openssl (OpenSSL 3 — Apache-2.0)
на Windows и Linux и CommonCrypto на macOS; провайдер NSS (MPL) не
используем. Важно для архитектуры (не проверено в коде, по документации
rusqlite): фичи bundled и bundled-sqlcipher
собирают один и тот же libsqlite3-sys и не
совмещаются в одном процессе. Поэтому весь пакет — Base, Mail,
Notes, индекс Hub — переводим на сборку SQLCipher: без ключа она
работает как обычный SQLite. Это нужно записать в
03-architecture.md.
sqlparser-rs (Apache-2.0, 0.63.0) — уже выбран в
§5.2 base.md. Подтверждаем и уточняем, где он применяется:
SQL → AST → QueryDesign, если запрос укладывается в
подмножество QBE; QBE → SQL через AST с кавычками по диалекту; перевод
Jet-SQL из MSysQueries — свой предпроцессор для
#дат#, */? в LIKE и
IIf, а скобки [Таблица].[Поле] разбирает
диалект MsSql; разбор HSQLDB-скриптов из .odb — диалектом
Generic. Ограничение: комментарии и форматирование теряются, поэтому
исходный текст SQL храним всегда.
Коннекторы — adopt за трейтом DbBackend
(§4.7 base.md):
tokio-postgres— PostgreSQL;mysql_async— MySQL/MariaDB;tiberius— MS SQL (TDS 7.2+, Azure SQL, TLS через rustls);odbc-api— ODBC. Драйвер-менеджер: на Windows системныйodbc32.dll, на Linux и macOS — системный unixODBC или iODBC. unixODBC под LGPL-2.1 (не проверено), его не поставляем, только загружаем, и делаем запись в реестр.
sqlx не берём: был бы второй стек драйверов, а поддержку
MS SQL из него убрали. DuckDB (MIT) — отдельный плагин
«связанные таблицы Parquet/CSV и аналитические запросы»; в базовую
установку его вместе с Polars не тянем.
Отчёты — свой банд-движок (§5.10
base.md). Референсы:
- FastReport Open Source (MIT, C#, ★3,1k, коммит
2026-09-11; проверено 2026-10-04) — движок полос, групп, итогов,
KeepTogether, повтора заголовка группы, CanGrow/CanShrink и
двухпроходной пагинации для «Страница N из M»; формат
.frxдаёт идеи дляreport_xml. Конкретные файлы движка не проверены. Порт алгоритмов без UI — 0,5–1 чел.-мес. экономии. - JasperReports (LGPL-3.0) и BIRT (EPL-2.0) — только документация (модели JRXML и ROM), без копирования (§4).
- Grist (Apache-2.0) — референс формульных столбцов: зависимости между столбцами и таблицами, trigger formulas (формула при вводе), summary tables. Нужен для вычисляемых полей и итоговых запросов Base, ≈0,3–0,5.
- dbeaver (Apache-2.0) — раскладка ER-схемы и конструктор запросов, референс для окна «Схема данных».
Экономия по Base против плана — 2–3 чел.-мес.:
SQLite, sqlparser-rs и драйверы уже заложены в base.md;
новое здесь — готовый SQLCipher, FastReport и Grist как референсы,
DuckDB-плагин. jetdb (§3.5) считается отдельно.
4. Класс 2 — решения владельца
В колонке «Вариант A» — взять компонент по правилам его лицензии. В колонке «Вариант B» — замена классов 0–1 или своя работа.
| Компонент | Лицензия | Зачем | Вариант A (по правилам лицензии) | Вариант B (класс 0–1 / своё) | Рекомендация |
|---|---|---|---|---|---|
| onenote_parser (onenote.rs) | MPL-2.0 | импорт .one/.onepkg в Notes (фаза 5, P1,
R*) |
крейт без правок, в процессе codec-host; в «О
программе» — ссылка на исходники; правки — только апстримом. 0,5–1
чел.-мес. |
своя реализация по [MS-ONESTORE]/[MS-ONE] + pyOneNote (Apache). 4–6 чел.-мес. | A — экономия 4–5 |
| libvisio (+ librevenge) | MPL-2.0 (librevenge — MPL/LGPL) | .vsd R* в Draw |
C++-библиотека в codec-host без правок; тянет
boost |
POI HDGF + «чистая комната» по [MS-VSDX]. 3–4 чел.-мес. | B: объём умеренный, C++-стек нежелателен |
| libmspub | MPL-2.0 | .pub R* в Write/Draw |
как libvisio | POI HPBF (только текст, 0,2) сейчас; полный импорт своими силами (3–4) в фазе 7 | B (текст), полный импорт — решить в фазе 7 |
| libetonyek | MPL-2.0 | Pages, Numbers, Keynote | как libvisio | numbers-parser + iWorkFileFormat + litchi (§3.7). 5–6 чел.-мес. | B; iWork '09 не поддерживаем |
| libpff | LGPL-3.0 | PST/OST | динамическая линковка | outlook-pst (MIT) | B — решение не нужно |
| epub-builder | MPL-2.0 | запись EPUB | крейт без правок | свой EPUB 3 R/W на zip + quick-xml (0,7) | B |
| cssparser, selectors, lightningcss | MPL-2.0 (не проверено) | CSS при импорте HTML | — | simplecss (MIT/Apache, не проверено) + свой каскад |
B |
good_lp, фича по умолчанию coin_cbc |
EPL-2.0 (CBC) | Solver | — | default-features = false + HiGHS; запрет
coin_cbc в deny.toml |
B |
| JasperReports; BIRT; Pentaho | LGPL-3.0; EPL-2.0; LGPL-2.1 | движок отчётов Base | отдельный JVM-процесс — неприемлемо для десктопа | свой движок + FastReport (MIT) как референс | B |
| ixion, orcus | MPL-2.0 | формулы и фильтры | — | IronCalc, свои кодеки | не нужны |
| unixODBC (или iODBC) | LGPL-2.1 (не проверено) | ODBC на Linux и macOS | системная библиотека, загружаем динамически, не поставляем | — | A: запись в реестр, юридический риск минимален |
| XstReader | MS-PL | PST | — | outlook-pst | не нужен. Предложение: внести MS-PL в класс 2 политики |
libwpd (для .wpd) |
MPL-2.0/LGPL (не проверено) | чтение WordPerfect в Write (P1) | как libvisio | своя реализация (≈3 чел.-мес.) | отложить: спрос низкий |
5. Запрещено (класс 3) и замены
| Проект | Лицензия | Где возникал соблазн | Замена |
|---|---|---|---|
mdbtools (+ обёртка mdbsql) |
GPL-2.0 | .mdb/.accdb; упомянут как референс в
base.md §6.2 и §9 и в 04-file-formats.md
§4.10 |
jetdb + jackcess (§3.5) |
epub (epub-rs) |
GPL-3.0 (проверено 2026-10-04) | чтение EPUB | свой EPUB R/W |
| HyperFormula | GPL-3.0 / коммерч. | движок формул | IronCalc (+ formualizer) |
| LibreOffice core, Gnumeric, Calligra, AbiWord | GPL/LGPL (в tsv — класс 3) | эталоны функций и фильтров doc/xls/ppt/rtf/vsd/pub | поведение изучаем только как пользователи (ферма эталонных рендеров из §1.3 roadmap); код класса 1 — Apache OpenOffice |
| ONLYOFFICE (x2t, sdkjs) | AGPL-3.0 | конвертеры форматов | POI, AOO, свои кодеки |
| EPPlus | PolyForm-Noncommercial | xlsx | rust_xlsxwriter, umya-spreadsheet, ClosedXML |
| NocoDB | собственная с 2026-01-29 | «таблицы-БД» | Baserow (MIT), Grist (Apache) |
| keynote-parser | лицензии нет = все права защищены | Keynote | numbers-parser, iWorkFileFormat, litchi |
| antiword, catdoc, wvWare | GPL (не проверено) | извлечение текста из doc | POI HWPF |
| pandoc | GPL-2.0+ (не проверено) | конвертеры md/rtf/epub/docx | comrak, свои кодеки |
R forecast |
GPL (не проверено) | алгоритм ETS | statsmodels (BSD-3) |
| LibreOffice или unoconv как встроенный конвертер | MPL/LGPL/GPL | «быстрый» импорт редких форматов | не встраиваем; каждый формат — своим кодеком или в R* |
Описания функций в Univer
locale/function-list/*/ru-RU.ts |
формально Apache-2.0, но тексты похожи на справку Microsoft | «Мастер функций» | пишем свои описания (§3.2) |
6. Что переносим кодом
Правило для всех строк: в заголовок каждого перенесённого файла —
«основано на <проект> (NOTICE и в окно «О программе → Лицензии» — точный текст
копирайта из LICENSE/NOTICE источника. Если у
источника двойная лицензия «MIT OR Apache-2.0», выбираем MIT: у неё нет
требования по NOTICE.
| Источник (файл / модуль) | Куда в MOffice | Лицензия | Атрибуция, NOTICE | Способ |
|---|---|---|---|---|
IronCalc base/src/expressions/{lexer,parser}/**,
parser/static_analysis.rs |
kernel/crates/meridian-calc/src/{parse,analysis}/ |
MIT | «IronCalc, © Nicolás Hatcher и авторы» | fork |
IronCalc base/src/functions/**, cast.rs,
arithmetic.rs, calc_result.rs,
implicit_intersection.rs, units.rs |
meridian-calc/src/functions/<категория>.rs |
MIT | то же | fork + переход на EvalContext |
IronCalc model.rs (spill_dynamic_array,
retire_own_spill_cells),
functions/spill_functions.rs |
meridian-calc/src/spill.rs |
MIT | то же | fork частей |
IronCalc generate_language/src/languages.json,
generate_locale/locales.json |
meridian-calc/locale/*.toml (+
ru.toml) |
MIT | то же | преобразование данных |
IronCalc base/src/test/**,
xlsx/tests/calc_tests/**/*.xlsx |
meridian-calc/tests/, корпус |
MIT | вне продукта | копия |
IronCalc
xlsx/src/import/{styles,conditional_formatting,metadata,tables}.rs,
export/{styles,conditional_formatting}.rs |
codecs/codec-ooxml/src/sml/ |
MIT | то же | fork частей |
formualizer
crates/formualizer-eval/src/engine/{interval_tree,csr_edges,delta_edges,lookup_index_cache,scheduler}.rs,
topo/ |
meridian-calc/src/graph/ |
MIT | «Formualizer, © авторы» | port / ref (Rust → Rust) |
formualizer src/builtins/math/aggregate.rs,
src/builtins/lookup/dynamic.rs |
meridian-calc/src/functions/ |
MIT | то же | port |
Univer
packages/engine-formula/src/functions/{web/filterxml,lookup/image,text/bahttext,text/dbcs}/index.ts |
meridian-calc/src/functions/ |
Apache-2.0 | «Univer, © 2023-present DreamNum Co., Ltd.» + Apache-2.0 | port TS → Rust |
Univer **/__tests__/index.spec.ts; formulajs
test/*.js |
meridian-calc/tests/oracle/ |
Apache-2.0; MIT | вне продукта | конвертер |
SheetJS SSF bits/*.js; test/* |
kernel/crates/meridian-numfmt/src/; корпус |
Apache-2.0 | «SheetJS SSF, © SheetJS LLC» | port |
| statsmodels, модуль Holt–Winters (путь не проверен) | meridian-calc/src/functions/statistical/ets.rs |
BSD-3-Clause | «© statsmodels developers» | port алгоритма |
Apache POI
poi/…/{hssf/record,ss/formula/ptg,ddf,hpsf}/**,
poi-scratchpad/…/{hwpf/model,hwpf/sprm,hslf/record,hslf/model/textproperties,hdgf,hpbf}/**,
poi-ooxml/…/xdgf/** |
codecs/codec-msbinary/{xls,ptg,officeart,props,doc,ppt},
codec-vector/vsd, codec-ooxml/vsdx,
codec-publisher |
Apache-2.0 | NOTICE Apache POI («This product includes software developed by The Apache Software Foundation») + Apache-2.0 | port |
calamine src/vba.rs |
meridian-script/src/vba/extract.rs |
MIT | «calamine, © Johann Tuffe» | fork |
msoffcrypto-tool
method/{rc4,rc4_cryptoapi,xor_obfuscation}.py,
format/{doc97,xls97,ppt97}.py |
codecs/codec-core/src/offcrypto/ |
MIT | «msoffcrypto-tool, © nolze» | port |
| jetdb (весь крейт) | codecs/codec-access/ |
MIT | «jetdb, © авторы» | fork |
jackcess impl/complex/**, impl/query/**;
список impl/expr/Default*Functions.java |
codec-access/src/{complex,query},
meridian-calc/src/compat/access.rs |
Apache-2.0 | NOTICE.txt jackcess + Apache-2.0 |
port; список функций — как спецификация |
numbers-parser, .proto-схемы (путь не проверен) |
codecs/codec-iwork/protos/ |
MIT (+ юридическое заключение) | «numbers-parser, © авторы» | port данных |
| FastReport, движок полос (путь не проверен) | meridian-base/src/report/engine.rs |
MIT | «FastReport, © Fast Reports Inc.» | port алгоритма |
| office-crypto, ms-offcrypto-writer, outlook-pst, cfb, calamine, rusqlite + SQLCipher, sqlparser, Polars, arrow/parquet, csv, encoding_rs, chardetng, HiGHS/highs, good_lp, Clarabel, argmin, statrs, nalgebra, rust_decimal, jiff | зависимости Cargo.toml |
см. §2 | SBOM (CycloneDX) → «О программе» автоматически | adopt |
7. Предложения в библию и план
component-map.md.- «Sheets / недостающие функции» переписать: formualizer (3) и Univer (4) — port; Univer и formulajs — тест-оракулы (§3.2).
- «Sheets / движок»: добавить formualizer как референс графа и спайк «IronCalc против formualizer» в I05.
- «CFB и шифрование»:
cfb+office-crypto+ms-offcrypto-writer(adopt) + порт msoffcrypto-tool для бинарных форматов. - Access → «jetdb fork + jackcess port частей». PST → «outlook-pst (Microsoft, MIT) adopt» вместо «своего по [MS-PST]».
- Новые строки: iWork (numbers-parser, iWorkFileFormat — ref), Visio
(POI XDGF/HDGF — port), Publisher (POI HPBF — port), отчёты Base
(FastReport — ref), EPUB (свой;
epub— GPL,epub-builder— MPL).
base.md.- §6.2 вместо «референсы: mdbtools, Jackcess…» — «fork jetdb + jackcess; mdbtools (GPL) не используется».
- §9 вместо «сверка с mdbtools/Jackcess» — «сверка jetdb ↔︎ jackcess».
- Ответ на §10.4: единая SQLCipher-сборка SQLite на весь пакет, провайдер — OpenSSL 3 или CommonCrypto (§3.8).
04-file-formats.md.- §4.10: убрать «по подходу MDB Tools».
- §4.4: VSD — «POI HDGF + [MS-VSDX], libvisio — класс 2».
- §5.1: добавить
outlook-pst,jetdb,office-crypto,ms-offcrypto-writer; дляcalamine— «adopt для R-сценариев + forkvba.rs». - §1.3, корпус, добавить: 211 xlsx и 2 768 тестов IronCalc, ≈2,4 млн эталонов SSF, 86 баз jackcess, тестовые файлы msoffcrypto-tool, ≈8,6 тыс. проверок Univer и formulajs.
sheets.md.- §4.6: старт — интерпретатор AST (
Arc<Node>, общие формулы) из IronCalc, байткод — после бенчмарков. - §5.10:
meridian-numfmt— порт SSF, эталоны SSF прогоняются в CI. - §5.16: симплекс, ветви и границы и отчёты устойчивости — HiGHS через
highs/good_lpбезcoin_cbc; GRG — argmin (L-BFGS) + свой слой активных ограничений; QP — Clarabel. - §5.21:
csv+encoding_rs+chardetngвместо своей статистики байтов; Polars — для «большого режима» и потоков данных. - §5.23: у каждой функции указать источник (IronCalc / formualizer / Univer / своё); 19 своих функций — по списку §3.1.
- Мастер функций: описания пишем сами.
- §4.6: старт — интерпретатор AST (
08-roadmap.md, E2.2.- I05: fork IronCalc + адаптер, ≈490 функций (вместо «150 функций»); I06: граф, пересчёт, 500+ функций.
- Высвобожденные 1–2 Rust FTE — на сводные таблицы и Chart; в I05 — двухнедельный спайк IronCalc против formualizer.
- E1.4: порт HWPF в I03–I05.
- E5.6: PST и accdb через outlook-pst и jetdb — эпик дешевле на 7–9 чел.-мес.; есть смысл поднять pst и accdb из P1 в P0 фазы 5.
12-license-policy.md.- MS-PL — в класс 2.
- При двойной лицензии (например, Apache-2.0/LGPL у java-libpst) выбираем разрешительную.
- Новый особый случай: тексты справки Microsoft внутри чужих проектов
(описания функций Univer) не берём; машинно извлечённые схемы
(
.protoiWork) — только после юридического заключения.
deny.toml(фаза 0).- Запретить
epub(GPL),coin_cbc/coin-cbc-sys(EPL),cssparser/selectors/lightningcss(MPL). onenote_parser— добавить вexceptionsпосле решения владельца.
- Запретить
03-architecture.md.- «Один SQLite на процесс — сборка SQLCipher».
codec-host— место для изолированных компонентов класса 2, если владелец их одобрит.
8. Непроверенное
Ниже — то, что в этой сессии не проверено. Остальные факты либо есть
в oss-verified.tsv, либо проверены 2026-10-04: по клонам,
через API crates.io и GitHub или по тексту LICENSE.
| Утверждение | Что сделать |
|---|---|
Возможности outlook-pst: OST, запись, потоковое чтение
файлов на 50 ГБ, экспорт типов MAPI-свойств для общего с MSG слоя |
спайк в I17 на корпусе PST |
Происхождение кода jetdb (автор ссылается на HACKING.md
mdbtools) и поддержка кодовых страниц Jet3 (cp1251) |
короткий юридический и технический аудит перед fork |
| formualizer: число активных авторов, устойчивость API 0.10, совпадение функций с Excel | спайк I05 (§3.1) |
| Качество импорта xlsx у IronCalc на реальном корпусе (3 000 файлов) | прогон corpus-tool в I05 |
Происхождение русских описаний функций Univer (сверено по стилю ABS
и ACOS и по ссылкам на support.microsoft.com) |
сравнение со справкой; до проверки — не брать |
Наличие NOTICE у Univer; лицензия npm-пакета
bessel (зависимость formulajs) |
проверить перед портом |
Пути исходников: FastReport (FastReport.Base/Engine),
statsmodels (tsa/holtwinters), numbers-parser
(protos), RTF-фильтры Apache OpenOffice |
при старте соответствующих задач |
Лицензии cssparser, selectors,
lightningcss (MPL-2.0 по памяти), simplecss
(MIT/Apache), unixODBC (LGPL-2.1), libwpd |
scripts/oss_verify.py |
GPL у antiword, catdoc, wvWare, pandoc, R forecast |
scripts/oss_verify.py (влияет только на список
«запрещено») |
Поддержка .numbers в SheetJS CE; актуальный апстрим SSF
в монорепо SheetJS |
проверить git.sheetjs.com |
Несовместимость фич bundled и
bundled-sqlcipher у rusqlite в одном бинарнике |
проверка сборкой в фазе 0 |
Правовой статус машинно извлечённых .proto-схем iWork и
интероперабельность по директиве ЕС 2009/24/EC |
юридическое заключение в фазе 0 |
| Полнота pyOneNote и litchi как референсов | при старте codec-onenote и
codec-iwork |
Лицензия jackcessencrypt (по README jetdb — Apache-2.0); репозитория
jahlborn/jackcess-encrypt на GitHub нет |
не нужен, если шифрование закрывает jetdb |
Дополнительных веб-запросов в этой сессии — около 45: API crates.io и
GitHub, 4 README, LICENSE SQLCipher и 4 клона: POI (частичный),
calamine, msoffcrypto-tool, formualizer. Это чуть выше лимита BRIEF
(~40); последние запросы ушли на лицензионно значимые вопросы
(good_lp, SQLCipher).