diff --git a/.gitignore b/.gitignore index 582c65b..0e3bead 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,18 @@ node_modules/ -report.docx -presentation.pptx -DocxGenerator.exe *.log *.pdf .plantuml-cache/ tools/plantuml.jar + +# Сгенерированные документы и презентации +report.docx +presentation.pptx + +# Пользовательские проекты в content/; в репозитории хранится только пример +content/* +!content/example/ +!content/example/** + +# Сгенерированные файлы примера тоже не коммитим +content/example/*.docx +content/example/*.pptx diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..dba63bd --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,111 @@ +# AGENTS.md — управление проектом SSAU Generator + +Репозиторий содержит два независимых генератора отчётных документов из Markdown. +Этот файл описывает управление проектом в целом. Правила работы с конкретным +документом — в [`docx/AGENTS.md`](docx/AGENTS.md) и [`pptx/AGENTS.md`](pptx/AGENTS.md). + +## Что использовать по запросу пользователя + +- Просит **сгенерировать документ** (отчёт, DOCX, пояснительную записку, + лабораторную работу) — используйте генератор в папке `docx/`. +- Просит **сгенерировать презентацию** (PPTX, слайды) — используйте генератор в + папке `pptx/`. + +Команды запускаются из корня репозитория; генератору указывается `config.yaml` +нужного проекта. Содержимое документа задаётся Markdown-файлами и `config.yaml` +проекта, а не кодом генератора. + +## Правила работы над проектом + +- **Уточните название проекта.** Если пользователь не указал, над каким проектом + ведётся работа, сначала спросите его. Проект — это папка `content/<проект>/`. +- **Один проект за сессию.** В рамках одной сессии работайте только над одним + проектом. +- **Создание — только через `--init`.** Новый проект создавайте командами с флагом + `--init` (см. ниже): они формируют правильную структуру и общий каталог + ресурсов. +- **Имя результата = имя проекта.** Документ и презентация собираются в папку + проекта, а имя файла совпадает с именем проекта: + `content/<проект>/<проект>.docx` и `content/<проект>/<проект>.pptx`. + Соответствующий путь задаётся ключом `output` в `config.yaml`. +- **Пересобирайте после правок.** При любом изменении исходных файлов + (`config.yaml`, `*.md`, ресурсов в `assets/`) заново запускайте сборку docx + и/или pptx, чтобы результат соответствовал исходникам. + +## Структура репозитория + +``` +ssau-generator/ +├── docx/ # генератор DOCX (только код) +├── pptx/ # генератор PPTX (только код) +├── tools/ # общий plantuml.jar (не в git) +├── content/ # проекты (в git хранится только example) +│ └── example/ +│ ├── assets/ # общие ресурсы проекта (для docx и pptx) +│ ├── docx/ # config.yaml + *.md +│ └── pptx/ # config.yaml + slides/ +├── AGENTS.md # этот файл +└── README.md +``` + +## Проекты и каталог content + +- **Один проект = одна папка** `content/<проект>/`. +- Внутри проекта при необходимости лежат папки `docx/` и `pptx/`. +- **Общие ресурсы проекта** (титульный лист, задники, изображения, исходники + `.puml`) размещаются в `content/<проект>/assets/` и используются обоими + генераторами. В `docx/` и `pptx/` внутри проекта хранятся только `config.yaml` + и Markdown. +- Папки `content/*` добавлены в `.gitignore`; в репозитории хранится только + `content/example/`. Рабочие проекты пользователя коммитить не нужно. + +## Создание нового проекта + +Проект создаётся командами с флагом `--init` — они формируют структуру и общие +ресурсы автоматически: + +```powershell +# только документ DOCX +node docx/src/cli.js --content content/<проект>/docx --init + +# только презентация PPTX +node pptx/src/cli.js -c content/<проект>/pptx/config.yaml --init + +# оба генератора (каталог content/<проект>/assets/ создаётся первым вызовом +# и переиспользуется вторым) +``` + +После создания отредактируйте `config.yaml` и Markdown; общие ресурсы +(титульный лист, задники, изображения, `.puml`) положите в +`content/<проект>/assets/`. + +## Сборка + +```powershell +# Документ DOCX +node docx/src/cli.js --content content/<проект>/docx --check +node docx/src/cli.js --content content/<проект>/docx + +# Презентация PPTX +node pptx/src/cli.js -c content/<проект>/pptx/config.yaml --check +node pptx/src/cli.js -c content/<проект>/pptx/config.yaml +``` + +Результат: `content/<проект>/<проект>.docx` или +`content/<проект>/<проект>.pptx` (имя и путь задаются ключом `output` в +`config.yaml`). После правок исходников пересобирайте файлы. + +## Требования + +- Node.js 18+, зависимости устанавливаются командой `npm install` в `docx/` и + `pptx/`. +- Java 11+ и файл `tools/plantuml.jar` (не хранится в git) — для рендеринга схем + PlantUML (`.puml`). + +## Правила + +- Для сборки документа не редактируйте код генераторов — меняйте `config.yaml` + и Markdown проекта. +- Не коммитьте содержимое `content/`, кроме `content/example/`. +- Не храните ресурсы внутри `docx/` и `pptx/` — общие файлы живут в + `content/<проект>/assets/`. diff --git a/README.md b/README.md index a056c3c..740b380 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,125 @@ -# lab_gen — генераторы отчётных документов +# 📄 SSAU Generator -Монорепозиторий из двух независимых Node.js-генераторов, которые собирают -отчётные документы из обычного Markdown по заданному шаблону/стандарту. +> **SSAU Generator** — это два независимых генератора отчётных документов из обычного **Markdown**: **DOCX**-отчёт по СТО 02068410-004-2018 и **PPTX**-презентация по шаблону Самарского университета. +> +> Главное — это **модульность** и **воспроизводимая сборка**: содержимое задаётся Markdown и `config.yaml`, а не правками кода. + +--- + +## 📦 Состав + +- **`docx/`** — генератор документов **DOCX** по дизайну СТО 02068410-004-2018 + - Титульный лист, оглавление, таблицы, рисунки (включая PlantUML), формулы, список источников и приложения +- **`pptx/`** — генератор презентаций **PPTX** по фирменному шаблону Самарского университета + - 16:9, синий фон, задники, логотип и фирменный шрифт заданы в `config.yaml` +- **`tools/plantuml.jar`** — общий рендерер схем PlantUML (не хранится в git) +- **`content/`** — проекты пользователя: `content/<проект>/{docx,pptx}` и общие ресурсы `content/<проект>/assets/` + +--- + +## 🚀 Возможности + +### 📄 Документ DOCX + +- Сборка из **обычного Markdown** по фиксированному дизайну СТО 02068410-004-2018 +- Готовый **титульный лист** (отдельный `.docx`) и **оглавление** (поле Word) +- Автоматическая **нумерация** разделов, рисунков, таблиц, формул и приложений +- **Таблицы** — обычные и с подписью и автономером +- **Рисунки** — готовые PNG и схемы **PlantUML**, рендеримые автоматически +- **Формулы** с пояснениями и нумерацией +- **Ссылки на источники** и перекрёстные ссылки на номера объектов +- Примечания, определения, приложения с буквенной нумерацией + +### 📽️ Презентация PPTX + +- Сборка из **Markdown**, по одному файлу на слайд +- Четыре типа слайдов: **титульный, разделитель, контент, финальный** — каждый со своим фоном +- **Богатая inline-разметка**: полужирный, курсив, акцент, моноширинный +- **Таблицы, изображения и PlantUML**, схемы-цепочки, карточки-метрики, плашки-выводы +- **Диаграммы** (bar, line, pie, doughnut, area, radar, scatter) из GFM-таблиц +- **Заметки докладчика** как сценарий выступления +- Двухколоночная вёрстка через параметр `side=left|right` + +--- + +## 📂 Структура ``` -lab_gen/ -├── docx/ # генератор DOCX по СТО 02068410-004-2018 (отчёт) -├── pptx/ # генератор PPTX по шаблону Самарского университета (презентация) -└── tools/ # общие внешние инструменты (plantuml.jar) +ssau-generator/ +├── docx/ # генератор DOCX (только код) +├── pptx/ # генератор PPTX (только код) +├── tools/ # общий plantuml.jar (не в git) +├── content/ # проекты (в git хранится только example) +│ └── example/ +│ ├── assets/ # общие ресурсы проекта (для docx и pptx) +│ ├── docx/ # config.yaml + *.md +│ └── pptx/ # config.yaml + slides/ +├── AGENTS.md # инструкции по управлению проектом +└── README.md ``` -## docx/ — DocxGenerator +> Каждый проект — отдельная папка `content/<проект>/`. Готовый пример со всеми возможностями — [`content/example/`](content/example/). -Автономный генератор отчётов **DOCX** из Markdown по дизайну -СТО 02068410-004-2018. Поддерживает титульный лист, оглавление, таблицы, рисунки -(включая PlantUML), формулы, список источников и приложения. +--- + +## 🛠 Требования + +- **Node.js 18+** и зависимости, устанавливаемые командой `npm install` в `docx/` и `pptx/` +- **Java 11+** и файл `tools/plantuml.jar` — для рендеринга схем PlantUML (`.puml`) + +--- + +## 📝 Быстрый старт ```powershell -cd docx -npm install -npm run check # проверка конфига и ссылок -npm run generate # собрать report.docx +npm install --prefix docx +npm install --prefix pptx + +# Документ DOCX +node docx/src/cli.js --content content/example/docx + +# Презентация PPTX +node pptx/src/cli.js -c content/example/pptx/config.yaml ``` -Полная документация — [docx/AGENTS.md](docx/AGENTS.md). +Готовый пример со всеми возможностями — [`content/example/`](content/example/). -## pptx/ — lab-gen-pptx +--- -Генератор презентаций **PPTX** из Markdown по фирменному шаблону Самарского -университета (16:9, синий фон, логотип, фирменный шрифт). Задники и правила -оформления извлечены из `presentation_16.pptx` и заданы в `config.yaml`. +## 🎯 Использование + +### Новый проект + +Проект создаётся командами с флагом `--init` — они формируют структуру и общий каталог ресурсов `content/<проект>/assets/`: ```powershell -cd pptx -npm install -npm run check # проверка конфига и ссылок -npm run generate # собрать presentation.pptx +# только документ DOCX +node docx/src/cli.js --content content/<проект>/docx --init + +# только презентация PPTX +node pptx/src/cli.js -c content/<проект>/pptx/config.yaml --init ``` -Формат слайдов, схема конфига и CLI описаны в [pptx/AGENTS.md](pptx/AGENTS.md). +### Сборка -## Требования +```powershell +# Документ DOCX +node docx/src/cli.js --content content/<проект>/docx --check +node docx/src/cli.js --content content/<проект>/docx -- Node.js 18+ (для локальной сборки). -- Java 11+ и `tools/plantuml.jar` — для рендеринга схем PlantUML (`.puml`) - в обоих генераторах. Путь задаётся ключом `plantuml.jar` в `config.yaml`. +# Презентация PPTX +node pptx/src/cli.js -c content/<проект>/pptx/config.yaml --check +node pptx/src/cli.js -c content/<проект>/pptx/config.yaml +``` + +Результат собирается в папку проекта и называется по имени проекта: `content/<проект>/<проект>.docx` и `content/<проект>/<проект>.pptx`. + +--- + +## 📚 Документация + +- Управление проектом: [AGENTS.md](AGENTS.md) +- Формат DOCX-документа: [docx/AGENTS.md](docx/AGENTS.md) +- Формат PPTX-презентации: [pptx/AGENTS.md](pptx/AGENTS.md) + +> 💡 **Важно:** Документ и презентация используют общий каталог ресурсов `content/<проект>/assets/`, поэтому титульный лист, задники и изображения переиспользуются обоими генераторами. diff --git a/pptx/content/assets/content-bg.jpg b/content/example/assets/content-bg.jpg similarity index 100% rename from pptx/content/assets/content-bg.jpg rename to content/example/assets/content-bg.jpg diff --git a/pptx/content/assets/final-bg.jpeg b/content/example/assets/final-bg.jpeg similarity index 100% rename from pptx/content/assets/final-bg.jpeg rename to content/example/assets/final-bg.jpeg diff --git a/content/example/assets/images/chart.png b/content/example/assets/images/chart.png new file mode 100644 index 0000000..b4089f8 Binary files /dev/null and b/content/example/assets/images/chart.png differ diff --git a/content/example/assets/images/diagram.png b/content/example/assets/images/diagram.png new file mode 100644 index 0000000..fe00700 Binary files /dev/null and b/content/example/assets/images/diagram.png differ diff --git a/content/example/assets/images/flow.puml b/content/example/assets/images/flow.puml new file mode 100644 index 0000000..e5f2c5a --- /dev/null +++ b/content/example/assets/images/flow.puml @@ -0,0 +1,18 @@ +@startuml +skinparam backgroundColor #FFFFFF +skinparam defaultFontName "Times New Roman" +skinparam shadowing false + +title Пример схемы PlantUML + +start +:Исходный Markdown; +:Разбор директив; +if (Есть схема .puml?) then (да) + :Рендеринг через plantuml.jar; +else (нет) + :Вставка готового PNG; +endif +:Сборка документа; +stop +@enduml diff --git a/content/example/assets/images/scheme.png b/content/example/assets/images/scheme.png new file mode 100644 index 0000000..ab6a3a7 Binary files /dev/null and b/content/example/assets/images/scheme.png differ diff --git a/pptx/content/assets/title-bg.jpeg b/content/example/assets/title-bg.jpeg similarity index 100% rename from pptx/content/assets/title-bg.jpeg rename to content/example/assets/title-bg.jpeg diff --git a/content/example/assets/title-page.docx b/content/example/assets/title-page.docx new file mode 100644 index 0000000..d37a675 Binary files /dev/null and b/content/example/assets/title-page.docx differ diff --git a/content/example/docx/01-introduction.md b/content/example/docx/01-introduction.md new file mode 100644 index 0000000..c3a2f47 --- /dev/null +++ b/content/example/docx/01-introduction.md @@ -0,0 +1,24 @@ +Настоящий документ — демонстрационный пример, который перечисляет все возможности +генератора DOCX. Исходный текст набирается в обычных Markdown-файлах, а оформление +полностью задаётся файлом `config.yaml` в соответствии с требованиями +СТО 02068410-004-2018 [@1]. + +Документ собирается из отдельных частей, перечисленных в разделе `sections`: + +- структурные разделы без номера (введение, заключение); +- нумеруемые разделы с автоматической нумерацией заголовков; +- список использованных источников; +- приложения с буквенной нумерацией объектов. + +Основные группы возможностей: + +- форматирование текста и заголовков; +- списки, в том числе многоуровневые; +- таблицы — обычные и с подписью; +- рисунки — готовые изображения и схемы PlantUML; +- формулы с пояснениями; +- примечания, определения и перекрёстные ссылки. + +Подробное описание каждого элемента приведено в разделе 1, примеры таблиц — в +разделе 2, сводные материалы — в приложении А. Оформление ссылок на источники +приведено в соответствии с действующими стандартами [@2], [@3]. diff --git a/content/example/docx/02-features.md b/content/example/docx/02-features.md new file mode 100644 index 0000000..0e5e013 --- /dev/null +++ b/content/example/docx/02-features.md @@ -0,0 +1,104 @@ +# ВОЗМОЖНОСТИ ГЕНЕРАТОРА + +Раздел перечисляет все поддерживаемые элементы и показывает соответствующий +синтаксис Markdown. Нумерация заголовков, рисунков, таблиц и формул выполняется +автоматически. + +## Заголовки и абзацы + +Заголовок раздела задаётся одним символом `#`, подраздел — двумя `##`, пункт — +тремя `###`. Обычные абзацы разделяются пустой строкой. + +### Третий уровень + +Полужирный и курсив в оформлении по стандарту отключены, поэтому `**жирный**` и +`*курсив*` выводятся как обычный текст. + +## Списки + +- первый элемент списка; +- второй элемент с вложенными пунктами: + 1. вложенный элемент, выводимый как «а)»; + 2. ещё один вложенный элемент. + +## Таблицы + +Обычная таблица (без подписи и номера): + +| Столбец A | Столбец B | Столбец C | +|---|---|---| +| 1 | 2 | 3 | +| 4 | 5 | 6 | + +Таблица с подписью и автоматическим номером (ссылка — @tbl:features): + +::: table "Возможности оформления" id=features note="Состав приведён условно" +| Элемент | Синтаксис | Результат | +|---|---|---| +| Таблица | `::: table` | Таблица с подписью | +| Рисунок | `::: figure` | Рисунок с подписью | +| Формула | `::: formula` | Нумерованная формула | +| Примечание | `::: note` | Примечание | +| Определения | `::: definitions` | Список терминов | +::: + +## Рисунки + +Готовое изображение вставляется директивой `figure`; файл ищется относительно +каталога `paths.assets`. Пример — рисунок @fig:diagram: + +::: figure "Готовое изображение" id=diagram file=images/diagram.png +а) функциональные блоки; +б) направления связей. +::: + +Схема PlantUML рендерится автоматически из исходного файла `.puml` — рисунок +@fig:flow: + +::: figure "Схема PlantUML" id=flow file=images/flow.puml +::: + +## Формулы + +Формула с автоматическим номером и списком пояснений: + +::: formula id=efficiency +K = (T_base - T_new)/T_base +::: + +::: where +K — коэффициент снижения затрат; +T_base — исходное значение показателя; +T_new — достигнутое значение показателя. +::: + +Ссылка на формулу: @eq:efficiency. + +## Примечания и определения + +::: note +Одиночное примечание к тексту. +::: + +::: notes +- первое примечание; +- второе примечание. +::: + +::: definitions +Термин — краткое определение термина; +Второй термин — ещё одно определение. +::: + +## Перекрёстные ссылки + +Записи @fig:diagram, @tbl:features и @eq:efficiency подставляют актуальные номера +рисунка, таблицы и формулы. Ссылки на источники оформляются как [@1] или +[@2, с. 10]. + +## Разрыв страницы + +::: pagebreak +::: + +Тематический разрыв `---` также трактуется как разрыв страницы. diff --git a/content/example/docx/03-tables.md b/content/example/docx/03-tables.md new file mode 100644 index 0000000..d6e59b4 --- /dev/null +++ b/content/example/docx/03-tables.md @@ -0,0 +1,18 @@ +# ПРИМЕРЫ ТАБЛИЦ + +Раздел показывает таблицы разной размерности. Широкая таблица @tbl:wide +заполняется данными из Markdown-строк. + +::: table "Таблица с несколькими столбцами" id=wide +| № | Наименование | Тип | Значение | Единица | +|---|---|---|---|---| +| 1 | Первый параметр | Числовой | 125 | шт. | +| 2 | Второй параметр | Строковый | 18 | — | +| 3 | Третий параметр | Логический | да | — | +| 4 | Четвёртый параметр | Числовой | 420 | руб. | +::: + +После таблицы можно продолжать обычный текст и списки: + +- перечисление подтабличных пояснений; +- ещё один элемент списка. diff --git a/content/example/docx/04-conclusion.md b/content/example/docx/04-conclusion.md new file mode 100644 index 0000000..2e7840f --- /dev/null +++ b/content/example/docx/04-conclusion.md @@ -0,0 +1,14 @@ +Демонстрационный документ перечислил все поддерживаемые генератором элементы +оформления по СТО 02068410-004-2018 [@1]. + +Основные результаты: + +- показаны заголовки, абзацы и многоуровневые списки; +- приведены обычные и подписанные таблицы; +- вставлены готовое изображение и схема PlantUML; +- продемонстрированы формулы, примечания и определения; +- проверены ссылки на источники и перекрёстные ссылки на объекты. + +Полный набор параметров оформления задаётся в файле `config.yaml`, а состав +документа — списком `sections`. Единицы измерений приведены в соответствии с +действующим стандартом [@4]. diff --git a/content/example/docx/05-bibliography.md b/content/example/docx/05-bibliography.md new file mode 100644 index 0000000..5d47c0e --- /dev/null +++ b/content/example/docx/05-bibliography.md @@ -0,0 +1,4 @@ +- ГОСТ 7.32-2017. Система стандартов по информации, библиотечному и издательскому делу. Отчёт о научно-исследовательской работе. Структура и правила оформления. — М. : Стандартинформ, 2017. — 32 с. +- ГОСТ Р 7.0.5-2008. Библиографическая ссылка. Общие требования и правила составления. — М. : Стандартинформ, 2008. — 23 с. +- Иванов, И. И. Оформление отчётных документов : учебное пособие / И. И. Иванов. — Самара : Изд-во Самарского университета, 2019. — 184 с. +- ГОСТ 8.417-2002. Государственная система обеспечения единства измерений. Единицы величин. — М. : Стандартинформ, 2002. — 32 с. diff --git a/content/example/docx/06-appendix-a.md b/content/example/docx/06-appendix-a.md new file mode 100644 index 0000000..2aecee9 --- /dev/null +++ b/content/example/docx/06-appendix-a.md @@ -0,0 +1,17 @@ +Сводные данные приведены в таблице @tbl:app-a. Номер таблицы в приложении +получает префикс буквы приложения. + +::: table "Сводная таблица" id=app-a +| Показатель | Значение | Комментарий | +|---|---|---| +| Рисунков в приложении | 1 | См. @fig:app-a | +| Таблиц в приложении | 1 | Текущая таблица | +| Формул в приложении | 0 | — | +::: + +Схема приложения приведена на рисунке @fig:app-a: + +::: figure "Схема приложения" id=app-a file=images/scheme.png +а) элементы схемы; +б) связи между элементами. +::: diff --git a/content/example/docx/config.yaml b/content/example/docx/config.yaml new file mode 100644 index 0000000..9bcee9b --- /dev/null +++ b/content/example/docx/config.yaml @@ -0,0 +1,47 @@ +# Демонстрационный проект генератора DOCX. +# Показывает все возможности оформления отчёта по СТО 02068410-004-2018. +# Все относительные пути считаются от каталога этого файла. +# Общие ресурсы проекта лежат выше, в ../assets, и используются и для docx, и для pptx. + +document: + # Имя файла = имя проекта = имя папки проекта, в папке проекта. + output: ../example.docx + # Титульный лист — общий ресурс проекта. + titlePage: ../assets/title-page.docx + features: + updateFields: true + +paths: + # Каталог рисунков; file=images/x.png ищется здесь. + assets: ../assets + +plantuml: + enabled: true + java: auto + # plantuml.jar лежит в корне репозитория. + jar: ../../../tools/plantuml.jar + format: png + charset: UTF-8 + cache: true + cacheDir: .plantuml-cache + timeoutMs: 30000 + +# Структура документа: порядок частей и их типы. +sections: + - type: toc + - file: 01-introduction.md + type: structural + title: Введение + - file: 02-features.md + type: numbered + - file: 03-tables.md + type: numbered + - file: 04-conclusion.md + type: structural + title: Заключение + - file: 05-bibliography.md + type: bibliography + - file: 06-appendix-a.md + type: appendix + letter: А + title: Демонстрационные материалы diff --git a/content/example/pptx/config.yaml b/content/example/pptx/config.yaml new file mode 100644 index 0000000..816c413 --- /dev/null +++ b/content/example/pptx/config.yaml @@ -0,0 +1,51 @@ +# Демонстрационный проект генератора PPTX. +# Показывает все типы слайдов и все доступные блоки разметки. +# Все относительные пути считаются от каталога этого файла. +# Общие ресурсы проекта лежат выше, в ../assets, и используются и для docx, и для pptx. + +presentation: + # Имя файла = имя проекта = имя папки проекта, в папке проекта. + output: ../example.pptx + author: "Автор примера" + track: "Название трека" + +theme: + width: 13.333 + height: 7.5 + font: "Segoe UI" + backgrounds: + # Задники — общие ресурсы проекта. + title: ../assets/title-bg.jpeg + content: ../assets/content-bg.jpg + final: ../assets/final-bg.jpeg + +plantuml: + enabled: true + java: auto + # plantuml.jar лежит в корне репозитория. + jar: ../../../tools/plantuml.jar + format: png + charset: UTF-8 + cache: true + cacheDir: .plantuml-cache + timeoutMs: 30000 + +# Каталог контента — папка этого config.yaml. +content: + dir: . + +# Список слайдов: тип задаёт макет, file — Markdown-файл слайда. +slides: + - { type: title, file: slides/00-title.md } + - { type: content, file: slides/01-text.md } + - { type: content, file: slides/02-lists.md } + - { type: content, file: slides/03-table.md } + - { type: content, file: slides/04-image.md } + - { type: content, file: slides/05-puml.md } + - { type: content, file: slides/06-metrics.md } + - { type: content, file: slides/07-flow.md } + - { type: content, file: slides/08-chart.md } + - { type: content, file: slides/09-columns.md } + - { type: content, file: slides/10-notes.md } + - { type: section, file: slides/11-section.md } + - { type: final, file: slides/12-final.md } diff --git a/content/example/pptx/slides/00-title.md b/content/example/pptx/slides/00-title.md new file mode 100644 index 0000000..5e9c120 --- /dev/null +++ b/content/example/pptx/slides/00-title.md @@ -0,0 +1,3 @@ +# Генератор презентаций + +## Демонстрация возможностей diff --git a/content/example/pptx/slides/01-text.md b/content/example/pptx/slides/01-text.md new file mode 100644 index 0000000..d46f3c8 --- /dev/null +++ b/content/example/pptx/slides/01-text.md @@ -0,0 +1,5 @@ +# Форматирование текста + +Абзацы и inline-разметка: **полужирный**, *курсив*, ==акцент== и `код`. + +Строки автоматически переносятся и подгоняются под ширину слайда. diff --git a/content/example/pptx/slides/02-lists.md b/content/example/pptx/slides/02-lists.md new file mode 100644 index 0000000..659123c --- /dev/null +++ b/content/example/pptx/slides/02-lists.md @@ -0,0 +1,6 @@ +# Списки + +- пункт первого уровня; +- второй пункт с вложенными элементами: + - вложенный пункт; + - ещё один вложенный пункт. diff --git a/content/example/pptx/slides/03-table.md b/content/example/pptx/slides/03-table.md new file mode 100644 index 0000000..e29d983 --- /dev/null +++ b/content/example/pptx/slides/03-table.md @@ -0,0 +1,10 @@ +# Таблицы + +::: table +| Блок | Директива | Назначение | +|---|---|---| +| Таблица | ::: table | Данные в виде таблицы | +| Метрики | ::: metrics | Карточки с числами | +| Схема | ::: flow | Цепочка блоков | +| Диаграмма | ::: chart | График или диаграмма | +::: diff --git a/content/example/pptx/slides/04-image.md b/content/example/pptx/slides/04-image.md new file mode 100644 index 0000000..d5fcace --- /dev/null +++ b/content/example/pptx/slides/04-image.md @@ -0,0 +1,5 @@ +# Изображения + +::: image ../assets/images/diagram.png height=3.6 +Подпись под рисунком выводится курсивом. +::: diff --git a/content/example/pptx/slides/05-puml.md b/content/example/pptx/slides/05-puml.md new file mode 100644 index 0000000..98cd5ae --- /dev/null +++ b/content/example/pptx/slides/05-puml.md @@ -0,0 +1,5 @@ +# PlantUML + +::: image ../assets/images/flow.puml height=4.6 +Схема собрана автоматически из исходного файла .puml. +::: diff --git a/content/example/pptx/slides/06-metrics.md b/content/example/pptx/slides/06-metrics.md new file mode 100644 index 0000000..915bb2e --- /dev/null +++ b/content/example/pptx/slides/06-metrics.md @@ -0,0 +1,8 @@ +# Метрики + +::: metrics +4 | типа слайдов +8 | типов блоков +12 | директив разметки +100% | возможностей +::: diff --git a/content/example/pptx/slides/07-flow.md b/content/example/pptx/slides/07-flow.md new file mode 100644 index 0000000..5daa179 --- /dev/null +++ b/content/example/pptx/slides/07-flow.md @@ -0,0 +1,5 @@ +# Схема-цепочка + +::: flow +Markdown -> Разбор -> Рендеринг -> PPTX +::: diff --git a/content/example/pptx/slides/08-chart.md b/content/example/pptx/slides/08-chart.md new file mode 100644 index 0000000..6f68d48 --- /dev/null +++ b/content/example/pptx/slides/08-chart.md @@ -0,0 +1,9 @@ +# Диаграммы + +::: chart bar "Пример столбчатой диаграммы" +| Категория | Значение | +|---|---| +| Блок | 8 | +| Типы слайдов | 4 | +| Директивы | 12 | +::: diff --git a/content/example/pptx/slides/09-columns.md b/content/example/pptx/slides/09-columns.md new file mode 100644 index 0000000..17f5fed --- /dev/null +++ b/content/example/pptx/slides/09-columns.md @@ -0,0 +1,12 @@ +# Две колонки + +::: image ../assets/images/scheme.png side=left height=3.6 +Рисунок в левой колонке. +::: + +::: callout "Плашка-вывод" side=right +Внутри плашки работает ==выделение== и списки: + +- первый пункт; +- второй пункт. +::: diff --git a/content/example/pptx/slides/10-notes.md b/content/example/pptx/slides/10-notes.md new file mode 100644 index 0000000..61caaea --- /dev/null +++ b/content/example/pptx/slides/10-notes.md @@ -0,0 +1,7 @@ +# Заметки докладчика + +Текст слайда набирается как обычно, а сценарий выступления — в директиве notes. + +::: notes +Эти строки видны только в режиме заметок и не попадают на слайд. +::: diff --git a/content/example/pptx/slides/11-section.md b/content/example/pptx/slides/11-section.md new file mode 100644 index 0000000..f39a697 --- /dev/null +++ b/content/example/pptx/slides/11-section.md @@ -0,0 +1,3 @@ +# Раздел + +## Разделительный слайд diff --git a/content/example/pptx/slides/12-final.md b/content/example/pptx/slides/12-final.md new file mode 100644 index 0000000..bd3c628 --- /dev/null +++ b/content/example/pptx/slides/12-final.md @@ -0,0 +1,3 @@ +# Спасибо за внимание + +Демонстрация возможностей генератора завершена. diff --git a/docx/AGENTS.md b/docx/AGENTS.md index bd6fdac..102508c 100644 --- a/docx/AGENTS.md +++ b/docx/AGENTS.md @@ -1,145 +1,123 @@ -# AGENTS.md — генератор DocxGenerator +# AGENTS.md — работа с документом DOCX -`DocxGenerator` — автономный инструмент, который собирает отчёт в формате **DOCX** из обычных -**Markdown**-файлов по фиксированному дизайну СТО 02068410-004-2018. Поведение полностью -задаётся файлом `config.yaml`. - -Документ создан и для людей, и для ИИ-агентов: он описывает CLI, формат контента, схему -конфига и порядок сборки `.exe`. - ---- +Генератор `docx/` собирает отчёт в формате **DOCX** из обычных **Markdown**-файлов +по фиксированному дизайну СТО 02068410-004-2018. Этот файл — инструкция агенту по +созданию и правке конкретного документа. Поведение полностью задаётся `config.yaml` +проекта, менять код генератора не нужно. ## 1. Требования -- Windows (собранный `.exe` под `win-x64`). -- Node.js **только для сборки** `.exe` из исходников. Конечному пользователю Node.js не нужен. -- Готовые PNG вставляются без внешних зависимостей. Для рендеринга PlantUML (`.puml`) - нужны установленная Java (JRE 11+) и файл `plantuml.jar` (см. п. 4, `plantuml`). +- Node.js 18+, зависимости ставятся командой `npm install` в папке `docx/`. +- Windows/macOS/Linux. +- Готовые PNG вставляются без внешних зависимостей. Для рендеринга PlantUML + (`.puml`) нужны Java 11+ и файл `plantuml.jar` (см. `plantuml` в конфиге). -## 2. Состав дистрибутива +## 2. Раскладка проекта + +Проект лежит в `content/<проект>/docx/` рядом с `config.yaml`: ``` -DocxGenerator.exe # исполняемый файл -config.yaml # настройки (создаётся автоматически при первом запуске) -content/ # Markdown-файлы документа и ресурсы - *.md - assets/ - images/ # PNG для рисунков (готовятся заранее) и исходники .puml - title-page.docx # титульный лист (по умолчанию content/assets/title-page.docx) -tools/ - plantuml.jar # рендерер PlantUML (для файлов .puml) -report.docx # результат сборки (путь задаётся document.output) +content/<проект>/ +├── assets/ # общие ресурсы проекта (общие с pptx) +│ ├── title-page.docx # титульный лист +│ └── images/ # PNG-рисунки и исходники .puml +└── docx/ + ├── config.yaml # настройки документа + ├── 01-introduction.md + ├── 02-*.md + └── 05-bibliography.md ``` -Все относительные пути в `config.yaml` считаются **от каталога самого `config.yaml`**. -Сам `config.yaml` и папки ищутся **рядом с `DocxGenerator.exe`**. +Все относительные пути в `config.yaml` считаются **от каталога самого +`config.yaml`**. Если ресурсы общие с презентацией, указывайте их через `../assets` +(например, `paths.assets: ../assets`, `document.titlePage: ../assets/title-page.docx`). -В монорепозитории общий `plantuml.jar` лежит в корне, в `tools/plantuml.jar`, -поэтому репозиторный `config.yaml` задаёт `plantuml.jar: ../tools/plantuml.jar`. -Для автономного дистрибутива положите `tools/plantuml.jar` рядом с `.exe` -(значение по умолчанию при `--init` — `tools/plantuml.jar`). +Отчёт собирается в папку проекта и называется по имени проекта: +`content/<проект>/<проект>.docx`. Значение ключа `document.output` при такой +раскладке — `../<проект>.docx`. + +Структуру проекта создавайте командой `--init`: она формирует `config.yaml`, +примеры `*.md` и общий каталог `content/<проект>/assets/` (титульный лист, +изображения), который используется и генератором `pptx`. + +Готовый пример со всеми возможностями — `content/example/docx/`. ## 3. Командная строка -``` -DocxGenerator [опции] +Из корня репозитория: - --config <путь> путь к config.yaml (по умолчанию рядом с exe) - --content каталог с config.yaml, content/ и assets/ (по умолчанию рядом с exe) +``` +node docx/src/cli.js [опции] + + --config <путь> путь к config.yaml (по умолчанию config.yaml в текущем каталоге) + --content каталог проекта: config.yaml, *.md и assets/ (по умолчанию текущий) --output <путь> переопределить путь выходного .docx --check только проверить конфиг и ссылки, без записи файла - --init создать шаблон config.yaml/content/assets и выйти + --init создать шаблон config.yaml/*.md/assets и выйти --verbose подробный вывод --version показать версию --help справка ``` -Поведение: - -- Если `config.yaml` не найден, инструмент **сам создаёт** `config.yaml`, примеры `content/*.md` - и `assets/images/placeholder.png`, печатает подсказку и завершается. -- `--check` не пишет DOCX, но сообщает обо всех ошибках (битые ссылки, выход `[@n]` за границы - списка источников, отсутствующие картинки и т.п.). - -Типичный цикл работы: +Типичный цикл: ```powershell -.\DocxGenerator.exe --init # первый запуск: получить шаблон -# ... правим config.yaml и content/*.md ... -.\DocxGenerator.exe --check # проверить -.\DocxGenerator.exe # собрать report.docx +node docx/src/cli.js --content content/<проект>/docx --init # создать структуру проекта +node docx/src/cli.js --content content/<проект>/docx --check # проверить +node docx/src/cli.js --content content/<проект>/docx # собрать ``` +После любого изменения исходников (`config.yaml`, `*.md`, ресурсов `assets/`) +**пересоберите документ**, чтобы результат соответствовал исходникам. + +Если `config.yaml` не найден, инструмент сам создаёт шаблон (`config.yaml`, +примеры Markdown и общий `assets/`) и завершается. + ## 4. Схема `config.yaml` -Любой ключ можно опустить — берётся значение по умолчанию (см. `src/config/defaults.js`). +Любой ключ можно опустить — берётся значение по умолчанию (см. +`docx/src/config/defaults.js`). ### document | Ключ | Тип | Смысл | |------|-----|-------| -| `output` | string | путь выходного `.docx` | -| `titlePage` | string/null | путь к готовому `title-page.docx` (по умолчанию `content/assets/title-page.docx`); `null` — без титульника | +| `output` | string | путь выходного `.docx` (относительно `config.yaml`) | +| `titlePage` | string/null | путь к готовому `title-page.docx`; `null` — без титульника | | `features.updateFields` | bool | обновлять поля (в т.ч. оглавление) при открытии в Word | -**Титульный лист.** Берётся готовый DOCX по пути `document.titlePage` и склеивается перед -документом; между титульником и основным текстом вставляется разрыв страницы. При `--init` -создаётся пример `content/assets/title-page.docx` — замените его своим. Значение `null` -отключает титульный лист. +Титульный лист склеивается перед документом, между ним и текстом вставляется +разрыв страницы. При `--init` создаётся пример `assets/title-page.docx`. ### paths | Ключ | Смысл | |------|-------| -| `assets` | корень ресурсов; `file=images/x.png` в директивах ищется здесь (по умолчанию `content/assets`) | +| `assets` | корень ресурсов; `file=images/x.png` в директивах ищется здесь | -### output -Путь и имя выходного `.docx` задаются ключом `document.output` (по умолчанию -`report.docx`). Путь считается от каталога `config.yaml` и может быть переопределён -флагом `--output`. +### Структура и оформление -### page -`width`, `height` (DXA, 1/20 pt), `margins: {left,right,top,bottom}` (twips). A4 и поля СТО -заданы по умолчанию. - -### typography -| Ключ | Смысл | -|------|-------| -| `font` | гарнитура (по умолчанию Times New Roman) | -| `sizeBody` / `sizeTable` / `sizeSmall` | размеры в half-points (28 = 14 pt) | -| `lineSpacing` | множитель межстрочного интервала (1.5 = полуторный) | -| `color` | цвет текста (hex, без `#`) | -| `useBold` | разрешить полужирный (СТО: `false`) | -| `allowEmphasis` | разрешить курсив (СТО: `false`) | - -### headings -Интервалы/выравнивание для `struct`, `section`, `subsection`, `point` (twips). - -### captions -`figure`, `table`, `tableContinue` — префиксы и тире подписей (`Рисунок`, `Таблица`, `—`). - -### lists -`bulletChar`, `letterSuffix`, `numberSuffix`, `nestedLevelStep`, `forbiddenLetters`. - -### numbering -`figures`, `tables`, `formulas`: `global` (сквозная по документу) или `section` (в пределах -раздела, вид `1.1`). Приложения всегда имеют префикс буквы (`А.1`). - -### formula -`spacingBeforeAfter`, `whereTabPosition`. - -### table -`font`, `size`, `borderColor`, `borderSize`, `cellMargins: {top,bottom,left,right}`, -`headerFill`, `cellFill`. - -### figure -`maxWidth` (px; `null` — по ширине полосы), `maxHeight` (px). +| Раздел | Назначение | +|--------|-----------| +| `page` | `width`, `height` (DXA), `margins` (twips) | +| `typography` | `font`, `sizeBody`/`sizeTable`/`sizeSmall`, `lineSpacing`, `color`, `useBold`, `allowEmphasis`, `language` | +| `headings` | интервалы/выравнивание `struct`, `section`, `subsection`, `point` | +| `captions` | префиксы и тире подписей `figure`, `table`, `tableContinue` | +| `lists` | `bulletChar`, `letterSuffix`, `numberSuffix`, `nestedLevelStep`, `forbiddenLetters` | +| `numbering` | `figures`, `tables`, `formulas`: `global` или `section` | +| `formula` | `spacingBeforeAfter`, `whereTabPosition` | +| `table` | `font`, `size`, `borderColor`, `borderSize`, `cellMargins`, `headerFill`, `cellFill` | +| `figure` | `maxWidth` (px, `null` — по ширине), `maxHeight` (px) | +| `pageNumber` | `align`, `format`, `startFrom` | +| `toc` | `enabled`, `title`, `depth` (1..3) | +| `bibliography` | `title` | +| `citation` | `bracketOpen`, `bracketClose`, `pagePrefix` | +| `appendix` | `labelPrefix`, `forbiddenLetters` | ### plantuml -Генерация рисунков из исходников PlantUML (см. п. 5, «Рисунки»). | Ключ | Тип | Смысл | |------|-----|-------| -| `enabled` | bool | включить рендеринг `.puml`; `false` — считать ошибкой при наличии `.puml` | -| `java` | string | исполняемый файл Java; `auto` — `%JAVA_HOME%\bin\java`, иначе `java` из PATH | +| `enabled` | bool | включить рендеринг `.puml`; `false` — считать ошибкой | +| `java` | string | `auto` — `%JAVA_HOME%\bin\java`, иначе `java` из PATH | | `jar` | string | путь к `plantuml.jar` (относительно `config.yaml`) | | `format` | string | только `png` | | `charset` | string | кодировка исходника (по умолчанию `UTF-8`) | @@ -147,43 +125,31 @@ DocxGenerator [опции] | `cacheDir` | string | каталог кэша PNG (относительно `config.yaml`) | | `timeoutMs` | int | таймаут рендера одной диаграммы, мс | -Ошибки рендера (нет `jar`, нет Java, синтаксическая ошибка) — **фатальные**: сборка -прекращается с кодом выхода `1`. Требуется установленная Java (JRE 11+) и файл -`plantuml.jar`; для части типов диаграмм нужен Graphviz либо встроенный Smlayout. - -### pageNumber -`align`, `format`, `startFrom`. - -### toc -`enabled` (bool), `title`, `depth` (1..3). Оглавление вставляется записью -`sections: [{ type: toc }]`. - -### bibliography / citation / appendix -`bibliography.title`, `citation: {bracketOpen,bracketClose,pagePrefix}`, -`appendix: {labelPrefix, forbiddenLetters}`. +Общий `plantuml.jar` репозитория лежит в `tools/plantuml.jar`; из проекта путь +вида `../../../tools/plantuml.jar`. Ошибки рендера (нет `jar`, нет Java, +синтаксическая ошибка) — фатальные: сборка останавливается с кодом `1`. ### sections — структура документа + Упорядоченный список частей: ```yaml sections: - - { type: toc } # поле оглавления - - { file: content/01-introduction.md, type: structural, title: Введение } - - { file: content/02-main.md, type: numbered } # # = 1, ## = 1.1, ### = 1.1.1 - - { file: content/03-conclusion.md, type: structural, title: Заключение } - - { file: content/04-bibliography.md, type: bibliography } - - { file: content/05-appendix-a.md, type: appendix, letter: А, title: Приложение } + - { type: toc } # поле оглавления + - { file: 01-introduction.md, type: structural, title: Введение } + - { file: 02-main.md, type: numbered } # # = 1, ## = 1.1, ### = 1.1.1 + - { file: 04-conclusion.md, type: structural, title: Заключение } + - { file: 05-bibliography.md, type: bibliography } + - { file: 06-appendix-a.md, type: appendix, letter: А, title: Приложение } ``` -Типы частей: - | type | Поведение | |------|-----------| | `toc` | вставляет оглавление (не требует `file`) | | `structural` | ненумерованный раздел (Введение/Заключение): заголовок = `title`, ЗАГЛАВНЫМИ, по центру, с новой страницы | | `numbered` | нумеруемый раздел; `#` = раздел, `##`/`###` = подраздел/пункт | | `bibliography` | список источников; нумеруется автоматически | -| `appendix` | приложение: заголовок «ПРИЛОЖЕНИЕ » + `title`, нумерация рисунков/таблиц с префиксом буквы | +| `appendix` | приложение: заголовок «ПРИЛОЖЕНИЕ » + `title`, буквенный префикс у рисунков/таблиц | ## 5. Формат контента @@ -197,12 +163,12 @@ sections: ### Пункт -> 1.1.1 Пункт ``` -Номера подставляются автоматически (Word-numbering). В `structural`/`appendix` заголовок -берётся из конфига, а заголовки внутри файла рендерятся как обычные заголовки без номера. +Номера подставляются автоматически (Word-numbering). В `structural`/`appendix` +заголовок берётся из `title`, а заголовки внутри файла рендерятся без номера. -### Абзацы, списки +### Абзацы и списки -Обычные абзацы и списки Markdown. Списки: +Обычные абзацы и списки Markdown. Пример: ```md - первый пункт; @@ -211,8 +177,8 @@ sections: 2. ещё один. ``` -Маркер вложенности выбирается автоматически: тире → `а)` → `1)`. Полужирный/курсив по -умолчанию игнорируются (СТО). +Маркер вложенности выбирается автоматически: тире → `а)` → `1)`. Полужирный и +курсив по умолчанию игнорируются (СТО). ### Таблицы @@ -237,13 +203,18 @@ sections: ::: ``` -`file` — относительно `config.paths.assets`. Если файла нет — предупреждение, подпись -всё равно выводится. +`file` — относительно `paths.assets`. Если файла нет — предупреждение, подпись +всё равно выводится. Подпись ставится под рисунком по центру: +`Рисунок N — Наименование`. Если пояснять нечего, тело директивы оставляют +пустым: -**PlantUML.** Если `file` оканчивается на `.puml` (`.plantuml`, `.pu`, `.iuml`), то файл -считается исходником PlantUML: инструмент рендерит его в PNG через локальный -`plantuml.jar` (см. `plantuml` в конфиге) и вставляет результат как обычный рисунок. -Нумерация, ссылки `@fig:id` и примечания работают так же. Пример: +```md +::: figure "Общая схема системы" id=common file=images/common.png +::: +``` + +**PlantUML.** Если `file` оканчивается на `.puml` (`.plantuml`, `.pu`, `.iuml`), +файл рендерится в PNG через `plantuml.jar` и вставляется как обычный рисунок: ```md ::: figure "Диаграмма последовательности" id=seq file=images/seq.puml @@ -252,18 +223,7 @@ sections: ::: ``` -Ошибка рендера — фатальная (код выхода `1`), `--check` тоже рендерит `.puml`. - -**Подписи по СТО.** Подпись ставится **под** рисунком по центру: `Рисунок N — Наименование` -(с прописной буквы, без точки в конце). Если на рисунке обозначены отдельные детали, -пояснительные данные размещают **над подписью** и оформляют перечислением `а)`, `б)`, `в)` — -именно так, как показано в примере выше. Если рисунок общий и пояснять нечего, указывают -только подпись `Рисунок N — Наименование`, а тело директивы оставляют пустым: - -```md -::: figure "Общая схема системы" id=common file=images/common.png -::: -``` +Ошибка рендера фатальна, `--check` тоже рендерит `.puml`. В приложениях номер рисунка получает префикс буквы: `Рисунок А.1 — Наименование`. @@ -281,8 +241,8 @@ a — коэффициент. ::: ``` -В формулах поддерживается простой синтаксис: `^` (степень), `_` (индекс), `/` (дробь). -Номер формулы ставится автоматически справа. +Поддерживается простой синтаксис: `^` (степень), `_` (индекс), `/` (дробь). Номер +формулы ставится автоматически справа. ### Примечания и термины @@ -313,56 +273,44 @@ a — коэффициент. ### Ссылки на источники -`[@1]` — ссылка на 1-й источник, `[@1, с. 96]` — с номером страницы. Список источников — -это Markdown-список в файле `type: bibliography`; порядок строк = номера источников. +`[@1]` — ссылка на 1-й источник, `[@1, с. 96]` — с номером страницы. Список +источников — Markdown-список в файле `type: bibliography`; порядок строк = номера. Ссылка вне диапазона — ошибка в `--check`. ### Перекрёстные ссылки -`@fig:id`, `@tbl:id`, `@eq:id` подставляют актуальный номер рисунка/таблицы/формулы -(например `2`, `1.1`, `А.1`). `id` задаётся в директиве. +`@fig:id`, `@tbl:id`, `@eq:id` подставляют актуальный номер рисунка/таблицы/ +формулы (например `2`, `1.1`, `А.1`). `id` задаётся в директиве. ### Блоки кода -Функция листингов удалена: fenced-блоки ``` игнорируются с предупреждением. +Fenced-блоки ``` игнорируются с предупреждением (функция листингов удалена). ## 6. Проверка и ошибки -`DocxGenerator --check` проверяет: +`--check` проверяет: -- корректность `config.yaml` (типы, существование файлов, допустимые буквы приложений); +- корректность `config.yaml` (типы, существование файлов, буквы приложений); - наличие всех `sections[].file`; - существование меток в `@fig/@tbl/@eq`; - диапазон ссылок `[@n]`; -- рендеринг всех `::: figure ... file=*.puml` (PlantUML). +- рендеринг всех `::: figure ... file=*.puml`. Ошибки печатаются списком и возвращают код выхода `1`. Предупреждения (например, отсутствующий PNG) не останавливают сборку; ошибки PlantUML — фатальные. -## 7. Сборка `.exe` из исходников +## 7. Подготовка диаграмм -```powershell -npm install -npm run build:exe # -> DocxGenerator.exe в корне (target node24-win-x64) -npm run generate # локальная сборка (node src/cli.js) -npm run check # проверка конфига и ссылок -``` - -Упаковка выполняется через `@yao-pkg/pkg`. Чтобы уменьшить размер, можно добавить -`--compress Brotli` в команду `build:exe`. - -### Подготовка диаграмм - -Готовые PNG кладутся в `content/assets/images/`. Для исходников PlantUML (`*.puml`) -инструмент рендерит PNG сам: положите исходник в `content/assets/images/`, укажите его в -`::: figure ... file=images/<имя>.puml` и поместите `plantuml.jar` в `tools/plantuml.jar` -(или задайте путь в `plantuml.jar`). Диаграммы других форматов (Mermaid, draw.io) готовятся -внешними средствами и вставляются как PNG. +Готовые PNG кладутся в общий каталог ресурсов (`content/<проект>/assets/images/`). +Исходники PlantUML (`.puml`) кладутся туда же и указываются в +`::: figure ... file=images/<имя>.puml`. Диаграммы других форматов (Mermaid, +draw.io) готовятся внешними средствами и вставляются как PNG. ## 8. Замечания по дизайну -- Дизайн фиксирован под СТО 02068410-004-2018; меняются только параметры из `config.yaml`. -- Полужирный и курсив по умолчанию отключены (`typography.useBold`, `allowEmphasis`). -- Шрифт, размеры, интервалы, отступы и подписи настраиваются в конфиге. -- Оглавление — поле Word; при открытии нажмите «Обновить поле», либо включено +- Дизайн фиксирован под СТО 02068410-004-2018; меняются только параметры из + `config.yaml`. +- Полужирный и курсив по умолчанию отключены (`typography.useBold`, + `allowEmphasis`). +- Оглавление — поле Word; при открытии нажмите «Обновить поле» либо включите `document.features.updateFields`. diff --git a/docx/README.md b/docx/README.md index a7784d8..90cd1cc 100644 --- a/docx/README.md +++ b/docx/README.md @@ -1,44 +1,29 @@ -# DocxGenerator +# SSAU Generator DOCX -Автономный генератор отчётов **DOCX** из **Markdown** по дизайну +Генератор отчётов **DOCX** из **Markdown** по дизайну [СТО 02068410-004-2018](documentation/STO_SGAU_02068410-004-2018.md). -Поведение полностью задаётся файлом `config.yaml`; путь выходного файла — ключ -`document.output`. +Содержимое задаётся Markdown-файлами и `config.yaml` проекта; путь выходного +файла — ключ `document.output`. -Полная документация: **[AGENTS.md](AGENTS.md)** — CLI, схема конфига, формат контента, -директивы и сборка `.exe`. +Полная инструкция по работе с документом: **[AGENTS.md](AGENTS.md)** — CLI, схема +конфига, формат контента, директивы и PlantUML. ## Быстрый старт ```powershell -.\DocxGenerator.exe --init # создать config.yaml, примеры content/ и content/assets/ -# ... правим config.yaml и content/*.md ... -.\DocxGenerator.exe --check # проверить ссылки и конфиг -.\DocxGenerator.exe # собрать report.docx +node docx/src/cli.js --content content/example/docx --check # проверка +node docx/src/cli.js --content content/example/docx # собрать report.docx ``` ## Разработка ```powershell npm install -npm run generate # локальная сборка report.docx -npm run check # проверка конфига и ссылок -npm run build:exe # собрать DocxGenerator.exe в корне (@yao-pkg/pkg, node24-win-x64) +npm run generate # локальная сборка (node src/cli.js) +npm run check # проверка конфига и ссылок +npm run init # создать шаблон проекта ``` -## Структура репозитория - -| Путь | Назначение | -|------|------------| -| `src/cli.js` | точка входа, разбор аргументов | -| `src/config/` | дефолты, загрузка и валидация `config.yaml`, шаблон | -| `src/markdown/` | markdown-it, директивы `:::`, инлайн-ссылки `[@n]`, `@fig/@tbl/@eq` | -| `src/render/` | сборка DOCX: стили, примитивы, нумерация, слияние титульника | -| `src/build.js` | оркестрация сборки | -| `content/` | примеры Markdown | -| `content/assets/` | PNG для рисунков, опциональный `title-page.docx` | -| `documentation/` | стандарт СТО | - -Готовые PNG кладутся в `content/assets/images/`. Исходники PlantUML (`*.puml`) можно указать -в `::: figure ... file=images/x.puml` — генератор отрендерит их в PNG через локальный -`plantuml.jar` (требуется Java 11+). +Структура кода: `src/cli.js` (точка входа), `src/config/` (дефолты, загрузка и +валидация `config.yaml`, шаблон), `src/markdown/` (markdown-it и директивы), +`src/render/` (сборка DOCX), `src/plantuml/` (рендеринг схем). diff --git a/docx/config.yaml b/docx/config.yaml deleted file mode 100644 index d36f0d2..0000000 --- a/docx/config.yaml +++ /dev/null @@ -1,145 +0,0 @@ -# Конфигурация генератора lab-gen. -# Все относительные пути считаются от каталога этого файла. -# Любой ключ можно опустить — будет использовано значение по умолчанию. - -document: - output: report.docx - titlePage: content/assets/title-page.docx - features: - updateFields: true -paths: - assets: content/assets -page: - width: 11906 - height: 16838 - margins: - left: 1701 - right: 851 - top: 1134 - bottom: 1134 -typography: - font: Times New Roman - sizeBody: 28 - sizeTable: 28 - sizeSmall: 24 - lineSpacing: 1.5 - indentFirst: 709 - color: '000000' - useBold: false - allowEmphasis: false -headings: - struct: - spacingBefore: 360 - spacingAfter: 560 - align: center - section: - spacingBefore: 920 - spacingAfter: 0 - align: left - subsection: - spacingBefore: 284 - spacingBeforeAfterSection: 240 - spacingAfter: 0 - align: left - point: - spacingBefore: 360 - spacingAfter: 0 -captions: - figure: - prefix: Рисунок - dash: — - align: center - table: - prefix: Таблица - dash: — - align: left - tableContinue: - prefix: Продолжение таблицы -lists: - bulletChar: '-' - letterSuffix: ) - numberSuffix: ) - forbiddenLetters: - - ё - - з - - й - - о - - ч - - ь - - ы - - ъ - nestedLevelStep: 360 -numbering: - figures: global - tables: global - formulas: global -formula: - spacingBeforeAfter: 360 - whereTabPosition: 720 -table: - font: Times New Roman - size: 28 - borderColor: '000000' - borderSize: 1 - cellMargins: - top: 57 - bottom: 57 - left: 113 - right: 113 - headerFill: FFFFFF - cellFill: FFFFFF -figure: - maxWidth: null - maxHeight: 620 -plantuml: - enabled: true - java: auto - jar: ../tools/plantuml.jar - format: png - charset: UTF-8 - cache: true - cacheDir: .plantuml-cache - timeoutMs: 30000 -pageNumber: - align: center - format: decimal - startFrom: 1 -toc: - enabled: true - title: Содержание - depth: 3 -bibliography: - title: Список использованных источников -citation: - bracketOpen: '[' - bracketClose: ']' - pagePrefix: с. -appendix: - labelPrefix: ПРИЛОЖЕНИЕ - forbiddenLetters: - - Ё - - З - - Й - - О - - Ч - - Ъ - - Ы - - Ь -sections: - - type: toc - - file: content/01-introduction.md - type: structural - title: Введение - - file: content/02-method.md - type: numbered - - file: content/03-spheres.md - type: numbered - - file: content/04-conclusion.md - type: structural - title: Заключение - - file: content/05-bibliography.md - type: bibliography - - file: content/06-appendix-a.md - type: appendix - letter: А - title: Сводная таблица применения метода diff --git a/docx/content/01-introduction.md b/docx/content/01-introduction.md deleted file mode 100644 index 9737791..0000000 --- a/docx/content/01-introduction.md +++ /dev/null @@ -1,41 +0,0 @@ -Объектом исследования выступает процесс выведения нового товара на рынок, -предметом — выбор метода реализации проекта по выводу новинки и его обоснование -в различных сферах деятельности. - -Актуальность работы обусловлена тем, что запуск нового товара сопровождается -высоким риском: значительная доля новинок не достигает устойчивых продаж, а -неудачный запуск приводит к прямым убыткам, потерям доли рынка и подрыву доверия -к бренду. По разным оценкам, до семи из десяти новых товаров уходят с рынка в -первые годы после появления, поэтому цена ошибки при выводе новинки особенно -велика [@1], [@2]. В этих условиях выбор управляемого и повторяемого метода -вывода товара на рынок становится практически значимой задачей: он позволяет -снизить неопределённость, распределить ресурсы проекта и своевременно отказаться -от бесперспективного направления [@7]. - -Под новым товаром в работе понимается продукт, услуга или их значимая -модификация, ранее не предлагавшиеся компанией целевой аудитории. Выведение -такого товара на рынок охватывает исследование спроса, разработку предложения, -его продвижение и получение обратной связи от клиентов. Именно комплексность -этих этапов и их взаимное влияние порождают основные риски: чем позже компания -узнаёт реакцию рынка, тем дороже исправлять допущенные ошибки [@5], [@7]. - -Целью работы является выбор метода реализации проекта по выведению нового товара -на рынок и обоснование его применимости в десяти сферах деятельности. Для -достижения цели необходимо решить следующие задачи: - -- изучить классические и гибкие методы выведения товара на рынок и их основные - ограничения; -- обосновать выбор метода Agile/Scrum применительно к запуску новинки; -- описать роли, артефакты и события выбранной методологии; -- раскрыть механизм проверки спроса через спринты и инкременты; -- обосновать применимость метода в производстве, связи, на транспорте, в - строительстве, коммерческой деятельности, юридических услугах, организации - праздников, бытовых услугах, IT-услугах и банковской сфере; -- сформулировать выводы об универсальности выбранного метода и условиях его - эффективного применения. - -При выполнении работы использованы методы системного анализа, сравнительного -анализа методов управления проектами, проектного моделирования и обобщения -практики [@3], [@4]. Структура работы соответствует поставленным задачам: первый -раздел посвящён обоснованию выбора метода, второй — его проверке в десяти сферах -деятельности, заключение содержит основные результаты и выводы. diff --git a/docx/content/02-method.md b/docx/content/02-method.md deleted file mode 100644 index 93622ab..0000000 --- a/docx/content/02-method.md +++ /dev/null @@ -1,154 +0,0 @@ -# ВЫБОР МЕТОДА ВЫВЕДЕНИЯ НОВОГО ТОВАРА НА РЫНОК - -В разделе рассматриваются основные методы реализации проекта по выведению нового -товара на рынок, формулируются критерии их сравнения и обосновывается выбор -методологии Agile/Scrum [@1], [@5]. - -## Обзор методов выведения товара на рынок - -В практике управления проектами сложились как классические, так и гибкие методы -вывода новинки на рынок. Классические подходы (Waterfall, Stage-Gate) строятся на -последовательном прохождении этапов и предполагают, что требования известны -заранее, а результат оценивается на завершающей стадии. Гибкие подходы -(Design Thinking, Lean Startup, Agile/Scrum) переносят проверку спроса внутрь -процесса и позволяют уточнять требования по мере получения отклика рынка. Краткая -характеристика методов приведена в таблице @tbl:methods. - -::: table "Сравнение методов выведения товара на рынок" id=methods -| Метод | Сущность | Основное ограничение | -|---|---|---| -| Waterfall (водопад) | последовательные этапы от идеи до запуска | поздняя обратная связь рынка | -| Stage-Gate | этапы с контрольными «воротами» go/kill | высокая стоимость стадии | -| Design Thinking | старт от потребности клиента, прототип и тест | не задаёт процесс управления | -| Lean Startup | минимальный продукт (MVP) и цикл «создать — измерить — научиться» | требует зрелой аналитики | -| Agile/Scrum | короткие итерации — спринты, готовый инкремент | нужна дисциплина команды | -| 4P (маркетинг-микс) | проработка товара, цены, каналов, продвижения | не покрывает разработку | -::: - -Сравнение методов проводится по четырём критериям: скорость получения обратной -связи, способность реагировать на изменения, стоимость проверки спроса и -прозрачность управления. Как видно из таблицы @tbl:methods, классические методы -предполагают длительный цикл и получают обратную связь рынка лишь на финальной -стадии. Для запуска нового товара, спрос на который ещё не подтверждён, это -создаёт повышенный риск: к моменту первых продаж значительная часть ресурсов уже -израсходована, а изменение требований требует дорогостоящей переработки. -Наиболее подходящим признан гибкий подход Agile и его методология Scrum [@2], -[@6]. Ключевые различия классического и гибкого подходов сведены в таблице -@tbl:compare. - -::: table "Сравнение классического и гибкого подходов" id=compare -| Критерий | Waterfall | Agile/Scrum | -|---|---|---| -| Обратная связь рынка | в конце проекта | в каждом спринте | -| Реакция на изменения | низкая | высокая | -| Готовый продукт | к концу проекта | в конце каждого спринта | -| Стоимость проверки спроса | высокая | низкая (пилотный инкремент) | -| Требования | фиксируются заранее | уточняются итеративно | -| Риск неудачного запуска | высокий | снижается поэтапно | -::: - -## Сущность методологии Agile/Scrum - -Agile — это гибкий подход к управлению проектами, закреплённый в «Манифесте -гибкой разработки» 2001 года. Манифест ставит в приоритет людей и взаимодействие -над процессами и инструментами, работающий продукт над исчерпывающей -документацией, сотрудничество с заказчиком над согласованием условий и готовность -к изменениям над следованиям первоначальному плану [@1]. На этих ценностях -строятся двенадцать принципов, важнейшими из которых для вывода нового товара -являются ранняя и частая поставка ценности, неразрывная работа бизнеса и -исполнителей и постоянная адаптация к меняющимся условиям рынка. - -Scrum — наиболее распространённая методология Agile: работа разбивается на -короткие итерации — спринты длительностью от одной до четырёх недель, каждая из -которых завершается готовым приростом продукта (инкрементом) [@2], [@3]. В основе -Scrum лежат три идеи: прозрачность (все участники видят состояние работы), -инспекция (результат регулярно проверяется) и адаптация (процесс меняется по -результатам проверки). Такой цикл «планирование — работа — проверка — улучшение» -позволяет проверять спрос небольшими порциями и снижать стоимость ошибки, что -особенно важно при запуске товара на непроверенном рынке [@3], [@4]. - -## Роли, артефакты и события Scrum - -Методология Scrum опирается на три роли, три артефакта и четыре события. Роли -отвечают за постановку целей и организацию работы, артефакты фиксируют требования -и прогресс, а события задают ритм и обеспечивают регулярную обратную связь. Роли -и артефакты приведены в таблице @tbl:scrum. - -::: table "Роли и артефакты методологии Scrum" id=scrum -| Элемент | Назначение | -|---|---| -| Product Owner | отвечает за ценность товара и ведёт Product Backlog | -| Scrum Master | убирает препятствия, следит за процессом | -| Команда разработки | 5–9 специалистов, создающих продукт | -| Product Backlog | перечень всех требований к новому товару | -| Sprint Backlog | план работ текущего спринта | -| Increment | готовый к показу прирост продукта | -::: - -Product Owner формирует и упорядочивает Product Backlog по ценности, принимает -результат спринта и представляет интересы заказчика. Scrum Master отвечает за -соблюдение правил методологии, помогает команде убирать препятствия и защищает -спринт от незапланированных работ. Команда разработки — самоорганизующаяся -группа из пяти–девяти специалистов, которая самостоятельно определяет, сколько -задач войдёт в спринт, и отвечает за качество инкремента. Каждый артефакт имеет -своё назначение: Product Backlog хранит все требования к товару, Sprint Backlog — -план текущей итерации, а Increment — готовую к показу часть продукта. Единое -понимание готовности фиксируется в критериях Definition of Done, что делает -результат спринта проверяемым. - -Цикл работы методологии при выводе товара на рынок приведён на рисунке -@fig:scrum-cycle. - -::: figure "Цикл Scrum при выводе нового товара на рынок" id=scrum-cycle file=images/scrum-cycle.puml -а) Product Backlog фиксирует требования к товару; -б) спринт завершается инкрементом; -в) Sprint Review даёт обратную связь рынка; -г) по результатам Review выполняется следующий спринт или масштабирование. -::: - -События Scrum задают ритм работы и обеспечивают инспекцию результата. Sprint -Planning открывает спринт и определяет его цель и состав работ. Daily Scrum — -короткая ежедневная встреча для синхронизации команды и выявления препятствий. -Sprint Review завершает спринт демонстрацией инкремента заказчику и рынку, а -Sprint Retrospective позволяет команде улучшить собственный процесс. Поскольку -каждый спринт заканчивается инкрементом, рынок получает способ проверить товар -до полного запуска производства и масштабных вложений. - -Результативность спринта оценивается по величине созданного инкремента и -получаемому эффекту. Скорость команды — суммарный объём задач, выполненных за -итерацию, — позволяет прогнозировать сроки вывода товара, а ожидаемый эффект -инкремента помогает сравнивать ценность планируемых улучшений с затратами на -спринт. Ожидаемый эффект рассчитывается по формуле @eq:effect. - -::: formula id=effect -E = C * V - Z -::: - -::: where -E — ожидаемый эффект спринта; -C — ценность инкремента для клиента; -V — вероятность подтверждения спроса; -Z — затраты на проведение спринта. -::: - -Положительный ожидаемый эффект служит основанием для развития товара, а -отрицательный — для корректировки состава требований. Такой расчёт делает -решение о продолжении или изменении проекта более обоснованным [@5]. - -## Обоснование выбора Scrum - -Выбор Scrum определяется рядом преимуществ применительно к выводу нового товара на -рынок [@3], [@4]: - -- рынок проверяется дешёвым инкрементом, а не дорогим запуском «с нуля»; -- обратная связь собирается в каждом спринте, что снижает риск ошибки; -- требования уточняются итеративно, поэтому изменения не приводят к переработке - всего проекта; -- прозрачность процесса обеспечивается ролями, артефактами и событиями; -- ранние пилотные продажи формируют выручку ещё до полного запуска; -- метод не зависит от отрасли и применим там, где есть клиент и обратная связь; -- скорость команды и результаты спринтов делают план развития измеримым. - -Таким образом, Agile/Scrum выбран в качестве метода реализации проекта по -выведению нового товара на рынок. Его применимость в десяти сферах деятельности -обоснована в следующем разделе. diff --git a/docx/content/03-spheres.md b/docx/content/03-spheres.md deleted file mode 100644 index 3005438..0000000 --- a/docx/content/03-spheres.md +++ /dev/null @@ -1,105 +0,0 @@ -# ОБОСНОВАНИЕ МЕТОДА AGILE/SCRUM В СФЕРАХ ДЕЯТЕЛЬНОСТИ - -В разделе обосновывается применимость метода Agile/Scrum в десяти сферах -деятельности. В каждой сфере рассматривается пример нового товара и показывается, -как его вывод на рынок организуется через спринты, пилотный инкремент и обратную -связь [@3], [@6]. Общая логика одинакова для всех сфер: сначала создаётся -ограниченный пробный продукт, затем замеряется результат, и только после этого -принимается решение о масштабировании (рисунок @fig:funnel). - -::: figure "Воронка вывода нового товара на рынок" id=funnel file=images/product-funnel.puml -а) спринт 0 уточняет требования и сегмент рынка; -б) спринты 1–2 создают минимальную версию товара; -в) спринты 3–4 проверяют спрос на ограниченной аудитории; -г) начиная со спринта 5 товар масштабируется по подтверждённым метрикам. -::: - -## Производство - -Новым товаром выступает линейка упаковки. Вместо единовременного перезапуска всех -линий выпускается пробная партия на одной линии, которая играет роль инкремента. -В ходе спринта замеряются себестоимость партии, доля брака и скорость переналадки -оборудования. Sprint Review с оптовыми покупателями показывает востребованность -новой упаковки, после чего производство масштабируется на остальные линии, а -замечания клиентов становятся задачами следующего спринта. - -## Связь - -Новый товар — тариф «Умный дом». Пилотный спринт запускает тариф для ста -абонентов, в ходе Sprint Review анализируются подключения, средний чек и отток. -Обратная связь абонентов позволяет скорректировать состав услуг и условия -подключения. По результатам обратной связи тариф дорабатывается и выводится на -массовый рынок без риска массового оттока при неудачной конфигурации. - -## Транспорт - -Новым товаром является сервис каршеринга мини-фургонов. Пилот реализуется пятью -машинами в одном районе; метрики загрузки, среднего времени аренды и спроса -оцениваются в конце спринта. Если загрузка подтверждает спрос, инкремент -признаётся успешным, и автопарк расширяется за счёт новых районов. Такой подход -позволяет проверить экономику сервиса до крупных капитальных вложений в технику. - -## Строительство - -Новый товар — модульные дома. Первый спринт предполагает возведение одного -пилотного модуля и его показ заказчикам. На Sprint Review фиксируются затраты на -монтаж, сроки и замечания по проекту, после чего они учитываются в следующем -инкременте — серийном модуле. Итеративная проверка снижает риск ошибок в типовом -проекте, который затем тиражируется на серию. - -## Коммерческая деятельность - -Новым товаром выступает подписка на наборы продуктов. Бокс-пилот на пятидесяти -клиентах позволяет измерить конверсию, средний чек и удержание. Обратная связь -покупателей формирует Sprint Backlog для доработки ассортимента и условий -подписки. Если удержание растёт, объём подписки увеличивается, а состав наборов -уточняется по отклику клиентов. - -## Предоставление юридических услуг - -Новый товар — пакет «юрфирма на аутсорсе». Пробный месяц для пяти клиентов даёт -инкремент услуги; на Sprint Review оцениваются востребованность, трудозатраты и -повторные обращения. На основе отзывов формируются тарифы и состав пакета. -Поэтапная проверка позволяет выстроить услугу под реальные ожидания клиентов, не -вкладываясь сразу в расширение штата юристов. - -## Организация праздников - -Новым товаром является онлайн-конструктор мероприятий. Один сценарий тестируется -на пробной группе клиентов; метрики вовлечённости, повторных заказов и средней -стоимости мероприятия анализируются в конце спринта. Успешный сценарий -становится основой каталога и автоматизации заказов, а непопулярные сценарии -исключаются без затрат на массовое продвижение. - -## Предоставление бытовых услуг - -Новый товар — подписка на уборку. Пилот с двадцатью подписчиками в одном районе -позволяет измерить удержание, среднее число заказов и загрузку исполнителей. По -результатам спринта сервис дорабатывается и масштабируется на другие районы. -Пилотный формат помогает наладить логистику и стандарты качества до выхода на -городской уровень. - -## IT-услуги - -Новым товаром выступает модуль SaaS-платформы. Бета-версия для десяти клиентов -является инкрементом; на Sprint Review собираются метрики использования, частоты -ошибок и NPS. Обратная связь определяет состав следующего релиза и приоритеты -доработки. Такой цикл соответствует самой природе гибкой разработки и позволяет -выпускать ценность небольшими, но регулярными порциями. - -## Банковские услуги - -Новый товар — вклад «Цель» в мобильном приложении. Тест на ограниченной группе -пользователей позволяет оценить долю открытий, средний срок и удержание. Даже в -регулируемой сфере спринты обеспечивают безопасную проверку спроса до полного -внедрения: пилот проводится в контролируемых условиях, а результат проходит -согласование с подразделениями банка. - -## Обобщение по сферам - -Рассмотренные примеры показывают, что различия между сферами касаются в первую -очередь содержания товара и применяемых метрик, тогда как структура процесса -остаётся общей. Везде выделяются заказчик, готовый участвовать в проверке -инкремента, и измеримый результат спринта, на основании которого принимается -решение о продолжении работы. Именно эта общность позволяет считать Agile/Scrum -универсальным методом выведения нового товара на рынок [@3], [@6]. diff --git a/docx/content/04-conclusion.md b/docx/content/04-conclusion.md deleted file mode 100644 index 6f6bbc1..0000000 --- a/docx/content/04-conclusion.md +++ /dev/null @@ -1,37 +0,0 @@ -В работе выбран метод реализации проекта по выведению нового товара на рынок и -обоснована его применимость в десяти сферах деятельности. - -В результате сравнительного анализа методов установлено, что классические подходы -(Waterfall, Stage-Gate) предполагают длительный цикл и позднюю обратную связь -рынка, что повышает риск запуска новинки. Сравнение по критериям скорости -обратной связи, реакции на изменения, стоимости проверки спроса и прозрачности -управления (таблица @tbl:compare) показало, что для непроверенного рынка -предпочтителен гибкий подход. В качестве метода выбран Agile/Scrum, поскольку он -проверяет спрос дешёвым инкрементом в каждом спринте и позволяет корректировать -товар по отклику рынка. - -Показано, что методология Scrum опирается на роли (Product Owner, Scrum Master, -команда разработки), артефакты (Product Backlog, Sprint Backlog, Increment) и -события (Sprint Planning, Daily Scrum, Sprint Review, Sprint Retrospective), что -делает процесс прозрачным и управляемым [@2], [@3]. В работе раскрыт механизм -оценки результативности итераций: ожидаемый эффект спринта рассчитывается по -формуле @eq:effect, а решение о развитии товара принимается по результатам Sprint -Review. Такой подход заменяет один дорогой запуск серией последовательных -проверок и снижает стоимость возможной ошибки. - -Обоснована применимость метода в производстве, связи, на транспорте, в -строительстве, коммерческой деятельности, юридических услугах, организации -праздников, бытовых услугах, IT-услугах и банковских услугах. В каждой сфере -вывод товара на рынок строится по единой логике: ограниченный пробный продукт — -замер результата — масштабирование. Различия касаются содержания товара и набора -метрик, тогда как структура процесса и роль обратной связи остаются неизменными. - -Практическая значимость работы состоит в том, что предложенный метод можно -применять как типовой алгоритм: выделить сегмент и требования, создать MVP, -провести пилот, измерить результат и принять решение о масштабировании. Это -позволяет компании управлять риском запуска новинки и обосновывать вложения -перед расширением производства или сервиса. - -Таким образом, выбранный метод Agile/Scrum является универсальным и позволяет -снизить риск и стоимость ошибки при выведении нового товара на рынок в различных -сферах деятельности. diff --git a/docx/content/05-bibliography.md b/docx/content/05-bibliography.md deleted file mode 100644 index ead8926..0000000 --- a/docx/content/05-bibliography.md +++ /dev/null @@ -1,7 +0,0 @@ -- Манифест гибкой разработки программного обеспечения. — 2001. — URL: https://agilemanifesto.org (дата обращения: 01.10.2026). -- Schwaber K., Sutherland J. The Scrum Guide: The Definitive Guide to Scrum. — 2020. — URL: https://scrumguides.org (дата обращения: 01.10.2026). -- Сазерленд Дж. Scrum. Революционный метод управления проектами. — М.: Манн, Иванов и Фербер, 2016. — 288 с. -- ГОСТ Р 54869-2011. Проектный менеджмент. Требования к управлению проектом. — М.: Стандартинформ, 2011. — 9 с. -- Cooper R. G. Perspective: The Stage-Gate Idea-to-Launch Process. — Journal of Product Innovation Management, 2008. — Vol. 25. — P. 213–232. -- Рис Э. Бизнес с нуля. Lean Startup для быстрого тестирования идей. — М.: Альпина Паблишер, 2014. — 253 с. -- Котлер Ф. Основы маркетинга. Краткий курс. — М.: Вильямс, 2019. — 496 с. diff --git a/docx/content/06-appendix-a.md b/docx/content/06-appendix-a.md deleted file mode 100644 index d118f10..0000000 --- a/docx/content/06-appendix-a.md +++ /dev/null @@ -1,17 +0,0 @@ -Сводная характеристика применения метода Agile/Scrum в десяти сферах деятельности -приведена в таблице @tbl:sphere-summary. - -::: table "Применение метода Agile/Scrum в сферах деятельности" id=sphere-summary -| № | Сфера | Новый товар | Пилотный инкремент спринта | -|---|---|---|---| -| 1 | Производство | новая линейка упаковки | пробная партия на одной линии | -| 2 | Связь | тариф «Умный дом» | пилот на 100 абонентов | -| 3 | Транспорт | каршеринг мини-фургонов | пять машин в одном районе | -| 4 | Строительство | модульные дома | один пилотный модуль | -| 5 | Коммерческая деятельность | подписка на наборы продуктов | бокс-пилот на 50 клиентов | -| 6 | Юридические услуги | пакет «юрфирма на аутсорсе» | пробный месяц для 5 клиентов | -| 7 | Организация праздников | онлайн-конструктор мероприятий | один сценарий на пробной группе | -| 8 | Бытовые услуги | подписка на уборку | 20 подписчиков в одном районе | -| 9 | IT-услуги | модуль SaaS-платформы | бета на 10 клиентов | -| 10 | Банковские услуги | вклад «Цель» в приложении | тест на группе пользователей | -::: diff --git a/docx/content/assets/images/product-funnel.puml b/docx/content/assets/images/product-funnel.puml deleted file mode 100644 index 8d70ad1..0000000 --- a/docx/content/assets/images/product-funnel.puml +++ /dev/null @@ -1,19 +0,0 @@ -@startuml -skinparam defaultFontName "Times New Roman" -skinparam defaultFontSize 13 -skinparam shadowing false -skinparam ArrowColor #1B87C9 -skinparam rectangleBorderColor #1B87C9 -skinparam rectangleBackgroundColor #EAF4FB - -title Воронка вывода нового товара на рынок - -rectangle "Идея и исследование рынка\nСпринт 0" as A -rectangle "MVP — минимальный товар\nСпринты 1–2" as B -rectangle "Пилот на ограниченной аудитории\nСпринты 3–4" as C -rectangle "Масштабирование товара\nСпринты 5 и далее" as D - -A --> B : спрос подтверждён -B --> C : инкремент принят -C --> D : метрики достигнуты -@enduml diff --git a/docx/content/assets/images/scrum-cycle.puml b/docx/content/assets/images/scrum-cycle.puml deleted file mode 100644 index 0791e3e..0000000 --- a/docx/content/assets/images/scrum-cycle.puml +++ /dev/null @@ -1,26 +0,0 @@ -@startuml -skinparam defaultFontName "Times New Roman" -skinparam defaultFontSize 13 -skinparam shadowing false -skinparam ArrowColor #1B87C9 -skinparam rectangleBorderColor #1B87C9 -skinparam rectangleBackgroundColor #EAF4FB - -title Цикл Scrum при выводе нового товара на рынок - -rectangle "Product Backlog — требования к товару" as PB -rectangle "Sprint Planning" as SP -rectangle "Спринт 1–4 недели" as S -rectangle "Increment — пробный продукт" as I -rectangle "Sprint Review — обратная связь рынка" as R -rectangle "Sprint Retrospective" as RET -rectangle "Масштабирование товара" as M - -PB --> SP -SP --> S -S --> I -I --> R -R --> RET -RET --> SP : следующий спринт -R --> M : спрос подтверждён -@enduml diff --git a/docx/content/assets/title-page.docx b/docx/content/assets/title-page.docx deleted file mode 100644 index ad44a2c..0000000 Binary files a/docx/content/assets/title-page.docx and /dev/null differ diff --git a/docx/package-lock.json b/docx/package-lock.json index 2554eff..3e7b99f 100644 --- a/docx/package-lock.json +++ b/docx/package-lock.json @@ -1,11 +1,11 @@ { - "name": "docxgenerator", + "name": "ssau-generator-docx", "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "docxgenerator", + "name": "ssau-generator-docx", "version": "2.0.0", "dependencies": { "docx": "^9.5.0", @@ -15,640 +15,7 @@ "markdown-it": "^14.1.0" }, "bin": { - "docxgenerator": "src/cli.js" - }, - "devDependencies": { - "@yao-pkg/pkg": "^6.23.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", - "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.29.7", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/generator": { - "version": "7.29.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", - "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.29.8", - "@babel/types": "^7.29.8", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", - "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", - "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", - "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.29.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.9.tgz", - "integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.29.8" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/template": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", - "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.7", - "@babel/parser": "^7.29.7", - "@babel/types": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.29.8", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", - "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.7", - "@babel/generator": "^7.29.8", - "@babel/helper-globals": "^7.29.7", - "@babel/parser": "^7.29.8", - "@babel/template": "^7.29.7", - "@babel/types": "^7.29.8", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.29.8", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", - "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.29.7", - "@babel/helper-validator-identifier": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", - "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", - "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", - "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", - "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", - "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", - "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", - "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", - "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", - "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", - "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", - "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", - "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", - "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", - "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", - "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", - "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", - "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", - "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", - "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", - "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", - "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", - "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", - "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", - "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", - "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", - "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", - "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@roberts_lando/vfs": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@roberts_lando/vfs/-/vfs-0.3.3.tgz", - "integrity": "sha512-YjkxVSLw5WMZQoARaryRAjcxA+GbBzWMJdwYZX5oLUt9cC/gew9as4Dn7tcLzPp7BPoR221VpTZ+78TRPawnjg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 22" + "ssau-generator-docx": "src/cli.js" } }, "node_modules/@types/node": { @@ -660,382 +27,18 @@ "undici-types": ">=7.24.0 <7.24.7" } }, - "node_modules/@yao-pkg/pkg": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/@yao-pkg/pkg/-/pkg-6.23.0.tgz", - "integrity": "sha512-+d8iqRcmDxPpTE5fbSmsn1rShktIKvMcQGcFhwLdH15A4g2fBcRVLXppeQmu9fbF98bhYXjCOj6UTf3odXxWiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/generator": "^7.23.0", - "@babel/parser": "^7.23.0", - "@babel/traverse": "^7.23.0", - "@babel/types": "^7.23.0", - "@roberts_lando/vfs": "^0.3.3", - "@yao-pkg/pkg-fetch": "3.6.6", - "esbuild": "^0.28.1", - "into-stream": "^9.1.0", - "multistream": "^4.1.0", - "picocolors": "^1.1.0", - "picomatch": "^4.0.2", - "postject": "^1.0.0-alpha.6", - "prebuild-install": "^7.1.1", - "resolve": "^1.22.10", - "resolve.exports": "^2.0.3", - "stream-meter": "^1.0.4", - "tar": "^7.5.7", - "tinyglobby": "^0.2.11", - "unzipper": "^0.12.3" - }, - "bin": { - "pkg": "lib-es5/bin.js" - }, - "engines": { - "node": ">=22.0.0" - } - }, - "node_modules/@yao-pkg/pkg-fetch": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/@yao-pkg/pkg-fetch/-/pkg-fetch-3.6.6.tgz", - "integrity": "sha512-Nu9ytHewcV6FuH4WvdpYZxz2XwiP2p30jlPBzbvwsS3OPYN7RRTyGrXhcmhS59O3AdXz/LW+4bozhV3alN+MEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picocolors": "^1.1.0", - "progress": "^2.0.3", - "semver": "^7.3.5", - "tar-fs": "^3.1.1", - "undici": "^7.28.0", - "yargs": "^16.2.0" - }, - "bin": { - "pkg-fetch": "lib-es5/bin.js" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "license": "Python-2.0" }, - "node_modules/b4a": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.9.0.tgz", - "integrity": "sha512-dpfcF9fDNR6++cthXR67iyhgqWy9CBouAvIWhIntzBG6cvK/cnIPiZQjBwi/ZqjjBEDGfoNDtmB0kTjroOJ3pQ==", - "dev": true, - "license": "Apache-2.0", - "peerDependencies": { - "react-native-b4a": "*" - }, - "peerDependenciesMeta": { - "react-native-b4a": { - "optional": true - } - } - }, - "node_modules/bare-events": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.9.2.tgz", - "integrity": "sha512-AIPKioV7/Y/8KfZ3AAhjPJxLLbY49S64Ym5DakZlUg75qQiTgUq9hEJoEwa4eUezPUlXRy/i5NpsKvo9jgKmoA==", - "dev": true, - "license": "Apache-2.0", - "peerDependencies": { - "bare-abort-controller": "*" - }, - "peerDependenciesMeta": { - "bare-abort-controller": { - "optional": true - } - } - }, - "node_modules/bare-fs": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.8.2.tgz", - "integrity": "sha512-+ZI68KHMUvosXfKbg/UOHK0tbCdRnegbvPEdEcZ3Nd6TetieQsJPRXBRXPdLyy8+3VSEbPXtsumTpEtt78xv9w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "bare-events": "^2.5.4", - "bare-path": "^3.0.0", - "bare-stream": "^2.6.4", - "bare-url": "^2.2.2", - "fast-fifo": "^1.3.2" - }, - "engines": { - "bare": ">=1.28.0" - }, - "peerDependencies": { - "bare-buffer": "*" - }, - "peerDependenciesMeta": { - "bare-buffer": { - "optional": true - } - } - }, - "node_modules/bare-path": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.1.2.tgz", - "integrity": "sha512-ZyKbsuuqK6Ag0K8pX6V5Txq6XeJRvY+wXucnFGRjiyVYP9YWDpIQugk/b+enRYrEYBJaqLzghRQpXPMR7341Nw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/bare-stream": { - "version": "2.13.4", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.4.tgz", - "integrity": "sha512-PcrQ8lVLbiJscNm1Kez+Yp4Gy4AHGcN1lzwjvf5NybWen7VvEgUfyfnXYJ2zNqWnzOfCb1Abq6lH8ti0syQszA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "b4a": "^1.8.1", - "streamx": "^2.25.0", - "teex": "^1.0.1" - }, - "peerDependencies": { - "bare-abort-controller": "*", - "bare-buffer": "*", - "bare-events": "*" - }, - "peerDependenciesMeta": { - "bare-abort-controller": { - "optional": true - }, - "bare-buffer": { - "optional": true - }, - "bare-events": { - "optional": true - } - } - }, - "node_modules/bare-url": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.5.4.tgz", - "integrity": "sha512-Gxa7UVWBr0/edU1b+TJhn/AZvMQUj9OGspvYsaTYQrAbZA4BOTZGL3LiZxvD+CeMlDH4juwD84+eTAp/bLYW5g==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "bare-path": "^3.0.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/commander": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || >=14" - } - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT" }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, "node_modules/docx": { "version": "9.7.1", "resolved": "https://registry.npmjs.org/docx/-/docx-9.7.1.tgz", @@ -1072,33 +75,6 @@ "pako": "~1.0.2" } }, - "node_modules/duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "readable-stream": "^2.0.2" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -1111,169 +87,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/esbuild": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", - "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.28.2", - "@esbuild/android-arm": "0.28.2", - "@esbuild/android-arm64": "0.28.2", - "@esbuild/android-x64": "0.28.2", - "@esbuild/darwin-arm64": "0.28.2", - "@esbuild/darwin-x64": "0.28.2", - "@esbuild/freebsd-arm64": "0.28.2", - "@esbuild/freebsd-x64": "0.28.2", - "@esbuild/linux-arm": "0.28.2", - "@esbuild/linux-arm64": "0.28.2", - "@esbuild/linux-ia32": "0.28.2", - "@esbuild/linux-loong64": "0.28.2", - "@esbuild/linux-mips64el": "0.28.2", - "@esbuild/linux-ppc64": "0.28.2", - "@esbuild/linux-riscv64": "0.28.2", - "@esbuild/linux-s390x": "0.28.2", - "@esbuild/linux-x64": "0.28.2", - "@esbuild/netbsd-arm64": "0.28.2", - "@esbuild/netbsd-x64": "0.28.2", - "@esbuild/openbsd-arm64": "0.28.2", - "@esbuild/openbsd-x64": "0.28.2", - "@esbuild/openharmony-arm64": "0.28.2", - "@esbuild/sunos-x64": "0.28.2", - "@esbuild/win32-arm64": "0.28.2", - "@esbuild/win32-ia32": "0.28.2", - "@esbuild/win32-x64": "0.28.2" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/events-universal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", - "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "bare-events": "^2.7.0" - } - }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "dev": true, - "license": "(MIT OR WTFPL)", - "engines": { - "node": ">=6" - } - }, - "node_modules/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true, - "license": "MIT" - }, - "node_modules/fs-extra": { - "version": "11.3.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", - "integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "dev": true, - "license": "MIT" - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "license": "ISC" - }, "node_modules/hash.js": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", @@ -1284,40 +97,6 @@ "minimalistic-assert": "^1.0.1" } }, - "node_modules/hasown": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", - "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, "node_modules/immediate": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", @@ -1330,65 +109,12 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "license": "ISC" - }, - "node_modules/into-stream": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-9.1.0.tgz", - "integrity": "sha512-DRsRnQrbzdFjaQ1oe4C6/EIUymIOEix1qROEJTF9dbMq+M4Zrm6VaLp6SD/B9IsiEjPZuBSnWWFN+udajugdWA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-core-module": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.17.0.tgz", - "integrity": "sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "license": "MIT" }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, "node_modules/js-yaml": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", @@ -1411,32 +137,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", - "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/jszip": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", @@ -1510,112 +210,12 @@ "integrity": "sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==", "license": "MIT" }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "license": "ISC" }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", - "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minizlib": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", - "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.1.2" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true, - "license": "MIT" - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/multistream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/multistream/-/multistream-4.1.0.tgz", - "integrity": "sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "once": "^1.4.0", - "readable-stream": "^3.6.0" - } - }, - "node_modules/multistream/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/nanoid": { "version": "5.1.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.11.tgz", @@ -1634,200 +234,18 @@ "node": "^18 || >=20" } }, - "node_modules/napi-build-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-abi": { - "version": "3.96.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.96.0.tgz", - "integrity": "sha512-rebQ/lz7i0EkoLzUVSrKRzA69zMkwLp95kKMWoMDkkM00Suxz0D7zEQPwRml5fQum24mj7bPvmlgLAmu2JCiYg==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", "license": "(MIT AND Zlib)" }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", - "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/postject": { - "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/postject/-/postject-1.0.0-alpha.6.tgz", - "integrity": "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "commander": "^9.4.0" - }, - "bin": { - "postject": "dist/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/prebuild-install": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", - "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", - "deprecated": "No longer maintained. Please contact the author of the relevant native addon; alternatives are available.", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^2.0.0", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/prebuild-install/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true, - "license": "ISC" - }, - "node_modules/prebuild-install/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/prebuild-install/node_modules/tar-fs": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.5.tgz", - "integrity": "sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/prebuild-install/node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "license": "MIT" }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/pump": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", - "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode.js": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", @@ -1837,22 +255,6 @@ "node": ">=6" } }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, "node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -1868,48 +270,6 @@ "util-deprecate": "~1.0.1" } }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.12", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", - "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve.exports": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", - "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -1925,94 +285,12 @@ "node": ">=11.0.0" } }, - "node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", "license": "MIT" }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/stream-meter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/stream-meter/-/stream-meter-1.0.4.tgz", - "integrity": "sha512-4sOEtrbgFotXwnEuzzsQBYEV1elAeFSO8rSGeTwabuX1RRn/kEq9JVH7I0MRBhKVRR0sJkr0M0QCH7yOLf9fhQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "^2.1.4" - } - }, - "node_modules/streamx": { - "version": "2.28.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.28.1.tgz", - "integrity": "sha512-zEzXb0s5Cds7tqMH6rhZ05lcJydCWiQPEwiNngVqzsxCc962vLY4Uw+mW7od8kDH258k2Uz/JrOkdIAAhSh9VA==", - "dev": true, - "license": "MIT", - "dependencies": { - "events-universal": "^1.0.0", - "fast-fifo": "^1.3.2", - "text-decoder": "^1.1.0" - } - }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -2022,229 +300,24 @@ "safe-buffer": "~5.1.0" } }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tar": { - "version": "7.5.22", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.22.tgz", - "integrity": "sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.1.0", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/tar-fs": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.3.tgz", - "integrity": "sha512-/hU4AXnIdZu+Gvl1pk0oI5f5HxWsCJRtY2aFaJdk9VvyL48DWU6iU5WAIPG+wIi1YvWA6eTJvIviP/tMAZZNwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - }, - "optionalDependencies": { - "bare-fs": "^4.0.1", - "bare-path": "^3.0.0" - } - }, - "node_modules/tar-stream": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.2.2.tgz", - "integrity": "sha512-+8NeqHRjQWH9nYlwo2gamAMImZCVzI4UoEgDpWorBt9OEfppiZn+uSkskzQKPWIZyji/C8fpWO7u69G0DX0tbg==", - "dev": true, - "license": "MIT", - "dependencies": { - "b4a": "^1.9.0", - "bare-fs": "^4.8.2", - "fast-fifo": "^1.3.2", - "streamx": "^2.28.1" - } - }, - "node_modules/teex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", - "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "streamx": "^2.12.5" - } - }, - "node_modules/text-decoder": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz", - "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "b4a": "^1.6.4" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", - "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/uc.micro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", "license": "MIT" }, - "node_modules/undici": { - "version": "7.30.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.30.0.tgz", - "integrity": "sha512-dkrQXeHSaoamnItlYbmzG0wFYrM0ZwDxCIg0A7aKjTyyhh9svRzCNFEzV+Vm05/yehjCzjDZ31KXfGEjYSztDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=20.18.1" - } - }, "node_modules/undici-types": { "version": "7.24.6", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", "license": "MIT" }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unzipper": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.12.5.tgz", - "integrity": "sha512-tXYOi9R57Uj/2Z25SOs5RRSzq886MBQj2gY8dPL+xl/kv6s6SvByoKfAtvfVeEuhntWDgjd2o9p2lb4TVPAz0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "bluebird": "~3.7.2", - "duplexer2": "~0.1.4", - "fs-extra": "11.3.1", - "graceful-fs": "^4.2.2", - "node-int64": "^0.4.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, "node_modules/xml": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", @@ -2272,55 +345,6 @@ "engines": { "node": ">=0.1" } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/yargs": { - "version": "16.2.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.2.tgz", - "integrity": "sha512-Nt9ZJjXTv5R8MHbqby/wXQ6Gi0Bb3TcYZkR1bzuL4yB2OxWPkXknz513gEF0GoA6tn00UpbPvERW8rzCuWCA6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } } } } diff --git a/docx/package.json b/docx/package.json index 9eff14d..358b98e 100644 --- a/docx/package.json +++ b/docx/package.json @@ -1,16 +1,16 @@ { - "name": "docxgenerator", + "name": "ssau-generator-docx", "version": "2.0.0", "private": true, - "description": "DocxGenerator — автономный генератор отчётов DOCX из Markdown по СТО 02068410-004-2018", + "description": "SSAU Generator DOCX — автономный генератор отчётов DOCX из Markdown по СТО 02068410-004-2018", "bin": { - "docxgenerator": "src/cli.js" + "ssau-generator-docx": "src/cli.js" }, "main": "src/index.js", "scripts": { "generate": "node src/cli.js", "check": "node src/cli.js --check", - "build:exe": "pkg . --targets node24-win-x64 --compress Brotli --output DocxGenerator.exe" + "init": "node src/cli.js --init" }, "dependencies": { "docx": "^9.5.0", @@ -18,16 +18,5 @@ "js-yaml": "^4.1.0", "jszip": "^3.10.1", "markdown-it": "^14.1.0" - }, - "devDependencies": { - "@yao-pkg/pkg": "^6.23.0" - }, - "pkg": { - "scripts": [ - "src/**/*.js" - ], - "targets": [ - "node24-win-x64" - ] } } diff --git a/docx/src/cli.js b/docx/src/cli.js index ad3aa04..2cb1f2e 100644 --- a/docx/src/cli.js +++ b/docx/src/cli.js @@ -14,17 +14,17 @@ const { ConfigError } = require('./util/errors'); const VERSION = '2.0.0'; -const HELP = `DocxGenerator ${VERSION} — генератор DOCX из Markdown (СТО 02068410-004-2018) +const HELP = `SSAU Generator DOCX ${VERSION} — генератор DOCX из Markdown (СТО 02068410-004-2018) Использование: - DocxGenerator.exe [опции] + node docx/src/cli.js [опции] Опции: - --config <путь> Путь к config.yaml (по умолчанию рядом с exe) - --content Каталог с config.yaml, content/ и assets/ (по умолчанию рядом с exe) + --config <путь> Путь к config.yaml (по умолчанию config.yaml в текущем каталоге) + --content Каталог проекта: config.yaml, *.md и assets/ (по умолчанию текущий) --output <путь> Переопределить путь выходного .docx --check Только проверить конфиг и ссылки, без записи - --init Создать шаблон config.yaml/content/assets и выйти + --init Создать шаблон config.yaml/*.md/assets и выйти --verbose Подробный вывод --version Показать версию --help Показать эту справку @@ -70,7 +70,7 @@ function parseArgs(argv) { } function defaultBaseDir() { - return process.pkg ? path.dirname(process.execPath) : process.cwd(); + return process.cwd(); } async function main() { @@ -101,7 +101,7 @@ async function main() { logger.info('Файлы уже существуют, ничего не создано.'); } logger.info(''); - logger.info('Отредактируйте config.yaml и файлы в content/, затем запустите DocxGenerator.exe снова.'); + logger.info('Отредактируйте config.yaml и файлы *.md, затем запустите генератор снова.'); return 0; } diff --git a/docx/src/config/defaults.js b/docx/src/config/defaults.js index f4d37af..29283c3 100644 --- a/docx/src/config/defaults.js +++ b/docx/src/config/defaults.js @@ -7,12 +7,12 @@ const DEFAULT_CONFIG = { document: { output: 'report.docx', - titlePage: 'content/assets/title-page.docx', + titlePage: 'assets/title-page.docx', features: { updateFields: true }, }, paths: { - assets: 'content/assets', + assets: 'assets', }, page: { @@ -28,6 +28,7 @@ const DEFAULT_CONFIG = { sizeSmall: 24, lineSpacing: 1.5, indentFirst: 709, + language: 'ru-RU', color: '000000', useBold: false, allowEmphasis: false, @@ -111,19 +112,19 @@ const DEFAULT_CONFIG = { sections: [ { type: 'toc' }, - { file: 'content/01-introduction.md', type: 'structural', title: 'Введение' }, - { file: 'content/02-analysis.md', type: 'numbered' }, - { file: 'content/03-design.md', type: 'numbered' }, - { file: 'content/04-conclusion.md', type: 'structural', title: 'Заключение' }, - { file: 'content/05-bibliography.md', type: 'bibliography' }, + { file: '01-introduction.md', type: 'structural', title: 'Введение' }, + { file: '02-analysis.md', type: 'numbered' }, + { file: '03-design.md', type: 'numbered' }, + { file: '04-conclusion.md', type: 'structural', title: 'Заключение' }, + { file: '05-bibliography.md', type: 'bibliography' }, { - file: 'content/06-appendix-a.md', + file: '06-appendix-a.md', type: 'appendix', letter: 'А', title: 'Сводные таблицы', }, { - file: 'content/07-appendix-b.md', + file: '07-appendix-b.md', type: 'appendix', letter: 'Б', title: 'Вспомогательные материалы', diff --git a/docx/src/config/template.js b/docx/src/config/template.js index f77b280..c9e0af8 100644 --- a/docx/src/config/template.js +++ b/docx/src/config/template.js @@ -8,21 +8,53 @@ const { DEFAULT_CONFIG } = require('./defaults'); const { diagramPng, chartPng } = require('../util/png'); const { buildSampleTitlePage } = require('../render/sample-titlepage'); -const CONFIG_HEADER = `# Конфигурация генератора DocxGenerator. +const CONFIG_HEADER = `# Конфигурация генератора SSAU Generator DOCX. # Все относительные пути считаются от каталога этого файла. # Любой ключ можно опустить — будет использовано значение по умолчанию. `; -function defaultConfigYaml() { +/** Каталог генератора внутри проекта (docx/ или pptx/). */ +function isGeneratorDir(baseDir) { + const base = path.basename(baseDir).toLowerCase(); + return base === 'docx' || base === 'pptx'; +} + +/** + * Раскладка проекта: имя проекта = имя папки проекта, общие ресурсы в + * content/<проект>/assets/, результат — content/<проект>/<проект>.docx. + */ +function projectLayout(baseDir) { + const isSub = isGeneratorDir(baseDir); + const projectDir = isSub ? path.dirname(baseDir) : baseDir; + const projectName = path.basename(projectDir) || 'project'; + return { + projectDir, + projectName, + assetsRel: isSub ? '../assets' : 'assets', + assetsDir: path.join(projectDir, 'assets'), + outputRel: isSub ? `../${projectName}.docx` : `${projectName}.docx`, + }; +} + +function defaultConfigYaml(layout) { + const config = { + ...DEFAULT_CONFIG, + document: { + ...DEFAULT_CONFIG.document, + output: layout.outputRel, + titlePage: `${layout.assetsRel}/title-page.docx`, + }, + paths: { assets: layout.assetsRel }, + }; return ( CONFIG_HEADER + - yaml.dump(DEFAULT_CONFIG, { noRefs: true, lineWidth: -1, sortKeys: false }) + yaml.dump(config, { noRefs: true, lineWidth: -1, sortKeys: false }) ); } const SAMPLE = { - 'content/01-introduction.md': `Целью работы является разработка информационной системы учёта + '01-introduction.md': `Целью работы является разработка информационной системы учёта заявок для отдела технической поддержки. Актуальность темы обусловлена ростом числа обращений и необходимостью их оперативной обработки [@1]. @@ -38,7 +70,7 @@ const SAMPLE = { действующими стандартами [@3], [@4]. `, - 'content/02-analysis.md': `# АНАЛИЗ ПРЕДМЕТНОЙ ОБЛАСТИ + '02-analysis.md': `# АНАЛИЗ ПРЕДМЕТНОЙ ОБЛАСТИ Раздел посвящён анализу процесса обработки обращений и обоснованию требований к информационной системе. Рассматриваются участники процесса, информационные потоки и ограничения предметной @@ -147,7 +179,7 @@ T_new — среднее время обработки заявки после ::: `, - 'content/03-design.md': `# ПРОЕКТИРОВАНИЕ ИНФОРМАЦИОННОЙ СИСТЕМЫ + '03-design.md': `# ПРОЕКТИРОВАНИЕ ИНФОРМАЦИОННОЙ СИСТЕМЫ В разделе описаны архитектура, модель данных и пользовательские сценарии разрабатываемой информационной системы. @@ -275,7 +307,7 @@ N — число обращений в месяц. ::: `, - 'content/04-conclusion.md': `В ходе работы проанализирована предметная область, спроектирована архитектура информационной + '04-conclusion.md': `В ходе работы проанализирована предметная область, спроектирована архитектура информационной системы и определены показатели эффективности [@6], [@7]. Основные результаты работы: @@ -289,7 +321,7 @@ N — число обращений в месяц. соответствии с действующим стандартом [@8]. `, - 'content/05-bibliography.md': `- ГОСТ 7.32-2017. Система стандартов по информации, библиотечному и издательскому делу. Отчёт о научно-исследовательской работе. Структура и правила оформления. — М. : Стандартинформ, 2017. — 32 с. + '05-bibliography.md': `- ГОСТ 7.32-2017. Система стандартов по информации, библиотечному и издательскому делу. Отчёт о научно-исследовательской работе. Структура и правила оформления. — М. : Стандартинформ, 2017. — 32 с. - ГОСТ Р 7.0.5-2008. Библиографическая ссылка. Общие требования и правила составления. — М. : Стандартинформ, 2008. — 23 с. - Иванов, И. И. Управление ИТ-сервисами : учебное пособие / И. И. Иванов. — Самара : Изд-во Самарского университета, 2019. — 184 с. - Петров, П. П. Обзор систем Service Desk / П. П. Петров // Информационные технологии. — 2020. — № 4. — С. 25–33. @@ -299,7 +331,7 @@ N — число обращений в месяц. - ГОСТ 8.417-2002. Государственная система обеспечения единства измерений. Единицы величин. — М. : Стандартинформ, 2002. — 32 с. `, - 'content/06-appendix-a.md': `Сводные данные по обращениям за отчётный период приведены в таблице @tbl:app-a1. + '06-appendix-a.md': `Сводные данные по обращениям за отчётный период приведены в таблице @tbl:app-a1. ::: table "Сводные данные по обращениям" id=app-a1 | Номер | Дата регистрации | Категория | Приоритет | Исполнитель | Статус | Время, мин | @@ -339,7 +371,7 @@ N — число обращений в месяц. ::: `, - 'content/07-appendix-b.md': `Схема размещения компонентов системы приведена на рисунке @fig:app-b1. + '07-appendix-b.md': `Схема размещения компонентов системы приведена на рисунке @fig:app-b1. ::: figure "Схема размещения компонентов" id=app-b1 file=images/appendix-scheme.png а) узлы развёртывания; @@ -361,29 +393,22 @@ N — число обращений в месяц. }; const IMAGES = { - 'content/assets/images/architecture.png': () => diagramPng(900, 420, [46, 94, 170]), - 'content/assets/images/data-flow.png': () => diagramPng(900, 380, [28, 140, 96]), - 'content/assets/images/interface.png': () => diagramPng(820, 480, [196, 120, 32]), - 'content/assets/images/chart.png': () => chartPng(820, 420, [122, 70, 190]), - 'content/assets/images/appendix-scheme.png': () => diagramPng(900, 520, [176, 48, 64]), + 'images/architecture.png': () => diagramPng(900, 420, [46, 94, 170]), + 'images/data-flow.png': () => diagramPng(900, 380, [28, 140, 96]), + 'images/interface.png': () => diagramPng(820, 480, [196, 120, 32]), + 'images/chart.png': () => chartPng(820, 420, [122, 70, 190]), + 'images/appendix-scheme.png': () => diagramPng(900, 520, [176, 48, 64]), }; -function scaffoldFiles() { - const files = { 'config.yaml': defaultConfigYaml() }; - for (const [name, content] of Object.entries(SAMPLE)) files[name] = content; - for (const [name, make] of Object.entries(IMAGES)) { - files[name] = { binary: make() }; - } - return files; -} - -/** Создаёт config.yaml, примеры content/ и ассеты, если их ещё нет. */ +/** + * Создаёт config.yaml, примеры Markdown и общие ресурсы проекта + * (content/<проект>/assets/), если их ещё нет. + */ async function ensureScaffold(baseDir) { - const files = scaffoldFiles(); + const layout = projectLayout(baseDir); const created = []; - for (const [name, content] of Object.entries(files)) { - const target = path.join(baseDir, name); - if (fs.existsSync(target)) continue; + const write = (target, content) => { + if (fs.existsSync(target)) return; fs.mkdirSync(path.dirname(target), { recursive: true }); if (content && typeof content === 'object' && content.binary) { fs.writeFileSync(target, content.binary); @@ -391,15 +416,17 @@ async function ensureScaffold(baseDir) { fs.writeFileSync(target, content, 'utf8'); } created.push(target); - } + }; - const titlePage = path.join(baseDir, 'content', 'assets', 'title-page.docx'); - if (!fs.existsSync(titlePage)) { - fs.mkdirSync(path.dirname(titlePage), { recursive: true }); - fs.writeFileSync(titlePage, await buildSampleTitlePage()); - created.push(titlePage); + write(path.join(baseDir, 'config.yaml'), defaultConfigYaml(layout)); + for (const [name, content] of Object.entries(SAMPLE)) { + write(path.join(baseDir, name), content); } + for (const [name, make] of Object.entries(IMAGES)) { + write(path.join(layout.assetsDir, name), { binary: make() }); + } + write(path.join(layout.assetsDir, 'title-page.docx'), await buildSampleTitlePage()); return created; } -module.exports = { defaultConfigYaml, scaffoldFiles, ensureScaffold, SAMPLE }; +module.exports = { defaultConfigYaml, projectLayout, ensureScaffold, SAMPLE }; diff --git a/docx/src/config/validate.js b/docx/src/config/validate.js index 6e94084..6edc91e 100644 --- a/docx/src/config/validate.js +++ b/docx/src/config/validate.js @@ -69,6 +69,9 @@ function validateConfig(config) { if (!(typeof typography.lineSpacing === 'number' && typography.lineSpacing > 0)) { errors.push('typography.lineSpacing: ожидалось положительное число'); } + if (typography.language != null && typeof typography.language !== 'string') { + errors.push('typography.language: ожидалась строка (например, ru-RU)'); + } for (const [key, value] of Object.entries(page.margins)) { if (!Number.isInteger(value) || value < 0) { diff --git a/docx/src/render/document.js b/docx/src/render/document.js index 3e7f8c8..1ddd63d 100644 --- a/docx/src/render/document.js +++ b/docx/src/render/document.js @@ -104,7 +104,14 @@ function renderInline(ctx, inlineToken, state) { push(textRun(ctx, ' ')); break; case 'hardbreak': - push(new TextRun({ break: 1, font: ctx.typography.font, size: ctx.typography.sizeBody })); + push( + new TextRun({ + break: 1, + font: ctx.typography.font, + size: ctx.typography.sizeBody, + ...(ctx.typography.language ? { language: { value: ctx.typography.language } } : {}), + }) + ); break; case 'strong_open': flags.bold = true; diff --git a/docx/src/render/primitives.js b/docx/src/render/primitives.js index d38ed6f..14763de 100644 --- a/docx/src/render/primitives.js +++ b/docx/src/render/primitives.js @@ -46,7 +46,7 @@ function alignmentOf(name) { function textRun(ctx, text, opts = {}) { const t = ctx.typography; - return new TextRun({ + const run = { text: text == null ? '' : String(text), font: t.font, size: opts.size || t.sizeBody, @@ -54,7 +54,9 @@ function textRun(ctx, text, opts = {}) { italics: t.allowEmphasis ? Boolean(opts.italics) : false, subScript: opts.subScript || false, superScript: opts.superScript || false, - }); + }; + if (t.language) run.language = { value: t.language }; + return new TextRun(run); } function flatten(...blocks) { @@ -325,7 +327,7 @@ function tableRow(ctx, cells, isHeader = false) { children: [textRun(ctx, line, { size: t.size })], spacing: { ...ctx.typography.lineSpacingSingle, before: 0, after: 0 }, alignment: AlignmentType.LEFT, - indent: {}, + indent: { left: 0, firstLine: 0, hanging: 0 }, }) ), }) @@ -388,12 +390,22 @@ function parseSimpleFormula(text) { let last = 0; let match; while ((match = re.exec(trimmed)) !== null) { - if (match.index > last) children.push(new MathRun(trimmed.slice(last, match.index))); - const run = new MathRun(match[2]); + let prefix = trimmed.slice(last, match.index); + const token = match[2]; + // Основание — завершающий идентификатор текста перед оператором. + const tail = /^([\s\S]*?)([A-Za-zА-Яа-я0-9]+)$/.exec(prefix); + let base = ''; + if (tail) { + base = tail[2]; + prefix = tail[1]; + } + if (prefix) children.push(new MathRun(prefix)); + const baseRuns = base ? [new MathRun(base)] : []; + const scriptRun = new MathRun(token); children.push( match[1] === '_' - ? new MathSubScript({ children: [run] }) - : new MathSuperScript({ children: [run] }) + ? new MathSubScript({ children: baseRuns, subScript: [scriptRun] }) + : new MathSuperScript({ children: baseRuns, superScript: [scriptRun] }) ); last = re.lastIndex; } @@ -580,6 +592,7 @@ function pageNumberFooter(ctx) { children: [PageNumber.CURRENT], font: ctx.typography.font, size: ctx.typography.sizeBody, + ...(ctx.typography.language ? { language: { value: ctx.typography.language } } : {}), }), ], }), diff --git a/docx/src/render/styles.js b/docx/src/render/styles.js index da78114..d1a7361 100644 --- a/docx/src/render/styles.js +++ b/docx/src/render/styles.js @@ -36,6 +36,7 @@ function buildContext(config) { lineSpacing, lineSpacingSingle, indentFirst: typography.indentFirst, + language: typography.language, }, figureMaxWidthPx: figure.maxWidth != null diff --git a/pptx/AGENTS.md b/pptx/AGENTS.md index 9c97910..8d4b0f3 100644 --- a/pptx/AGENTS.md +++ b/pptx/AGENTS.md @@ -1,66 +1,94 @@ -# AGENTS.md — генератор lab-gen-pptx +# AGENTS.md — работа с презентацией PPTX -`lab-gen-pptx` собирает презентацию **PPTX** из обычных **Markdown**-файлов по -шаблону Самарского университета. Поведение задаётся файлом `config.yaml`. +Генератор `pptx/` собирает презентацию **PPTX** из обычных **Markdown**-файлов по +шаблону Самарского университета. Этот файл — инструкция агенту по созданию и +правке конкретной презентации. Поведение задаётся `config.yaml` проекта, менять код +генератора не нужно. ## 1. Требования -- Node.js 18+. +- Node.js 18+, зависимости ставятся командой `npm install` в папке `pptx/`. - Зависимости: `pptxgenjs`, `js-yaml`. -- Для директив `::: image` с файлами `.puml` — Java 11+ (берётся из - `JAVA_HOME`, иначе `java` из PATH) и файл `plantuml.jar` (см. `config.plantuml`). +- Для директив `::: image` с файлами `.puml` — Java 11+ (из `JAVA_HOME`, иначе + `java` из PATH) и файл `plantuml.jar` (см. `config.plantuml`). -## 2. Состав +## 2. Раскладка проекта + +Проект лежит в `content/<проект>/pptx/` рядом с `config.yaml`: ``` -config.yaml # настройки (тема, тексты, таблицы, список слайдов) -content/ - slides/*.md # по одному Markdown-файлу на слайд - assets/ # задники (title-bg.jpeg, content-bg.jpg, final-bg.jpeg), - # готовые PNG/JPEG и исходники PlantUML (*.puml) -presentation.pptx # результат сборки (ключ presentation.output) -.plantuml-cache/ # кэш отрендеренных PlantUML (ключ plantuml.cacheDir) -src/ # cli.js, config.js, parse.js, render.js, plantuml.js, build.js +content/<проект>/ +├── assets/ # общие ресурсы проекта (общие с docx) +│ ├── title-bg.jpeg # задники +│ ├── content-bg.jpg +│ ├── final-bg.jpeg +│ └── images/ # готовые PNG/JPEG и исходники .puml +└── pptx/ + ├── config.yaml + └── slides/ + ├── 00-title.md + └── 01-*.md ``` -Все относительные пути считаются **от каталога `config.yaml`**. +Все относительные пути считаются **от каталога `config.yaml`**. Общие с документом +ресурсы указывайте через `../assets` (например, +`backgrounds.title: ../assets/title-bg.jpeg`). Каталог контента — ключ +`content.dir` (по умолчанию `.` — папка самого `config.yaml`). -Общий `plantuml.jar` монорепозитория лежит в корне, в `tools/plantuml.jar` -(`plantuml.jar: ../tools/plantuml.jar`). Для автономного дистрибутива положите -`tools/plantuml.jar` рядом с `config.yaml` и задайте путь `tools/plantuml.jar`. +Презентация собирается в папку проекта и называется по имени проекта: +`content/<проект>/<проект>.pptx`. Значение ключа `presentation.output` при такой +раскладке — `../<проект>.pptx`. + +Структуру проекта создавайте командой `--init`: она формирует `config.yaml`, +примеры слайдов и общий каталог `content/<проект>/assets/` (задники), который +используется и генератором `docx`. + +Готовый пример со всеми возможностями — `content/example/pptx/`. ## 3. Командная строка +Из корня репозитория: + ``` -lab-gen-pptx [config.yaml] [опции] +node pptx/src/cli.js [config.yaml] [опции] -c, --config путь к config.yaml (по умолчанию config.yaml) -o, --output переопределить имя выходного файла --check только проверить конфиг и ссылки + --init создать шаблон config.yaml/slides/assets и выйти -v, --verbose подробный вывод -h, --help справка --version версия ``` +Типичный цикл: + ```powershell -npm run check -npm run generate +node pptx/src/cli.js -c content/<проект>/pptx/config.yaml --init # создать структуру проекта +node pptx/src/cli.js -c content/<проект>/pptx/config.yaml --check # проверить +node pptx/src/cli.js -c content/<проект>/pptx/config.yaml # собрать ``` +После любого изменения исходников (`config.yaml`, слайдов, ресурсов `assets/`) +**пересоберите презентацию**, чтобы результат соответствовал исходникам. + +Если `config.yaml` не найден, инструмент сам создаёт шаблон (`config.yaml`, +примеры слайдов и общий `assets/`) и завершается. + ## 4. Схема `config.yaml` | Раздел | Назначение | |---|---| | `presentation` | `output`, `author`, `track` | | `theme` | `width`/`height` (дюймы), `font`, `colors`, `backgrounds`, `slideNumber` | -| `text` | макеты текста для типов слайдов `titleSlide`, `section`, `content`, `final` | +| `text` | макеты текста для типов `titleSlide`, `section`, `content`, `final` | | `table` | размер шрифта, цвета шапки/ячеек/границ | | `callout` | плашка-вывод: заливка, рамка, цвета и размеры шрифтов | | `metrics` | карточки-метрики: заливка, цвета, размеры значения и подписи | -| `flow` | нативная схема-цепочка: заливка, рамка, стрелки, размер | +| `flow` | схема-цепочка: заливка, рамка, стрелки, размер | | `chart` | палитра, размер шрифта, легенда, высота диаграммы | | `plantuml` | рендеринг `*.puml` (см. п. 5) | -| `content.dir` | каталог контента | +| `content.dir` | каталог контента (по умолчанию `.`) | | `slides` | список слайдов: `{ type, file }` | Типы слайдов: `title`, `section`, `content`, `final`. Каждому типу соответствует @@ -93,7 +121,7 @@ npm run generate | 1 | 2 | ::: -::: image assets/pic.png +::: image ../assets/images/pic.png подпись под рисунком ::: @@ -127,9 +155,9 @@ npm run generate ``` Параметр `side=left|right` ставит плашку в левую или правую колонку слайда. -Если у слайда есть блоки с `side`, они верстаются в две колонки (левая/правая), -а остальные блоки — как обычно. Типовое сочетание: `::: image ... side=left` -и `::: callout ... side=right`. +Если у слайда есть блоки с `side`, они верстаются в две колонки, а остальные +блоки — как обычно. Не смешивайте на одном слайде обычный текст и колонки +(`side`) — они накладываются. ### Директива `::: metrics` @@ -145,8 +173,7 @@ npm run generate ### Директива `::: flow` -Нативная схема-цепочка из скруглённых блоков со стрелками. Шаги разделяются -`->` (или `→`), можно писать по одному на строку: +Схема-цепочка из скруглённых блоков со стрелками. Шаги разделяются `->` (или `→`): ```md ::: flow @@ -154,14 +181,14 @@ Sprint Planning -> Спринт -> Sprint Review -> Ретроспектива ::: ``` -Если ширина блока становится малой, схема автоматически разворачивается +Если блоки становятся слишком узкими, схема автоматически разворачивается вертикально. ### Директива `::: chart <тип> "Заголовок"` Диаграмма на основе GFM-таблицы: первая колонка — категории, остальные — -числовые ряды (заголовки колонок = имена рядов). Поддерживаемые типы: -`bar`, `bar3d`, `line`, `pie`, `doughnut`, `area`, `radar`, `scatter`. +числовые ряды (заголовки колонок = имена рядов). Типы: `bar`, `bar3d`, `line`, +`pie`, `doughnut`, `area`, `radar`, `scatter`. ```md ::: chart doughnut "Новинки, которые не выживают" @@ -174,38 +201,38 @@ Sprint Planning -> Спринт -> Sprint Review -> Ретроспектива ### Директива `::: image` и PlantUML -`file` — относительно `content.dir` (`content/`). Если файл оканчивается на -`.puml` (`.plantuml`, `.pu`, `.iuml`), он рендерится в PNG через `plantuml.jar` -(см. `config.plantuml`) и вставляется как обычный рисунок: +`file` — относительно `content.dir`. Если файл оканчивается на `.puml` +(`.plantuml`, `.pu`, `.iuml`), он рендерится в PNG через `plantuml.jar` и +вставляется как обычный рисунок: ```md -::: image assets/scrum-cycle.puml height=3.2 +::: image ../assets/images/scrum-cycle.puml height=3.2 Цикл Scrum: от Product Backlog до масштабирования товара ::: ``` Подпись (строка под директивой) выводится под рисунком курсивом. Растровые -PNG/JPEG вставляются как есть. Необязательный параметр `height=<дюймы>` -(`h=`) ограничивает высоту рисунка, чтобы уместить под ним другие блоки; -пропорции сохраняются, рисунок центрируется. Параметр `side=left|right` -ставит рисунок в колонку (см. `::: callout`). +PNG/JPEG вставляются как есть. Параметр `height=<дюймы>` (`h=`) ограничивает +высоту рисунка (пропорции сохраняются, рисунок центрируется). `side=left|right` +ставит рисунок в колонку. ## 6. Задники -Изображения-задники извлечены из `presentation_16.pptx` в -`content/assets/` (`title-bg.jpeg`, `content-bg.jpg`, `final-bg.jpeg`). При замене -шаблона положите новые файлы и обновите пути в `theme.backgrounds`. +Задники лежат в общем каталоге ресурсов проекта +(`content/<проект>/assets/`: `title-bg.jpeg`, `content-bg.jpg`, `final-bg.jpeg`). +При замене шаблона положите новые файлы и обновите пути в `theme.backgrounds`. ## 7. Шрифт -В шаблоне используется фирменный `Elektra Text Pro`, который обычно не установлен -в системе (иначе Word подставляет случайный шрифт). Поэтому по умолчанию задан -`Segoe UI` — близкий современный sans. Альтернативы: `Calibri`, `Candara`, -`Corbel`, `Noto Sans`, `Arial`. Смените `theme.font` при необходимости. +В исходном шаблоне используется фирменный `Elektra Text Pro`, который обычно не +установлен в системе. Поэтому по умолчанию задан `Segoe UI` — близкий современный +sans. Альтернативы: `Calibri`, `Candara`, `Corbel`, `Noto Sans`, `Arial`. +Смените `theme.font` при необходимости. ## 8. Проверка результата -Презентацию можно отрендерить для визуальной проверки через LibreOffice: +`--check` проверяет конфиг и наличие слайдов/ресурсов. Презентацию можно +отрендерить для визуальной проверки через LibreOffice: ```powershell soffice --headless --convert-to pdf --outdir . presentation.pptx diff --git a/pptx/config.yaml b/pptx/config.yaml deleted file mode 100644 index 31a02df..0000000 --- a/pptx/config.yaml +++ /dev/null @@ -1,130 +0,0 @@ -# Конфигурация генератора презентаций lab-gen-pptx. -# Шаблон: Самарский университет, presentation_16.pptx. -# Все относительные пути считаются от каталога этого файла. - -presentation: - output: presentation.pptx - author: "Степанов П.А." - track: "ДОП 11" - group: "6403-020302D" - -theme: - width: 13.333 - height: 7.5 - # Шрифт презентации. Elektra Text Pro (фирменный) не установлен в системе, - # поэтому используется близкий современный sans. Замените при необходимости. - font: "Segoe UI" - colors: - white: "FFFFFF" - ink: "1F2933" - brand: "1B87C9" - muted: "6B7280" - accent: "0E6BA8" - tint: "EAF4FB" - line: "BFD3DD" - backgrounds: - title: content/assets/title-bg.jpeg - content: content/assets/content-bg.jpg - final: content/assets/final-bg.jpeg - slideNumber: - show: true - x: 12.17 - y: 6.86 - w: 0.5 - h: 0.42 - fontSize: 14 - # color — для тёмных фонов (разделитель), contentColor — для белых (контент) - color: "FFFFFF" - contentColor: "FFFFFF" - bold: true - align: "center" - -text: - titleSlide: - title: { x: 6.7, y: 1.85, w: 5.95, h: 1.9, fontSize: 28, align: center, color: white } - subtitle: { x: 6.7, y: 3.75, w: 5.95, h: 0.7, fontSize: 16, align: center, color: white } - body: { x: 6.7, y: 4.65, w: 5.95, h: 1.7, fontSize: 14, align: center, color: white } - section: - title: { x: 6.4, y: 2.55, w: 6.35, h: 2.4, fontSize: 26, bold: true, align: center, color: white } - content: - title: { x: 0.6, y: 0.20, w: 12.15, h: 0.66, fontSize: 24, align: center, color: white, valign: middle } - body: { x: 0.75, y: 0.98, w: 11.85, h: 5.7, fontSize: 18, align: left, color: ink, valign: top } - bulletSize: 18 - subBulletSize: 16 - final: - title: { x: 6.7, y: 2.85, w: 5.95, h: 1.6, fontSize: 28, bold: true, align: center, color: white } - body: { x: 6.7, y: 4.65, w: 5.95, h: 1.7, fontSize: 14, align: center, color: white } - -table: - fontSize: 14 - headerFill: "1B87C9" - headerColor: "FFFFFF" - cellColor: "1F2933" - borderColor: "BFD3DD" - -callout: - fill: "EAF4FB" - border: "1B87C9" - titleColor: "0E6BA8" - textColor: "1F2933" - titleFontSize: 18 - fontSize: 15 - lineWidth: 1.25 - -metrics: - fill: "1B87C9" - valueColor: "FFFFFF" - labelColor: "EAF4FB" - valueFontSize: 30 - labelFontSize: 13 - gap: 0.2 - height: 1.25 - -flow: - fill: "EAF4FB" - border: "1B87C9" - textColor: "1F2933" - arrowColor: "1B87C9" - fontSize: 13 - height: 1.0 - gap: 0.4 - -chart: - palette: ["1B87C9", "7FB2D9", "0E6BA8", "BFD3DD"] - fontSize: 12 - legend: true - height: 3.4 - -# Рендеринг PlantUML (::: image assets/schema.puml). -# Требуется Java 11+ (берётся из JAVA_HOME, иначе java из PATH) и plantuml.jar. -# Общий jar монорепозитория лежит в корне: tools/plantuml.jar. -plantuml: - enabled: true - java: auto - jar: ../tools/plantuml.jar - format: png - charset: UTF-8 - cache: true - cacheDir: .plantuml-cache - timeoutMs: 30000 - -content: - dir: content - -slides: - - { type: title, file: slides/00-title.md } - - { type: content, file: slides/01-agenda.md } - - { type: content, file: slides/01-task.md } - - { type: content, file: slides/02-why-scrum.md } - - { type: content, file: slides/03-roles.md } - - { type: content, file: slides/04-events.md } - - { type: content, file: slides/12-scrum-cycle.md } - - { type: content, file: slides/05-launch.md } - - { type: section, file: slides/06-spheres.md } - - { type: content, file: slides/07a-spheres-1-2.md } - - { type: content, file: slides/07b-spheres-3-4.md } - - { type: content, file: slides/07c-spheres-5-6.md } - - { type: content, file: slides/07d-spheres-7-8.md } - - { type: content, file: slides/07e-spheres-9-10.md } - - { type: content, file: slides/10-conclusion.md } - - { type: final, file: slides/11-final.md } diff --git a/pptx/content/assets/scrum-cycle.puml b/pptx/content/assets/scrum-cycle.puml deleted file mode 100644 index cd0600c..0000000 --- a/pptx/content/assets/scrum-cycle.puml +++ /dev/null @@ -1,24 +0,0 @@ -@startuml -skinparam defaultFontName "Times New Roman" -skinparam defaultFontSize 13 -skinparam shadowing false -skinparam ArrowColor #1B87C9 -skinparam rectangleBorderColor #1B87C9 -skinparam rectangleBackgroundColor #EAF4FB - -rectangle "Product Backlog — требования к товару" as PB -rectangle "Sprint Planning" as SP -rectangle "Спринт 1–4 недели" as S -rectangle "Increment — пробный продукт" as I -rectangle "Sprint Review — обратная связь рынка" as R -rectangle "Sprint Retrospective" as RET -rectangle "Масштабирование товара" as M - -PB --> SP -SP --> S -S --> I -I --> R -R --> RET -RET --> SP : следующий спринт -R --> M : спрос подтверждён -@enduml diff --git a/pptx/content/slides/00-title.md b/pptx/content/slides/00-title.md deleted file mode 100644 index f7be6c0..0000000 --- a/pptx/content/slides/00-title.md +++ /dev/null @@ -1,13 +0,0 @@ -# Современные проектные технологии - -## Метод выведения нового товара на рынок: Agile / Scrum - -Степанов П.А., группа 6403-020302D - -Слушатель программы профессиональной переподготовки «Современные проектные технологии» - -ИОТ-трек «ДОП 11» - -::: notes -Добрый день, уважаемые члены итоговой аттестационной комиссии. Меня зовут Степанов П.А., я слушатель программы профессиональной переподготовки «Современные проектные технологии», ИОТ-трек «ДОП 11», группа 6403-020302D. Разрешите представить решение итогового задания по теме «Современные проектные технологии» — метод выведения нового товара на рынок. -::: diff --git a/pptx/content/slides/01-agenda.md b/pptx/content/slides/01-agenda.md deleted file mode 100644 index a968cd7..0000000 --- a/pptx/content/slides/01-agenda.md +++ /dev/null @@ -1,12 +0,0 @@ -# План доклада - -- ==Метод== выведения нового товара: Agile / Scrum -- Почему выбран именно Scrum -- Роли, артефакты и события методологии -- Как спринты проверяют спрос на рынке -- Применение в ==десяти сферах== деятельности -- Выводы и практический результат - -::: notes -Структура доклада. Сначала я обосную выбор метода — Agile и Scrum. Затем покажу, как устроена методология: роли, артефакты и события. Отдельно объясню, как спринты позволяют проверять спрос на рынке. После этого докажу универсальность метода на десяти сферах деятельности: от производства до банковских услуг. В завершение приведу выводы и практический результат. -::: diff --git a/pptx/content/slides/01-task.md b/pptx/content/slides/01-task.md deleted file mode 100644 index f3fd8b6..0000000 --- a/pptx/content/slides/01-task.md +++ /dev/null @@ -1,19 +0,0 @@ -# Постановка задачи - -- Выбрать метод выведения нового товара на рынок -- Обосновать его применимость в ==десяти сферах== деятельности -- Показать, как метод работает в каждой сфере - -::: metrics -70% | новых товаров уходят с рынка -10 | сфер применения метода -4 | недели — максимальная длина спринта -::: - -::: callout "Проблема и решение" -Запуск новинки — это **высокий риск**. Нужен управляемый и повторяемый процесс вывода товара — таким процессом является **Agile / Scrum**. -::: - -::: notes -Задача итогового задания — выбрать метод выведения нового товара на рынок и обосновать его в десяти сферах: от производства до банковских услуг. Запуск новинки всегда сопряжён с риском: до семи из десяти новых товаров не выживают на рынке. Поэтому нужен управляемый и повторяемый процесс, и в качестве такого метода я выбрал Agile и его самую популярную методологию — Scrum. -::: diff --git a/pptx/content/slides/02-why-scrum.md b/pptx/content/slides/02-why-scrum.md deleted file mode 100644 index d68e907..0000000 --- a/pptx/content/slides/02-why-scrum.md +++ /dev/null @@ -1,18 +0,0 @@ -# Почему выбран Agile / Scrum - -- Agile — гибкий подход к управлению проектами, закреплён в ==манифесте 2001 года== -- Scrum — самая распространённая Agile-методология в мире -- Работа идёт короткими итерациями — *спринтами* от одной до четырёх недель -- Каждый спринт даёт готовый прирост продукта — ==инкремент== -- Обратная связь с рынком собирается на каждом шаге, а не в конце проекта - -::: chart doughnut "Новинки, которые не выживают на рынке" -| Итог | Доля, % | -|---|---| -| Успешные новинки | 30 | -| Уходят с рынка | 70 | -::: - -::: notes -Почему именно Agile и Scrum. Agile — это гибкий подход к управлению проектами, закреплённый в манифесте 2001 года. Scrum — самая распространённая Agile-методология. Работа разбивается на короткие спринты длиной от одной до четырёх недель. Каждый спринт завершается готовым приростом продукта. Благодаря этому обратная связь с рынком собирается постоянно, а не только в конце. Именно поэтому гибкий подход снижает риск: как показывают оценки, до семи из десяти новинок не выживают при традиционном запуске. -::: diff --git a/pptx/content/slides/03-roles.md b/pptx/content/slides/03-roles.md deleted file mode 100644 index cd9ddcc..0000000 --- a/pptx/content/slides/03-roles.md +++ /dev/null @@ -1,21 +0,0 @@ -# Scrum: роли и артефакты - -- **Product Owner** — отвечает за ценность товара и ведёт Product Backlog -- **Scrum Master** — убирает препятствия и следит за соблюдением процесса -- **Команда разработки** — от пяти до девяти специалистов, создающих продукт - -::: table -| Артефакт Scrum | Назначение | -|---|---| -| Product Backlog | все требования к новому товару | -| Sprint Backlog | план работ текущего спринта | -| Increment | готовый к показу прирост продукта | -::: - -::: callout "Прозрачность" -Все артефакты видны команде и заказчику, а критерии готовности зафиксированы в ==Definition of Done==. -::: - -::: notes -В Scrum три роли. Product Owner отвечает за ценность товара и ведёт Product Backlog — список всех требований. Scrum Master убирает препятствия и следит за соблюдением процесса. Команда разработки из пяти–девяти специалистов создаёт продукт. Три артефакта: Product Backlog со всеми требованиями, Sprint Backlog с планом текущего спринта и Increment — готовый прирост продукта. Единое понимание готовности фиксируется в критериях Definition of Done. -::: diff --git a/pptx/content/slides/04-events.md b/pptx/content/slides/04-events.md deleted file mode 100644 index 66d0ee6..0000000 --- a/pptx/content/slides/04-events.md +++ /dev/null @@ -1,18 +0,0 @@ -# Scrum: события спринта - -::: flow -Sprint Planning -> Спринт -> Sprint Review -> Ретроспектива -::: - -- **Sprint Planning** — планируем, что войдёт в спринт -- **Daily Scrum** — пятнадцать минут на синхронизацию команды -- **Sprint Review** — показываем прирост заказчику и рынку -- **Sprint Retrospective** — улучшаем процесс работы команды - -::: callout "Результат спринта" -Каждый спринт заканчивается рабочим ==инкрементом== — кандидатом на рынок. -::: - -::: notes -Спринт состоит из четырёх событий. На Sprint Planning команда решает, что войдёт в спринт. Daily Scrum — пятнадцатиминутная синхронизация каждый день. На Sprint Review прирост показывают заказчику и рынку. На Sprint Retrospective команда улучшает свой процесс. Каждый спринт заканчивается рабочим инкрементом, который можно показать рынку. Далее цикл повторяется: планирование, спринт, демонстрация, ретроспектива. -::: diff --git a/pptx/content/slides/05-launch.md b/pptx/content/slides/05-launch.md deleted file mode 100644 index 11ee86a..0000000 --- a/pptx/content/slides/05-launch.md +++ /dev/null @@ -1,18 +0,0 @@ -# Как Scrum выводит товар на рынок - -::: flow -Спринт 0: исследование -> MVP -> Пилот и метрики -> Масштабирование -::: - -- **Спринт 0** — исследование рынка, выбор сегмента, формирование Product Backlog -- **Спринты 1–2** — создание MVP: минимальной версии товара для первых клиентов -- **Спринты 3–4** — пилот на ограниченной аудитории и сбор метрик -- **Спринт 5 и далее** — доработка по обратной связи и масштабирование - -::: callout "Итог" -Рынок проверяется ==дешёвым инкрементом==, а не дорогим запуском «с нуля». -::: - -::: notes -Как Scrum выводит товар на рынок. Спринт ноль — исследование рынка и формирование списка требований. Спринты один и два — создание минимального продукта для первых клиентов. Спринты три и четыре — пилот на ограниченной аудитории и сбор метрик. Дальше — доработка по обратной связи и масштабирование. Демонстрация реальным клиентам позволяет проверить спрос до крупных вложений. Итог: рынок проверяется дешёвым инкрементом, а не дорогим запуском с нуля. -::: diff --git a/pptx/content/slides/06-spheres.md b/pptx/content/slides/06-spheres.md deleted file mode 100644 index e34fee5..0000000 --- a/pptx/content/slides/06-spheres.md +++ /dev/null @@ -1,7 +0,0 @@ -# Agile / Scrum в десяти сферах деятельности - -Обоснование универсальности выбранного метода - -::: notes -Теперь покажу, что метод Agile и Scrum применим не только в IT, но и в десяти различных сферах деятельности. -::: diff --git a/pptx/content/slides/07a-spheres-1-2.md b/pptx/content/slides/07a-spheres-1-2.md deleted file mode 100644 index 56b58d2..0000000 --- a/pptx/content/slides/07a-spheres-1-2.md +++ /dev/null @@ -1,21 +0,0 @@ -# Сферы 1–2: производство и связь - -::: callout "1. Производство — новая линейка упаковки" -- Новый товар: линейка упаковки для розницы. -- Пилотный спринт: пробная партия на ==одной линии==. -- Метрика Sprint Review: себестоимость, доля брака, скорость переналадки. -- Решение: масштабирование на остальные линии по подтверждённому спросу. -- Особенность: переналадка одной линии дешевле полного перезапуска. -::: - -::: callout "2. Связь — тариф «Умный дом»" -- Новый товар: тариф «Умный дом» для абонентов. -- Пилотный спринт: подключение ==100 абонентов==. -- Метрика Sprint Review: число подключений, средний чек, отток. -- Решение: доработка состава услуг и вывод тарифа на массовый рынок. -- Особенность: пилот ограничен абонентской базой и не грозит массовым оттоком. -::: - -::: notes -Первые две сферы. В производстве новая линейка упаковки запускается пробной партией на одной линии: замеряют себестоимость, долю брака и скорость переналадки. По результатам Sprint Review производство масштабируется на остальные линии. В связи тариф «Умный дом» тестируется на ста абонентах: анализируют подключения, средний чек и отток, после чего состав услуг уточняется и тариф выводится на массовый рынок. Общая логика: ограниченный пилот, замер метрики, затем масштабирование. -::: diff --git a/pptx/content/slides/07b-spheres-3-4.md b/pptx/content/slides/07b-spheres-3-4.md deleted file mode 100644 index 060080a..0000000 --- a/pptx/content/slides/07b-spheres-3-4.md +++ /dev/null @@ -1,21 +0,0 @@ -# Сферы 3–4: транспорт и строительство - -::: callout "3. Транспорт — каршеринг мини-фургонов" -- Новый товар: сервис каршеринга мини-фургонов. -- Пилотный спринт: ==пять машин== в одном районе. -- Метрика Sprint Review: загрузка, среднее время аренды, спрос. -- Решение: расширение автопарка и запуск в новых районах. -- Особенность: экономика сервиса проверяется до закупки техники. -::: - -::: callout "4. Строительство — модульные дома" -- Новый товар: модульные дома для застройки. -- Пилотный спринт: возведение ==одного пилотного модуля== и показ заказчикам. -- Метрика Sprint Review: затраты на монтаж, сроки, замечания. -- Решение: серийный модуль с учётом правок и тиражирование. -- Особенность: типовой проект снижает стоимость серии. -::: - -::: notes -Транспорт и строительство. В транспорте сервис каршеринга мини-фургонов стартует с пяти машин в одном районе: оценивают загрузку, среднее время аренды и спрос. Если экономика подтверждается, автопарк расширяется. В строительстве сначала возводится один пилотный модульный дом и показывается заказчикам: фиксируют затраты, сроки и замечания, после чего серийный модуль тиражируется. Итеративная проверка снижает риск ошибок в типовом проекте. -::: diff --git a/pptx/content/slides/07c-spheres-5-6.md b/pptx/content/slides/07c-spheres-5-6.md deleted file mode 100644 index d076692..0000000 --- a/pptx/content/slides/07c-spheres-5-6.md +++ /dev/null @@ -1,21 +0,0 @@ -# Сферы 5–6: коммерция и юридические услуги - -::: callout "5. Коммерция — подписка на наборы продуктов" -- Новый товар: подписка на наборы продуктов. -- Пилотный спринт: бокс-пилот на ==50 клиентах==. -- Метрика Sprint Review: конверсия, средний чек, удержание. -- Решение: доработка ассортимента и условий подписки. -- Особенность: состав набора гибко меняется по спросу. -::: - -::: callout "6. Юридические услуги — пакет «юрфирма на аутсорсе»" -- Новый товар: пакет «юрфирма на аутсорсе». -- Пилотный спринт: пробный месяц для ==5 клиентов==. -- Метрика Sprint Review: востребованность, трудозатраты, повторные обращения. -- Решение: тарифы и состав пакета формируются по отзывам. -- Особенность: расширение штата юристов только после подтверждения спроса. -::: - -::: notes -Коммерция и юридические услуги. В коммерции подписка на продуктовые наборы запускается бокс-пилотом на пятидесяти клиентах: измеряют конверсию, средний чек и удержание, после чего уточняют ассортимент и условия. В юридических услугах пакет «юрфирма на аутсорсе» предлагается пяти клиентам на пробный месяц: оценивают востребованность и трудозатраты. Пилот позволяет выстроить услугу под реальные ожидания клиентов, не вкладываясь сразу в расширение штата. -::: diff --git a/pptx/content/slides/07d-spheres-7-8.md b/pptx/content/slides/07d-spheres-7-8.md deleted file mode 100644 index d498e7f..0000000 --- a/pptx/content/slides/07d-spheres-7-8.md +++ /dev/null @@ -1,21 +0,0 @@ -# Сферы 7–8: организация праздников и бытовые услуги - -::: callout "7. Организация праздников — онлайн-конструктор мероприятий" -- Новый товар: онлайн-конструктор мероприятий. -- Пилотный спринт: ==один сценарий== на пробной группе. -- Метрика Sprint Review: вовлечённость, повторные заказы, средняя стоимость. -- Решение: каталог успешных сценариев и автоматизация заказов. -- Особенность: непопулярные сценарии не масштабируются и не продвигаются. -::: - -::: callout "8. Бытовые услуги — подписка на уборку" -- Новый товар: подписка на уборку. -- Пилотный спринт: ==20 подписчиков== в одном районе. -- Метрика Sprint Review: удержание, число заказов, загрузка исполнителей. -- Решение: стандарты качества и масштабирование на другие районы. -- Особенность: логистика и качество отрабатываются в пилоте. -::: - -::: notes -Организация праздников и бытовые услуги. Онлайн-конструктор мероприятий тестируется на одной пробной группе: смотрят вовлечённость, повторные заказы и среднюю стоимость. Успешный сценарий становится основой каталога. Подписка на уборку стартует с двадцати подписчиков в одном районе: измеряют удержание, число заказов и загрузку исполнителей, после чего налаживают логистику и стандарты качества и выходят на другие районы. -::: diff --git a/pptx/content/slides/07e-spheres-9-10.md b/pptx/content/slides/07e-spheres-9-10.md deleted file mode 100644 index 9d9c9c2..0000000 --- a/pptx/content/slides/07e-spheres-9-10.md +++ /dev/null @@ -1,21 +0,0 @@ -# Сферы 9–10: IT-услуги и банки - -::: callout "9. IT-услуги — модуль SaaS-платформы" -- Новый товар: новый модуль SaaS-платформы. -- Пилотный спринт: ==бета на 10 клиентов==. -- Метрика Sprint Review: использование, частота ошибок, NPS. -- Решение: состав следующего релиза по обратной связи. -- Особенность: регулярные релизы — естественный режим гибкой разработки. -::: - -::: callout "10. Банковские услуги — вклад «Цель»" -- Новый товар: вклад «Цель» в мобильном приложении. -- Пилотный спринт: тест на ==ограниченной группе пользователей==. -- Метрика Sprint Review: доля открытий, средний срок, удержание. -- Решение: полное внедрение после согласования с подразделениями банка. -- Особенность: пилот проводится в контролируемых регулируемых условиях. -::: - -::: notes -Последние две сферы. В IT новый модуль SaaS-платформы выходит в бету на десять клиентов: измеряют использование, частоту ошибок и NPS, а обратная связь определяет состав следующего релиза — это естественный режим гибкой разработки. В банковских услугах вклад «Цель» тестируется на ограниченной группе пользователей приложения: оценивают долю открытий, срок и удержание. Даже в регулируемой сфере пилот в контролируемых условиях позволяет безопасно проверить спрос до полного внедрения. -::: diff --git a/pptx/content/slides/10-conclusion.md b/pptx/content/slides/10-conclusion.md deleted file mode 100644 index a052590..0000000 --- a/pptx/content/slides/10-conclusion.md +++ /dev/null @@ -1,17 +0,0 @@ -# Выводы - -- Agile/Scrum — ==универсальный метод== выведения товара на рынок -- Спринты заменяют один дорогой запуск серией дешёвых проверок -- Роли, артефакты и события делают процесс прозрачным и управляемым -- Метод работает везде, где есть клиент и обратная связь — от производства до банков -- Результат — снижение риска и стоимости ошибки при запуске новинки - -::: metrics -10 | сфер применения -30% | новинок выживают -4 | недели — длина спринта -::: - -::: notes -Таким образом, Agile и Scrum — универсальный метод выведения товара на рынок. Спринты заменяют один дорогой запуск серией дешёвых проверок. Роли, артефакты и события делают процесс прозрачным и управляемым. Метод работает везде, где есть клиент и обратная связь: от производства до банковских услуг. Результат — снижение риска и стоимости ошибки при запуске новинки. -::: diff --git a/pptx/content/slides/11-final.md b/pptx/content/slides/11-final.md deleted file mode 100644 index 561018e..0000000 --- a/pptx/content/slides/11-final.md +++ /dev/null @@ -1,9 +0,0 @@ -# Спасибо за внимание - -Степанов П.А., группа 6403-020302D - -Слушатель программы профессиональной переподготовки «Современные проектные технологии», ИОТ-трек «ДОП 11» - -::: notes -На этом мой доклад закончен, спасибо за внимание. Готов ответить на ваши вопросы. -::: diff --git a/pptx/content/slides/12-scrum-cycle.md b/pptx/content/slides/12-scrum-cycle.md deleted file mode 100644 index 394dfd5..0000000 --- a/pptx/content/slides/12-scrum-cycle.md +++ /dev/null @@ -1,17 +0,0 @@ -# Жизненный цикл Scrum - -::: image assets/scrum-cycle.puml side=left -Цикл Scrum: от Product Backlog до масштабирования товара -::: - -::: callout "Как замкнут цикл" side=right -- Product Backlog фиксирует требования к товару. -- Спринт длится 1–4 недели и завершается готовым ==инкрементом==. -- Sprint Review показывает инкремент рынку, ретроспектива улучшает процесс. -- Подтверждённый спрос ведёт к масштабированию, иначе цикл повторяется. -- Каждый виток спирали снижает неопределённость и стоимость ошибки. -::: - -::: notes -На этой схеме слева показан цикл Scrum. Из Product Backlog формируется план спринта. Спринт длится от одной до четырёх недель и завершается инкрементом — готовым пробным продуктом. На Sprint Review рынок даёт обратную связь, после чего команда проводит ретроспективу. Если спрос подтверждён, товар масштабируется; если нет — цикл повторяется с уточнёнными требованиями. Каждый виток снижает неопределённость. -::: diff --git a/pptx/package-lock.json b/pptx/package-lock.json index e101935..79f20ef 100644 --- a/pptx/package-lock.json +++ b/pptx/package-lock.json @@ -1,18 +1,18 @@ { - "name": "lab-gen-pptx", + "name": "ssau-generator-pptx", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "lab-gen-pptx", + "name": "ssau-generator-pptx", "version": "1.0.0", "dependencies": { "js-yaml": "^4.1.0", "pptxgenjs": "^3.12.0" }, "bin": { - "lab-gen-pptx": "src/cli.js" + "ssau-generator-pptx": "src/cli.js" } }, "node_modules/@types/node": { diff --git a/pptx/package.json b/pptx/package.json index 9e7f179..2d12b16 100644 --- a/pptx/package.json +++ b/pptx/package.json @@ -1,10 +1,10 @@ { - "name": "lab-gen-pptx", + "name": "ssau-generator-pptx", "version": "1.0.0", "private": true, - "description": "Генератор презентаций PPTX из Markdown по шаблону Самарского университета", + "description": "SSAU Generator PPTX — генератор презентаций PPTX из Markdown по шаблону Самарского университета", "bin": { - "lab-gen-pptx": "src/cli.js" + "ssau-generator-pptx": "src/cli.js" }, "main": "src/index.js", "scripts": { diff --git a/pptx/src/cli.js b/pptx/src/cli.js index 24f968b..cd84a03 100644 --- a/pptx/src/cli.js +++ b/pptx/src/cli.js @@ -1,8 +1,10 @@ #!/usr/bin/env node "use strict"; +const fs = require("fs"); const path = require("path"); const { build } = require("./build"); +const { ensureScaffold } = require("./scaffold"); function parseArgs(argv) { const options = { config: "config.yaml" }; @@ -20,6 +22,9 @@ function parseArgs(argv) { case "--check": options.check = true; break; + case "--init": + options.init = true; + break; case "--verbose": case "-v": options.verbose = true; @@ -43,15 +48,16 @@ function parseArgs(argv) { } function printHelp() { - console.log(`lab-gen-pptx — генератор презентаций PPTX из Markdown + console.log(`SSAU Generator PPTX — генератор презентаций PPTX из Markdown Использование: - lab-gen-pptx [config.yaml] [опции] + node pptx/src/cli.js [config.yaml] [опции] Опции: -c, --config путь к config.yaml (по умолчанию config.yaml) -o, --output переопределить имя выходного файла --check только проверить конфигурацию и ссылки + --init создать шаблон config.yaml/slides/assets и выйти -v, --verbose подробный вывод -h, --help показать справку --version показать версию @@ -68,6 +74,26 @@ async function main() { } const configPath = path.resolve(options.config); + + if (options.init || !fs.existsSync(configPath)) { + const targetDir = path.dirname(configPath); + try { + const created = await ensureScaffold(targetDir); + if (created.length) { + console.log("Создан шаблон генератора:"); + created.forEach((file) => console.log(" " + path.relative(targetDir, file))); + } else { + console.log("Файлы уже существуют, ничего не создано."); + } + console.log(""); + console.log("Отредактируйте config.yaml и файлы в slides/, затем запустите генератор снова."); + } catch (error) { + console.error(error.message); + process.exitCode = 1; + } + return undefined; + } + try { const result = await build({ config: configPath, check: options.check, output: options.output }); const { config, issues } = result; diff --git a/pptx/src/config.js b/pptx/src/config.js index 448a3d4..2f54763 100644 --- a/pptx/src/config.js +++ b/pptx/src/config.js @@ -24,9 +24,9 @@ const DEFAULTS = { line: "BFD3DD", }, backgrounds: { - title: "content/assets/title-bg.jpeg", - content: "content/assets/content-bg.jpg", - final: "content/assets/final-bg.jpeg", + title: "assets/title-bg.jpeg", + content: "assets/content-bg.jpg", + final: "assets/final-bg.jpeg", }, slideNumber: { show: true, @@ -110,7 +110,7 @@ const DEFAULTS = { timeoutMs: 30000, }, content: { - dir: "content", + dir: ".", }, slides: [], }; diff --git a/pptx/src/plantuml.js b/pptx/src/plantuml.js index 2d79d4b..19f246d 100644 --- a/pptx/src/plantuml.js +++ b/pptx/src/plantuml.js @@ -114,7 +114,7 @@ function cacheFileName(sourceBuffer, cfg) { } async function renderCached(sourceBuffer, cfg) { - const dir = cfg.cacheDir || path.join(os.tmpdir(), "lab-gen-pptx-plantuml"); + const dir = cfg.cacheDir || path.join(os.tmpdir(), "ssau-generator-pptx-plantuml"); const target = path.join(dir, cacheFileName(sourceBuffer, cfg)); if (cfg.cache && fs.existsSync(target)) { diff --git a/pptx/src/png.js b/pptx/src/png.js new file mode 100644 index 0000000..4e8d6f0 --- /dev/null +++ b/pptx/src/png.js @@ -0,0 +1,68 @@ +"use strict"; + +const zlib = require("zlib"); + +const CRC_TABLE = (() => { + const table = new Int32Array(256); + for (let n = 0; n < 256; n += 1) { + let c = n; + for (let k = 0; k < 8; k += 1) { + c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1; + } + table[n] = c; + } + return table; +})(); + +function crc32(buffer) { + let crc = -1; + for (let i = 0; i < buffer.length; i += 1) { + crc = CRC_TABLE[(crc ^ buffer[i]) & 0xff] ^ (crc >>> 8); + } + return (crc ^ -1) >>> 0; +} + +function chunk(type, data) { + const length = Buffer.alloc(4); + length.writeUInt32BE(data.length, 0); + const typeBuf = Buffer.from(type, "ascii"); + const crc = Buffer.alloc(4); + crc.writeUInt32BE(crc32(Buffer.concat([typeBuf, data])), 0); + return Buffer.concat([length, typeBuf, data, crc]); +} + +/** Кодирует PNG, получая цвет пикселя через getPixel(x, y) -> [r,g,b]. */ +function encodePng(width, height, getPixel) { + const signature = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]); + const ihdr = Buffer.alloc(13); + ihdr.writeUInt32BE(width, 0); + ihdr.writeUInt32BE(height, 4); + ihdr[8] = 8; + ihdr[9] = 2; + + const rowLength = width * 3; + const raw = Buffer.alloc((rowLength + 1) * height); + for (let y = 0; y < height; y += 1) { + const offset = y * (rowLength + 1); + for (let x = 0; x < width; x += 1) { + const [r, g, b] = getPixel(x, y); + const px = offset + 1 + x * 3; + raw[px] = r; + raw[px + 1] = g; + raw[px + 2] = b; + } + } + + return Buffer.concat([ + signature, + chunk("IHDR", ihdr), + chunk("IDAT", zlib.deflateSync(raw, { level: 9 })), + chunk("IEND", Buffer.alloc(0)), + ]); +} + +function solidPng(width, height, color) { + return encodePng(width, height, () => color); +} + +module.exports = { solidPng, encodePng }; diff --git a/pptx/src/scaffold.js b/pptx/src/scaffold.js new file mode 100644 index 0000000..a160768 --- /dev/null +++ b/pptx/src/scaffold.js @@ -0,0 +1,115 @@ +"use strict"; + +const fs = require("fs"); +const path = require("path"); +const yaml = require("js-yaml"); + +const { DEFAULTS, deepMerge } = require("./config"); +const { solidPng } = require("./png"); + +const CONFIG_HEADER = `# Конфигурация генератора SSAU Generator PPTX. +# Все относительные пути считаются от каталога этого файла. +# Любой ключ можно опустить — будет использовано значение по умолчанию. + +`; + +const SAMPLE = { + "slides/00-title.md": `# Название презентации + +## Подзаголовок +`, + "slides/01-content.md": `# Первый слайд + +- первый пункт списка; +- второй пункт списка: + + - вложенный пункт; + +Обычный абзац с **полужирным**, *курсивом* и ==выделением==. +`, + "slides/02-final.md": `# Спасибо за внимание +`, +}; + +// Цвета задников: [R, G, B]. +const BRAND = [27, 135, 201]; +const BACKGROUNDS = { + "title-bg.png": BRAND, + "content-bg.png": [255, 255, 255], + "final-bg.png": BRAND, +}; + +function isGeneratorDir(baseDir) { + const base = path.basename(baseDir).toLowerCase(); + return base === "docx" || base === "pptx"; +} + +/** + * Раскладка проекта: имя проекта = имя папки проекта, общие ресурсы в + * content/<проект>/assets/, результат — content/<проект>/<проект>.pptx. + */ +function projectLayout(baseDir) { + const isSub = isGeneratorDir(baseDir); + const projectDir = isSub ? path.dirname(baseDir) : baseDir; + const projectName = path.basename(projectDir) || "project"; + return { + projectDir, + projectName, + assetsRel: isSub ? "../assets" : "assets", + assetsDir: path.join(projectDir, "assets"), + outputRel: isSub ? `../${projectName}.pptx` : `${projectName}.pptx`, + }; +} + +function defaultConfigYaml(layout) { + const config = deepMerge(DEFAULTS, { + presentation: { output: layout.outputRel }, + theme: { + backgrounds: { + title: `${layout.assetsRel}/title-bg.png`, + content: `${layout.assetsRel}/content-bg.png`, + final: `${layout.assetsRel}/final-bg.png`, + }, + }, + content: { dir: "." }, + slides: [ + { type: "title", file: "slides/00-title.md" }, + { type: "content", file: "slides/01-content.md" }, + { type: "final", file: "slides/02-final.md" }, + ], + }); + return ( + CONFIG_HEADER + + yaml.dump(config, { noRefs: true, lineWidth: -1, sortKeys: false }) + ); +} + +/** + * Создаёт config.yaml, примеры слайдов и общие ресурсы проекта + * (content/<проект>/assets/), если их ещё нет. + */ +async function ensureScaffold(baseDir) { + const layout = projectLayout(baseDir); + const created = []; + const write = (target, content) => { + if (fs.existsSync(target)) return; + fs.mkdirSync(path.dirname(target), { recursive: true }); + if (content && typeof content === "object" && content.binary) { + fs.writeFileSync(target, content.binary); + } else { + fs.writeFileSync(target, content, "utf8"); + } + created.push(target); + }; + + write(path.join(baseDir, "config.yaml"), defaultConfigYaml(layout)); + for (const [name, content] of Object.entries(SAMPLE)) { + write(path.join(baseDir, name), content); + } + for (const [name, color] of Object.entries(BACKGROUNDS)) { + write(path.join(layout.assetsDir, name), { binary: solidPng(1920, 1080, color) }); + } + return created; +} + +module.exports = { projectLayout, defaultConfigYaml, ensureScaffold, SAMPLE }; diff --git a/video-script.md b/video-script.md deleted file mode 100644 index e4d9f8f..0000000 --- a/video-script.md +++ /dev/null @@ -1,98 +0,0 @@ -# Сценарий видеодоклада (≈5 минут) - -Докладчик: **Степанов П.А.**, группа **6403-020302D**, ИОТ-трек **«ДОП 11»**, -программа **«Современные проектные технологии»**. -Слайды — файл `pptx/presentation.pptx` (заметки докладчика дублируют этот текст). - ---- - -## 0:00–0:20. Приветствие (с паспортом) - -> Добрый день, уважаемые члены итоговой аттестационной комиссии. Меня зовут -> Степанов П.А. *(показать в камеру разворот паспорта)*, группа 6403-020302D, я -> являюсь слушателем программы профессиональной переподготовки «Современные -> проектные технологии», ИОТ-трек «ДОП 11». Разрешите представить решение -> итогового задания по теме «Современные проектные технологии». - -*(Слайд 1 — титульный.)* - -## 0:20–0:45. План доклада - -Сначала обосную выбор метода, затем покажу устройство методологии, проверку -спроса через спринты и применение в десяти сферах деятельности. *(Слайд 2.)* - -## 0:45–1:20. Постановка задачи - -Задача итогового задания — выбрать метод выведения нового товара на рынок и -обосновать его применимость в десяти сферах деятельности. Запуск новинки всегда -сопряжён с риском: до семи из десяти новых товаров не выживают на рынке. Поэтому -нужен управляемый и повторяемый процесс. В качестве такого метода я выбрал Agile -и его самую популярную методологию — Scrum. *(Слайд 3.)* - -## 1:20–2:30. Метод: Agile и Scrum - -Agile — это гибкий подход к управлению проектами, закреплённый в манифесте -2001 года. Scrum — самая распространённая Agile-методология. Работа разбивается на -короткие спринты длиной от одной до четырёх недель, каждый из которых завершается -готовым приростом продукта. *(Слайд 4.)* - -В Scrum три роли: Product Owner отвечает за ценность товара, Scrum Master убирает -препятствия, команда разработки создаёт продукт. Три артефакта — Product Backlog, -Sprint Backlog и Increment. Четыре события — планирование, ежедневная встреча, -обзор спринта и ретроспектива. *(Слайды 5–6.)* - -Весь цикл замкнут: из Product Backlog формируется спринт, который завершается -инкрементом; Sprint Review показывает результат рынку, а подтверждённый спрос ведёт -к масштабированию. *(Слайд 7.)* - -Ключевое преимущество: рынок проверяется дешёвым инкрементом — сначала минимальный -продукт, затем развитие по отклику реальных клиентов. *(Слайд 8.)* - -## 2:30–4:10. Применение в десяти сферах - -Покажу, что метод работает не только в IT. *(Слайд 9.)* В каждой сфере — свой -пилотный инкремент и своя метрика спринта. - -- **Производство** — линейка упаковки запускается пробной партией на одной линии; - метрики — себестоимость и доля брака. **Связь** — тариф «Умный дом» тестируется - на ста абонентах; смотрят подключения и отток. *(Слайд 10.)* -- **Транспорт** — каршеринг мини-фургонов стартует с пяти машин в одном районе; - метрики — загрузка и спрос. **Строительство** — сначала возводится один пилотный - модуль; оценивают затраты и сроки монтажа. *(Слайд 11.)* -- **Коммерция** — подписка на продуктовые наборы запускается бокс-пилотом на - пятидесяти клиентах; метрики — конверсия и удержание. **Юридические услуги** — - пакет «юрфирма на аутсорсе» предлагается пяти клиентам на пробный месяц. - *(Слайд 12.)* -- **Организация праздников** — онлайн-конструктор тестируется на одной группе по - вовлечённости и заказам. **Бытовые услуги** — подписка на уборку стартует с - двадцати подписчиков; важны удержание и загрузка. *(Слайд 13.)* -- **IT-услуги** — новый модуль SaaS выходит в бету на десять клиентов; метрики — - использование и NPS. **Банковские услуги** — вклад «Цель» тестируется на - ограниченной группе приложения. *(Слайд 14.)* - -Везде логика одна: ограниченный пробный продукт — замер метрики на Sprint Review — -масштабирование. - -## 4:10–4:45. Выводы - -Agile и Scrum — универсальный метод выведения товара на рынок. Спринты заменяют -один дорогой запуск серией дешёвых проверок. Метод работает везде, где есть клиент -и обратная связь: от производства до банковских услуг. Результат — снижение риска -и стоимости ошибки при запуске новинки. *(Слайд 15.)* - -## 4:45–5:00. Заключение - -> На этом мой доклад закончен, спасибо за внимание. - -*(Слайд 16.)* - ---- - -## Чек-лист записи - -- [ ] В начале доклада — **демонстрация паспорта** в камеру. -- [ ] В кадре одновременно видны **вы и презентация**. -- [ ] Приветствие, основная часть и заключение — по формулировкам выше. -- [ ] Формат файла — **mp4**, имя: `Видео защита Фамилия И.О.mp4`. -- [ ] Загрузить в облако: https://disk.ssau.ru/s/s8dSapsJ7bbn8yb -- [ ] PDF ответа: `Итоговое задание Фамилия И.О.pdf` — в «Материалы итогового задания».