TreeMap
무료 오픈소스 디스크 사용량 시각화 도구로, 사각형 트리맵·중복 파일 탐색·디스크 가득 예측·정리 시 파일을 휴지통으로만 이동한다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
EX-EL — Набор инструментов для работы с документами Результат — release/mac/Apps4Excel.app. Результат — release/Apps4Excel-1.0.0.dmg. Примечание: DMG собирается через встроенный hdiutil. Скрипт scripts/build-dmg-only.sh создаёт DMG с ярлыком Applications для стандартной установки перетаскиванием. Если нужно собрать только DMG из уже готового .app:README 전문 보기 ↗
Набор офисных инструментов: сравнение, конвертация и правка Excel, Word, PDF, PowerPoint, HTML и изображений, плюс несколько игр. Это одностраничное веб-приложение (React + Vite), которое выкладывается мэшапом в Qlik Sense.
Главный принцип — всё работает в браузере пользователя. Серверной части нет, файлы никуда не отправляются, интернет не нужен. Сервер только раздаёт статические файлы сборки. Тяжёлые движки (распознавание текста, нейросеть удаления фона, Python для PDF → PowerPoint) лежат рядом со сборкой и работают через WebAssembly.
git clone <url-репозитория>
cd app4docs
npm install
npm run dev # http://localhost:5173 (порт можно задать переменной PORT)
| Команда | Что делает |
|---|---|
npm run dev | Сервер разработки Vite |
npm run build | Сборка в dist/ |
npm run preview | Локальный просмотр собранной версии |
npm run lint | ESLint |
npx tsc -b | Проверка типов (в npm run build не входит) |
В корпоративной сети с подменой сертификатов может понадобиться .npmrc в
корне проекта (файл в .gitignore):
strict-ssl=false
npm run build # → dist/ (~146 МБ, из них ~137 МБ — движки)
node dist-utils/index.cjs # → unit-app-light.zip в корне проекта
dist-utils/index.cjs упаковывает сборку в расширение-мэшап:
dist/ описание unit-app-light.qext (type mashup, версия 0.1.0.0);wbfolder.wbl;dist/ в unit-app-light.zip (~72 МБ).⚠️
dist-utils/в.gitignore— в репозитории его нет, утилиту передают отдельно. Без неё мэшап собирается вручную: положить вdist/файлunit-app-light.qextс полями выше и заархивировать содержимоеdist/.
Архив импортируется в QMC: Extensions → Import (при обновлении расширение
заменяется). Приложение открывается по адресу
https://<сервер>/[<префикс прокси>/]extensions/unit-app-light/index.html.
Что важно знать о сервере Qlik. Сборка уже приспособлена к его ограничениям, отдельно настраивать сервер не нужно:
| Ограничение сервера | Как обходит сборка |
|---|---|
| Отдаёт только разрешённые типы файлов (иначе HTTP 415) | В сборке только .html .js .css .json .txt .svg; шрифты встроены в CSS |
| Файрвол режет «опасные» слова и расширения в адресе (403) | Файлы движков названы нейтральными хэшами xxxxxxxx_N.txt |
| Файрвол читает тело ответа (403) | Двоичные файлы движков лежат gzip → HEX-текстом (только 0-9a-f) |
| Файрвол режет большие ответы | Части не больше 6 МБ |
Подробно механизм описан ниже в разделе «PDF → PowerPoint», общий загрузчик —
src/utils/chunkedAssets.ts.
Настройки сборки (vite.config.ts): base: './' — пути относительные,
сборку можно положить в любую папку; маршрутизация через HashRouter
(index.html#/PdfEditor) — переписывать адреса на сервере не нужно; имена
JS/CSS с хэшем содержимого — не кэшировать нужно только index.html.
Content-Security-Policy портала. Если она включена, для всех инструментов
нужны: script-src 'self' 'wasm-unsafe-eval' (WebAssembly), worker-src 'self'
(фоновые потоки), connect-src 'self' (загрузка движков), img-src 'self' data: blob:
(превью). Шахматы и шашки при заблокированном потоке считают ход на самой
странице (src/games/engineRunner.ts), остальные инструменты с потоками без
него не работают.
Проверка после выкладки: главная открывается без ошибок 403/415 в консоли (F12); компьютер в шахматах отвечает на ход; OCR скана в конвертере документов; удаление фона в конвертере изображений; PDF → PowerPoint на небольшом файле; открытие XLSX в Excel-группираторе.
| Что | Версия |
|---|---|
| Node.js (сборка) | ≥ 20.19 или ≥ 22.12 |
| npm | ≥ 10 |
| Браузер | Современный Chromium (Edge, Chrome, Яндекс); IE и режим IE не поддерживаются |
| Протокол | HTTPS — без него не работают Cache Storage и проверка SHA-256 движков |
package-lock.json в .gitignore, а у большинства зависимостей версии с ^,
поэтому сборки на разных машинах могут отличаться. Точно закреплены версии,
от которых зависят файлы в public/: onnxruntime-web, а также CodeMirror и acorn.
app4docs/
├── index.html # точка входа Vite
├── vite.config.ts # base './', шрифты в CSS, имена чанков
├── src/
│ ├── index.tsx # запуск React, HashRouter, тема
│ ├── routes.tsx # все маршруты
│ ├── pages/
│ │ ├── HomePage.tsx # главная: карточки инструментов, опрос, ссылки
│ │ └── <Инструмент>/ # страница + engine/ или core/ (логика без React)
│ ├── components/ # общие: PageShell, модальные окна, тема
│ ├── games/ # движки шахмат и шашек, EngineRunner
│ ├── workers/ # фоновые потоки Excel (разбор, экспорт)
│ ├── utils/ # chunkedAssets (загрузка движков), bgRemoval, pdfWorker
│ ├── styles/ # токены, компоненты, тёмная тема, шрифты
│ └── assets/fonts/ # Inter, Liberation Sans (для PDF)
├── public/ # копируется в dist как есть
│ ├── aibg/ # нейросеть удаления фона (~57 МБ)
│ ├── ocr/ # Tesseract + языки rus/eng (~15 МБ)
│ └── pdf2pptx/ # Pyodide + движок PDF → PowerPoint (~65 МБ)
└── scripts/
├── vendor-*.mjs # переупаковка движков в public/ (нужен интернет)
└── offer-check.ts # стенд проверки движка оферт на настоящих DOCX
Движки в public/ уже лежат в репозитории; скрипты vendor-*.mjs нужны только
при их обновлении.
| Задача | Библиотеки |
|---|---|
| Интерфейс | React 19, react-router 7, TypeScript 5.8, Vite 7 |
| Excel | exceljs |
| PDF: чтение и отрисовка | pdfjs-dist 5 |
| PDF: запись | pdf-lib + @pdf-lib/fontkit, jsPDF |
| Word | docx, docx-preview, mammoth |
| PPTX, DOCX как пакеты | JSZip + собственный разбор XML |
| Изображения | ag-psd, html-to-image, html2canvas |
| Графики | Recharts |
| Распознавание текста (OCR) | tesseract.js 7 (WebAssembly) |
| Нейросеть удаления фона | onnxruntime-web 1.22.0 (WebAssembly) |
| Python в браузере | Pyodide 0.28.3, PyMuPDF, python-pptx |
| Редактор кода, разбор JS | CodeMirror 6, acorn |
| Прочее | file-saver, react-rnd |
Ни одна библиотека не грузится с CDN во время работы — всё входит в сборку.
Каждый инструмент — страница src/pages/<Имя>/ со своим маршрутом в
src/routes.tsx и карточкой на главной (src/pages/HomePage.tsx). Метка
«Тест» на карточке (isTest: true) означает опытную эксплуатацию.
| Инструмент | Маршрут | Что делает |
|---|---|---|
| HTML-редактор (тест) | #/HtmlStudio | Правка HTML-отчётов от ИИ: тексты, блоки, таблицы, данные графиков, цвета |
| Перенос в шаблон | #/PptxRestyle | Перекладывает презентации в корпоративный шаблон: фон, шрифты, цвета |
| PDF → PowerPoint | #/PdfToPptx | Редактируемая презентация из PDF |
| Сравнение Excel/Word/PDF | #/compare | Excel — по ячейкам с выравниванием строк, Word и PDF — по абзацам и таблицам |
| HTML/JSON-таблицы → Excel | #/htmlToExcel | Находит таблицы в HTML или JSON и выгружает в XLSX со стилями |
| Конвертер изображений | #/ImageConverter | SVG, PNG, JPG, WebP, GIF, BMP, PDF, PSD → PNG, JPEG, WebP, BMP, ICO, PDF; удаление фона |
| PDF Studio | #/PdfEditor | Объединение, порядок, повороты, подписи, вымарывание, OCR, формы, сжатие |
| Excel-группиратор | #/ExcelTableBuilder | Объединяет несколько Excel-файлов по ключам с пометкой файла-источника |
| Генератор графиков | #/ChartCraft | Графики из XLSX/CSV или вставки из Excel; экспорт в PNG, SVG, HTML |
| Конвертер документов | #/PdfToWord | PDF ↔ Word, распознавание сканов |
| Объединение изменений в оферту | #/OfferMerge | Собирает правки из нескольких DOCX и обновляет текст оферты |
| Сравнение по рабочим местам | #/WorkplaceCompare | Сверка двух Excel-выгрузок рабочих мест (АС «Друг») с фильтрами |
| Игры | #/Chess, #/Checkers, #/ChessLessons, #/SnakeGame, #/DocMatchGame | Шахматы и шашки против компьютера, уроки шахмат, змейка |
Старые адреса #/Svg2Png и #/JpgToPdfPage открывают конвертер изображений.
Загружаете две Excel-выгрузки по рабочим местам — позиции сопоставляются автоматически, изменения подсвечиваются: 🔴 было, 🟢 стало, 🔵 новая, 🟡 удалена. Фильтры строятся по данным, результат выгружается в Excel.
Сравнивает любые пары: Excel с Excel, Word и PDF в любом сочетании (например, подписанный PDF с исходным .docx). Excel сравнивается по ячейкам; удалённая или вставленная строка не сдвигает сравнение остальных — строки выравниваются. Word и PDF — по абзацам и таблицам. Текст PDF собирается в абзацы, колонтитулы и номера страниц отбрасываются, переносы склеиваются, таблицы с видимыми границами распознаются как таблицы; у каждого различия указана страница. Скан без текстового слоя сравнить нельзя — об этом выводится сообщение.
Вставляете HTML-код страницы (сохранить страницу — Ctrl+S) или JSON — инструмент находит все таблицы и показывает предпросмотр. Можно выбрать таблицы, отфильтровать строки и колонки и выгрузить в Excel с сохранением стилей. Таблицы, которые страница дорисовывает скриптом, в сохранённом HTML могут отсутствовать.
Объединяет несколько Excel-файлов (выгрузки за разные периоды или от разных подразделений) в одну таблицу:
1.1. Высшее, 2.1. Среднее специальное;
ячейки с разделителями (, ; ;) разбиваются и нумеруются.Палитра проверена на различимость при нарушениях цветовосприятия, цвета не повторяются. Пустые ячейки не превращаются в нули, даты сортируются по времени, числа с пробелами, запятой, ₽ и % читаются как числа. Холст: несколько графиков, стрелки, рамки, надписи, мини-карта, отмена любого действия (Ctrl+Z / Ctrl+Y). Горячие клавиши: V — выбор, P — карандаш, A — стрелка, R — рамка, T — надпись, E — ластик, 0 — вписать холст.
Разбирает документы с инструкциями изменений (алгоритмом, без ИИ) и применяет
их к тексту оферты: сноски, пункты, новые редакции, строки таблиц. Правки
выделяются цветом или записываются как исправления Word. Движок —
src/pages/OfferMerge/engine/, стенд для прогона на настоящих документах —
scripts/offer-check.ts.
src/pages/PdfToPptx/)Страница #/PdfToPptx. Каждая страница PDF становится слайдом того же
размера: текст — текстовыми блоками, картинки — картинками, графика —
фигурами PowerPoint. Режим «точная копия» — фон картинкой + текст поверх.
Движок — Python-проект pdf2pptx
(PyMuPDF + python-pptx). В браузере он запускается без изменений через
Pyodide — CPython, собранный в WebAssembly, — в
фоновом потоке (src/pages/PdfToPptx/pdf2pptx.worker.ts). Результат
совпадает с серверной версией байт в байт.
Всё нужное лежит в public/pdf2pptx/ и попадает в dist/ как есть:
runtime/ — Pyodide 0.28.3 и wasm-колёса (PyMuPDF, lxml, Pillow, python-pptx); в hex ~64 МБ;engine/ — Python-код движка;manifest.json — список файлов и коммит движка.Содержимое файлов — hex, под ограничения Qlik. У сервера Qlik Sense несколько проверок, и все срабатывали на файлах движка:
HTTP 415.FilterOther) отвечает HTTP 403,
если в адресе есть «архивное» расширение (.zip, .whl…) или опасное
слово (scr…pt — XSS-шаблон, ловит даже scrpt).Поэтому:
0-9a-f + .txt, напр. e7eec9cb_0.txt): ни
слова, ни расширения..wasm, .whl, .zip, .py) кодируется
в hex (символы 0-9a-f). В таком тексте физически нет ни <, ни кавычек,
ни ../, ни слов script/select/union — нужных символов просто нет,
поэтому ни одно правило WAF не срабатывает. Заодно hex не содержит
zip-структуры (почтовый шлюз не пересобирает) и не является base64 (письмо не
блокируется). Цена — вдвое больший объём (среда ~64 МБ), но это одноразовая
загрузка в кэш.…_0.txt, …_1.txt, … .Соответствие «логическое имя → реальные файлы» задаёт manifest.json (store);
воркер (engineAssets.makeCachedFetch) находит по нему файлы, качает части,
склеивает, сверяет с манифестом (размер и SHA-256) и декодирует hex обратно в
байты, проставляя нужный content-type. pyodide.mjs (ES-модуль, грузится по
своему имени) → pyodide.loader.js; pyodide.asm.js и pyodide-lock.json
отдаются как есть. Все имена и части создаёт scripts/vendor-pdf2pptx.mjs.
Интернет не нужен: файлы движка входят в сборку и грузятся с того же сервера, что и приложение (внешних запросов нет — проверено с полностью закрытым интернетом).
Файлы кладутся в Cache Storage браузера под ключом версии
(src/pages/PdfToPptx/engineAssets.ts), поэтому скачиваются один раз — даже
если хостинг запрещает HTTP-кэширование (Cache-Control: no-store). Главная
страница тихо подкачивает их в фоне через несколько секунд простоя, так что к
открытию инструмента скачивать уже нечего; при обновлении движка старая версия
из кэша удаляется. Cache Storage работает только по https (или localhost) —
по http движок просто грузится без постоянного кэша.
# код движка из соседнего клона ../pdf2pptx (или --engine-dir <путь>)
node scripts/vendor-pdf2pptx.mjs
# пересобрать среду Pyodide и колёса (нужен интернет: npm, PyPI, cdn.jsdelivr.net)
node scripts/vendor-pdf2pptx.mjs --runtime --force
Версии колёс жёстко связаны с Pyodide (ABI pyodide_2025_0, Python 3.13) —
обновлять их нужно вместе, в одном месте: начало скрипта.
.txt, .js, .json), отдельная настройка списка расширений в QMC
не нужна (см. «Содержимое файлов — hex, под ограничения Qlik» выше)..wasm не как application/wasm, фоновый поток сам
исправляет тип — отдельно настраивать Qlik не нужно.script-src 'wasm-unsafe-eval'. Движок распознаёт этот случай и пишет об
этом прямо в ошибке..woff2, поэтому шрифт Inter (латиница и кириллица)
встраивается прямо в CSS (src/styles/fonts.css, assetsInlineLimit в
vite.config.ts) — отдельных файлов шрифтов в сборке нет.manifest.json записаны размер и SHA-256 каждого файла движка. Если файл
изменился по дороге (почтовый шлюз, антивирус, архиватор), ошибка назовёт
его и покажет, сколько байт пришло и сколько ожидалось. Испорченная копия
в кэше браузера удаляется и скачивается заново.src/pages/PdfToWord/)Маршрут #/PdfToWord. Всё работает в браузере, без сервера и интернета.
src/pages/PdfToWord/engine/)PDF хранит не абзацы, а фрагменты текста с координатами, поэтому документ восстанавливается по геометрии страницы:
extract.ts — текст с настоящими шрифтами (pdf.js отдаёт внутренние имена
вида g_d0_f1, настоящее имя TimesNewRomanPS-BoldMT берётся из объекта
шрифта → гарнитура, жирный, курсив), фрагменты режутся на слова; цвет слова —
по отрисованной странице; линии (залитые тонкие прямоугольники и обводки),
заливки, фигуры и картинки — из списка операций до отрисовки (после неё
pdf.js заменяет контуры объектами Path2D).tables.ts — таблицы по линиям сетки: объединённые ячейки (там, где между
ячейками нет линии), заливка ячеек, цвет и толщина рамки.layout.ts — колонтитулы, подчёркивание/зачёркивание, нарисованные маркеры
списков, плашки под текстом, векторные графики (картинкой вместе с
подписями), колонки (вертикальные «коридоры» без текста), абзацы
(межстрочный шаг, красная строка, правило «следующее слово поместилось бы —
значит, конец абзаца»), выравнивание, отступы, интервалы, заголовки,
таблицы без рамок по выровненным столбцам.index.ts — два прохода (сначала колонтитулы по всем страницам), склейка
абзацев и таблиц через границу страниц, разрывы страниц, поля документа.docx.ts — сборка .docx: размер и поля страниц, разделы с колонками,
колонтитулы с полями номера страницы, стили «Заголовок 1–3».Сканы (engine/ocr.ts) распознаются Tesseract (tesseract.js, Apache-2.0;
модели русского и английского LSTM 4.0.0_best_int). Страница выравнивается
по наклону, линии таблиц и подчёркивания находятся на растре и стираются
перед повторным распознаванием (иначе сетка превращается в «мусор»), таблица
строится тем же движком по найденным линиям; жирный — по толщине штриха;
печати, подписи и фото вне текста — картинками.
Файлы распознавания лежат в public/ocr/ (~15 МБ) и доставляются как движок
PDF → PowerPoint: JS-файлы под нейтральными именами xxxxxxxx.js, модели —
HEX-текстом частями xxxxxxxx_N.txt, всё сверяется с manifest.json
(размер, SHA-256) и кэшируется в браузере (src/utils/chunkedAssets.ts).
Без blob-потоков. Пересобрать: node scripts/vendor-ocr.mjs (берёт файлы
из node_modules; заодно правит одну ошибку tesseract.js 7 с языками,
переданными байтами). При выкладке в QlikSense папку ocr кладут рядом с
index.html, как pdf2pptx.
src/pages/PdfToWord/word2pdf/)PAGE/NUMPAGES заменяются метками и заполняются на
каждой странице; колонтитулы наследуются от предыдущего раздела, как в Word.foreignObject, запасной вариант —
html2canvas) и кладётся в PDF; поверх — невидимый текстовый слой (шрифт
Liberation Sans, SIL OFL 1.1), поэтому в PDF работают поиск и копирование.src/utils/pdfWorker.ts — общий поток pdf.js для всех PDF-инструментов. В его
код дописаны полифиллы Math.sumPrecise и Map.getOrInsert(Computed):
pdfjs-dist 5 вызывает их внутри потока при разборе встроенных шрифтов, а без
них шрифты PDF не загружаются (текст рисуется запасным шрифтом).
Партия с компьютером прямо в браузере, без сервера и без внешних библиотек —
работает и в закрытой сети. Все игры открываются одной кнопкой «🎮 Игры» внизу
главной страницы (маршруты #/Chess, #/ChessLessons, #/Checkers).
Уроки шахмат (#/ChessLessons) — 12 уроков для тех, кто никогда не играл:
доска и названия полей, как ходит каждая фигура, взятие, шах и защита от
него, мат, рокировка, взятие на проходе, пат и мат ферзём/ладьёй против
компьютера. В каждом — короткое объяснение и задание на доске: найти поле,
собрать звёзды фигурой за минимум ходов, съесть фигуры, найти верный ход
(с объяснением, почему другой ход не подходит). Есть подсказки, пропуск
задания и прогресс, который сохраняется в браузере. Все задания проверяются
скриптом: решения верные, минимум ходов совпадает с заявленным.
Общее для обеих игр
src/games/engineRunner.ts), а в
консоли появляется строка [engine] … с причиной.Шахматы — все правила: рокировка, взятие на проходе, превращение пешки (с выбором фигуры), мат, пат, ничья по 50 ходам, троекратному повторению и недостатку материала. Ходы — перетаскиванием или кликами, нотация с русскими буквами фигур (Кр, Ф, Л, С, К). На уровнях 4–6 показывается оценка позиции.
Русские шашки — бить обязательно (простые бьют и назад), взятие до конца, турецкий удар, дамка ходит и бьёт на любое расстояние, простая, дошедшая до края во время взятия, продолжает бить дамкой. Ничья — 15 ходов только дамками без взятий или троекратное повторение. Шашки, которые обязаны бить, подсвечиваются; многоходовое взятие отмечается по полям.
Как устроено
src/games/chess/engine.ts — доска 0x88, генератор ходов проверен
perft-тестами (6 эталонных позиций, до 4,8 млн узлов), поиск альфа-бета с
итеративным углублением, таблицей перестановок, нулевым ходом, LMR и
форсированным поиском взятий; оценка — материал, позиционные таблицы,
пешечная структура, добивание в эндшпиле.src/games/checkers/engine.ts — генератор ходов по правилам русских шашек
и альфа-бета с продлением, пока есть обязательные взятия.levels.ts рядом с движками, уроки — в
src/games/chess/lessons.ts (каждый шаг — позиция FEN и тип задания).src/pages/PdfEditor/)Объединение, порядок, повороты, правки страниц, подписи, распознавание и сжатие — целиком в браузере.
core/build.ts: копии исходных страниц (формы заполнены
и «сплющены» шрифтом с кириллицей), поворот, затем распознанный текст и
аннотации, обрезка полей / вписывание в A4, номера страниц и водяной знак.core/geometry.ts: всё рисуется в системе отображаемой
страницы (X вправо, Y вверх) и переводится матрицей с учётом /Rotate и
CropBox. Аннотации — в повороте самой страницы (как в редакторе), номера и
водяной знак — в итоговой ориентации.src/assets/fonts/ — урезан до латиницы и кириллицы (~47 КБ), встраивается
через @pdf-lib/fontkit. Тот же шрифт в редакторе, поэтому переносы строк
совпадают.core/ocr.ts, движок конвертера документов
(PdfToWord/engine/ocr.ts) без выравнивания наклона, чтобы слова легли на
свои места; слой — текст с режимом отрисовки 3 (невидимый).getFieldObjects), значения кладутся в
его annotationStorage для миниатюр и заполняются pdf-lib при сборке.components/PageView.tsx).components/SignatureLibrary.tsx: рисование, загрузка с
удалением белого фона, библиотека в localStorage.Кнопка ✂️ на карточке изображения и «Убрать фон у всех». Окно —
src/pages/ImageConverter/components/BackgroundRemover.tsx, общий код —
src/utils/bgRemoval/:
aiWorker.ts). Вход
320×320; грубая маска доводится guided filter по исходнику, поэтому волосы
и мягкие края получают полупрозрачность.Файлы нейросети лежат в public/aibg/ (~57 МБ) и попадают в dist/aibg/ —
их нужно выкладывать вместе с приложением. Доставка как у pdf2pptx: gzip →
HEX-текст → части до 6 МБ с нейтральными именами xxxxxxxx_N.txt, проверка
SHA-256 по manifest.json, кэш в Cache Storage. Служебный JS-модуль движка
подключается обычным файлом (aibg/xxxxxxxx.js), а не blob-ссылкой, поэтому
работает и при строгой политике безопасности (CSP) портала.
Пересобрать файлы (например, после обновления onnxruntime-web):
node scripts/vendor-aibg.mjs # скачать модель и упаковать
node scripts/vendor-aibg.mjs --model silueta.onnx # взять модель с диска
Версия onnxruntime-web в package.json закреплена точно (1.22.0): служебный
модуль в public/aibg/ собран из неё.
src/pages/PptxRestyle/)Перекладывает презентации в новый корпоративный шаблон: фон, шрифты, цвета и место заголовков берутся из шаблона, содержимое — из исходников. Несколько файлов собираются в одну презентацию (каждый — разделом). Всё в браузере.
Движок — engine/ (JSZip + DOM, без сторонних библиотек PowerPoint):
template.ts — анализ шаблона. Шаблон может быть «настоящим» (оформление
в макетах) или набором слайдов-примеров (фон-картинка и шрифты прямо на
слайдах, как у фирменных шаблонов). Находятся фоны и их роли (титульный,
основной, раздел, финальный), шрифт, кегль, цвет и место заголовка, шрифт и
цвет текста, фирменная палитра и цвет «карточек», светлое/тёмное оформление.styles.ts — «закрепление» унаследованного оформления: положение
плейсхолдеров, маркеры и отступы, размер и цвет текста берутся из макета и
мастера исходника и записываются на слайд — иначе при смене макета они
потерялись бы.restyle.ts — перекраска: шрифты шаблона; цвет текста с проверкой
контраста к реальному фону под ним (фон слайда или заливка фигуры);
насыщенные цвета — в ближайший по тону цвет палитры (красный «внимание»
без близкого цвета в палитре остаётся красным); светлые плашки на тёмном
шаблоне — в «карточки»; таблицы — сетка и шапка в стиле шаблона;
заголовок — на место шаблона с подбором кегля, чтобы не наехать на
содержимое.build.ts — сборка: пакет шаблона без слайдов-примеров, перенос слайдов
со всеми картинками, диаграммами (перекрашиваются ряды и подписи),
заметками; 4:3 вписывается в 16:9; разделы по файлам; удаление
неиспользуемых частей шаблона.Проверка: pptx-результат открывается PowerPoint/LibreOffice, все связи и
типы частей на месте, порядок элементов XML соответствует схеме.
src/pages/HtmlStudio/)Правка HTML-файлов (например, отчётов, которые сгенерировал ИИ) без знания кода. Всё в браузере, файл никуда не отправляется.
iframe без allow-scripts): клик
выделяет блок, двойной клик — правка текста на месте, плавающая панель
форматирования, хлебные крошки, вставка блоков, перемещение
(Alt+↑/↓), дублирование (Ctrl+D), удаление (Delete), отмена (Ctrl+Z/Y).
Панель «Блок»: текст, ссылки, замена картинок, цвета, размеры, отступы,
атрибуты (обработчики on* запрещены), операции с таблицами.core/data.ts, разбор
через acorn): массивы, записи, словари, наборы Chart.js/ECharts/ApexCharts.
Правка в сетке, вставка из Excel, импорт XLSX/CSV, выгрузка в Excel.
Запись обратно меняет только литералы — форматирование кода сохраняется.style#he-custom-css).Ограничения: содержимое, которое рисуют скрипты, видно только в «Просмотре» (в визуальном режиме такие контейнеры заштрихованы); библиотеки с CDN без интернета не загрузятся; если CSP портала блокирует скрипты предпросмотра — используйте «В браузере». Черновик автоматически сохраняется в localStorage.
Например, чтобы передать файлы через почтовый шлюз, который режет
непривычные расширения: добавить .pdf ко всем файлам в папке и вернуть обратно.
macOS / Linux (Terminal):
find . -type f -exec mv {} {}.pdf \;
find . -type f -name "*.pdf" -exec sh -c 'mv "$1" "${1%.pdf}"' _ {} \;
Windows (PowerShell):
Get-ChildItem -Recurse -File | Rename-Item -NewName { $_.Name + ".pdf" }
Get-ChildItem -Recurse -File -Filter "*.pdf" | Rename-Item -NewName { $_.Name -replace '\.pdf$', '' }