From 8eb94354160d5b8cb33bf9523d508a91e4fa487d Mon Sep 17 00:00:00 2001 From: okxlin <61420215+okxlin@users.noreply.github.com> Date: Sat, 1 Aug 2026 04:37:21 +0800 Subject: [PATCH] feat: add Photofield app --- apps/photofield/0.24.1/.env.sample | 6 ++ apps/photofield/0.24.1/data.yml | 83 ++++++++++++++++++ apps/photofield/0.24.1/docker-compose.yml | 35 ++++++++ apps/photofield/0.24.1/scripts/init.sh | 91 ++++++++++++++++++++ apps/photofield/0.24.1/scripts/uninstall.sh | 5 ++ apps/photofield/0.24.1/scripts/upgrade.sh | 5 ++ apps/photofield/README.md | 34 ++++++++ apps/photofield/data.yml | 33 +++++++ apps/photofield/latest/.env.sample | 6 ++ apps/photofield/latest/data.yml | 83 ++++++++++++++++++ apps/photofield/latest/docker-compose.yml | 35 ++++++++ apps/photofield/latest/scripts/init.sh | 91 ++++++++++++++++++++ apps/photofield/latest/scripts/uninstall.sh | 5 ++ apps/photofield/latest/scripts/upgrade.sh | 5 ++ apps/photofield/logo-LICENSE.txt | 3 + apps/photofield/logo.png | Bin 0 -> 1296 bytes 16 files changed, 520 insertions(+) create mode 100644 apps/photofield/0.24.1/.env.sample create mode 100644 apps/photofield/0.24.1/data.yml create mode 100644 apps/photofield/0.24.1/docker-compose.yml create mode 100755 apps/photofield/0.24.1/scripts/init.sh create mode 100755 apps/photofield/0.24.1/scripts/uninstall.sh create mode 100755 apps/photofield/0.24.1/scripts/upgrade.sh create mode 100644 apps/photofield/README.md create mode 100644 apps/photofield/data.yml create mode 100644 apps/photofield/latest/.env.sample create mode 100644 apps/photofield/latest/data.yml create mode 100644 apps/photofield/latest/docker-compose.yml create mode 100755 apps/photofield/latest/scripts/init.sh create mode 100755 apps/photofield/latest/scripts/uninstall.sh create mode 100755 apps/photofield/latest/scripts/upgrade.sh create mode 100644 apps/photofield/logo-LICENSE.txt create mode 100644 apps/photofield/logo.png diff --git a/apps/photofield/0.24.1/.env.sample b/apps/photofield/0.24.1/.env.sample new file mode 100644 index 000000000..e117e0f67 --- /dev/null +++ b/apps/photofield/0.24.1/.env.sample @@ -0,0 +1,6 @@ +CONTAINER_NAME=photofield-compose +PANEL_APP_BIND_ADDRESS=127.0.0.1 +PANEL_APP_PORT_HTTP=8080 +APP_DATA_DIR=./data +PHOTO_LIBRARY_DIR=./photos +TZ=Asia/Shanghai diff --git a/apps/photofield/0.24.1/data.yml b/apps/photofield/0.24.1/data.yml new file mode 100644 index 000000000..2ff3dfacb --- /dev/null +++ b/apps/photofield/0.24.1/data.yml @@ -0,0 +1,83 @@ +additionalProperties: + formFields: + - default: 127.0.0.1 + edit: true + envKey: PANEL_APP_BIND_ADDRESS + labelEn: Bind Address + labelZh: 绑定地址 + label: + en: Bind Address + zh: 绑定地址 + zh-Hant: 綁定位址 + ja: バインドアドレス + ko: 바인드 주소 + ru: Адрес привязки + ms: Alamat ikatan + pt-br: Endereco de vinculacao + required: true + type: text + - default: 8080 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: HTTP Port + labelZh: HTTP 端口 + label: + en: HTTP Port + zh: HTTP 端口 + zh-Hant: HTTP 連接埠 + ja: HTTP ポート + ko: HTTP 포트 + ru: HTTP-порт + ms: Port HTTP + pt-br: Porta HTTP + required: true + rule: paramPort + type: number + - default: ./data + edit: true + envKey: APP_DATA_DIR + labelEn: Cache Data Directory + labelZh: 缓存数据目录 + label: + en: Cache Data Directory + zh: 缓存数据目录 + zh-Hant: 快取資料目錄 + ja: キャッシュデータディレクトリ + ko: 캐시 데이터 디렉터리 + ru: Каталог данных кэша + ms: Direktori data cache + pt-br: Diretorio de dados do cache + required: true + type: text + - default: ./photos + edit: true + envKey: PHOTO_LIBRARY_DIR + labelEn: Photo Library Directory + labelZh: 照片库目录 + label: + en: Photo Library Directory + zh: 照片库目录 + zh-Hant: 照片庫目錄 + ja: 写真ライブラリディレクトリ + ko: 사진 라이브러리 디렉터리 + ru: Каталог фототеки + ms: Direktori pustaka foto + pt-br: Diretorio da biblioteca de fotos + required: true + type: text + - default: Asia/Shanghai + edit: true + envKey: TZ + labelEn: Time Zone + labelZh: 时区 + label: + en: Time Zone + zh: 时区 + zh-Hant: 時區 + ja: タイムゾーン + ko: 시간대 + ru: Часовой пояс + ms: Zon waktu + pt-br: Fuso horario + required: true + type: text diff --git a/apps/photofield/0.24.1/docker-compose.yml b/apps/photofield/0.24.1/docker-compose.yml new file mode 100644 index 000000000..e2541e008 --- /dev/null +++ b/apps/photofield/0.24.1/docker-compose.yml @@ -0,0 +1,35 @@ +services: + photofield: + image: "ghcr.io/smilyorg/photofield:v0.24.1@sha256:34de0c7b4680ffe3f23c35976c16e2c554f91c41902c37517a4a2c28f4433e79" + container_name: ${CONTAINER_NAME} + restart: unless-stopped + networks: + - 1panel-network + ports: + - "${PANEL_APP_BIND_ADDRESS}:${PANEL_APP_PORT_HTTP}:8080" + environment: + - PHOTOFIELD_ADDRESS=:8080 + - PHOTOFIELD_DATA_DIR=/app/data + - TZ=${TZ} + volumes: + - "${APP_DATA_DIR}:/app/data" + - "${PHOTO_LIBRARY_DIR}:/app/photos:ro" + read_only: true + tmpfs: + - /tmp:rw,nosuid,nodev,noexec,size=64m,mode=1777 + cap_drop: + - ALL + security_opt: + - no-new-privileges:true + healthcheck: + test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1:8080/ || exit 1"] + interval: 20s + timeout: 5s + retries: 6 + start_period: 15s + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/apps/photofield/0.24.1/scripts/init.sh b/apps/photofield/0.24.1/scripts/init.sh new file mode 100755 index 000000000..af277de2e --- /dev/null +++ b/apps/photofield/0.24.1/scripts/init.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" +ENV_FILE="${ENV_FILE:-${ROOT_DIR}/.env}" + +fail() { + printf '%s\n' "$1" >&2 + exit 1 +} + +read_env_value() { + local key="$1" + local value="" + value="$(sed -n "s/^${key}=//p" "$ENV_FILE" | tail -n 1)" + case "$value" in + \"*\") value="${value#\"}"; value="${value%\"}" ;; + \'*\') value="${value#\'}"; value="${value%\'}" ;; + esac + printf '%s\n' "$value" +} + +configured_value() { + local key="$1" + if [[ -v "$key" ]]; then + printf '%s\n' "${!key}" + else + read_env_value "$key" + fi +} + +resolve_safe_path() { + local key="$1" + local value="$2" + local resolved + + [[ -n "$value" ]] || fail "$key must not be empty" + case "$value" in + *$'\n'* | *$'\r'* | *"\$"* | *"\`"*) fail "$key contains unsupported characters" ;; + esac + + if [[ "$value" = /* ]]; then + resolved="$(realpath -m -- "$value")" + [[ "$resolved" != "/" ]] || fail "$key must not be the filesystem root" + else + resolved="$(realpath -m -- "${ROOT_DIR}/${value#./}")" + case "$resolved" in + "${ROOT_DIR}"/*) ;; + *) fail "$key must remain inside the application version directory when relative" ;; + esac + fi + + [[ ! -L "$resolved" ]] || fail "$key must not be a symbolic link" + printf '%s\n' "$resolved" +} + +[[ -f "$ENV_FILE" && ! -L "$ENV_FILE" ]] || fail "$ENV_FILE must be a regular file" + +port="$(configured_value PANEL_APP_PORT_HTTP)" +[[ "$port" =~ ^[0-9]+$ ]] || fail "PANEL_APP_PORT_HTTP must be an integer" +((10#$port >= 1 && 10#$port <= 65535)) || fail "PANEL_APP_PORT_HTTP must be between 1 and 65535" + +bind_address="$(configured_value PANEL_APP_BIND_ADDRESS)" +[[ "$bind_address" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ || "$bind_address" == "::1" ]] || \ + fail "PANEL_APP_BIND_ADDRESS must be an IPv4 address or ::1" + +timezone="$(configured_value TZ)" +[[ "$timezone" =~ ^[A-Za-z0-9_+./-]+$ && "$timezone" != *..* ]] || fail "TZ contains unsupported characters" + +data_dir="$(resolve_safe_path APP_DATA_DIR "$(configured_value APP_DATA_DIR)")" +photo_dir="$(resolve_safe_path PHOTO_LIBRARY_DIR "$(configured_value PHOTO_LIBRARY_DIR)")" + +[[ ! -e "$data_dir" || -d "$data_dir" ]] || fail "APP_DATA_DIR must be a directory" +[[ ! -e "$photo_dir" || -d "$photo_dir" ]] || fail "PHOTO_LIBRARY_DIR must be a directory" +install -d -m 0750 -- "$data_dir" +install -d -m 0750 -- "$photo_dir" + +config_file="${data_dir}/configuration.yaml" +[[ ! -L "$config_file" ]] || fail "configuration.yaml must not be a symbolic link" +[[ ! -e "$config_file" || -f "$config_file" ]] || fail "configuration.yaml must be a regular file" +if [[ ! -e "$config_file" ]]; then + config_tmp="$(mktemp "${data_dir}/.photofield-config.XXXXXX")" + cat > "$config_tmp" <<'YAML' +collections: + - name: Photos + dirs: + - /app/photos +YAML + chmod 0640 "$config_tmp" + mv -- "$config_tmp" "$config_file" +fi diff --git a/apps/photofield/0.24.1/scripts/uninstall.sh b/apps/photofield/0.24.1/scripts/uninstall.sh new file mode 100755 index 000000000..9199050e2 --- /dev/null +++ b/apps/photofield/0.24.1/scripts/uninstall.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Photo and cache data are intentionally left to 1Panel's uninstall options. +exit 0 diff --git a/apps/photofield/0.24.1/scripts/upgrade.sh b/apps/photofield/0.24.1/scripts/upgrade.sh new file mode 100755 index 000000000..5ec28d784 --- /dev/null +++ b/apps/photofield/0.24.1/scripts/upgrade.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" +exec "$SCRIPT_DIR/init.sh" diff --git a/apps/photofield/README.md b/apps/photofield/README.md new file mode 100644 index 000000000..b36acae9a --- /dev/null +++ b/apps/photofield/README.md @@ -0,0 +1,34 @@ +# Photofield + +## 产品介绍 + +Photofield 是一款注重速度和简洁性的自托管照片图库。它从只读目录索引照片,使用 SQLite 保存缩略图与索引缓存,不会修改原始照片。 + +## 主要功能 + +- 可缩放的高密度照片浏览界面 +- 快速文件索引、EXIF 元数据读取与多级缩略图缓存 +- 支持相册、时间线、瀑布流、地图和高亮等布局 +- 支持 JPEG、PNG、HEIF、视频等多种媒体格式 +- 原始照片目录以只读方式挂载,缓存与配置独立保存 + +## 访问说明 + +应用没有内建账号、认证或授权。安装时默认仅绑定到 `127.0.0.1`,建议通过同机 HTTPS 反向代理访问并在代理层配置认证;只有在可信网络中才应改为 `0.0.0.0`。 + +照片目录以只读方式挂载到容器。缓存目录包含 `configuration.yaml`、SQLite 索引和缩略图缓存,升级前应备份该目录。卸载时脚本不会主动删除照片或缓存,最终是否移除缓存目录由 1Panel 的卸载选项决定。 + +媒体解析器处理操作员挂载的文件。当前上游镜像系列曾包含 libjxl 和 TIFF 解码器的高危缺陷;应只挂载可信媒体库、限制网络访问,并及时更新镜像。Photofield 不是面向不可信匿名上传的媒体处理服务。 + +## Introduction + +Photofield is a fast, self-hosted photo gallery focused on simple, non-invasive browsing. It indexes a read-only photo library and keeps generated thumbnails and SQLite cache data in a separate writable data directory. + +## Features + +- Zoomable, high-density photo browsing +- Fast file indexing, metadata extraction, and thumbnail caching +- Album, timeline, wall, map, and highlight layouts +- Read-only source libraries with separate writable cache data + +The application has no built-in authentication or authorization. It binds to `127.0.0.1` by default; publish it through a same-host HTTPS reverse proxy with access control. Mount only trusted media libraries, keep the photo mount read-only, back up the data directory before upgrades, and update promptly when media-decoder fixes are released. diff --git a/apps/photofield/data.yml b/apps/photofield/data.yml new file mode 100644 index 000000000..f8e8ba855 --- /dev/null +++ b/apps/photofield/data.yml @@ -0,0 +1,33 @@ +name: Photofield +tags: + - Media + - Website +title: 高速只读自托管照片图库 +description: 高速只读自托管照片图库 +additionalProperties: + key: photofield + name: Photofield + tags: + - Media + - Website + shortDescZh: 高速只读自托管照片图库 + shortDescEn: Fast read-only self-hosted photo gallery + description: + en: A fast self-hosted photo gallery that indexes read-only photo libraries. + zh: 一款可索引只读照片目录的高速自托管照片图库。 + zh-Hant: 一款可索引唯讀照片目錄的高速自架照片圖庫。 + ja: 読み取り専用の写真ライブラリを索引化する高速なセルフホスト写真ギャラリーです。 + ko: 읽기 전용 사진 라이브러리를 색인하는 빠른 자체 호스팅 사진 갤러리입니다. + ru: Быстрая самостоятельно размещаемая фотогалерея для индексации каталогов только для чтения. + ms: Galeri foto hos kendiri yang pantas untuk mengindeks pustaka foto baca sahaja. + pt-br: Galeria de fotos auto-hospedada e rapida que indexa bibliotecas somente leitura. + type: website + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://photofield.dev + github: https://github.com/SmilyOrg/photofield + document: https://photofield.dev/quick-start + architectures: + - amd64 + - arm64 diff --git a/apps/photofield/latest/.env.sample b/apps/photofield/latest/.env.sample new file mode 100644 index 000000000..e117e0f67 --- /dev/null +++ b/apps/photofield/latest/.env.sample @@ -0,0 +1,6 @@ +CONTAINER_NAME=photofield-compose +PANEL_APP_BIND_ADDRESS=127.0.0.1 +PANEL_APP_PORT_HTTP=8080 +APP_DATA_DIR=./data +PHOTO_LIBRARY_DIR=./photos +TZ=Asia/Shanghai diff --git a/apps/photofield/latest/data.yml b/apps/photofield/latest/data.yml new file mode 100644 index 000000000..2ff3dfacb --- /dev/null +++ b/apps/photofield/latest/data.yml @@ -0,0 +1,83 @@ +additionalProperties: + formFields: + - default: 127.0.0.1 + edit: true + envKey: PANEL_APP_BIND_ADDRESS + labelEn: Bind Address + labelZh: 绑定地址 + label: + en: Bind Address + zh: 绑定地址 + zh-Hant: 綁定位址 + ja: バインドアドレス + ko: 바인드 주소 + ru: Адрес привязки + ms: Alamat ikatan + pt-br: Endereco de vinculacao + required: true + type: text + - default: 8080 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: HTTP Port + labelZh: HTTP 端口 + label: + en: HTTP Port + zh: HTTP 端口 + zh-Hant: HTTP 連接埠 + ja: HTTP ポート + ko: HTTP 포트 + ru: HTTP-порт + ms: Port HTTP + pt-br: Porta HTTP + required: true + rule: paramPort + type: number + - default: ./data + edit: true + envKey: APP_DATA_DIR + labelEn: Cache Data Directory + labelZh: 缓存数据目录 + label: + en: Cache Data Directory + zh: 缓存数据目录 + zh-Hant: 快取資料目錄 + ja: キャッシュデータディレクトリ + ko: 캐시 데이터 디렉터리 + ru: Каталог данных кэша + ms: Direktori data cache + pt-br: Diretorio de dados do cache + required: true + type: text + - default: ./photos + edit: true + envKey: PHOTO_LIBRARY_DIR + labelEn: Photo Library Directory + labelZh: 照片库目录 + label: + en: Photo Library Directory + zh: 照片库目录 + zh-Hant: 照片庫目錄 + ja: 写真ライブラリディレクトリ + ko: 사진 라이브러리 디렉터리 + ru: Каталог фототеки + ms: Direktori pustaka foto + pt-br: Diretorio da biblioteca de fotos + required: true + type: text + - default: Asia/Shanghai + edit: true + envKey: TZ + labelEn: Time Zone + labelZh: 时区 + label: + en: Time Zone + zh: 时区 + zh-Hant: 時區 + ja: タイムゾーン + ko: 시간대 + ru: Часовой пояс + ms: Zon waktu + pt-br: Fuso horario + required: true + type: text diff --git a/apps/photofield/latest/docker-compose.yml b/apps/photofield/latest/docker-compose.yml new file mode 100644 index 000000000..562387f84 --- /dev/null +++ b/apps/photofield/latest/docker-compose.yml @@ -0,0 +1,35 @@ +services: + photofield: + image: "ghcr.io/smilyorg/photofield:latest" + container_name: ${CONTAINER_NAME} + restart: unless-stopped + networks: + - 1panel-network + ports: + - "${PANEL_APP_BIND_ADDRESS}:${PANEL_APP_PORT_HTTP}:8080" + environment: + - PHOTOFIELD_ADDRESS=:8080 + - PHOTOFIELD_DATA_DIR=/app/data + - TZ=${TZ} + volumes: + - "${APP_DATA_DIR}:/app/data" + - "${PHOTO_LIBRARY_DIR}:/app/photos:ro" + read_only: true + tmpfs: + - /tmp:rw,nosuid,nodev,noexec,size=64m,mode=1777 + cap_drop: + - ALL + security_opt: + - no-new-privileges:true + healthcheck: + test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1:8080/ || exit 1"] + interval: 20s + timeout: 5s + retries: 6 + start_period: 15s + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/apps/photofield/latest/scripts/init.sh b/apps/photofield/latest/scripts/init.sh new file mode 100755 index 000000000..af277de2e --- /dev/null +++ b/apps/photofield/latest/scripts/init.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" +ENV_FILE="${ENV_FILE:-${ROOT_DIR}/.env}" + +fail() { + printf '%s\n' "$1" >&2 + exit 1 +} + +read_env_value() { + local key="$1" + local value="" + value="$(sed -n "s/^${key}=//p" "$ENV_FILE" | tail -n 1)" + case "$value" in + \"*\") value="${value#\"}"; value="${value%\"}" ;; + \'*\') value="${value#\'}"; value="${value%\'}" ;; + esac + printf '%s\n' "$value" +} + +configured_value() { + local key="$1" + if [[ -v "$key" ]]; then + printf '%s\n' "${!key}" + else + read_env_value "$key" + fi +} + +resolve_safe_path() { + local key="$1" + local value="$2" + local resolved + + [[ -n "$value" ]] || fail "$key must not be empty" + case "$value" in + *$'\n'* | *$'\r'* | *"\$"* | *"\`"*) fail "$key contains unsupported characters" ;; + esac + + if [[ "$value" = /* ]]; then + resolved="$(realpath -m -- "$value")" + [[ "$resolved" != "/" ]] || fail "$key must not be the filesystem root" + else + resolved="$(realpath -m -- "${ROOT_DIR}/${value#./}")" + case "$resolved" in + "${ROOT_DIR}"/*) ;; + *) fail "$key must remain inside the application version directory when relative" ;; + esac + fi + + [[ ! -L "$resolved" ]] || fail "$key must not be a symbolic link" + printf '%s\n' "$resolved" +} + +[[ -f "$ENV_FILE" && ! -L "$ENV_FILE" ]] || fail "$ENV_FILE must be a regular file" + +port="$(configured_value PANEL_APP_PORT_HTTP)" +[[ "$port" =~ ^[0-9]+$ ]] || fail "PANEL_APP_PORT_HTTP must be an integer" +((10#$port >= 1 && 10#$port <= 65535)) || fail "PANEL_APP_PORT_HTTP must be between 1 and 65535" + +bind_address="$(configured_value PANEL_APP_BIND_ADDRESS)" +[[ "$bind_address" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ || "$bind_address" == "::1" ]] || \ + fail "PANEL_APP_BIND_ADDRESS must be an IPv4 address or ::1" + +timezone="$(configured_value TZ)" +[[ "$timezone" =~ ^[A-Za-z0-9_+./-]+$ && "$timezone" != *..* ]] || fail "TZ contains unsupported characters" + +data_dir="$(resolve_safe_path APP_DATA_DIR "$(configured_value APP_DATA_DIR)")" +photo_dir="$(resolve_safe_path PHOTO_LIBRARY_DIR "$(configured_value PHOTO_LIBRARY_DIR)")" + +[[ ! -e "$data_dir" || -d "$data_dir" ]] || fail "APP_DATA_DIR must be a directory" +[[ ! -e "$photo_dir" || -d "$photo_dir" ]] || fail "PHOTO_LIBRARY_DIR must be a directory" +install -d -m 0750 -- "$data_dir" +install -d -m 0750 -- "$photo_dir" + +config_file="${data_dir}/configuration.yaml" +[[ ! -L "$config_file" ]] || fail "configuration.yaml must not be a symbolic link" +[[ ! -e "$config_file" || -f "$config_file" ]] || fail "configuration.yaml must be a regular file" +if [[ ! -e "$config_file" ]]; then + config_tmp="$(mktemp "${data_dir}/.photofield-config.XXXXXX")" + cat > "$config_tmp" <<'YAML' +collections: + - name: Photos + dirs: + - /app/photos +YAML + chmod 0640 "$config_tmp" + mv -- "$config_tmp" "$config_file" +fi diff --git a/apps/photofield/latest/scripts/uninstall.sh b/apps/photofield/latest/scripts/uninstall.sh new file mode 100755 index 000000000..9199050e2 --- /dev/null +++ b/apps/photofield/latest/scripts/uninstall.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Photo and cache data are intentionally left to 1Panel's uninstall options. +exit 0 diff --git a/apps/photofield/latest/scripts/upgrade.sh b/apps/photofield/latest/scripts/upgrade.sh new file mode 100755 index 000000000..5ec28d784 --- /dev/null +++ b/apps/photofield/latest/scripts/upgrade.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" +exec "$SCRIPT_DIR/init.sh" diff --git a/apps/photofield/logo-LICENSE.txt b/apps/photofield/logo-LICENSE.txt new file mode 100644 index 000000000..510648d2c --- /dev/null +++ b/apps/photofield/logo-LICENSE.txt @@ -0,0 +1,3 @@ +Source: https://github.com/SmilyOrg/photofield/blob/v0.24.1/ui/public/android-chrome-192x192.png +License: MIT +Copyright: Photofield contributors diff --git a/apps/photofield/logo.png b/apps/photofield/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ad16326d94cb1c18ef42ad1f3ff544f97b3abc08 GIT binary patch literal 1296 zcmeAS@N?(olHy`uVBq!ia0vp^TR@nD8Ax&oe*=;X+XH+;T!Hle|Fi!8U-AF{s{j92 zf)RuPA=iRMfU+Q|fB%3aP#jtD>i_@e|Np-nq71A6qIe0+KxAWA{r+rx!l?=AT8 zZ1K-`OFrM6_jqC7gK6E5=JY;YI^o%xiLduedwY1sr>k>6oSA*Qt?h0{$BWIA-yE2J ze`43&_Kx?bX1!QH`R)E0wJX@`flgN`3GxeO;FLB^oO|N=w{L7}DNAqvP8A5={xO6_ zquXMY@CO;QJ7>;hhj|>FZKRj4_M@u7AZ{34ko|=0Z zbcHi+{{1&UTi#)d=Fv?aXWz{H-<*H-z9+NV%sIwAZ-aL3*t2V&;i{O;S9)f@UVXZo z>-4gF8MC%u6}xV<_SM>(c~?R|->p6VDC+ntn>$NS^xvI#aBKg?*LHOV-+jB4J5s;h zzxtQYeUjh*vv&+EXYuTk{v3S%Q1iAb{~p7z{pJ>nB=}2@MJzrXxb$+unoEBgxpTK_ zzd7{eM3UX+hq`88GES_^x^dyE+3vhV=j}dahc7;DmHcsmZS_Ov?Go-1PQtS;w5XXZ z(+q7@KWBoVL9FY024?U^TmaqHfW@c^u693!09KFH)B0 zb7wnUuxGmNGa)YbwnyFPe=c0)=okKT<4?(pn@{qozA*?` zuFEpH=F6@dUjOH0oZH#a}T`=2_jPYxutAS!{JJHVj>6s`J(T^HihN2b~+r zuD(BVS3NNKi%Nrv>u1@&7hf%5yML@9EMvFnS*@)R%wIqCh|srb`X(-?olBK86$`pT zx8FPSbiw{zD$5yfm0Oyb9Qc^}?7bUvg*WnM@jDw6ZntUStqB zf7Q14-U}87wuj5Z?|gbEU&C(2$nd}X8(&IU<}3E-gEd3agKvQ~lbv_hpG?{BFN{p((ZBI^wqM{*r4gtoSK@-Lc(;e&9rc zlwRP>U;mxCr82>RWoI2Vr(xN9Am>;7#g{Vee%CLacG}%o^gkg|W^dQ!{$r`4Us|P? z79a6tcds;=HKpa64%`?>V)S?|y2`}m21EXb zGg`Ua({EO-RmgdDBemzMyuh~eN3N~-a(&s}Eb&C|h?ukG@)x&S%6*Y9G@p{zbJuo3 z_T9a?lk8T#yrr_&OlnWs>?QfPE}EYeceXA+U150p@N@pRFa9%$`WcA7<*wuhm2sY~ KelF{r5}E)@{IA;p literal 0 HcmV?d00001