@@ -0,0 +1,62 @@
# ПЛАН: компонент выбора файлов/папок/архивов → файловое дерево
> Для Flash. Vanilla JS, БЕЗ React и сборщика (как drhider). Новое — только если проще.
> Переиспользуемый компонент (слой 1 из `PLAN-upload-layers.md`).
## Решения (фиксировано)
| Вопрос | Решение | Почему |
|---|---|---|
| Стек | **vanilla JS ** , один модуль | drhider без сборщика; React избыточен |
| ZIP | * * `fflate` ** (`unzipSync` /`unzip` + `filter` ) | заменяет ручной `parseZip` (~200 строк); 8 kB; filter по расширению ДО распаковки |
| Выбор папки | `webkitdirectory` (оставить) | уже в drhider, рекурсивно |
| Дерево | **свой лёгкий ** рендер (ленивый + делегирование) | jsTree старые, react — нет |
| Единственная новая зависимость | `fflate` (CDN `unpkg` /`jsdelivr` ) | оправдано и проще |
## Модель узла
```
node = { type:'dir'|'zip'|'file', name, path, size, file, children, collapsed }
```
- `path` для file — полный относительный путь: `"Папка/архив.zip/Внутри/файл.txt"` .
- Дубль = `path` +`size` → пропуск; имя то же, размер другой → суффикс `_2` .
## API компонента
```
createFilePicker({ container, allowedExt, maxFileBytes, onSelectionChange }) -> {
pickFiles(), pickFolder(),
getFlatFiles() -> [{path,name,size,file}], // в слой закачки
getOverNames(), clear(), setStatus(path, html)
}
```
## Сборка дерева
1. **Папка ** : `webkitRelativePath="Top/…"` → отбросить `Top` → вставить по сегментам.
2. **Файлы ** : в корень; `.zip` → `fflate.unzip` (рекурсивно по вложенным `.zip` ), узел `zip` + дети.
3. **Фильтр ** : лист принимается только если расширение ∈ `allowedExt` ; `.zip` — ради раскрытия.
## Рендер (сотни файлов)
- Свёрнутый `dir` /`zip` **не рендерит детей ** (ленивый).
- Плоский список «видимых строк» одним проходом (или `DocumentFragment` ).
- Клики — **делегирование ** (один обработчик на контейнер по `data-path` ), не сотни слушателей.
- `getFlatFiles()` — обход дерева, только листья-файлы.
## Шаги (для Flash)
1. Подключить `fflate` (CDN). Написать обёртку `zip.js` : `listZip(f) -> [{path,name,size,file}]` с `filter` по `allowedExt` .
2. Модель узла + вставка по сегментам пути.
3. Сборка из `folderInput` (webkitRelativePath) и `fileInput` (раскрытие zip рекурсивно).
4. Дедуп (`path` +`size` , суффикс `_2` ).
5. Рендер дерева: collapse, ленивый рендер, делегирование кликов.
6. Фильтр `allowedExt` + лимит + статус «пропущен (лимит)».
7. `getFlatFiles()` → слой закачки.
## Чек-лист приёмки
- [ ] дерево папок/архивов сворачивается/разворачивается;
- [ ] путь файла из архива виден (`Папка/архив.zip/…` );
- [ ] дубли исключены, коллизия имени → `_2` ;
- [ ] `allowedExt` — параметр (фильтр и в zip, и в папке);
- [ ] сотни файлов не тормозят (ленивый рендер + делегирование);
- [ ] `getFlatFiles()` отдаёт только учитываемые файлы.
## Не делать (не оправдано)
- React / сборщик / jQuery-деревья (jsTree, Fancytree).
- Виртуализация `react-arborist` — только если появятся тысячи узлов и будет React.