Compare commits

..
7 Commits
Author SHA1 Message Date
prodik 6cd851aa56 increase ram 2026-10-01 16:41:01 +03:00
prodik 79216ce45e synology: compose на абсолютные пути NAS + адаптация README/AGENT
- docker-compose.yaml: /volume1/docker/lampac/... (данные), /volume4/Torrents (DLNA), Курсы -> dlna/Cources:ro
- README/AGENT: описание ветки synology, таблица томов NAS, инструкции переноса
- мерж main (разрешение конфликтов документации)
2026-10-01 16:38:13 +03:00
prodik c6154706db Документация: synology синхронизирована с main 2026-10-01 16:30:55 +03:00
prodik 95db691a0d Синхронизация с main: Docker-развёртывание Lampac NextGen
Содержимое ветки заменено на актуальное из main:
- docker-compose.yaml (ghcr.io/lampac-nextgen/lampac, относительные пути)
- config/init.conf, modules/ (override-файлы)
- README.md, AGENT.md, .gitignore
Старый деплой (immisterio/lampac, configs/, plugins/, update.sh) удалён.
2026-10-01 16:30:15 +03:00
Фёдоров Дмитрий 20cfe276d3 fix 2025-03-25 23:24:29 +03:00
Фёдоров Дмитрий e4b5ae99b4 add lampainit.my.js 2025-03-25 23:17:00 +03:00
Фёдоров Дмитрий 280c0b8acc fix 2025-03-25 12:54:22 +03:00
264 changed files with 483 additions and 184566 deletions
+7 -13
View File
@@ -1,18 +1,12 @@
# Локальные данные и кеш (только корневые каталоги; якорь «/» обязателен —
# иначе «cache/» игнорирует и mods/Music/Services/Cache/ и т.п.)
/cache/
/database/
# Секреты
config/passwd
# Локальные данные и кеш
cache/
database/
# Медиа DLNA (том ./dlna -> /lampac/data/dlna)
/dlna/
dlna/
# Системное
.DS_Store
# Серверный override (Proxmox: том DLNA -> /mnt/torrents), живёт только на сервере
docker-compose.override.yml
config/passwd
config/init.conf
# TorrServer: состояние не трекаем, бинарник — треким
/data/ts/*
!/data/ts/TorrServer-linux
+67 -130
View File
@@ -1,148 +1,85 @@
# AGENT.md — инструкции для ИИ-агентов
# AGENT.md — инструкции для AI-агента
Работа с проектом: локальный Docker-развёртывание [Lampac NextGen](https://github.com/lampac-nextgen/lampac). Человек читает ответы **только на русском**.
## О проекте
## Источники правды (порядок приоритета)
Это **deployment-репозиторий** для локального развёртывания Lampac NextGen (активный форк заброшенного Lampac) в Docker на **Synology NAS**. Исходники форка сюда не клонируются — используется официальный образ `ghcr.io/lampac-nextgen/lampac`.
1. **Официальная документация** — [docs.lampac.dev](https://docs.lampac.dev) (полный текст страниц: `https://docs.lampac.dev/llms-full.txt`, индекс: `llms.txt`). Не гадать по памяти — проверять в доках.
2. **Живой контейнер** — состояние модулей, манифестов и конфигов брать из контейнера:
```bash
docker exec lampac sh -c 'cat /lampac/module/<Имя>/manifest.json'
docker exec lampac cat /lampac/current.conf # merged-конфиг: base + init
```
3. **Логи контейнера** — `docker logs lampac`.
4. Локальные файлы проекта: `docker-compose.yaml`, `config/init.conf`, `mods/`.
**Ветка `synology` (текущая)** — как `main`, но `docker-compose.yaml` с **абсолютными путями томов NAS**: `/volume1/docker/lampac/...` (данные проекта), `/volume4/Torrents` (медиа DLNA), `/volume1/homes/prodik/NAS/Курсы` → `/lampac/data/dlna/Cources:ro`. Локального каталога `dlna/` в репо нет — медиа живут на томах.
## Ключевые правила
- Форк: https://github.com/lampac-nextgen/lampac (347+ звёзд, ежедневные коммиты, релизы)
- Документация: https://docs.lampac.dev
- Образ: `ghcr.io/lampac-nextgen/lampac:latest` (multi-arch: amd64/arm64)
- Порт: **9118**, рабочая директория в контейнере: `/lampac`
- Последняя задеплоенная версия: `1.61.2` (при установке 01.10.2026)
- Git: `ssh://git@gitea.prodik.ru:222/prodik/lampac.git`, ветка **synology** (эта); `main` — то же самое с относительными путями томов; remote настроен как `origin`
- Коммиты: `git add -A && git commit && git push origin synology` — секреты/данные отсекает `.gitignore`; в git идут только compose, `init.conf`, `modules/`, доки, `.gitignore`
### 1. Никогда не правь файлы внутри контейнера/образа
## Файлы
Файлы в `/lampac/module/` (и любые другие в образе) **сгорают при обновлении** (`docker compose pull && up -d`). Включение встроенного модуля делается только пользовательской копией:
| Файл | Назначение | Правила |
| --- | --- | --- |
| `docker-compose.yaml` | Единственный compose-файл | **абсолютные пути томов NAS** (`/volume1/docker/lampac/...`, `/volume4/Torrents`, `Курсы`); фиксированной сети/subnet нет (дефолтная сеть compose) |
| `config/init.conf` | Конфиг сервера (JSON) | hot-reload для большинства ключей (кроме `BaseModule.SkipModules` — нужен рестарт); строго валидный JSON |
| `config/passwd` | Пароль root, **секрет** | не выводить в чат/логи/коммиты, в `.gitignore` |
| `modules/*/manifest.json` | Manifest-оверрайды (`enable: true`) | монтируются поверх `/lampac/module/<Name>/manifest.json`; для модулей, у которых в образе `enable: false` (сейчас: `Tracks`, `Music`, `Tg-notify.bot`, `AdminPanel`) |
| `modules/LampaWeb/plugins/extensions.json` | Каталог магазина плагинов (`/extensions`) | override образного файла, добавлена секция «Lampac» (DLNA); после правки сбросить кеш `cache/static/63/` |
| `cache/` | Кеш | монтируется в `/lampac/cache` |
| `database/` | SQLite-БД (Sync, TimeCode, SISI) | монтируется в `/lampac/database`, не удалять |
| `.gitignore` | Игнорируемые пути | в игноре: `config/passwd` (секрет), `cache/`, `database/`, `.DS_Store`; остальное (init.conf, modules/, compose, доки) — переносимое |
| `README.md` / `AGENT.md` | Документация | обновлять при любых изменениях развёртывания |
## Основные команды
```bash
docker cp lampac:/lampac/module/<Имя> "mods/<Имя>"
# в mods/<Имя>/manifest.json -> "enable": true
# в docker-compose.yaml -> "- ./mods/<Имя>:/lampac/mods/<Имя>"
# docker compose up -d
docker compose up -d # запуск
docker compose pull && docker compose up -d # обновление
docker compose restart lampac # рестарт (нужен только для passwd)
docker compose logs -f --tail 100 lampac # логи
docker compose ps # статус
curl -fsS "http://localhost:9118/version?type=hash" # health-check (ожидается 200 + hash)
curl -fsS -o /dev/null -w '%{http_code}\n' http://localhost:9118/online.js # ожидается 200
```
См. также официальные шаги: [Включить модуль](https://docs.lampac.dev/modules/overview), [Пользовательские модули](https://docs.lampac.dev/maintenance/custom-modules).
Проверка работоспособности после любых изменений: health-check выше + контейнер в статусе `healthy`.
Сейчас в `mods/`: `AdminPanel`, `Tracks`, `Tg-notify.bot`, `TelegramAuth`, `TelegramAuthBot`. **`mods/Music` удалён** (remote-коммит `remove Music`): в образе у Music `manifest.enable: false`, поэтому модуль не грузится, `/music.js` → 404, секция `"Music"` и плагин убраны из `init.conf`. `mods/WatchTogether` тоже удалён (вернуть — той же механикой, он в списке «ещё можно включить» в README).
## Правила работы
**Веб-клиент `lampa-main` — в git** (каталог `lampa-main/`), на сервере смонтирован bind-mountом в `/lampac/wwwroot/lampa-main` (override). В образе клиента нет, `LampaCron` из GitHub не докачивает (нет доступа к GitHub) — клиент держим в репозитории, чтобы переживал пересоздание контейнера. Обновление: архив https://github.com/yumata/lampa/archive/refs/heads/main.zip -> `lampa-main/` (топ `lampa-main-main` -> `lampa-main`), `chown -R 1000:1000`, коммит + `git pull` на сервере (перезапуск не нужен, статика).
1. **Отвечать по-русски.**
2. После любых изменений в проекте — дополнять `README.md` и `AGENT.md`.
3. Конфиг менять только в `config/init.conf`; валидность проверять: `python3 -m json.tool config/init.conf`.
4. Включение/выключение модулей — через `BaseModule.SkipModules` в `init.conf` (добавить имя = выключить; имя = имя папки в `/lampac/module/`, группы вроде `OnlineAnime` выключаются целиком). `SkipModules` **не hot-reload** — после правки нужен `docker compose restart lampac`. Модули, у которых в образе `manifest.json: enable: false` (`Tracks`, `Music`, `Tg-notify.bot`, `AdminPanel`), включаются только manifest-оверрайдом: копия манифеста с `enable: true` в `modules/<Name>/manifest.json` + монтирование в compose. Список модулей: https://docs.lampac.dev/modules/overview
- Текущее состояние: выключены `OnlineAnime`, `OnlineUKR`, `OnlinePaid`, `OnlineGEO`, `Transcoding`, `WebLog`; включены все остальные (TorrServer, Sync/TimeCode/Storage/SyncEvents, Catalog, JacRed, DLNA, SISI, Tracks, Music, Tg-notify.bot, AdminPanel).
- Плагины Lampa: `/online.js`, `/sisi.js`, `/dlna.js` и т.д. Большинство Lampac сам подключает клиенту через `/lampainit.js` (см. ниже про `initPlugins`); при необходимости плагин можно добавить вручную по URL.
- **Два уровня включения модуля:** (1) `SkipModules`/manifest — модуль скомпилирован и работает на сервере; (2) `LampaWeb.initPlugins.<name>` в `init.conf` — плагин попадает в список, который `/lampainit.js` добавляет клиенту Lampa (`Lampa.Plugins.add`). Без второго флага сервер отвечает, но пункт в Lampa не появится (так было с `dlna` — флаг `initPlugins.dlna` добавлен в init.conf). Дефолты флагов — в `current.conf` секция `LampaWeb.initPlugins`.
- **Магазин плагинов** в Lampa (Настройки → Плагины) читает `/extensions` → `LampaWeb/plugins/extensions.json` (каталог образа). Свои записи добавляются через override-файл в `modules/LampaWeb/plugins/extensions.json` (монтирован в compose). Ответ кешируется `Staticache` на диске: `cache/static/<bucket>/` — после правки удалить соответствующий файл (`grep -rl secuses cache/static/`) или весь каталог static, затем перезапросить.
5. Новые пользовательские модули класть в `mods/<Name>/` (монтировать в `/lampac/mods/<Name>`), переопределения плагинов — `plugins/lampainit.js` → `/lampac/plugins/override/lampainit.js`.
6. Не раскрывать пароль из `passwd`, не коммитить его, не выводить в логи.
7. Не открывать порт 9118 в интернет без файрвола/reverse proxy; модули `DLNA`, `Tracks`, `Transcoding`, `GStreamer`, `Catalog` не предназначены для публичного доступа.
8. Образ пиннить по тегу при необходимости воспроизводимости (в compose сейчас `:latest`).
### 2. Механика загрузки модуля (4 независимых фильтра)
## Структура контейнера (важные пути)
Модуль грузится, только если выполнены **все**:
| Фильтр | Где |
|---|---|
| `"enable": true` | `manifest.json` модуля (копия в `mods/` для встроенных) |
| Имя **не** в `BaseModule.SkipModules` | `base.conf` (в образе) + `config/init.conf` |
| Имя попадает в `BaseModule.LoadModules` | если allowlist задан (у нас не задан — грузится всё остальное) |
| Runtime-флаг | секция модуля в `config/init.conf`, например `"gst": { "enable": true }` |
`SkipModules` имеет приоритет над `LoadModules` — модуль из обоих списков **не** грузится. Паттерны: точное имя, группа (`OnlineUKR`), regex (`LME.*`), `.*`.
### 3. `config/init.conf` — валидный JSON
JSON **без** trailing comma. Перед применением правок проверять:
```bash
python3 -m json.tool config/init.conf > /dev/null && echo OK
```text
/lampac/
├── init.conf # конфиг (смонтирован с хоста)
├── passwd # пароль root (смонтирован с хоста)
├── cache/ # кеш (смонтирован)
├── database/ # SQLite и бэкапы конфига (смонтирован)
├── mods/ # пользовательские модули (Roslyn компилирует .cs на лету)
├── module/ # встроенные модули образа
├── plugins/override/ # переопределения JS-плагинов
└── wwwroot/ # статика Lampa UI
```
После правки конфига: `docker compose restart` (том смонтирован, `up -d` не нужен). После правки `manifest.json` в `mods/` с `dynamic: true` — тоже `restart` (или ждать hot-rebuild). После изменения томов в compose — `docker compose up -d`.
Горячая перезагрузка: `init.conf` watcher каждую секунду; `mods/*.cs` перекомпилируются при изменении.
### 4. Клиентские плагины Lampa
## Troubleshooting
- Встроенные плагины: флаги `LampaWeb.initPlugins` (`tracks`, `dlna`, `catalog`, `sync`, `backup`, ...).
- Дополнительные: `LampaWeb.customPlugins` — записи со `status: 1` добавляются как есть; поддерживается плейсхолдер `{localhost}` (подставляется реальный адрес сервера).
- Если плагин «не виден» в веб-клиенте — сначала проверить HTTP-статус его URL на сервере (`curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:9118/<плагин>.js`), а не лезть в клиент.
### 4.1 Каталог плагинов (store) `/extensions`
- Раздел «Плагины» веб-клиента грузит каталог с `/extensions` (при `LampaWeb.initPlugins.pirate_store: true`).
- Источник: `/lampac/module/LampaWeb/plugins/extensions.json` — переопределён mount из `./plugins/extensions.json`. Править хост-файл, в контейнер не залезать.
- `{localhost}` в ссылках store сервер заменяет своим адресом при выдаче.
- Статика: `/lampac/plugins/` **не раздаётся** (проверено: файл → 404), корень `wwwroot` — раздаётся. Все плагины каталога — **локальный mirror** в `./plugins/`, смонтирован **одним directory-mount** в `/lampac/wwwroot/plugins/` → ссылки store `{localhost}/plugins/<имя>.js`. Не монтировать каталог целиком в корень `wwwroot` — скроется веб-клиент `lampa-main`.
- Обновление плагина: исходный URL — в `plugins/sources.json`; скачать, перезаписать файл, перезапуск не нужен (статика).
- При проверке скачанного плагина отличать: (а) реальный код, (б) лоадер `putScriptAsync` (абсолютные URL — безопасен локально; host от currentScript — **требуется патч**, см. showy.js), (в) пустой stub/placeholder (мёртвый плагин, из каталога удалять).
- **Кеш-ловушка**: ответ `/extensions` (и других LampaWeb-маршрутов) кешируется на диск в `/lampac/cache/static/<bucket>/<id>.json` (named volume `lampac_cache`); кеш переживает `docker compose restart`. После правки store: `docker exec lampac rm -rf /lampac/cache/static/59` (bucket `/extensions`), перезапуск не нужен. Заголовок `X-StatiCache-Status: HIT/MISS` показывает состояние.
### 5. AdminPanel API из скриптов (root-авторизация)
- Root-пароль = содержимое `config/passwd`. Механизм: cookie `accspasswd=<пароль>` (таков штатный сценарий: страница входа `auth.html` сама кладёт пароль в эту cookie). Заголовок `lcrqpasswd` — для внутренних вызовов, на `/adminpanel/api/*` с ним уходит 302 на `/adminpanel/auth`.
- Не передавать root-пароль в query string (предупреждение доков).
- Сервер может отвечать 404 вместо 401/403, чтобы не раскрывать админский endpoint.
- Основные маршруты: `GET /adminpanel/api/init` (чтение), `POST /adminpanel/api/init` (полная запись), `POST /adminpanel/api/init/section/{key}` (секция), `GET /adminpanel/api/current` (merged-конфиг), `GET /adminpanel/api/users-json`.
- Правка секций через API пишется в `init.conf` — watcher подхватит без рестарта (runtime-параметры). `customPlugins` — runtime-параметр: плагин появляется в `/lampainit.js` через ~1 с.
### 6. Диагностика «модуль не найден»
Чек-лист (в этом порядке):
1. `curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:9118/<маршрут>` — 404 подтверждает, что модуль не загружен.
2. `docker logs lampac | grep -E "compilation|loaded module" | grep <Имя>` — скомпилирован ли и загружен ли.
3. Манифест: `enable: true`? (в `mods/` для встроенных)
4. Фильтры `SkipModules`/`LoadModules` в `config/init.conf`.
5. Runtime-секция модуля в `config/init.conf`.
6. В логе после старта ожидаются строки `compilation <Имя>`, `configure module: <Имя>` (если есть конфиг-секция), `loaded module: <Имя>`.
### 7. Команды эксплуатации
```bash
docker compose up -d # запуск / пересоздание (при изменении compose)
docker compose restart # после правки init.conf / mods
docker compose logs -f # логи
docker compose pull && docker compose up -d # обновление (сначала поменять тег в compose)
docker exec lampac sh -c '...' # осмотр состояния в контейнере
```
`container_name: lampac` — контейнер один; одновременный запуск нескольких compose-файлов с одним именем невозможен. `docker-compose.override.yml` (gitignore) живёт только на сервере Proxmox и не коммитится.
### 8. Чего не трогать
- `config/passwd`, `dlna/` — в .gitignore, не коммитить. `cache`/`database` — **named Docker volumes** (`lampac_cache`, `lampac_database`), в git не попадают. Ловушка `.gitignore`: паттерны без якоря (`cache/`) матчат каталоги на любой глубине и без учёта регистра — из-за этого `mods/Music/Services/Cache/` не попадал в git и ломала Roslyn-компицию на сервере (CS0103, crash-loop). Новые данные/каталоги проверять через `git status`/`git check-ignore -v`.
- В named volume данные принадлежат тому, кто их туда положил: после миграции/копии `chown -R 1000:1000` (процесс в контейнере — `lampac:1000`), иначе SQLite «attempt to write a readonly database».
Исключение: `cache/static/` (в volume `lampac_cache`) — одноразовый диск-кеш ответов LampaWeb; очистка (`docker exec lampac rm -rf /lampac/cache/static/<bucket>`) — штатное действие после правки store/статических маршрутов (см. 4.1).
- Тег образа в `docker-compose.yaml` закреплён **точным digest** (`1.68.0@sha256:752dafd8…`): тег 1.68.0 на ghcr mutable, его переиздавали, и новая сборка ломает Roslyn-компиляцию наших копий `mods/` (пример: `Music` → `CS0103 MusicMetadataCacheService`, crash-loop). Обновление образа = новый digest + пересборка копий `mods/` из нового образа. Не делать «просто» `docker compose pull` без фиксации digest.
- `LampaWeb.autoupdate` — веб-клиент Lampa сам обновляется из git (`yumata/lampa`), `wwwroot/lampa-main` в контейнере перезаписывается — туда не править.
### 9. После изменений в проекте
Обновлять `README.md` и `AGENT.md` в той же ревизии: структура, включённые модули, секции конфига, новые правила.
### 10. Безопасность (не публиковать)
`config/passwd`, cookie `accspasswd`, заголовок `lcrqpasswd`, `bot_token` в `TelegramBot`, `bot_token` в `TelegramAuthBot`, `mutations_api_secret`. Маршруты `/adminpanel`, `/weblog`, `Tracks`, `Catalog`, `DLNA`, proxy-модули — только для доверенной сети без WAF не открывать.
**Секреты:** в git `config/init.conf` — секреты **пустые**. Реальные значения — в `config/secrets.env` (gitignored), боевой конфиг — `config/init.custom.conf` (gitignored). Собирается скриптом: `python3 scripts/config-secrets.py apply`. Перед коммитом: `python3 scripts/config-secrets.py check` (должен выдать `секретов в config/init.conf нет — ok`). После `git pull`/смены ветки `apply` запускается автоматически через git-хуки (`scripts/install-git-hooks.sh`).
### 11. Tg-notify.bot (Telegram-бот)
- Механика: long polling по `TelegramBot.bot_token`; если токен пуст — polling не стартует (в логе `[TelegramBot] Установите bot_token…`, сервер работает). После правки секции: `docker compose restart lampac`.
- **Токен только локально:** в git `config/init.conf` поле пустое (правило 10). Реальный токен живёт в `config/secrets.env`, а `docker-compose.yaml` монтирует `config/init.custom.conf` (собрать: `python3 scripts/config-secrets.py apply`). После `git pull` хук `post-merge` делает `apply` сам; если нет хуков — выполнить вручную. Второй экземпляр на том же токене даёт `Conflict: terminated by other getUpdates request`.
- Три подсистемы: трекер серий (Trakt→TMDB), трекер озвучек (параллельно Mirage/Collaps/VideoHub через `lampac_host`: `/lite/mirage`, `/lite/collaps`, `/lite/cdnvideohub`), клиентский плагин `tg-notify.js` (вкладка «TG Подписки», перехват 🔔). Полный разбор — в README.md.
- Данные подписок: `database/tgnotify/{users.json,subscriptions.json}` (том `./database/`, в .gitignore). Не «чинить» вручную — это живые данные бота.
- Диагностика: `GET /tg-notify.js` (200 без авторизации), `GET /api/tg/voices` (200), `/api/tg/*` остальной — требует `user_uid`. Озвучки могут не работать, если балансеры недоступны (проверить `GET /lite/mirage` — тело `disable`/ошибка, `/lite/collaps` — 503); тогда уведомления приходят только о выходе серий.
- `kp_api_key` опционален: без него VideoHub резолвит `kinopoisk_id` только через мост `/externalids` (покрытие ~40%), иначе — молча пропускается, Mirage/Collaps работают.
### 12. TelegramAuth / TelegramAuthBot (вход через Telegram)
- Не путать с Tg-notify.bot (уведомления): эта пара — **аутентификация** (вход в Lampa через Telegram вместо пароля), группа Community. Копии в `mods/TelegramAuth/` и `mods/TelegramAuthBot/`, манифесты `enable: true`, из `SkipModules` убраны (у нас `SkipModules: []`).
- **Сейчас: API-режим.** `TelegramAuth.enable: false` → `accsdb` не поднимается, гейт неактивен, доступ не режется; работают привязки, `/tg/auth/*`, админ-API. `TelegramAuthBot` — бот **`@GatusMonBot`**, long polling идёт (`Telegram API OK`).
- Гейт (`LampaWeb.telegramAuthGate`) активен только при `accsdb.enable: true` + `telegramAuthGate.enabled: true` + непустом `botUsername`, иначе тихий откат на `deny.js`. Включать **только вместе с `accsdb`**, и сначала связать свои устройства через бота — иначе текущие UID получат отказ.
- `mutations_api_secret` одинаковый в обоих модулях, ненулевой; `bot_token` — в `init.conf`, **не коммитить** (правило 10): в git оба поля пустые.
- `owner_telegram_ids: [143672]` → владелец создаётся как `admin` при старте. `auto_provision_users: true` + `auto_provision_activate_immediately: false` → новые привязки ждут одобрения (`/users` в боте, кнопки Принять/Отклонить).
- Данные: `database/tgauth/{users.json,admins.json,user_langs.json}` (том `lampac_database`, владелец `1000:1000`). Живые данные — не «чинить» руками.
- Проверка: `GET /tg/auth/status?uid=x` → 200; `GET /tg/auth/admin/users` → 401 без заголовка, 200 с `X-TelegramAuth-Mutations-Secret`.
## Размещение на сервере (обновлено 06.10.2026)
- Проэкт живёт в **Proxmox VM 130 «lampac»** (Debian 13), IP **192.168.88.243/24**, статика в `/etc/network/interfaces` (ens18). Старый LXC-контейнер 122 отключён и более не используется.
- Логин для SSH: `prodik` (sudo без пароля). Проxmox-хост: `root@192.168.88.254`.
- `/mnt/torrents` — CIFS `//10.6.0.1/Torrents` (Synology), креды в `/etc/smb_cred`, mount в `/etc/fstab`. Добрается через маршрут `10.6.0.0/30 via 192.168.88.254` (строка `up ip route ...` в `/etc/network/interfaces`) — Synology видна только через Proxmox.
- Docker: пакет `docker.io` (Debian) + compose v2 в `/usr/local/lib/docker/cli-plugins/docker-compose`.
- Поднятие после ребута VM: всё авто (onboot=1, docker enabled, fstab nofail). Если контейнер не healthy — смотри «SQLite не может создать базу» в README: `chown -R 1000:1000 /var/lib/docker/volumes/lampac_{database,cache}/_data`.
- **Контейнер нестабилен / Chromium падает** — проверить `shm_size: 1024mb` в compose (обязательно для Playwright).
- **Пути томов** — в этой ветке compose использует абсолютные пути NAS (`/volume1/docker/lampac/...`, `/volume4/Torrents`); при переносе на другой хост их обязательно заменить. Относительные пути — в ветке `main`.
- **Не стартует после правки init.conf** — проверить JSON: `python3 -m json.tool config/init.conf`; бэкапы в `/lampac/database/backup/init/`.
- **Модуль не загрузился** — смотреть `docker compose logs lampac | grep -E "skip compilation|loaded module"`; для модулей с `enable: false` в образе проверить manifest-оверрайд и его монтирование в compose.
- **Tg-notify молчит** — нужен `bot_token` в секции `TelegramBot` init.conf (без него long polling не стартует, в логе предупреждение).
- **Занят порт 9118** — `lsof -i :9118` или сменить порт в `init.conf` (`listen.port`) и в `ports` compose-файла одновременно.
- **Сеть** — в compose нет фиксированной сети/subnet; используется дефолтная сеть проекта (`lampac_default`).
- **Обновление сломало конфиг** — свериться с https://github.com/lampac-nextgen/lampac/blob/main/config/example.init.conf (новые ключи добавляются в стартовый конфиг).
+197 -302
View File
@@ -1,345 +1,240 @@
Lampac NextGen — локальный Docker-развёртывание
# Lampac NextGen — self-hosted backend для Lampa (Docker, Synology NAS)
> Сервер: Proxmox VM 130 «lampac», Debian 13, 192.168.88.243, логин prodik. Детали — AGENT.md (раздел Размещение на сервере).
Локальное развёртывание **[Lampac NextGen](https://github.com/lampac-nextgen/lampac)** — активного форка оригинального Lampac, чей основной репозиторий больше не поддерживается.
Локальное развёртывание [Lampac NextGen](https://github.com/lampac-nextgen/lampac) — самохостируемого бекенда для Lampa — в Docker. Официальная документация: [docs.lampac.dev](https://docs.lampac.dev).
> **Ветка `synology`** — вариант для Synology NAS: в `docker-compose.yaml` используются **абсолютные пути** томов (`/volume1/docker/lampac/...`), а не относительные, как в ветке `main`.
## Быстрый старт
## Почему этот форк
```bash
docker compose up -d # первый запуск
docker compose logs -f # логи (строки compilation / configure module / loaded module)
docker compose restart # после правки config/init.conf или манифестов в mods/
```
Оригинальный Lampac (`Mirrowol/Lampac`) давно не обновляется. Из форков наибольшую популярность набрал **lampac-nextgen/lampac**:
- Веб-клиент Lampa: **http://localhost:9118**
- Админ-панель: **http://localhost:9118/adminpanel** (root-пароль из `config/passwd`)
- TorrServer-прокси: `http://localhost:9118/ts/*` (порт TorrServer — 9085)
| Показатель | Значение |
| --- | --- |
| Репозиторий | https://github.com/lampac-nextgen/lampac |
| Stars / Forks | ~347 / ~80 (самый популярный форк Lampac) |
| Активность | ежедневные коммиты, релизы (последний `v1.61.2` — 30.09.2026) |
| Стек | ASP.NET Core, .NET 10, AGPL-3.0 |
| Docker-образ | `ghcr.io/lampac-nextgen/lampac` (amd64 + arm64) |
| Документация | https://docs.lampac.dev |
| Чат | https://t.me/LampacTalks/13998 |
По умолчанию сервер слушает порт **9118**; если порт занят — меняй `listen.port` в `config/init.conf` до первого запуска.
## Первая установка: SQLite не может создать базу в named volume
**Симптом.** Свежий `docker compose up -d` уходит в crash-loop (`Restarting (139)`, healthcheck `unhealthy`), в логах:
```
Unhandled exception. Microsoft.Data.Sqlite.SqliteException (0x80004005):
SQLite Error 14: 'unable to open database file'.
at Microsoft.Data.Sqlite.SqliteConnection.Open()
at Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal.SqliteDatabaseCreator.Create()
at Microsoft.EntityFrameworkCore.RelationalDatabaseCreator.EnsureCreated()
at Core.Program.Run(String[] args)
```
**Причина.** Процесс в контейнере работает от uid `1000` (пользователь образа `lampac`), а Docker при первом создании named volume делает его владельцем `root:root`. Смонтированный каталог `/lampac/database` поэтому недоступен на запись для `lampac`, `sqlite3` получает `EACCES` и приложение падает сразу после `EnsureCreated()` — база не создаётся ни разу, поэтому изнутри контейнера это не лечится.
Та же первопричина у второй ошибки первого запуска:
```
System.UnauthorizedAccessException: Access to the path '/lampac/passwd' is denied.
```
`config/passwd` монтируется файлом и тоже должен принадлежать uid `1000`.
**Лечение** — на хосте, от root:
```bash
# тома (первый запуск или миграция/копия томов)
chown -R 1000:1000 /var/lib/docker/volumes/lampac_database/_data \
/var/lib/docker/volumes/lampac_cache/_data
# файл пароля (владелец 1000, права 600 — читает только процесс контейнера)
chown 1000:1000 config/passwd && chmod 600 config/passwd
docker compose up -d # или docker compose restart, если контейнер уже создан
```
**Проверка:**
```bash
docker compose ps # Up (healthy)
docker logs --since 2m lampac | grep -ci unhandled # 0
ls -ln /var/lib/docker/volumes/lampac_database/_data/Sisi.sql # uid/gid 1000
```
> После лечения в `lampac_database` должны появиться `Sisi.sql`, `Sync.sql`, `TimeCode.sql`, `tgnotify/`, `tracks/`, `storage/` — это и есть признак, что базы созданы.
Проверить uid процесса в контейнере: `docker exec lampac id` → `uid=1000(lampac)`.
Правило: **любой bind-mount файл/каталог, в который пишет контейнер, должен принадлежать `1000:1000`** (см. `.gitignore` для `config/passwd`, `dlna/`, `lampa-main/`).
## Секреты (вынесены из git)
Модули `TelegramBot`, `TelegramAuthBot`, `TelegramAuth` читают `bot_token` и `mutations_api_secret` из конфига. В репозитории эти поля **всегда пустые** — реальные значения живут в файле, который не коммитится.
| Файл | В git? | Назначение |
|---|---|---|
| `config/init.conf` | ✅ | Шаблон конфига, секреты **пустые**. Именно его редактируете для обычных настроек (`listen`, `SkipModules`, `initPlugins`, модули). |
| `config/secrets.env` | ❌ .gitignore | Токены ботов и `mutations_api_secret`. `TELEGRAM_NOTIFY_BOT_TOKEN`, `TELEGRAM_AUTH_BOT_TOKEN`, `TELEGRAM_AUTH_MUTATIONS_SECRET`. |
| `config/init.custom.conf` | ❌ .gitignore | Боевой конфиг, который монтируется в контейнер. Собирается из шаблона + `secrets.env` скриптом. |
| `scripts/config-secrets.py` | ✅ | Собирает/разбирает боевой конфиг: `apply`, `export`, `check`, `status`. |
| `scripts/install-git-hooks.sh` | ✅ | Устанавливает хуки: `post-merge`/`post-checkout` → `apply`, `pre-commit` → `check`. |
| `docker-compose.yaml` | ✅ | Монтирует `./config/init.custom.conf:/lampac/init.conf` (не `init.conf`). |
**Рабочий процесс:**
```bash
# первый раз / после git pull:
python3 scripts/config-secrets.py apply # init.custom.conf = шаблон + secrets.env
docker compose up -d # рекреация из-за нового mount
# правки в init.conf:
# 1) правите config/init.conf (шаблон)
# 2) python3 scripts/config-secrets.py apply -> обновляет init.custom.conf
# 3) docker compose restart lampac
# перед коммитом:
python3 scripts/config-secrets.py export # секреты -> пустые в шаблоне
git add config/init.conf
git commit -m "..."
```
**Git-хуки (рекомендуется):** `bash scripts/install-git-hooks.sh` — после `git pull`/смены ветки `apply` запустится сам, а `pre-commit` не даст случайно закоммитить секреты.
> `docker-compose.override.yml` (в .gitignore) — серверный override для Proxmox (том DLNA -> `/mnt/torrents`), живёт только на сервере.
Что умеет: агрегация ссылок с 70+ VOD/аниме/18+ источников, встроенный TorrServer, DLNA, JacRed, транскодинг (GStreamer/FFmpeg), синхронизация закладок, хостинг Lampa UI, Telegram-уведомления, WAF и многое другое.
## Структура проекта
| Путь | Назначение |
|---|---|
| `docker-compose.yaml` | Основной сервис (образ `ghcr.io/lampac-nextgen/lampac:1.68.1`) |
| `docker-compose.override.yml` | Серверный override (Proxmox: том DLNA -> `/mnt/torrents`), в .gitignore |
| `config/init.conf` | Шаблон конфига (JSON, в git, секреты **пустые**) |
| `config/init.custom.conf` | Боевой конфиг (в .gitignore, монтируется в `/lampac/init.conf`) |
| `config/secrets.env` | Токены ботов и `mutations_api_secret` (в .gitignore) |
| `config/passwd` | Пароль root для `/adminpanel` и `/weblog` (в .gitignore) |
| `lampa-main/` | Веб-клиент Lampa (в git, bind-mount в `/lampac/wwwroot/lampa-main`) |
| volume `lampac_cache` | Кеш (`/lampac/cache`) — Docker named volume |
| volume `lampac_database` | SQLite-базы Sync, TimeCode, tg-notify, tracks, storage (`/lampac/database`) — Docker named volume |
| `dlna/` | Локальные медиа для DLNA (`/lampac/data/dlna`) |
| `plugins/extensions.json` | Каталог плагинов для веб-клиента (раздел «Плагины»), отдаётся через `/extensions` |
| `mods/<Имя>/` | Пользовательские копии встроенных модулей с `enable: true` |
```text
/volume1/docker/lampac/ # корень проекта на NAS
├── docker-compose.yaml # compose-файл (порт 9118, абсолютные пути томов)
├── config/
│ ├── init.conf # Конфигурация сервера (JSON, hot-reload)
│ └── passwd # Пароль root (СЕКРЕТ, не коммитить)
├── modules/ # Overridе-файлы, монтируемые поверх файлов образа
│ ├── Tracks/manifest.json
│ ├── Music/manifest.json
│ ├── Tg-notify.bot/manifest.json
│ ├── AdminPanel/manifest.json
│ └── LampaWeb/plugins/extensions.json # каталог магазина плагинов (+DLNA)
├── cache/ # Кеш (→ /lampac/cache)
├── database/ # SQLite-БД: Sync, TimeCode, SISI (→ /lampac/database)
├── README.md # Эта документация
├── AGENT.md # Инструкции для AI-агента
└── .gitignore
```
> Веб-клиент `lampa-main` **хранится в git** (каталог `lampa-main/`) и смонтирован bind-mountом в `/lampac/wwwroot/lampa-main` (в `docker-compose.override.yml` на сервере), поэтому переживает пересоздание контейнера. В образе клиента нет, а `LampaCron` автообновление из GitHub не докачивает (на сервере нет доступа к GitHub) — поэтому клиент держим в репозитории. Обновить клиент: скачать архив с https://github.com/yumata/lampa/archive/refs/heads/main.zip, распаковать в `lampa-main/` (топ-каталог `lampa-main-main` переименовать в `lampa-main`), `chown -R 1000:1000 lampa-main`, закоммитить; на сервере `git pull` — перезапуск не нужен (статика). См. также `scripts/restore-lampa-main.sh`.
Тома, заданные в `docker-compose.yaml` (вне репозитория):
## Включённые модули из `mods/`
| Путь хоста (NAS) | В контейнере | Доступ |
| --- | --- | --- |
| `/volume1/docker/lampac/config/passwd` | `/lampac/passwd` | rw |
| `/volume1/docker/lampac/config/init.conf` | `/lampac/init.conf` | ro |
| `/volume1/docker/lampac/cache` | `/lampac/cache` | rw |
| `/volume1/docker/lampac/database` | `/lampac/database` | rw |
| `/volume1/docker/lampac/modules/*/...` | `/lampac/module/...` | ro |
| `/volume4/Torrents` | `/lampac/data/dlna` | rw — медиа DLNA |
| `/volume1/homes/prodik/NAS/Курсы` | `/lampac/data/dlna/Cources` | ro — подпапка внутри DLNA |
Встроенные модули с `"enable": false` в `manifest.json` внутри образа **нельзя включать правкой файла в контейнере** — файлы пропадут при обновлении. Механика по официальной документации ([модули Lampac](https://docs.lampac.dev/modules/overview), [пользовательские модули](https://docs.lampac.dev/maintenance/custom-modules)):
## Быстрый старт
1. Скопировать модуль из образа в `mods/<Имя>/` на хосте:
```bash
docker cp lampac:/lampac/module/<Имя> "mods/<Имя>"
```
2. В `mods/<Имя>/manifest.json` поставить `"enable": true`.
3. Добавить том в `docker-compose.yaml`:
```yaml
- ./mods/<Имя>:/lampac/mods/<Имя>
```
4. При необходимости добавить секцию модуля в `config/init.conf` (runtime-флаг).
5. `docker compose up -d` (при добавлении тома) или `restart` (при правке манифеста с `dynamic: true`).
Требования: Docker 24+ с Compose v2 (проверка: `docker compose version`).
### Сейчас подключены
```bash
# 1. Запуск
docker compose up -d
| Модуль | Что даёт | Секция в init.conf |
|---|---|---|
| `Tracks` | `/tracks.js`, `/ffprobe` — субтитры и дорожки | `"Tracks": { "enable": true }` |
| `AdminPanel` | `/adminpanel` — редактор init.conf, current.conf, users.json | `"AdminPanel": { "enable": true }` |
| `Tg-notify.bot` | `/tg-notify.js`, `/api/tg/*` — уведомления о новых сериях в Telegram | секция `"TelegramBot"` |
| `TelegramAuth` | `/tg/auth/*` — привязка UID устройства к учётке Telegram, HTTP API статуса | секция `"TelegramAuth"` (`enable: false` → без accsdb-гейта) |
| `TelegramAuthBot` | `@GatusMonBot` — long-polling бот привязки и админ-команды | секция `"TelegramAuthBot"` |
# 2. Проверка
curl -fsS "http://localhost:9118/version?type=hash" # должен вернуть hash
curl -fsS -o /dev/null -w '%{http_code}\n' http://localhost:9118/online.js # 200
Клиентский плагин `tg-notify.js` зарегистрирован в `LampaWeb.customPlugins`; `{localhost}` в URL автоматически подставляется сервером.
# 3. Логи / статус
docker compose logs -f lampac
docker compose ps
```
> **Модуль `Music` удалён из `mods/`** (коммит `remove Music`): в образе у него `manifest.enable: false`, поэтому `/music.js` → 404, секция `"Music"` из `init.conf` убрана, плагин из `customPlugins` убран. Вернуть музыку — той же механикой: скопировать `lampac:/lampac/module/Music` в `mods/Music`, поставить `enable: true`, вернуть секцию и плагин.
## Доступ
### Ещё можно включить тем же способом
| Сервис | URL |
| --- | --- |
| Веб-интерфейс (Lampa UI) | http://localhost:9118/ |
| Плагин Online для Lampa | http://localhost:9118/online.js |
| Плагин SISI (18+) | http://localhost:9118/sisi.js |
| Плагин DLNA для Lampa | http://localhost:9118/dlna.js |
| AdminPanel (вход) | http://localhost:9118/adminpanel/auth |
| Проверка версии | http://localhost:9118/version?type=hash |
В образе выключены также: `DatabaseEditor`, `ExternalBind`, `LogUserRequest-Lite`, `Transcoding`, `Music`, `WatchTogether`.
Чтобы подключить сервер к Lampa: откройте Lampa → Настройки → «Другие сервисы» (или вставьте адрес вручную) → `http://IP_МАШИНЫ:9118`.
Для доступа с других устройств локальной сети используйте LAN-IP машины, например `http://192.168.x.x:9118` (порт уже проброшен на `0.0.0.0`).
## Конфигурация
- `config/init.conf` — JSON. После правки: `docker compose restart`. Следи за валидностью JSON (лишняя запятая ломает парсинг).
- `BaseModule.SkipModules` / `BaseModule.LoadModules` — фильтры загрузки модулей (имя, группа, regex). `SkipModules` имеет приоритет над `LoadModules`.
- `LampaWeb.initPlugins` — флаги встроенных плагинов веб-клиента; `LampaWeb.customPlugins` — дополнительные плагины (`status: 1`).
- `LampaWeb.autoupdate: true` — Lampa Web-клиент автообновляется из `yumata/lampa` (раз в 90 минут).
### `config/init.conf`
## Установка плагинов по ссылке через веб (AdminPanel)
Основной конфиг (JSON). **Перечитывается автоматически без перезапуска** контейнера (watcher каждую секунду, бэкапы — внутри контейнера в `/lampac/database/backup/init/`). После правки достаточно сохранить файл.
Список плагинов, который сервер раздаёт всем клиентам через `/lampainit.js` и `/on.js`, собирается по `LampaWeb.initPlugins` + `LampaWeb.customPlugins`. Watcher перечитывает `init.conf` без перезапуска (интервал ~1 с, runtime-параметры применяются на лету).
Ключевые разделы:
1. Открой **http://localhost:9118/adminpanel**, введи root-пароль (содержимое `config/passwd`) — пароль сохраняется в cookie `accspasswd` (штатный механизм root-авторизации).
2. В редакторе `init.conf` открой секцию **`LampaWeb`** → **`customPlugins`** и добавь запись:
```json
{ "url": "https://example.com/plugin.js", "status": 1, "name": "ИмяПлагина" }
```
Поддерживается плейсхолдер `{localhost}` — сервер подставит свой адрес.
3. Сохрани — перезапуск не нужен. Проверка: `curl -s http://localhost:9118/lampainit.js | grep <имя>`.
Нюансы:
- `status: 1` — активная запись.
- Family-dedup: `name.js` и `name/js/{token}` считаются одним плагином; если в registry клиента уже есть один вариант, второй из серверного списка не добавляется.
- Внешние URL должны быть доступны из браузеров клиентов и отдавать CORS-заголовки.
- Альтернатива без сервера: вставить ссылку напрямую в веб-клиенте Lampa (настройки → «Плагины») — тогда плагин живёт только в localStorage этого браузера и грузится браузером напрямую.
API (для скриптов): `GET/POST /adminpanel/api/init`, `POST /adminpanel/api/init/section/{key}` с cookie `accspasswd=<root-пароль>`.
## Каталог плагинов (раздел «Плагины» в веб-клиенте)
В веб-клиенте Lampa раздел «Плагины» грузит каталог (store) с маршрута **`/extensions`** (включается при `LampaWeb.initPlugins.pirate_store: true`). Содержимое берётся из файла `LampaWeb/plugins/extensions.json` модуля — у нас он переопределён файловым mount из `./plugins/extensions.json` (см. `docker-compose.yaml`). Плейсхолдер `{localhost}` в ссылках сервер заменяет своим адресом.
**Все плагины каталога размещены локально** (mirror): `.js`-файлы лежат в `./plugins/`, каталог целиком смонтирован в `/lampac/wwwroot/plugins/` (одна строка в compose) и ссылки в каталоге ведут на `{localhost}/plugins/<имя>.js`. (Целиком в корень `wwwroot` монтировать нельзя — перекроется веб-клиент `lampa-main`.) Сами файлы плагинов всегда локальные; исключение — плагин-лоадеры, подгружающие основной код с внешнего хоста: «Клубничка 18+» (rc.bwa.ad) и Showy (showy.online/online.js — файл локально патчен под абсолютный URL, иначе он бы подгружал `/online.js` с нашего сервера). Остальные скачаны целиком (для pubtorr / torrentmanager / td скачано тело, а не лоадер).
- `plugins/sources.json` — карта «локальный файл → исходный URL». Для обновления плагина: скачать файл по исходному URL, перезаписать локальный, перезапуск не нужен.
- `plugins/modss.js` — локальная patched-копия MODS's (заменён вызов `Lampa.Utils.isPWA()`), раздаётся как `/plugins/modss.js`, но из каталога исключена (upstream мёртв: загрузчик отвечает stub-ошибкой «Используйте: lampa.mx»). Вернуть карточку можно, добавив запись с `link: "{localhost}/plugins/modss.js"`.
Удалены из каталога (мёртвы upstream, проверено по факту выдачи):
- «MODS's» (`lampa.stream/modss`) — загрузчик отвечает stub-ошибкой;
- «Отзывы и рецензии» (`lampaplugins.github.io/store/o.js`) — файл заменён автором на пустой stub;
- «Вторая кнопка Торренты», «Поиск локального TorrServer», «Горячие кнопки», «Золотая Тема», «Тип управления», «Старый стиль», «Мультфильмы» — публичных копий нет;
- «Телевидение by Skaz» / «ТВ by skaz» / «ТВ by skaz 2.0» — файлы заменены placeholder-заглушками;
- «Импорт/Экспорт закладок, истории» (`skaz.tv/export.js`) — 404.
Важный нюанс — **диск-кеш ответа**: маршруты LampaWeb кешируют ответы в `/lampac/cache/static/<bucket>/<id>.json` (named volume `lampac_cache`), кеш переживает рестарт контейнера. После правки `extensions.json` для мгновенного применения удалить закешированную запись:
```bash
docker exec lampac rm -rf /lampac/cache/static/59 # bucket /extensions; либо весь /lampac/cache/static
```
Перезапуск контейнера при этом **не требуется** (маршрут читает файл при каждом запросе, если нет кеш-записи).
## Tg-notify.bot: Telegram-бот уведомлений о новых сериях
Фоновый Telegram-бот (long polling): пользователь подписывается на сериал прямо из карточки Lampa, бот отслеживает выход новых эпизодов и появление выбранной озвучки и шлёт в Telegram уведомление с обложкой, номером серии и описанием из TMDB.
Модуль объединяет три подсистемы:
1. **Трекер новых серий** — Trakt API (если задан `trakt_client_id`), иначе TMDB.
2. **Трекер озвучек** — параллельный опрос встроенных балансиров **Mirage**, **Collaps** и **VideoHub** через `lampac_host` (`/lite/mirage`, `/lite/collaps`, `/lite/cdnvideohub`); берётся максимальный эпизод из всех источников.
3. **Клиентский плагин** `tg-notify.js` — вкладка «TG Подписки», перехват кнопки 🔔 в карточке, меню выбора озвучки.
### Как это работает (поток)
1. **Привязка аккаунта** — во вкладке «TG Подписки» в Lampa выдаётся deep-link `/start link_{uid}` (для UID вида email — `/start link64_{base64url(uid)}`). После `/start` бот сохраняет связку `chat_id ↔ lampac_uid` в `database/tgnotify/users.json`; подписки становятся общими для всех устройств этого аккаунта.
2. **Подписка** — в карточке сериала кнопка 🔔 перехватывается плагином, показывается меню озвучек (`GET /api/tg/voices`), выбор уходит на `POST /api/tg/subscribe` и сохраняется в `subscriptions.json`.
3. **Фоновый цикл `CheckAll`** — раз в `check_interval_minutes` (первый прогон — через 2 минуты после старта, вручную — `/check`): новые серии через Trakt→TMDB; если выбрана конкретная озвучка — параллельно Mirage + Collaps + VideoHub.
4. **Уведомление** — сообщение вида:
```
🎬 Название
🎙 Озвучка
📺 S05E08 — Название эпизода
Описание (до 300 символов)
```
с обложкой кадра из TMDB (`still_path`), если есть.
### Конфигурация (секция `TelegramBot` в `config/init.conf`)
| Поле | Назначение |
|---|---|
| `bot_token` | Токен от [@BotFather](https://t.me/BotFather). **Обязателен** — без него long polling не стартует (в логе предупреждение, сервер работает) |
| `tmdb_api_key` | Ключ TMDB v3: обложки, описания эпизодов, определение актуального сезона |
| `trakt_client_id` | Client ID Trakt; основной источник новых серий (если пуст — только TMDB) |
| `lampac_host` | Базовый URL Lampac для запросов к балансерам; в Docker — `http://127.0.0.1:9118` |
| `lampac_token` | Токен `accsdb`; обязателен, если включена защита (иначе балансеры вернут ошибку входа) |
| `kp_api_key` | Ключ kinopoiskapiunofficial.tech — резолвинг `tmdb_id → kinopoisk_id` по названию для VideoHub (опционально; без него покрытие ~40% через мост `/externalids`) |
| `check_interval_minutes` | Период фоновой проверки (дефолт 60) |
| `tmdb_lang` | Язык метаданных TMDB (дефолт `ru-RU`, фоллбэк `en-US`) |
| `data_dir` | Каталог `users.json`/`subscriptions.json` (дефолт `database/tgnotify` — у нас это том `./database/`, переживает рестарты) |
### Быстрый старт
1. [@BotFather](https://t.me/BotFather) → `/newbot` → получить токен.
2. `config/init.conf` → `TelegramBot.bot_token` = токен.
3. `docker compose restart lampac` (по желанию — заполнить `tmdb_api_key` и `trakt_client_id`).
4. В Lampa (http://localhost:9118) вкладка «TG Подписки» → deep-link → `/start` у бота.
5. В карточке сериала — 🔔, выбрать озвучку (или «без озвучки» — уведомление о самом факте выхода серии).
### Команды бота
| Команда | Действие |
|---|---|
| `/start` | Приветствие; `/start link_{uid}` — привязка аккаунта |
| `/list` | Список активных подписок |
| `/check` | Принудительная проверка в фоне |
| `/help` | Справка |
| `/unlink` | Отвязать аккаунт |
### HTTP API
| Метод | Маршрут | Назначение |
|---|---|---|
| `GET` | `/tg-notify.js` | Раздача клиентского плагина (AllowAnonymous) |
| `POST` | `/api/tg/subscribe` | Подписка на сериал/озвучку |
| `POST` | `/api/tg/unsubscribe` | Отписка |
| `GET` | `/api/tg/status?tmdb_id=` | Статус подписки текущего пользователя |
| `GET` | `/api/tg/voices?title=&year=&season=&tmdb_id=` | Доступные озвучки (Mirage + Collaps + VideoHub) |
| `GET` | `/api/tg/link` | Deep-link для привязки бота |
| `GET` | `/api/tg/subscriptions` | Все подписки пользователя с метаданными |
Все маршруты, кроме `/tg-notify.js` и `/api/tg/voices`, требуют `requestInfo.user_uid` (вход в аккаунт).
### Состояние на нашем инстансе
- Модуль загружен, `/tg-notify.js` → 200, плагин уже в `LampaWeb.customPlugins`, вкладка «TG Подписки» видна; аккаунт привязан (`database/tgnotify/users.json`).
- `bot_token` заполняется **только локально**: в git поле пустое (правило 10), токен вставлен в `config/init.conf` на сервере и при работе `@KlinkerZabbixBot` (`[TelegramBot] @KlinkerZabbixBot запущен!`). После любого `git pull`/правки конфига токен нужно вернуть на место — иначе polling не стартует.
- Трекинг озвучек зависит от балансиров: на текущий момент `GET /lite/mirage` → тело `disable`, `GET /lite/collaps` → `503` — до тех пор, пока они не будут доступны (или не включится `lampac_token` при защите), бот будет уведомлять только о выходе серий (TMDB/Trakt).
## TelegramAuth + TelegramAuthBot: вход в Lampa через Telegram
Пара модулей из группы **Community** — замена пароля аккаунта подтверждением в Telegram (сценарий: ТВ, где вводить пароль неудобно). Не путать с Tg-notify.bot — тот только уведомляет о сериях.
- **`TelegramAuth`** — серверная часть: хранение пользователей/устройств, HTTP API `/tg/auth/*`, синхронизация UID в `accsdb`; **Telegram Auth Gate** — вместо экрана `deny.js` (модалка пароля) показывает fullscreen-оверлей с UID, кнопкой «Открыть Telegram» и QR-кодом на крупных экранах.
- **`TelegramAuthBot`** — long-polling бот: пользователь открывает бота (`/start link_{uid}` или отправляет UID), бот сам вызывает `POST /tg/auth/bind/complete`; есть админ-команды. HTTP UI нет.
Активация гейта — только при трёх условиях сразу: `accsdb.enable: true` + `LampaWeb.telegramAuthGate.enabled: true` + непустой `botUsername`. Иначе тихий откат на `deny.js`.
Конфиг (по образцу `init.merge.example.json` модулей):
```json
"TelegramAuth": {
"enable": true,
"mutations_api_secret": "SECRET"
},
"TelegramAuthBot": {
"enable": true,
"bot_token": "ТОКЕН_ОТ_BOTFATHER",
"mutations_api_secret": "SECRET"
},
"LampaWeb": {
"telegramAuthGate": {
"enabled": true,
"botUsername": "имя_бота_без_@",
"serviceName": "lampa"
}
```jsonc
{
"listen": { "ip": "0.0.0.0", "port": 9118, "scheme": "http" },
"BaseModule": {
"SkipModules": [/* выключенные модули, см. ниже */]
},
"LampaWeb": { "initPlugins": { "dlna": true } }, // попадание плагина в список клиента Lampa
"TorrServer": { "enable": true, "tsport": 9085, "releases": "latest" },
"TelegramBot": { "enable": true, "bot_token": "", "lampac_host": "http://127.0.0.1:9118" },
"chromium": { "enable": true }, // Playwright для обхода JS-защит
"online": { "name": "Lampac NextGen" },
"sisi": { "NextHUB": true }
}
```
`mutations_api_secret` должен совпадать в обоих модулях и быть ненулевым — защищает `bind/complete` и бот-админку; вместе с `bot_token` не публиковать. Оба модуля выключены в `base.conf` (`SkipModules`) и в манифестах (`enable: false`).
### Текущий набор модулей
**Состояние у нас:** модули **включены** (копии в `mods/TelegramAuth/` и `mods/TelegramAuthBot/`, манифесты `enable: true`, `SkipModules` пуст), работают в **API-режиме**: `TelegramAuth.enable: false` → `accsdb` не поднимается, гейт неактивен, доступ не режется. Бот `@GatusMonBot` — `Telegram API OK`, long polling идёт; `owner_telegram_ids: [143672]` создаёт владельца ролью `admin` при старте, `auto_provision_users: true` + `auto_provision_activate_immediately: false` — новые привязки висят в pending до одобрения кнопкой у админа. Секрет `mutations_api_secret` (одинаков в обеих секциях) и `bot_token` лежат в `config/init.conf` **только на сервере**.
**Выключены** (`BaseModule.SkipModules`): `OnlineAnime`, `OnlineUKR`, `OnlinePaid`, `OnlineGEO`, `Transcoding`, `WebLog`.
**Порядок включения гейта (когда решим):** поставить `TelegramAuth.enable: true` → в `LampaWeb` секцию `telegramAuthGate` (`enabled: true`, `botUsername: "GatusMonBot"`) → подключить клиентский оверлей (`deny.js` / `telegram_auth_gate.js`) → **сначала связать свои устройства через бота**, иначе текущие UID получат отказ.
**Включены дополнительно к стартовому набору:**
## Обновление Lampac
- `Catalog`, `JacRed`, `Sync` (вместе с `Storage`, `SyncEvents`, `TimeCode`), `TorrServer`, `DLNA`, `SISI` — убраны из `SkipModules`.
- `Tracks`, `Music`, `Tg-notify.bot`, `AdminPanel` — включены через manifest-оверрайды в `modules/*/manifest.json` (в образе у них `enable: false`; файлы монтируются поверх `/lampac/module/<Name>/manifest.json`).
Чтобы выключить/включить любой другой модуль — добавьте или уберите его имя в `SkipModules` (имя = имя папки в `/lampac/module/`, включая группы вроде `OnlineAnime`). Изменение применяется после `docker compose restart lampac` (SkipModules не hot-reload). Убрать из списка группу `Sync` целиком отключит и `TimeCode`/`Storage`/`SyncEvents`.
Список всех модулей и маршрутов: https://docs.lampac.dev/modules/overview
### TorrServer
Включён (`TorrServer` в `init.conf`, бинарник сам скачивается с GitHub в `/lampac/data/ts/`). Доступ **только из локальной сети**:
- внутренний порт TorrServer `9085` **не проброшен на хост** — снаружи он недоступен;
- внешний доступ идёт только через прокси `http://LAN_IP:9118/ts/` (порт 9118 в compose);
- из интернета сервер не доступен, пока порт 9118 закрыт файрволом/роутером (см. «Безопасность»).
Пароль (`tspass`) генерируется при старте; Web-UI — `http://LAN_IP:9118/ts/`.
### Tg-notify (Telegram-бот)
Модуль `Tg-notify.bot` загружен, но long polling не стартует, пока не задан токен: впишите `bot_token` (от [@BotFather](https://t.me/BotFather)) в секцию `TelegramBot` файла `init.conf` — конфиг подхватится автоматически. Опционально: `tmdb_api_key`, `trakt_client_id`, `kp_api_key` (описание полей — в README модуля).
### DLNA в интерфейсе Lampa
Чтобы плагин DLNA появился в Lampa, нужно две вещи:
1. **Модуль** загружен (уже включён: `loaded module: DLNA`).
2. **Флаг `LampaWeb.initPlugins.dlna`** в `init.conf` — именно он решает, попадёт ли DLNA в список плагинов, который Lampac отдаёт клиенту (`/lampainit.js`). Сейчас выставлен `true`; без него Lampa плагин не увидит (модуль работает, а пункт в меню не появляется).
```jsonc
"LampaWeb": { "initPlugins": { "dlna": true } }
```
Аналогично включаются флаги `tracks`, `catalog`, `dorama`, `sync`, `backup`, `watch_together` и др. (список — `LampaWeb/Models/InitPlugins.cs`, дефолты — в `current.conf`).
После правки перезагрузите страницу Lampa — `lampainit.js` сам добавит плагин (`Lampa.Plugins.add`) и он появится в Настройки → Плагины (со статусом включён). Ручное добавление по ссылке тоже работает: `http://IP_МАШИНЫ:9118/dlna.js`. Прямой UI модуля — `http://IP_МАШИНЫ:9118/dlna`.
**В магазине плагинов** (Настройки → Плагины/«Магазин») каталог отдаётся из `/extensions` — файла `LampaWeb/plugins/extensions.json` внутри образа, где DLNA по умолчанию нет. Добавлена запись через override: `modules/LampaWeb/plugins/extensions.json` (секция «Lampac» в начале каталога) монтируется поверх образного файла. Магазин кешируется (`Staticache`) — после правки этого файла кеш надо сбросить: удалить `cache/static/63/*` (каталог по хешу URL) или перезапустить контейнер.
### AdminPanel
Веб-админка Lampac: правка `init.conf`/`current.conf`, пользователи `users.json`.
- Вход: `http://IP_МАШИНЫ:9118/adminpanel/auth` — пароль из `config/passwd` (cookie `accspasswd`, живёт 180 дней).
- Панель: `http://IP_МАШИНЫ:9118/adminpanel` (без входа — 302 на страницу auth).
- Доступ к админке не открывайте в интернет без защиты — см. README модуля AdminPanel.
### `config/passwd`
Пароль учётной записи `root` в одну строку (используется для служебных функций и WebLog). Сгенерирован при установке; для смены отредактируйте файл и перезапустите контейнер: `docker compose restart lampac`.
## Обновление
```bash
docker compose pull
docker compose up -d
```
Перед обновлением проверить, что в `docker-compose.yaml` раскомментированы нужные тома. Данные сохраняются в примонтированных томах: `config/`, `cache/`, `database/`, `dlna/`, `mods/`, `lampa-main/`.
Данные (`init.conf`, `passwd`, `cache/`, `database/`, `modules/`) переживают обновление, т.к. смонтированы томами с абсолютными путями NAS.
`wwwroot/lampa-main` смонтирован как bind-mount из `./lampa-main/` (см. раздел «Структура проекта»), поэтому переживает рекреацию контейнера. Если директория на хосте пуста — `bash scripts/restore-lampa-main.sh scripts/lampa-main.zip` (архив берётся с https://github.com/yumata/lampa/archive/refs/heads/main.zip).
## Перенос на другой сервер
**Образ закреплён точным digest** (`1.68.0@sha256:752dafd8…`): тег `1.68.0` на ghcr — mutable, его переиздавали, и в новой сборке **копии модулей в `mods/`** (Roslyn компилирует их на каждом старте) перестают собираться — `CS0103` по символам из старого билда и crash-loop сервера. Чтобы обновить образ: взять новый digest, пересобрать копии модулей в `mods/` из нового образа (`docker cp lampac:/lampac/module/<Имя> mods/<Имя>` + вернуть `"enable": true`) и заменить digest в `docker-compose.yaml`. Не делать «просто» `docker compose pull` без фиксации digest.
Игнорируемые пути (`.gitignore`): `config/passwd`, `cache/`, `database/`, `.DS_Store`.
**Копировать обязательно:**
```bash
docker-compose.yaml
config/init.conf # вся конфигурация
config/passwd # СЕКРЕТ — переносить вне git (scp/rsync)
modules/ # override-файлы (manifest ×4, extensions.json)
README.md AGENT.md .gitignore
```
**Копировать по желанию** (данные пользователя, иначе создадутся заново):
```bash
database/ # закладки Sync, позиции TimeCode, SISI, библиотека Music
```
**Не копировать** — регенерируется автоматически: `cache/`, содержимое `/lampac/data` внутри контейнера (GeoLite2, ffmpeg/ffprobe, бинарник TorrServer, Lampa UI). Медиа DLNA лежат на томах NAS (`/volume4/Torrents`, `Курсы`) и копируются отдельно по необходимости.
Порядок переноса: скопировать файлы → **в `docker-compose.yaml` заменить абсолютные пути томов на новые** → `docker compose up -d` → health-check: `curl "http://localhost:9118/version?type=hash"`. Порт 9118 менять не обязательно.
## Полезные команды
```bash
docker compose restart lampac # перезапуск
docker compose stop lampac # остановить
docker compose down # остановить и удалить контейнер (тома сохраняются)
docker compose logs -f --tail 100 lampac # логи
docker compose exec lampac sh # шелл внутри контейнера
docker compose pull && docker compose up -d # обновление до свежего latest
```
## Безопасность
По предупреждению официальной документации:
- Порт 9118 проброшен на все интерфейсы — при выходе в интернет закройте его файрволом или поднимите reverse proxy с аутентификацией. Внутренний порт TorrServer (9085) не проброшен вовсе: он доступен только контейнеру, внешний доступ к TorrServer идёт исключительно через `/ts/` на 9118.
- Модули `DLNA`, `Tracks`, `Transcoding`, `GStreamer`, `Catalog` не экранируют входящие запросы — не открывайте их публично без защиты.
- `config/passwd` содержит секрет — файл добавлен в `.gitignore`.
- Не публикуй в интернет без аутентификации, WAF и ограничения сети: `/adminpanel`, `/weblog`, `/database-editor`, `Tracks`, `Transcoding`, `Catalog`, `DLNA`, proxy-модули.
- Нигде не раскрывай `config/passwd`, cookie `accspasswd`, заголовок `lcrqpasswd`.
- **Секреты в git не попадают**: `TelegramBot.bot_token`, `TelegramAuthBot.bot_token`, `mutations_api_secret` хранятся в `config/secrets.env` (в .gitignore). В git `config/init.conf` эти поля всегда пустые. Реальный боевой конфиг — `config/init.custom.conf` (тоже gitignored), собирается скриптом `scripts/config-secrets.py apply` из шаблона + секретов. Перед `git add config/init.conf`: `python3 scripts/config-secrets.py check` → должно быть `check: секретов в config/init.conf нет — ок`.
- Для публикации за reverse proxy: [deployment/reverse-proxy](https://docs.lampac.dev/deployment/reverse-proxy) (HTTPS в ответах, реальный IP клиента, WebSocket, SSE, streaming).
- `shm_size: 4096mb` — рекомендованный минимум для Playwright/Chromium.
## Git-репозиторий
Код проекта хранится в Gitea: `ssh://git@gitea.prodik.ru:222/prodik/lampac.git`.
- **`main`** — основная ветка: относительные пути томов (подходит для любого сервера).
- **`synology`** (эта ветка) — то же содержимое, но `docker-compose.yaml` адаптирован под Synology NAS: абсолютные пути `/volume1/docker/lampac/...`, тома `/volume4/Torrents` и `Курсы`.
```bash
git remote -v # origin должен указывать на этот репозиторий
git add -A # секреты/данные не попадут (.gitignore)
git commit -m "описание"
git push origin synology
```
В git попадают только: `docker-compose.yaml`, `config/init.conf`, `modules/**`, `README.md`, `AGENT.md`, `.gitignore`. Секреты (`passwd`), `cache/`, `database/` — в `.gitignore`.
## Ссылки
- Репозиторий форка: https://github.com/lampac-nextgen/lampac
- Документация: https://docs.lampac.dev
- Быстрый старт: https://docs.lampac.dev/quickstart
- Docker: https://docs.lampac.dev/deployment/docker
- Конфигурация: https://docs.lampac.dev/configuration/overview
- Релизы: https://github.com/lampac-nextgen/lampac/releases
+54
View File
@@ -0,0 +1,54 @@
{
"listen": {
"version": true,
"ip": "0.0.0.0",
"port": 9118,
"scheme": "http",
"localhost": "127.0.0.1"
},
"BaseModule": {
"SkipModules": [
"OnlineAnime",
"OnlineUKR",
"OnlinePaid",
"OnlineGEO",
"Transcoding"
]
},
"TorrServer": {
"enable": true,
"tsport": 9085,
"releases": "latest"
},
"TelegramBot": {
"enable": true,
"bot_token": "",
"lampac_host": "http://127.0.0.1:9118"
},
"LampaWeb": {
"initPlugins": {
"dlna": true
}
},
"chromium": {
"enable": true,
"executablePath": "/usr/bin/chromium"
},
"openstat": {
"enable": true
},
"online": {
"name": "Lampac NextGen",
"spiderName": "Lampac NextGen",
"version": true,
"btn_priority_forced": true
},
"sisi": {
"lgbt": false,
"spider": false,
"NextHUB": true,
"history": {
"enable": false
}
}
}
Binary file not shown.
+17 -16
View File
@@ -3,23 +3,24 @@ name: lampac
services:
lampac:
image: ghcr.io/lampac-nextgen/lampac:1.72.0
image: ghcr.io/lampac-nextgen/lampac:latest
container_name: lampac
ports:
- 80:80
- 9118:9118
restart: unless-stopped
# shm_size: 4096mb
shm_size: 4096mb
# logging:
# options:
# tag: "{{.Name}}"
volumes:
- ./config/passwd:/lampac/passwd
- ./config/init.conf:/lampac/init.conf
- ./plugins/extensions.json:/lampac/module/LampaWeb/plugins/extensions.json
- ./plugins:/lampac/wwwroot/plugins
- ./mods:/lampac/mods
- ./cache:/lampac/cache
- ./database:/lampac/database
- ./dlna:/lampac/data/dlna
- ./data/ts:/lampac/data/ts
#volumes:
# cache:
# database:
- /volume1/docker/lampac/config/passwd:/lampac/passwd
- /volume1/docker/lampac/config/init.conf:/lampac/init.conf
- /volume1/docker/lampac/cache:/lampac/cache
- /volume1/docker/lampac/database:/lampac/database
- /volume1/docker/lampac/modules/Tracks/manifest.json:/lampac/module/Tracks/manifest.json:ro
- /volume1/docker/lampac/modules/Music/manifest.json:/lampac/module/Music/manifest.json:ro
- /volume1/docker/lampac/modules/Tg-notify.bot/manifest.json:/lampac/module/Tg-notify.bot/manifest.json:ro
- /volume1/docker/lampac/modules/AdminPanel/manifest.json:/lampac/module/AdminPanel/manifest.json:ro
- /volume1/docker/lampac/modules/LampaWeb/plugins/extensions.json:/lampac/module/LampaWeb/plugins/extensions.json:ro
- /volume4/Torrents:/lampac/data/dlna
- /volume1/homes/prodik/NAS/Курсы:/lampac/data/dlna/Cources:ro
-5
View File
@@ -1,5 +0,0 @@
.git
.idea
.dockerignore
Dockerfile
README.md
-6
View File
@@ -1,6 +0,0 @@
FROM httpd:alpine3.15
ARG domain
ARG prefix="http://"
RUN test -n "$domain" || (echo "ERROR: domain is not set" && false)
COPY . /usr/local/apache2/htdocs/
RUN sed -i -e "s|{domain}|$domain|" -e "s|{PREFIX}|$prefix|" /usr/local/apache2/htdocs/msx/start.json
-339
View File
@@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
-26
View File
@@ -1,26 +0,0 @@
# Lampa
Приложение полностью бесплатное и использует публичные ссылки для просмотра информации о фильмах, новинках, популярных фильмов и т.д. Вся доступная информация используется исключительно в познавательных целях, приложение не использует свои собственные серверы для распространения информации.
Исходники лампы доступны тут: https://github.com/yumata/lampa-source
#### Устройства
* LG WebOS
* Samsung Tizen
* MSX
* Android
* MacOS
* Windows
## Установка для MSX
На данный момент ручная установка, вам необходим свой собственный хостинг или локальный веб-сервер.
1. Тут же нажмите на зеленую кнопку (Code) и выберите (Download ZIP) загрузите файлы на хостинг или веб-сервер.
2. Откройте файл `msx/start.json` и замените содержиое `{domain}` на свой домен или IP
3. Откройте MSX и выполните установку
## Запуск в Docker'е
1. Соберите образ `docker build --build-arg domain={domain} -t lampa . `
2. Запустите контейнер `docker run -p 8080:80 -d --restart unless-stopped -it --name lampa lampa`
-6
View File
@@ -1,6 +0,0 @@
# Security Policy
:x: Этот проект не обеспечивает безопасность ваших данных.
Проект поддерживает возможность подключать сторонние плагины. Непроверенные плагины могут содержать в себе вредоносный код, который может пагубно повлиять на работу приложения.
Устанавливайте только проверенные плагины.
-56844
View File
File diff suppressed because one or more lines are too long
-8
View File
@@ -1,8 +0,0 @@
{
"app_version": "3.3.5",
"css_version": "3.3.4",
"css_digital": 334,
"app_digital": 335,
"time": 1791132984642,
"hash": "25ee3b0d1c845b4c71b87e7f3af98637"
}
-16239
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-342
View File
@@ -1,342 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, noarchive">
<title>Transfonter demo</title>
<link href="stylesheet.css" rel="stylesheet">
<style>
/*
http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
/* common styles */
body {
background: #f1f1f1;
color: #000;
}
.page {
background: #fff;
width: 920px;
margin: 0 auto;
padding: 20px 20px 0 20px;
overflow: hidden;
}
.font-container {
overflow-x: auto;
overflow-y: hidden;
margin-bottom: 40px;
line-height: 1.3;
white-space: nowrap;
padding-bottom: 5px;
}
h1 {
position: relative;
background: #444;
font-size: 32px;
color: #fff;
padding: 10px 20px;
margin: 0 -20px 12px -20px;
}
.letters {
font-size: 25px;
margin-bottom: 20px;
}
.s10:before {
content: '10px';
}
.s11:before {
content: '11px';
}
.s12:before {
content: '12px';
}
.s14:before {
content: '14px';
}
.s18:before {
content: '18px';
}
.s24:before {
content: '24px';
}
.s30:before {
content: '30px';
}
.s36:before {
content: '36px';
}
.s48:before {
content: '48px';
}
.s60:before {
content: '60px';
}
.s72:before {
content: '72px';
}
.s10:before, .s11:before, .s12:before, .s14:before,
.s18:before, .s24:before, .s30:before, .s36:before,
.s48:before, .s60:before, .s72:before {
font-family: Arial, sans-serif;
font-size: 10px;
font-weight: normal;
font-style: normal;
color: #999;
padding-right: 6px;
}
pre {
display: block;
position: relative;
padding: 9px;
margin: 0 0 10px;
font-family: Monaco, Menlo, Consolas, "Courier New", monospace !important;
font-size: 13px;
line-height: 1.428571429;
color: #333;
font-weight: normal !important;
font-style: normal !important;
background-color: #f5f5f5;
border: 1px solid #ccc;
overflow-x: auto;
border-radius: 4px;
}
pre:after {
display: block;
position: absolute;
right: 0;
top: 0;
content: 'Usage';
line-height: 1;
padding: 5px 8px;
font-size: 12px;
color: #767676;
background-color: #fff;
border: 1px solid #ccc;
border-right: none;
border-top: none;
border-radius: 0 4px 0 4px;
z-index: 10;
}
/* responsive */
@media (max-width: 959px) {
.page {
width: auto;
margin: 0;
}
}
</style>
</head>
<body>
<div class="page">
<div class="demo" style="font-family: 'Segoe UI'; font-weight: 300; font-style: normal;">
<h1>Segoe UI Light</h1>
<pre>.your-style {
font-family: 'Segoe UI';
font-weight: 300;
font-style: normal;
}</pre>
<div class="font-container">
<p class="letters">
абвгдеёжзийклмнопрстуфхцчшщъыьэюя <br />
АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ <br />
abcdefghijklmnopqrstuvwxyz <br />
ABCDEFGHIJKLMNOPQRSTUVWXYZ <br /> 0123456789.:,;()*!?'@#<>$%&^+-=~
</p>
<p class="s10" style="font-size: 10px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s11" style="font-size: 11px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s12" style="font-size: 12px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s14" style="font-size: 14px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s18" style="font-size: 18px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s24" style="font-size: 24px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s30" style="font-size: 30px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s36" style="font-size: 36px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s48" style="font-size: 48px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s60" style="font-size: 60px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s72" style="font-size: 72px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
</div>
</div>
<div class="demo" style="font-family: 'Segoe UI'; font-weight: bold; font-style: italic;">
<h1>Segoe UI Bold Italic</h1>
<pre>.your-style {
font-family: 'Segoe UI';
font-weight: bold;
font-style: italic;
}</pre>
<div class="font-container">
<p class="letters">
абвгдеёжзийклмнопрстуфхцчшщъыьэюя <br />
АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ <br />
abcdefghijklmnopqrstuvwxyz <br />
ABCDEFGHIJKLMNOPQRSTUVWXYZ <br /> 0123456789.:,;()*!?'@#<>$%&^+-=~
</p>
<p class="s10" style="font-size: 10px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s11" style="font-size: 11px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s12" style="font-size: 12px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s14" style="font-size: 14px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s18" style="font-size: 18px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s24" style="font-size: 24px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s30" style="font-size: 30px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s36" style="font-size: 36px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s48" style="font-size: 48px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s60" style="font-size: 60px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s72" style="font-size: 72px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
</div>
</div>
<div class="demo" style="font-family: 'Segoe UI'; font-weight: 600; font-style: normal;">
<h1>Segoe UI Semibold</h1>
<pre>.your-style {
font-family: 'Segoe UI';
font-weight: 600;
font-style: normal;
}</pre>
<div class="font-container">
<p class="letters">
абвгдеёжзийклмнопрстуфхцчшщъыьэюя <br />
АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ <br />
abcdefghijklmnopqrstuvwxyz <br />
ABCDEFGHIJKLMNOPQRSTUVWXYZ <br /> 0123456789.:,;()*!?'@#<>$%&^+-=~
</p>
<p class="s10" style="font-size: 10px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s11" style="font-size: 11px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s12" style="font-size: 12px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s14" style="font-size: 14px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s18" style="font-size: 18px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s24" style="font-size: 24px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s30" style="font-size: 30px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s36" style="font-size: 36px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s48" style="font-size: 48px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s60" style="font-size: 60px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s72" style="font-size: 72px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
</div>
</div>
<div class="demo" style="font-family: 'Segoe UI'; font-weight: normal; font-style: normal;">
<h1>Segoe UI</h1>
<pre>.your-style {
font-family: 'Segoe UI';
font-weight: normal;
font-style: normal;
}</pre>
<div class="font-container">
<p class="letters">
абвгдеёжзийклмнопрстуфхцчшщъыьэюя <br />
АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ <br />
abcdefghijklmnopqrstuvwxyz <br />
ABCDEFGHIJKLMNOPQRSTUVWXYZ <br /> 0123456789.:,;()*!?'@#<>$%&^+-=~
</p>
<p class="s10" style="font-size: 10px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s11" style="font-size: 11px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s12" style="font-size: 12px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s14" style="font-size: 14px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s18" style="font-size: 18px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s24" style="font-size: 24px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s30" style="font-size: 30px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s36" style="font-size: 36px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s48" style="font-size: 48px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s60" style="font-size: 60px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s72" style="font-size: 72px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
</div>
</div>
<div class="demo" style="font-family: 'Segoe UI'; font-weight: bold; font-style: normal;">
<h1>Segoe UI Bold</h1>
<pre>.your-style {
font-family: 'Segoe UI';
font-weight: bold;
font-style: normal;
}</pre>
<div class="font-container">
<p class="letters">
абвгдеёжзийклмнопрстуфхцчшщъыьэюя <br />
АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ <br />
abcdefghijklmnopqrstuvwxyz <br />
ABCDEFGHIJKLMNOPQRSTUVWXYZ <br /> 0123456789.:,;()*!?'@#<>$%&^+-=~
</p>
<p class="s10" style="font-size: 10px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s11" style="font-size: 11px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s12" style="font-size: 12px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s14" style="font-size: 14px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s18" style="font-size: 18px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s24" style="font-size: 24px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s30" style="font-size: 30px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s36" style="font-size: 36px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s48" style="font-size: 48px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s60" style="font-size: 60px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s72" style="font-size: 72px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
</div>
</div>
<div class="demo" style="font-family: 'Segoe UI'; font-weight: normal; font-style: italic;">
<h1>Segoe UI Italic</h1>
<pre>.your-style {
font-family: 'Segoe UI';
font-weight: normal;
font-style: italic;
}</pre>
<div class="font-container">
<p class="letters">
абвгдеёжзийклмнопрстуфхцчшщъыьэюя <br />
АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ <br />
abcdefghijklmnopqrstuvwxyz <br />
ABCDEFGHIJKLMNOPQRSTUVWXYZ <br /> 0123456789.:,;()*!?'@#<>$%&^+-=~
</p>
<p class="s10" style="font-size: 10px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s11" style="font-size: 11px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s12" style="font-size: 12px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s14" style="font-size: 14px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s18" style="font-size: 18px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s24" style="font-size: 24px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s30" style="font-size: 30px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s36" style="font-size: 36px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s48" style="font-size: 48px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s60" style="font-size: 60px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
<p class="s72" style="font-size: 72px;">Съешь же ещё этих мягких французских булок, да выпей чаю.</p>
</div>
</div>
</div>
</body>
</html>
-67
View File
@@ -1,67 +0,0 @@
/* This stylesheet generated by Transfonter (https://transfonter.org) on August 23, 2017 4:44 PM */
@font-face {
font-family: 'Segoe UI';
src: url('SegoeUI-Light.eot');
src: local('Segoe UI Light'), local('SegoeUI-Light'),
url('SegoeUI-Light.eot?#iefix') format('embedded-opentype'),
url('SegoeUI-Light.woff') format('woff'),
url('SegoeUI-Light.ttf') format('truetype');
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'Segoe UI';
src: url('SegoeUI-BoldItalic.eot');
src: local('Segoe UI Bold Italic'), local('SegoeUI-BoldItalic'),
url('SegoeUI-BoldItalic.eot?#iefix') format('embedded-opentype'),
url('SegoeUI-BoldItalic.woff') format('woff'),
url('SegoeUI-BoldItalic.ttf') format('truetype');
font-weight: bold;
font-style: italic;
}
@font-face {
font-family: 'Segoe UI';
src: url('SegoeUI-SemiBold.eot');
src: local('Segoe UI Semibold'), local('SegoeUI-SemiBold'),
url('SegoeUI-SemiBold.eot?#iefix') format('embedded-opentype'),
url('SegoeUI-SemiBold.woff') format('woff'),
url('SegoeUI-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Segoe UI';
src: url('SegoeUI.eot');
src: local('Segoe UI'), local('SegoeUI'),
url('SegoeUI.eot?#iefix') format('embedded-opentype'),
url('SegoeUI.woff') format('woff'),
url('SegoeUI.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Segoe UI';
src: url('SegoeUI-Bold.eot');
src: local('Segoe UI Bold'), local('SegoeUI-Bold'),
url('SegoeUI-Bold.eot?#iefix') format('embedded-opentype'),
url('SegoeUI-Bold.woff') format('woff'),
url('SegoeUI-Bold.ttf') format('truetype');
font-weight: bold;
font-style: normal;
}
@font-face {
font-family: 'Segoe UI';
src: url('SegoeUI-Italic.eot');
src: local('Segoe UI Italic'), local('SegoeUI-Italic'),
url('SegoeUI-Italic.eot?#iefix') format('embedded-opentype'),
url('SegoeUI-Italic.woff') format('woff'),
url('SegoeUI-Italic.ttf') format('truetype');
font-weight: normal;
font-style: italic;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="icons/mstile-150x150.png"/>
<TileColor>#1d1f20</TileColor>
</tile>
</msapplication>
</browserconfig>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 668 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

-39
View File
@@ -1,39 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="420.000000pt" height="420.000000pt" viewBox="0 0 420.000000 420.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.14, written by Peter Selinger 2001-2017
</metadata>
<g transform="translate(0.000000,420.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M2007 3654 c-1 -1 -35 -5 -76 -8 -147 -13 -340 -67 -491 -137 -430
-202 -752 -597 -859 -1055 -32 -138 -36 -183 -35 -379 0 -199 18 -307 76 -480
53 -160 168 -367 270 -489 90 -108 234 -240 335 -306 l48 -31 -49 43 c-282
246 -452 544 -504 884 -14 95 -7 373 12 464 78 375 287 686 604 899 70 47 258
141 282 141 9 0 20 4 25 9 14 13 208 58 285 67 115 13 322 8 421 -11 503 -97
912 -455 1069 -935 54 -165 65 -238 64 -435 0 -195 -16 -295 -69 -449 -84
-243 -247 -477 -440 -631 -90 -71 -86 -73 11 -6 234 162 438 410 547 667 44
103 88 247 102 335 3 19 9 59 14 89 17 100 7 383 -18 497 -90 426 -327 775
-682 1006 -209 135 -440 218 -681 243 -56 6 -256 12 -261 8z"/>
<path d="M1955 3079 c-103 -14 -130 -20 -224 -51 -416 -137 -723 -489 -804
-921 -21 -113 -20 -312 3 -427 20 -100 53 -208 76 -250 l14 -25 -5 25 c-21
101 -26 294 -10 370 3 14 8 41 11 60 51 295 268 592 549 750 98 55 259 109
375 126 67 10 248 11 300 3 25 -4 63 -11 85 -14 51 -9 171 -49 242 -81 123
-57 205 -116 319 -229 170 -169 279 -389 311 -626 13 -100 6 -311 -13 -364 -5
-14 -4 -17 4 -10 6 6 24 51 41 100 97 292 76 633 -56 900 -135 271 -367 486
-643 593 -60 24 -182 57 -245 68 -57 9 -271 12 -330 3z"/>
<path d="M1981 2364 c-148 -40 -262 -128 -330 -255 -145 -268 -20 -605 264
-717 62 -25 112 -33 190 -33 221 1 407 137 478 349 88 261 -49 544 -310 639
-85 31 -214 38 -292 17z"/>
<path d="M1429 2209 c-13 -17 -29 -36 -34 -42 -51 -59 -119 -200 -147 -306
-16 -58 -21 -108 -22 -216 -1 -136 4 -170 39 -280 93 -288 335 -508 640 -582
76 -18 251 -24 335 -11 178 27 349 115 479 248 77 77 86 88 127 155 88 145
124 268 129 435 6 201 -37 353 -144 517 -68 103 -107 144 -74 78 56 -110 81
-228 78 -357 -3 -93 -8 -131 -32 -203 -81 -252 -293 -443 -553 -499 -89 -20
-265 -14 -350 12 -254 76 -442 267 -511 519 -47 171 -21 409 57 531 24 36 10
37 -17 1z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

-19
View File
@@ -1,19 +0,0 @@
{
"name": "",
"short_name": "",
"icons": [
{
"src": "android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "android-chrome-384x384.png",
"sizes": "384x384",
"type": "image/png"
}
],
"theme_color": "#1d1f20",
"background_color": "#1d1f20",
"display": "standalone"
}
-4
View File
@@ -1,4 +0,0 @@
<svg width="124" height="124" viewBox="0 0 124 124" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="124" height="124" fill="white"/>
<path d="M39.0059 63.0098C35.7733 63.9615 33.1661 65.0666 32.0316 65.9666C31.6922 66.2358 31.2871 66.3663 30.885 66.3663C30.3406 66.3663 29.8014 66.1268 29.4367 65.6671C28.8028 64.8678 28.9368 63.706 29.736 63.072C31.8024 61.4333 35.7772 60.1092 37.9625 59.466C38.941 59.1772 39.9678 59.7375 40.2559 60.7162C40.5441 61.6949 39.9844 62.7217 39.0059 63.0098ZM64.0188 75.1729C64.967 80.0419 64.0457 84.4863 61.3548 88.0259C58.9834 91.1449 55.4136 93.3037 51.3029 94.1041C50.1647 94.3257 49.0251 94.4353 47.9017 94.4353C44.9682 94.4353 42.1407 93.6887 39.7051 92.2416C35.8827 89.9706 33.3613 86.1963 32.4132 81.3272L32.3947 81.2318C32.2315 80.3842 32.6771 79.5366 33.4678 79.1906C34.816 78.6002 36.3494 78.0237 38.0251 77.4772C38.5542 77.3046 39.1329 77.3799 39.6006 77.682C45.9662 81.7976 51.6329 80.6939 55.9889 74.4909C56.3088 74.0353 56.817 73.7484 57.3723 73.7096C59.1299 73.5875 60.7678 73.5466 62.2403 73.5879C63.1041 73.6121 63.8358 74.2321 64.0014 75.0803L64.0192 75.1716L64.0188 75.1729ZM60.6022 77.2695C59.9252 77.2775 59.2165 77.3017 58.4801 77.3421C55.2098 81.6507 51.203 83.8423 46.8448 83.8427C44.1224 83.8429 41.264 82.9883 38.3604 81.2601C37.6629 81.499 36.9967 81.7426 36.3665 81.9891C38.4663 89.3032 45.0636 91.5554 50.5967 90.4783C56.1305 89.4009 61.3991 84.8387 60.6022 77.2695ZM51.0339 60.6676C54.3877 60.3368 57.2194 60.3831 58.608 60.7913C58.782 60.8426 58.9573 60.8669 59.1299 60.8669C59.9282 60.8669 60.6644 60.3452 60.901 59.5407C61.1887 58.5619 60.6289 57.5354 59.6501 57.2473C57.2473 56.5407 53.4408 56.718 50.6708 56.9915C49.6556 57.0915 48.9139 57.9959 49.014 59.011C49.1144 60.0262 50.0202 60.7679 51.0339 60.6676ZM72.7728 37.1017C72.8319 37.1072 72.8904 37.1101 72.9483 37.1101C73.8901 37.1101 74.6948 36.3928 74.7851 35.4363C74.8807 34.4206 74.1351 33.5197 73.1194 33.424C69.7644 33.1078 66.9938 32.5212 65.7085 31.8548C64.8024 31.3851 63.6878 31.7389 63.2186 32.6448C62.7491 33.5502 63.1027 34.665 64.0084 35.1346C66.3496 36.3481 70.5046 36.8881 72.7728 37.1017ZM85.5443 37.1101C85.6024 37.1101 85.6609 37.1072 85.7198 37.1017C88.4914 36.8406 92.2618 36.2871 94.4849 35.1342C95.3905 34.6646 95.7437 33.5496 95.2742 32.6442C94.8044 31.7389 93.6898 31.3857 92.7841 31.8548C91.4996 32.521 88.7293 33.1076 85.3732 33.424C84.3577 33.5197 83.6119 34.4204 83.7075 35.4363C83.7976 36.3928 84.6023 37.1101 85.5443 37.1101ZM75.4964 73.145C78.0104 86.0563 68.8638 99.4938 53.7478 105.096C53.5596 105.166 53.3614 105.204 53.1608 105.21C52.7526 105.222 52.3434 105.229 51.9387 105.229C36.3662 105.229 23.463 96.3388 21.0128 83.7545L16.061 58.3255C15.5687 55.7975 18.0456 53.4709 23.8562 51.003C28.5758 48.9985 34.983 47.1531 41.898 45.8068C48.8129 44.4603 55.444 43.7634 60.5712 43.8537C66.883 43.9606 70.0521 45.1881 70.5444 47.7159L75.4964 73.145ZM71.8704 73.851L66.9524 48.5957C66.49 48.2423 64.4642 47.517 59.3639 47.5414C54.6574 47.5728 48.7051 48.2445 42.6041 49.4326C36.5031 50.6207 30.7338 52.2315 26.3593 53.9683C21.6208 55.8499 20.017 57.2914 19.7208 57.793L24.6387 83.0485C26.7897 94.0965 38.5882 101.831 52.7479 101.526C65.9902 96.4962 74.0216 84.8992 71.8704 73.851ZM97.9489 20.6521C92.9336 19.5867 86.2916 19 79.2467 19C72.2017 19 65.5597 19.5865 60.5443 20.6521C54.3692 21.9637 51.4932 23.7742 51.4932 26.3498V37.6804C51.4932 38.7006 52.32 39.5275 53.3402 39.5275C54.3604 39.5275 55.1873 38.7006 55.1873 37.6804V26.5267C55.5735 26.091 57.4232 24.9826 62.4343 24.0414C67.0599 23.1727 73.0308 22.6943 79.2467 22.6943C85.4627 22.6943 91.4333 23.1727 96.0592 24.0414C101.07 24.9826 102.92 26.091 103.306 26.5267V52.2559C103.306 62.6279 94.8721 71.8079 82.319 75.0994C81.3322 75.3582 80.742 76.3679 81.0008 77.3544C81.2183 78.1842 81.9668 78.7336 82.7863 78.7336C82.9412 78.7336 83.0988 78.7139 83.256 78.6728C90.0331 76.8957 95.8862 73.498 100.182 68.8469C104.643 64.0181 107 58.2812 107 52.2559V26.3498C107 23.7742 104.124 21.9637 97.9489 20.6521ZM87.8868 63.6196C87.9621 63.6196 88.0378 63.6151 88.1134 63.6056C89.8625 63.3893 91.4779 63.1166 92.9145 62.7948C93.758 62.6057 94.3576 61.8569 94.3576 60.9925V60.8995C94.3576 56.052 92.67 51.9284 89.4775 48.9747C86.2074 45.9491 81.6103 44.4246 76.8687 44.7951C75.8516 44.8743 75.0915 45.7629 75.1707 46.7798C75.2499 47.7969 76.1373 48.5598 77.1554 48.4779C80.8766 48.1879 84.4521 49.3577 86.969 51.6864C89.0812 53.6404 90.3233 56.32 90.6032 59.4945C89.9376 59.6162 89.2376 59.7278 88.5074 59.8288C85.5663 57.1988 82.4577 55.737 79.2562 55.4815C78.2403 55.4014 77.3492 56.1591 77.2679 57.1758C77.1869 58.1927 77.9454 59.0828 78.9623 59.1641C81.5311 59.3691 84.1028 60.6945 86.6064 63.1036C86.9524 63.4367 87.4123 63.6196 87.8868 63.6196Z" fill="#3E3E3E"/>
</svg>

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

-21
View File
@@ -1,21 +0,0 @@
<svg width="397" height="302" viewBox="0 0 397 302" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M122.003 95.4765C92.9786 116.871 70.0644 103.118 36.4575 126.04C4.49517 147.841 -3.57918 180.131 1.32297 217.731C5.90544 252.879 25.7644 286.406 63.9542 295.668C114.365 307.893 120.475 283.443 173.941 271.217C227.407 258.992 233.517 286.499 299.203 288.027C363.996 289.535 395.498 227.023 396.969 150.491C398.497 71.026 343.205 -8.47608 264.069 0.729362C198.382 8.37027 151.027 74.082 122.003 95.4765Z" fill="white" fill-opacity="0.3"/>
<rect x="107" y="46" width="192" height="241" rx="9" stroke="white" stroke-width="6"/>
<circle cx="169.5" cy="90.5" r="11.5" fill="white"/>
<circle cx="235.5" cy="90.5" r="11.5" fill="white"/>
<rect x="179" y="129" width="47" height="12" rx="6" fill="white"/>
<rect x="126" y="194" width="154" height="9" rx="4.5" fill="white"/>
<rect x="126" y="222" width="154" height="9" rx="4.5" fill="white"/>
<rect x="126" y="250" width="154" height="9" rx="4.5" fill="white"/>
<circle cx="33.5" cy="176.5" r="7.5" stroke="white" stroke-width="4"/>
<circle cx="43.5" cy="280.5" r="7.5" stroke="white" stroke-width="4"/>
<circle cx="382" cy="196" r="5" stroke="white" stroke-width="4"/>
<rect x="331" y="290" width="19" height="5" rx="2.5" fill="white"/>
<rect x="338" y="302" width="19" height="5" rx="2.5" transform="rotate(-90 338 302)" fill="white"/>
<rect x="370" y="73.2632" width="17" height="4.47368" rx="2.23684" fill="white"/>
<rect x="376.263" y="84" width="17" height="4.47368" rx="2.23684" transform="rotate(-90 376.263 84)" fill="white"/>
<rect x="322" y="41.1578" width="14" height="3.68421" rx="1.84211" fill="white"/>
<rect x="327.158" y="50" width="14" height="3.68421" rx="1.84211" transform="rotate(-90 327.158 50)" fill="white"/>
<rect x="67" y="213.158" width="14" height="3.68421" rx="1.84211" fill="white"/>
<rect x="72.1578" y="222" width="14" height="3.68421" rx="1.84211" transform="rotate(-90 72.1578 222)" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

-6
View File
@@ -1,6 +0,0 @@
<svg width="184" height="184" viewBox="0 0 184 184" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="92" cy="92" r="88" stroke="white" stroke-width="8"/>
<circle cx="58.5" cy="55.5" r="11.5" fill="white"/>
<circle cx="124.5" cy="55.5" r="11.5" fill="white"/>
<path d="M47 133C52 123.167 67.8 103.5 91 103.5C114.2 103.5 130.667 123.167 136 133" stroke="white" stroke-width="8" stroke-linecap="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 419 B

-25
View File
@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
<g>
<path fill="#fff" d="M256,0C114.84,0,0,114.84,0,256s114.84,256,256,256s256-114.84,256-256S397.16,0,256,0z M256,475.429
c-120.997,0-219.429-98.432-219.429-219.429S135.003,36.571,256,36.571S475.429,135.003,475.429,256S376.997,475.429,256,475.429z
"/>
</g>
</g>
<g>
<g>
<path fill="#fff" d="M256,134.095c-10.1,0-18.286,8.186-18.286,18.286v207.238c0,10.1,8.186,18.286,18.286,18.286
c10.1,0,18.286-8.186,18.286-18.286V152.381C274.286,142.281,266.1,134.095,256,134.095z"/>
</g>
</g>
<g>
<g>
<path fill="#fff" d="M359.619,237.714H152.381c-10.1,0-18.286,8.186-18.286,18.286c0,10.1,8.186,18.286,18.286,18.286h207.238
c10.1,0,18.286-8.186,18.286-18.286C377.905,245.9,369.719,237.714,359.619,237.714z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

-42
View File
@@ -1,42 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="405.272px" height="405.272px" viewBox="0 0 405.272 405.272" style="enable-background:new 0 0 405.272 405.272;"
xml:space="preserve">
<g>
<path d="M393.401,124.425L179.603,338.208c-15.832,15.835-41.514,15.835-57.361,0L11.878,227.836
c-15.838-15.835-15.838-41.52,0-57.358c15.841-15.841,41.521-15.841,57.355-0.006l81.698,81.699L336.037,67.064
c15.841-15.841,41.523-15.829,57.358,0C409.23,82.902,409.23,108.578,393.401,124.425z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 953 B

-42
View File
@@ -1,42 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
<g>
<path fill="#fff" d="M482.909,67.2H29.091C13.05,67.2,0,80.25,0,96.291v319.418C0,431.75,13.05,444.8,29.091,444.8h453.818
c16.041,0,29.091-13.05,29.091-29.091V96.291C512,80.25,498.95,67.2,482.909,67.2z M477.091,409.891H34.909V102.109h442.182
V409.891z"/>
</g>
</g>
<g>
<g>
<rect fill="#fff" x="126.836" y="84.655" width="34.909" height="342.109"/>
</g>
</g>
<g>
<g>
<rect fill="#fff" x="350.255" y="84.655" width="34.909" height="342.109"/>
</g>
</g>
<g>
<g>
<rect fill="#fff" x="367.709" y="184.145" width="126.836" height="34.909"/>
</g>
</g>
<g>
<g>
<rect fill="#fff" x="17.455" y="184.145" width="126.836" height="34.909"/>
</g>
</g>
<g>
<g>
<rect fill="#fff" x="367.709" y="292.364" width="126.836" height="34.909"/>
</g>
</g>
<g>
<g>
<rect fill="#fff" x="17.455" y="292.364" width="126.836" height="34.909"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 485 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

-5
View File
@@ -1,5 +0,0 @@
<svg width="268" height="105" viewBox="0 0 268 105" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M66.2291 76.9251H23.478L13.8766 103.596H0L38.9665 1.40374H50.7406L89.7772 103.596H75.9707L66.2291 76.9251ZM27.5429 65.8356H62.2343L44.8536 18.0381L27.5429 65.8356Z" fill="white"/>
<path d="M103.514 103.596V1.40374H136.873C147.947 1.40374 156.263 3.69652 161.823 8.28209C167.43 12.8676 170.233 19.6524 170.233 28.6364C170.233 33.4091 168.878 37.6437 166.168 41.3402C163.459 44.99 159.767 47.8209 155.095 49.8329C160.608 51.377 164.954 54.3249 168.131 58.6765C171.355 62.9813 172.967 68.1283 172.967 74.1176C172.967 83.2888 170 90.4947 164.066 95.7353C158.132 100.976 149.745 103.596 138.906 103.596H103.514ZM116.97 55.7988V92.5769H139.186C145.447 92.5769 150.376 90.9626 153.974 87.734C157.618 84.4586 159.44 79.9666 159.44 74.258C159.44 61.9519 152.759 55.7988 139.396 55.7988H116.97ZM116.97 44.99H137.294C143.181 44.99 147.877 43.516 151.381 40.5682C154.932 37.6203 156.707 33.6197 156.707 28.5662C156.707 22.9512 155.072 18.8803 151.801 16.3536C148.531 13.7801 143.555 12.4933 136.873 12.4933H116.97V44.99Z" fill="white"/>
<path d="M268 71.1698C266.738 81.9786 262.744 90.3309 256.016 96.2266C249.334 102.076 240.434 105 229.314 105C217.259 105 207.588 100.672 200.299 92.0154C193.057 83.359 189.436 71.7781 189.436 57.2727V47.4465C189.436 37.9479 191.118 29.5956 194.482 22.3897C197.893 15.1838 202.705 9.66243 208.919 5.82553C215.134 1.94184 222.329 0 230.505 0C241.345 0 250.035 3.04144 256.576 9.12433C263.117 15.1604 266.925 23.5361 268 34.2513H254.474C253.306 26.1096 250.759 20.2139 246.835 16.5642C242.957 12.9144 237.514 11.0896 230.505 11.0896C221.908 11.0896 215.157 14.2714 210.251 20.635C205.392 26.9987 202.962 36.0528 202.962 47.7975V57.6939C202.962 68.7834 205.275 77.6036 209.901 84.1544C214.526 90.7052 220.997 93.9806 229.314 93.9806C236.789 93.9806 242.513 92.2961 246.484 88.9271C250.502 85.5114 253.166 79.5922 254.474 71.1698H268Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

-4
View File
@@ -1,4 +0,0 @@
<svg width="139" height="105" viewBox="0 0 139 105" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M125.969 0.375122H47.5564C43.6325 0.375122 39.955 2.11446 37.4647 5.15569L0.979756 49.7513C-0.326911 51.3503 -0.326911 53.6496 0.979756 55.2486L37.469 99.8486C39.9546 102.886 43.6325 104.625 47.5564 104.625H125.969C133.155 104.625 139 98.7792 139 91.5936V13.4063C139 6.22026 133.155 0.375122 125.969 0.375122V0.375122ZM130.313 91.5936C130.313 93.9904 128.365 95.9372 125.969 95.9372H47.5564C46.2458 95.9372 45.0197 95.356 44.1925 94.3464L9.95578 52.4997L44.1881 10.6574C45.0197 9.64349 46.2454 9.06227 47.5564 9.06227H125.969C128.365 9.06227 130.312 11.0095 130.312 13.4058C130.313 13.4063 130.313 91.5936 130.313 91.5936V91.5936Z" fill="white"/>
<path d="M96.8349 27.71L78.1873 46.3576L59.5397 27.71L53.3975 33.8522L72.0451 52.4998L53.3975 71.1474L59.5397 77.2897L78.1873 58.6421L96.8349 77.2897L102.977 71.1474L84.3296 52.4998L102.977 33.8522L96.8349 27.71Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 992 B

-3
View File
@@ -1,3 +0,0 @@
<svg width="144" height="103" viewBox="0 0 144 103" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M123.428 0H82.2858V20.5998H123.429V51.4996L41.1456 51.4969L56.5718 36.0493L41.1433 20.5994L0 61.8001L41.1429 103L56.5715 87.5501L41.1406 72.0978L123.429 72.0901C134.774 72.0901 144 62.8514 144 51.4904V20.6005C144 9.23909 134.774 0.000384834 123.428 0V0Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 386 B

-3
View File
@@ -1,3 +0,0 @@
<svg width="106" height="106" viewBox="0 0 106 106" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M53 0C23.7771 0 0 23.7771 0 53C0 82.2229 23.7771 106 53 106C82.2229 106 106 82.2229 106 53C106 23.7771 82.2229 0 53 0ZM90.524 25.8574C84.8132 28.1231 78.9435 29.9185 72.9214 31.0977C70.3641 22.6774 66.303 14.6147 60.7248 7.32063C72.9413 9.38763 83.528 16.218 90.524 25.8574ZM67.999 67.4425C58.0482 66.0778 47.9451 66.0778 37.9944 67.4425C35.9539 57.9423 35.9472 48.1108 37.9811 38.6039C42.9234 39.2796 47.9186 39.75 53 39.75C58.0814 39.75 63.07 39.2796 68.0122 38.6039C70.0461 48.1108 70.0395 57.9423 67.999 67.4425ZM66.2831 32.1246C57.4653 33.2641 48.5281 33.2641 39.7102 32.1246C42.4265 23.6049 46.8653 15.529 53 8.374C59.1347 15.529 63.5669 23.6049 66.2831 32.1246ZM45.262 7.32063C39.6837 14.6147 35.6293 22.6774 33.072 31.0977C27.0565 29.9185 21.1867 28.1231 15.476 25.8574C22.4654 16.218 33.0521 9.38763 45.262 7.32063ZM6.625 53C6.625 45.2752 8.55288 38.001 11.9051 31.588C18.2386 34.1916 24.7378 36.2387 31.4224 37.5836C29.2958 47.7662 29.2957 58.2801 31.429 68.4694C24.751 69.801 18.2254 71.8349 11.9051 74.4319C8.55288 68.0056 6.625 60.7314 6.625 53ZM15.476 80.1426C21.1867 77.8769 27.0565 76.0815 33.072 74.9022C35.6293 83.3226 39.6904 91.3853 45.2686 98.6794C33.0521 96.6124 22.4654 89.782 15.476 80.1426ZM39.7169 73.8754C48.5281 72.7359 57.4653 72.7359 66.2831 73.8754C63.5669 82.3951 59.1281 90.471 53 97.626C46.8653 90.471 42.4331 82.3951 39.7169 73.8754ZM60.7248 98.6794C66.303 91.3853 70.3641 83.3226 72.9214 74.9022C78.9369 76.0815 84.8132 77.8835 90.524 80.1426C83.528 89.782 72.9413 96.6124 60.7248 98.6794ZM74.5644 68.4561C76.6976 58.2735 76.7042 47.7596 74.571 37.577C81.2556 36.2321 87.7614 34.1916 94.0949 31.5814C97.4471 38.001 99.375 45.2752 99.375 53C99.375 60.7314 97.4471 68.0056 94.0949 74.4186C87.7746 71.8282 81.249 69.7944 74.5644 68.4561Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

-3
View File
@@ -1,3 +0,0 @@
<svg width="161" height="42" viewBox="0 0 161 42" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.5 0.5V34.5H153.5V0.5" stroke="white" stroke-width="14"/>
</svg>

Before

Width:  |  Height:  |  Size: 174 B

-5
View File
@@ -1,5 +0,0 @@
<svg width="235" height="104" viewBox="0 0 235 104" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M46.1288 74.7143H27.2774L21.5649 104H11.3537L17.0662 74.7143H0V64.9286H18.9228L23.8499 39.6429H5.42692V29.7143H25.7779L31.6332 0H41.8444L35.9891 29.7143H54.8405L60.6958 0H70.9784L65.1231 29.7143H79.6901V39.6429H63.1951L58.268 64.9286H74.3346V74.7143H56.4114L50.6989 104H40.4163L46.1288 74.7143ZM29.134 64.9286H47.9854L52.9125 39.6429H34.0611L29.134 64.9286Z" fill="white"/>
<path d="M129.461 48.2143H158.452V60.7143H129.461V93.5714H116.179V60.7143H87.1878V48.2143H116.179V17.8571H129.461V48.2143Z" fill="white"/>
<path d="M235 45.8571H175.447V34.3571H235V45.8571ZM235 75.5H175.447V64.0714H235V75.5Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 731 B

-3
View File
@@ -1,3 +0,0 @@
<svg width="94" height="104" viewBox="0 0 94 104" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M92.9663 48.0363L49.884 1.21349C48.4062 -0.404497 45.5915 -0.404497 44.1136 1.21349L1.03142 48.0363C-0.0182146 49.1809 -0.294985 50.8249 0.331665 52.2452C0.958315 53.6655 2.35784 54.5759 3.91402 54.5759H26.1079V100.098C26.1079 102.252 27.8625 104 30.0244 104H63.968C66.13 104 67.8846 102.252 67.8846 100.098V54.5759H90.0784C91.6346 54.5759 93.0341 53.6603 93.666 52.2452C94.2979 50.8301 94.0159 49.1809 92.9663 48.0363Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 550 B

-14
View File
@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
<g>
<path fill="#fff" d="M391.416,0H120.584c-17.778,0-32.242,14.464-32.242,32.242v460.413c0,7.016,3.798,13.477,9.924,16.895
c2.934,1.638,6.178,2.45,9.421,2.45c3.534,0,7.055-0.961,10.169-2.882l138.182-85.312l138.163,84.693
c5.971,3.669,13.458,3.817,19.564,0.387c6.107-3.418,9.892-9.872,9.892-16.875V32.242C423.657,14.464,409.194,0,391.416,0z
M384.967,457.453l-118.85-72.86c-6.229-3.817-14.07-3.798-20.28,0.032l-118.805,73.35V38.69h257.935V457.453z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 839 B

-20
View File
@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
<g>
<path fill="#fff" d="M225.474,0C101.151,0,0,101.151,0,225.474c0,124.33,101.151,225.474,225.474,225.474
c124.33,0,225.474-101.144,225.474-225.474C450.948,101.151,349.804,0,225.474,0z M225.474,409.323
c-101.373,0-183.848-82.475-183.848-183.848S124.101,41.626,225.474,41.626s183.848,82.475,183.848,183.848
S326.847,409.323,225.474,409.323z"/>
</g>
</g>
<g>
<g>
<path fill="#fff" d="M505.902,476.472L386.574,357.144c-8.131-8.131-21.299-8.131-29.43,0c-8.131,8.124-8.131,21.306,0,29.43l119.328,119.328
c4.065,4.065,9.387,6.098,14.715,6.098c5.321,0,10.649-2.033,14.715-6.098C514.033,497.778,514.033,484.596,505.902,476.472z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1019 B

-25
View File
@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
<g>
<path fill="#fff" d="M478.354,146.286H33.646c-12.12,0-21.943,9.823-21.943,21.943v321.829c0,12.12,9.823,21.943,21.943,21.943h444.709
c12.12,0,21.943-9.823,21.943-21.943V168.229C500.297,156.109,490.474,146.286,478.354,146.286z M456.411,468.114H55.589V190.171
h400.823V468.114z"/>
</g>
</g>
<g>
<g>
<path fill="#fff" d="M441.783,73.143H70.217c-12.12,0-21.943,9.823-21.943,21.943c0,12.12,9.823,21.943,21.943,21.943h371.566
c12.12,0,21.943-9.823,21.943-21.943C463.726,82.966,453.903,73.143,441.783,73.143z"/>
</g>
</g>
<g>
<g>
<path fill="#fff" d="M405.211,0H106.789c-12.12,0-21.943,9.823-21.943,21.943c0,12.12,9.823,21.943,21.943,21.943h298.423
c12.12,0,21.943-9.823,21.943-21.943C427.154,9.823,417.331,0,405.211,0z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

Some files were not shown because too many files have changed in this diff Show More