mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2025-11-05 10:52:49 +00:00
Compare commits
68 Commits
2025-09-05
...
2025-09-09
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7adf1a9b5 | ||
|
|
36fb86eaf8 | ||
|
|
495c47224e | ||
|
|
7af71384b4 | ||
|
|
e318152ee3 | ||
|
|
17dc7c90a1 | ||
|
|
226a5bce8f | ||
|
|
ffd2ed01b9 | ||
|
|
3348e2fff0 | ||
|
|
def41f66f4 | ||
|
|
02a1a732f8 | ||
|
|
2494af7e1c | ||
|
|
0c4711d99f | ||
|
|
039f73a5ed | ||
|
|
74b58d5b10 | ||
|
|
61044104a2 | ||
|
|
fac612077a | ||
|
|
135b3ff964 | ||
|
|
393b853119 | ||
|
|
6bb2938e34 | ||
|
|
fbf16fd54d | ||
|
|
d6d4fd034f | ||
|
|
aa4999dac6 | ||
|
|
b6c0b50e79 | ||
|
|
0f07f1927e | ||
|
|
4493d86e51 | ||
|
|
fbfeeeb88f | ||
|
|
2366111bba | ||
|
|
5fb42b87f1 | ||
|
|
500c35c58d | ||
|
|
ca3446c90e | ||
|
|
4c3d42d5d1 | ||
|
|
299a10efe8 | ||
|
|
7adac2a342 | ||
|
|
eb58b10d75 | ||
|
|
5e46d81c45 | ||
|
|
2963926c45 | ||
|
|
d9a0b863a8 | ||
|
|
db6369f3c6 | ||
|
|
d450e263f0 | ||
|
|
462960d9bf | ||
|
|
8ea4829e8a | ||
|
|
c5d23dc883 | ||
|
|
3dc973e4ac | ||
|
|
751f488f9e | ||
|
|
0ed4363247 | ||
|
|
e77612c27e | ||
|
|
59c8e214af | ||
|
|
c790f03a6b | ||
|
|
54d4d58b15 | ||
|
|
889a58c00e | ||
|
|
e9a5d7587a | ||
|
|
6f84046741 | ||
|
|
ff96351db8 | ||
|
|
1b632199b3 | ||
|
|
9fb02a93b4 | ||
|
|
3aa56651d8 | ||
|
|
17d4c59041 | ||
|
|
2bfb35779b | ||
|
|
83b93390c9 | ||
|
|
7ce47ad414 | ||
|
|
646e0c31f4 | ||
|
|
0c7e200a94 | ||
|
|
a9b02b3e9c | ||
|
|
b62adc2c5c | ||
|
|
3438b046e5 | ||
|
|
cbd6d6d0f3 | ||
|
|
cf6c429c57 |
89
CHANGELOG.md
89
CHANGELOG.md
@@ -10,8 +10,97 @@
|
|||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit the project's popularity for potentially malicious purposes.
|
Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit the project's popularity for potentially malicious purposes.
|
||||||
|
|
||||||
|
## 2025-09-10
|
||||||
|
|
||||||
|
## 2025-09-09
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Tududi: v0.81 [@vhsdream](https://github.com/vhsdream) ([#7517](https://github.com/community-scripts/ProxmoxVE/pull/7517))
|
||||||
|
- WGDashboard: Revert back to old update method [@tremor021](https://github.com/tremor021) ([#7500](https://github.com/community-scripts/ProxmoxVE/pull/7500))
|
||||||
|
- AdventureLog: remove folder during update process [@MickLesk](https://github.com/MickLesk) ([#7507](https://github.com/community-scripts/ProxmoxVE/pull/7507))
|
||||||
|
- PLANKA: Fix backup and restore commands [@tremor021](https://github.com/tremor021) ([#7505](https://github.com/community-scripts/ProxmoxVE/pull/7505))
|
||||||
|
- Recyclarr: Suppress config creation output [@tremor021](https://github.com/tremor021) ([#7502](https://github.com/community-scripts/ProxmoxVE/pull/7502))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- Pulse: standardise install/update with Pulse repo script [@vhsdream](https://github.com/vhsdream) ([#7519](https://github.com/community-scripts/ProxmoxVE/pull/7519))
|
||||||
|
|
||||||
|
### 🌐 Website
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Refactor GitHubStarsButton to wrap in Link component for external navigation [@BramSuurdje](https://github.com/BramSuurdje) ([#7492](https://github.com/community-scripts/ProxmoxVE/pull/7492))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- Bump vite from 7.0.0 to 7.1.5 in /frontend [@dependabot[bot]](https://github.com/dependabot[bot]) ([#7522](https://github.com/community-scripts/ProxmoxVE/pull/7522))
|
||||||
|
|
||||||
|
- #### 📝 Script Information
|
||||||
|
|
||||||
|
- swizzin: Change category from nvr to media [@MickLesk](https://github.com/MickLesk) ([#7511](https://github.com/community-scripts/ProxmoxVE/pull/7511))
|
||||||
|
|
||||||
|
## 2025-09-08
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- CT's: fix missing variable declaration (actualBudget, openziti, umlautadaptarr) [@MickLesk](https://github.com/MickLesk) ([#7483](https://github.com/community-scripts/ProxmoxVE/pull/7483))
|
||||||
|
- karakeep: fix service file [@CrazyWolf13](https://github.com/CrazyWolf13) ([#7482](https://github.com/community-scripts/ProxmoxVE/pull/7482))
|
||||||
|
- Update searxng-install.sh [@sebguy](https://github.com/sebguy) ([#7469](https://github.com/community-scripts/ProxmoxVE/pull/7469))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- Immich: bump to version 1.141.1 [@vhsdream](https://github.com/vhsdream) ([#7418](https://github.com/community-scripts/ProxmoxVE/pull/7418))
|
||||||
|
- [core]: switch all base_settings to variables [@MickLesk](https://github.com/MickLesk) ([#7479](https://github.com/community-scripts/ProxmoxVE/pull/7479))
|
||||||
|
|
||||||
|
- #### 💥 Breaking Changes
|
||||||
|
|
||||||
|
- RustDesk Server: Update the credentials info [@tremor021](https://github.com/tremor021) ([#7473](https://github.com/community-scripts/ProxmoxVE/pull/7473))
|
||||||
|
|
||||||
|
### 🌐 Website
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Format numerical values in DataFetcher component for better readability [@BramSuurdje](https://github.com/BramSuurdje) ([#7477](https://github.com/community-scripts/ProxmoxVE/pull/7477))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- feat: enhance github stars button to be better looking and more compact [@BramSuurdje](https://github.com/BramSuurdje) ([#7464](https://github.com/community-scripts/ProxmoxVE/pull/7464))
|
||||||
|
|
||||||
|
## 2025-09-07
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Update ExecStart path for karakeep service [@CrazyWolf13](https://github.com/CrazyWolf13) ([#7460](https://github.com/community-scripts/ProxmoxVE/pull/7460))
|
||||||
|
|
||||||
## 2025-09-06
|
## 2025-09-06
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Resilio Sync ([#7442](https://github.com/community-scripts/ProxmoxVE/pull/7442))
|
||||||
|
- leantime ([#7414](https://github.com/community-scripts/ProxmoxVE/pull/7414))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- use debian source for direct installation of MQTT [@EtlamGit](https://github.com/EtlamGit) ([#7423](https://github.com/community-scripts/ProxmoxVE/pull/7423))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- feat: added mobile ui subscription nag removal [@ivan-penchev](https://github.com/ivan-penchev) ([#7164](https://github.com/community-scripts/ProxmoxVE/pull/7164))
|
||||||
|
|
||||||
|
### 🌐 Website
|
||||||
|
|
||||||
|
- #### 📝 Script Information
|
||||||
|
|
||||||
|
- MediaManager Configuration Path [@austinpilz](https://github.com/austinpilz) ([#7408](https://github.com/community-scripts/ProxmoxVE/pull/7408))
|
||||||
|
- Paperless-NGX: Remove default credentials from json [@tremor021](https://github.com/tremor021) ([#7403](https://github.com/community-scripts/ProxmoxVE/pull/7403))
|
||||||
|
|
||||||
## 2025-09-05
|
## 2025-09-05
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
### 🚀 Updated Scripts
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
|
|||||||
# Source: https://actualbudget.org/
|
# Source: https://actualbudget.org/
|
||||||
|
|
||||||
APP="Actual Budget"
|
APP="Actual Budget"
|
||||||
var_tags="finance"
|
var_tags="${var_tags:-finance}"
|
||||||
var_cpu="2"
|
var_cpu="${var_cpu:-2}"
|
||||||
var_ram="2048"
|
var_ram="${var_ram:-2048}"
|
||||||
var_disk="4"
|
var_disk="${var_disk:-4}"
|
||||||
var_os="debian"
|
var_os="${var_os:-debian}"
|
||||||
var_version="12"
|
var_version="${var_version:-12}"
|
||||||
var_unprivileged="1"
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
header_info "$APP"
|
header_info "$APP"
|
||||||
variables
|
variables
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ function update_script() {
|
|||||||
|
|
||||||
msg_info "Backup Old Installation"
|
msg_info "Backup Old Installation"
|
||||||
cp -r /opt/adventurelog /opt/adventurelog-backup
|
cp -r /opt/adventurelog /opt/adventurelog-backup
|
||||||
|
rm -rf /opt/adventurelog
|
||||||
msg_ok "Backup done"
|
msg_ok "Backup done"
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "adventurelog" "seanmorley15/adventurelog"
|
fetch_and_deploy_gh_release "adventurelog" "seanmorley15/adventurelog"
|
||||||
|
|||||||
6
ct/headers/leantime
Normal file
6
ct/headers/leantime
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
__ __ _
|
||||||
|
/ / ___ ____ _____ / /_(_)___ ___ ___
|
||||||
|
/ / / _ \/ __ `/ __ \/ __/ / __ `__ \/ _ \
|
||||||
|
/ /___/ __/ /_/ / / / / /_/ / / / / / / __/
|
||||||
|
/_____/\___/\__,_/_/ /_/\__/_/_/ /_/ /_/\___/
|
||||||
|
|
||||||
6
ct/headers/resiliosync
Normal file
6
ct/headers/resiliosync
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
____ _ ___ _____
|
||||||
|
/ __ \___ _____(_) (_)___ / ___/__ ______ _____
|
||||||
|
/ /_/ / _ \/ ___/ / / / __ \ \__ \/ / / / __ \/ ___/
|
||||||
|
/ _, _/ __(__ ) / / / /_/ / ___/ / /_/ / / / / /__
|
||||||
|
/_/ |_|\___/____/_/_/_/\____/ /____/\__, /_/ /_/\___/
|
||||||
|
/____/
|
||||||
@@ -61,7 +61,7 @@ function update_script() {
|
|||||||
done
|
done
|
||||||
msg_ok "Image-processing libraries up to date"
|
msg_ok "Image-processing libraries up to date"
|
||||||
fi
|
fi
|
||||||
RELEASE="1.140.1"
|
RELEASE="1.141.1"
|
||||||
if check_for_gh_release "immich" "immich-app/immich" "${RELEASE}"; then
|
if check_for_gh_release "immich" "immich-app/immich" "${RELEASE}"; then
|
||||||
msg_info "Stopping Services"
|
msg_info "Stopping Services"
|
||||||
systemctl stop immich-web
|
systemctl stop immich-web
|
||||||
|
|||||||
@@ -53,6 +53,11 @@ function update_script() {
|
|||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if grep -q '^ExecStart=/usr/bin/node\s\+dist/index\.mjs$' /etc/systemd/system/karakeep-workers.service; then
|
||||||
|
sed -i -E 's#^(ExecStart=/usr/bin/node\s+dist/)index\.mjs$#\1index.js#' /etc/systemd/system/karakeep-workers.service
|
||||||
|
systemctl daemon-reload
|
||||||
|
fi
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "karakeep" "karakeep-app/karakeep"
|
fetch_and_deploy_gh_release "karakeep" "karakeep-app/karakeep"
|
||||||
if command -v corepack >/dev/null; then
|
if command -v corepack >/dev/null; then
|
||||||
$STD corepack disable
|
$STD corepack disable
|
||||||
|
|||||||
62
ct/leantime.sh
Normal file
62
ct/leantime.sh
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||||
|
# Copyright (c) 2021-2025 community-scripts ORG
|
||||||
|
# Author: Stroopwafe1
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://leantime.io
|
||||||
|
|
||||||
|
APP="Leantime"
|
||||||
|
var_tags="${var_tags:-productivity}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-2048}"
|
||||||
|
var_disk="${var_disk:-20}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-12}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d /opt/leantime ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "leantime" "Leantime/leantime"; then
|
||||||
|
msg_info "Creating Backup"
|
||||||
|
mariadb-dump leantime >"/opt/${APP}_db_backup_$(date +%F).sql"
|
||||||
|
tar -czf "/opt/${APP}_backup_$(date +%F).tar.gz" "/opt/${APP}"
|
||||||
|
mv /opt/leantime /opt/leantime_bak
|
||||||
|
msg_ok "Backup Created"
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "leantime" "Leantime/leantime" "prebuild" "latest" "/opt/leantime" Leantime*.tar.gz
|
||||||
|
|
||||||
|
msg_info "Restoring Config & Permissions"
|
||||||
|
mv /opt/leantime_bak/config/.env /opt/leantime/config/.env
|
||||||
|
chown -R www-data:www-data "/opt/leantime"
|
||||||
|
chmod -R 750 "/opt/leantime"
|
||||||
|
msg_ok "Restored Config & Permissions"
|
||||||
|
|
||||||
|
msg_info "Removing Backup"
|
||||||
|
rm -rf /opt/leantime_bak
|
||||||
|
msg_ok "Removed Backup"
|
||||||
|
msg_ok "Updated Successfully"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed Successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}/install${CL}"
|
||||||
@@ -6,13 +6,13 @@ source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/m
|
|||||||
# Source: https://github.com/openziti/ziti
|
# Source: https://github.com/openziti/ziti
|
||||||
|
|
||||||
APP="openziti-controller"
|
APP="openziti-controller"
|
||||||
var_tags="network;openziti-controller"
|
var_tags="${var_tags:-network;openziti-controller}"
|
||||||
var_cpu="2"
|
var_cpu="${var_cpu:-2}"
|
||||||
var_ram="1024"
|
var_ram="${var_ram:-1024}"
|
||||||
var_disk="8"
|
var_disk="${var_disk:-8}"
|
||||||
var_os="debian"
|
var_os="${var_os:-debian}"
|
||||||
var_version="12"
|
var_version="${var_version:-12}"
|
||||||
var_unprivileged="1"
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
header_info "$APP"
|
header_info "$APP"
|
||||||
variables
|
variables
|
||||||
|
|||||||
25
ct/planka.sh
25
ct/planka.sh
@@ -34,12 +34,13 @@ function update_script() {
|
|||||||
msg_ok "Stopped $APP"
|
msg_ok "Stopped $APP"
|
||||||
|
|
||||||
msg_info "Backing up data"
|
msg_info "Backing up data"
|
||||||
mkdir -p /opt/planka-backup/{favicons,user-avatars,background-images,attachments}
|
BK="/opt/planka-backup"
|
||||||
mv /opt/planka/.env /opt/planka-backup
|
mkdir -p "$BK"/{favicons,user-avatars,background-images,attachments}
|
||||||
[ -d /opt/planka/public/favicons ] && find /opt/planka/public/favicons -maxdepth 1 -type f -exec mv -t /opt/planka-backup/favicons {} +
|
[ -f /opt/planka/.env ] && mv /opt/planka/.env "$BK"/
|
||||||
[ -d /opt/planka/public/user-avatars ] && find /opt/planka/public/user-avatars -maxdepth 1 -type f -exec mv -t /opt/planka-backup/user-avatars {} +
|
[ -d /opt/planka/public/favicons ] && cp -a /opt/planka/public/favicons/. "$BK/favicons/"
|
||||||
[ -d /opt/planka/public/background-images ] && find /opt/planka/public/background-images -maxdepth 1 -type f -exec mv -t /opt/planka-backup/background-images {} +
|
[ -d /opt/planka/public/user-avatars ] && cp -a /opt/planka/public/user-avatars/. "$BK/user-avatars/"
|
||||||
[ -d /opt/planka/private/attachments ] && find /opt/planka/private/attachments -maxdepth 1 -type f -exec mv -t /opt/planka-backup/attachments {} +
|
[ -d /opt/planka/public/background-images ] && cp -a /opt/planka/public/background-images/. "$BK/background-images/"
|
||||||
|
[ -d /opt/planka/private/attachments ] && cp -a /opt/planka/private/attachments/. "$BK/attachments/"
|
||||||
rm -rf /opt/planka
|
rm -rf /opt/planka
|
||||||
msg_ok "Backed up data"
|
msg_ok "Backed up data"
|
||||||
|
|
||||||
@@ -51,11 +52,13 @@ function update_script() {
|
|||||||
msg_ok "Updated Frontend"
|
msg_ok "Updated Frontend"
|
||||||
|
|
||||||
msg_info "Restoring data"
|
msg_info "Restoring data"
|
||||||
mv /opt/planka-backup/.env /opt/planka/
|
[ -f "$BK/.env" ] && mv "$BK/.env" /opt/planka/.env
|
||||||
[ -d /opt/planka-backup/favicons ] && find /opt/planka-backup/favicons -maxdepth 1 -type f -exec mv -t /opt/planka/public/favicons {} +
|
mkdir -p /opt/planka/public/{favicons,user-avatars,background-images} /opt/planka/private/attachments
|
||||||
[ -d /opt/planka-backup/user-avatars ] && find /opt/planka-backup/user-avatars -maxdepth 1 -type f -exec mv -t /opt/planka/public/user-avatars {} +
|
[ -d "$BK/favicons" ] && cp -a "$BK/favicons/." /opt/planka/public/favicons/
|
||||||
[ -d /opt/planka-backup/background-images ] && find /opt/planka-backup/background-images -maxdepth 1 -type f -exec mv -t /opt/planka/public/background-images {} +
|
[ -d "$BK/user-avatars" ] && cp -a "$BK/user-avatars/." /opt/planka/public/user-avatars/
|
||||||
[ -d /opt/planka-backup/attachments ] && find /opt/planka-backup/attachments -maxdepth 1 -type f -exec mv -t /opt/planka/private/attachments {} +
|
[ -d "$BK/background-images" ] && cp -a "$BK/background-images/." /opt/planka/public/background-images/
|
||||||
|
[ -d "$BK/attachments" ] && cp -a "$BK/attachments/." /opt/planka/private/attachments/
|
||||||
|
rm -rf "$BK"
|
||||||
msg_ok "Restored data"
|
msg_ok "Restored data"
|
||||||
|
|
||||||
msg_info "Starting $APP"
|
msg_info "Starting $APP"
|
||||||
|
|||||||
13
ct/pulse.sh
13
ct/pulse.sh
@@ -28,10 +28,6 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! -f ~/.pulse ]]; then
|
|
||||||
msg_error "Old Installation Found! Please recreate the container due big changes in the software."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if check_for_gh_release "pulse" "rcourtman/Pulse"; then
|
if check_for_gh_release "pulse" "rcourtman/Pulse"; then
|
||||||
SERVICE_PATH="/etc/systemd/system"
|
SERVICE_PATH="/etc/systemd/system"
|
||||||
msg_info "Stopping Services"
|
msg_info "Stopping Services"
|
||||||
@@ -43,19 +39,20 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "pulse" "rcourtman/Pulse" "prebuild" "latest" "/opt/pulse" "*-linux-amd64.tar.gz"
|
fetch_and_deploy_gh_release "pulse" "rcourtman/Pulse" "prebuild" "latest" "/opt/pulse" "*-linux-amd64.tar.gz"
|
||||||
|
ln -sf /opt/pulse/bin/pulse /usr/local/bin/pulse
|
||||||
chown -R pulse:pulse /etc/pulse /opt/pulse
|
chown -R pulse:pulse /etc/pulse /opt/pulse
|
||||||
if [[ -f "$SERVICE_PATH"/pulse.service ]]; then
|
if [[ -f "$SERVICE_PATH"/pulse-backend.service ]]; then
|
||||||
mv "$SERVICE_PATH"/pulse.service "$SERVICE_PATH"/pulse-backend.service
|
mv "$SERVICE_PATH"/pulse-backend.service "$SERVICE_PATH"/pulse.service
|
||||||
fi
|
fi
|
||||||
sed -i -e 's|pulse/pulse|pulse/bin/pulse|' \
|
sed -i -e 's|pulse/pulse|pulse/bin/pulse|' \
|
||||||
-e 's/^Environment="API.*$//' "$SERVICE_PATH"/pulse-backend.service
|
-e 's/^Environment="API.*$//' "$SERVICE_PATH"/pulse.service
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
if grep -q 'pulse-home:/bin/bash' /etc/passwd; then
|
if grep -q 'pulse-home:/bin/bash' /etc/passwd; then
|
||||||
usermod -s /usr/sbin/nologin pulse
|
usermod -s /usr/sbin/nologin pulse
|
||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Starting Services"
|
msg_info "Starting Services"
|
||||||
systemctl start pulse-backend
|
systemctl start pulse
|
||||||
msg_ok "Started Services"
|
msg_ok "Started Services"
|
||||||
msg_ok "Updated Successfully"
|
msg_ok "Updated Successfully"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ function update_script() {
|
|||||||
msg_ok "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "recyclarr" "recyclarr/recyclarr" "prebuild" "latest" "/usr/local/bin" "recyclarr-linux-x64.tar.xz"
|
fetch_and_deploy_gh_release "recyclarr" "recyclarr/recyclarr" "prebuild" "latest" "/usr/local/bin" "recyclarr-linux-x64.tar.xz"
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
systemctl start recyclarr
|
systemctl start recyclarr
|
||||||
msg_ok "Started Service"
|
msg_ok "Started Service"
|
||||||
|
|||||||
44
ct/resiliosync.sh
Normal file
44
ct/resiliosync.sh
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||||
|
# Copyright (c) 2021-2025 community-scripts ORG
|
||||||
|
# Author: David Bennett (dbinit)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://www.resilio.com/sync
|
||||||
|
|
||||||
|
APP="Resilio Sync"
|
||||||
|
var_tags="${var_tags:-sync}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-2048}"
|
||||||
|
var_disk="${var_disk:-8}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-12}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
if [[ ! -d /var/lib/resilio-sync ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
msg_info "Updating ${APP} LXC"
|
||||||
|
$STD apt-get update
|
||||||
|
$STD apt-get -y upgrade
|
||||||
|
msg_ok "Updated Successfully"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed Successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}https://${IP}:8888${CL}"
|
||||||
11
ct/tududi.sh
11
ct/tududi.sh
@@ -27,17 +27,22 @@ function update_script() {
|
|||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
NODE_VERSION="22" setup_nodejs
|
||||||
|
|
||||||
if check_for_gh_release "tududi" "chrisvel/tududi"; then
|
if check_for_gh_release "tududi" "chrisvel/tududi"; then
|
||||||
msg_info "Stopping Service"
|
msg_info "Stopping Service"
|
||||||
systemctl stop tududi
|
systemctl stop tududi
|
||||||
msg_ok "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
msg_info "Remove and backup Files"
|
msg_info "Remove and backup Files"
|
||||||
|
DB="$(sed -n '/^DB_FILE/s/[^=]*=//p' /opt/tududi/backend/.env)"
|
||||||
|
export DB_FILE="$DB"
|
||||||
cp /opt/tududi/backend/.env /opt/tududi.env
|
cp /opt/tududi/backend/.env /opt/tududi.env
|
||||||
rm -rf /opt/tududi/backend/dist
|
rm -rf /opt/tududi/backend/dist
|
||||||
msg_ok "Backup and removed Files"
|
msg_ok "Backup and removed Files"
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "tududi" "chrisvel/tududi" "tarball" "v0.80" "/opt/tududi"
|
fetch_and_deploy_gh_release "tududi" "chrisvel/tududi" "tarball" "latest" "/opt/tududi"
|
||||||
|
|
||||||
msg_info "Updating ${APP}"
|
msg_info "Updating ${APP}"
|
||||||
cd /opt/tududi
|
cd /opt/tududi
|
||||||
@@ -48,6 +53,10 @@ function update_script() {
|
|||||||
mv ./public/locales ./backend/dist
|
mv ./public/locales ./backend/dist
|
||||||
mv ./public/favicon.* ./backend/dist
|
mv ./public/favicon.* ./backend/dist
|
||||||
mv /opt/tududi.env /opt/tududi/.env
|
mv /opt/tududi.env /opt/tududi/.env
|
||||||
|
sed -i -e 's|/tududi$|/tududi/backend|' \
|
||||||
|
-e 's|npm run start|bash /opt/tududi/backend/cmd/start.sh|' \
|
||||||
|
/etc/systemd/system/tududi.service
|
||||||
|
systemctl daemon-reload
|
||||||
msg_ok "Updated $APP"
|
msg_ok "Updated $APP"
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
|
|||||||
# Source: https://github.com/PCJones/UmlautAdaptarr
|
# Source: https://github.com/PCJones/UmlautAdaptarr
|
||||||
|
|
||||||
APP="UmlautAdaptarr"
|
APP="UmlautAdaptarr"
|
||||||
var_tags="arr"
|
var_tags="${var_tags:-arr}"
|
||||||
var_cpu="1"
|
var_cpu="${var_cpu:-1}"
|
||||||
var_ram="512"
|
var_ram="${var_ram:-512}"
|
||||||
var_disk="4"
|
var_disk="${var_disk:-4}"
|
||||||
var_os="debian"
|
var_os="${var_os:-debian}"
|
||||||
var_version="12"
|
var_version="${var_version:-12}"
|
||||||
var_unprivileged="1"
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
header_info "$APP"
|
header_info "$APP"
|
||||||
variables
|
variables
|
||||||
|
|||||||
@@ -28,6 +28,12 @@ function update_script() {
|
|||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
if ! dpkg -s git >/dev/null 2>&1; then
|
||||||
|
msg_info "Installing git"
|
||||||
|
$STD apt-get update
|
||||||
|
$STD apt-get install -y git
|
||||||
|
msg_ok "Installed git"
|
||||||
|
fi
|
||||||
apt-get update
|
apt-get update
|
||||||
apt-get -y upgrade
|
apt-get -y upgrade
|
||||||
if [[ -d /etc/wgdashboard ]]; then
|
if [[ -d /etc/wgdashboard ]]; then
|
||||||
|
|||||||
3
frontend/components.json
generated
3
frontend/components.json
generated
@@ -13,5 +13,8 @@
|
|||||||
"aliases": {
|
"aliases": {
|
||||||
"components": "@/components",
|
"components": "@/components",
|
||||||
"utils": "@/lib/utils"
|
"utils": "@/lib/utils"
|
||||||
|
},
|
||||||
|
"registries": {
|
||||||
|
"@animate-ui": "https://animate-ui.com/r/{name}.json"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
134
frontend/package-lock.json
generated
134
frontend/package-lock.json
generated
@@ -31,8 +31,9 @@
|
|||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"framer-motion": "^11.18.2",
|
"framer-motion": "^11.18.2",
|
||||||
"fuse.js": "^7.1.0",
|
"fuse.js": "^7.1.0",
|
||||||
"lucide-react": "^0.453.0",
|
"lucide-react": "^0.542.0",
|
||||||
"mini-svg-data-uri": "^1.4.4",
|
"mini-svg-data-uri": "^1.4.4",
|
||||||
|
"motion": "^12.23.12",
|
||||||
"next": "15.5.2",
|
"next": "15.5.2",
|
||||||
"next-themes": "^0.4.4",
|
"next-themes": "^0.4.4",
|
||||||
"nuqs": "^2.4.1",
|
"nuqs": "^2.4.1",
|
||||||
@@ -46,6 +47,7 @@
|
|||||||
"react-dom": "19.0.0",
|
"react-dom": "19.0.0",
|
||||||
"react-icons": "^5.5.0",
|
"react-icons": "^5.5.0",
|
||||||
"react-simple-typewriter": "^5.0.1",
|
"react-simple-typewriter": "^5.0.1",
|
||||||
|
"react-use-measure": "^2.1.7",
|
||||||
"sharp": "^0.33.5",
|
"sharp": "^0.33.5",
|
||||||
"simple-icons": "^13.21.0",
|
"simple-icons": "^13.21.0",
|
||||||
"sonner": "^1.7.4",
|
"sonner": "^1.7.4",
|
||||||
@@ -7664,11 +7666,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fdir": {
|
"node_modules/fdir": {
|
||||||
"version": "6.4.6",
|
"version": "6.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
|
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
|
||||||
"integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==",
|
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"picomatch": "^3 || ^4"
|
"picomatch": "^3 || ^4"
|
||||||
},
|
},
|
||||||
@@ -9293,12 +9298,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lucide-react": {
|
"node_modules/lucide-react": {
|
||||||
"version": "0.453.0",
|
"version": "0.542.0",
|
||||||
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.453.0.tgz",
|
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.542.0.tgz",
|
||||||
"integrity": "sha512-kL+RGZCcJi9BvJtzg2kshO192Ddy9hv3ij+cPrVPWSRzgCWCVazoQJxOjAwgK53NomL07HB7GPHW120FimjNhQ==",
|
"integrity": "sha512-w3hD8/SQB7+lzU2r4VdFyzzOzKnUjTZIF/MQJGSSvni7Llewni4vuViRppfRAa2guOsY5k4jZyxw/i9DQHv+dw==",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc"
|
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/magic-string": {
|
"node_modules/magic-string": {
|
||||||
@@ -10339,6 +10344,32 @@
|
|||||||
"pathe": "^2.0.1"
|
"pathe": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/motion": {
|
||||||
|
"version": "12.23.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/motion/-/motion-12.23.12.tgz",
|
||||||
|
"integrity": "sha512-8jCD8uW5GD1csOoqh1WhH1A6j5APHVE15nuBkFeRiMzYBdRwyAHmSP/oXSuW0WJPZRXTFdBoG4hY9TFWNhhwng==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"framer-motion": "^12.23.12",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@emotion/is-prop-valid": "*",
|
||||||
|
"react": "^18.0.0 || ^19.0.0",
|
||||||
|
"react-dom": "^18.0.0 || ^19.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@emotion/is-prop-valid": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/motion-dom": {
|
"node_modules/motion-dom": {
|
||||||
"version": "11.18.1",
|
"version": "11.18.1",
|
||||||
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.18.1.tgz",
|
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.18.1.tgz",
|
||||||
@@ -10354,6 +10385,48 @@
|
|||||||
"integrity": "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==",
|
"integrity": "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/motion/node_modules/framer-motion": {
|
||||||
|
"version": "12.23.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.12.tgz",
|
||||||
|
"integrity": "sha512-6e78rdVtnBvlEVgu6eFEAgG9v3wLnYEboM8I5O5EXvfKC8gxGQB8wXJdhkMy10iVcn05jl6CNw7/HTsTCfwcWg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"motion-dom": "^12.23.12",
|
||||||
|
"motion-utils": "^12.23.6",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@emotion/is-prop-valid": "*",
|
||||||
|
"react": "^18.0.0 || ^19.0.0",
|
||||||
|
"react-dom": "^18.0.0 || ^19.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@emotion/is-prop-valid": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/motion/node_modules/motion-dom": {
|
||||||
|
"version": "12.23.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.12.tgz",
|
||||||
|
"integrity": "sha512-RcR4fvMCTESQBD/uKQe49D5RUeDOokkGRmz4ceaJKDBgHYtZtntC/s2vLvY38gqGaytinij/yi3hMcWVcEF5Kw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"motion-utils": "^12.23.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/motion/node_modules/motion-utils": {
|
||||||
|
"version": "12.23.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.23.6.tgz",
|
||||||
|
"integrity": "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
@@ -11362,9 +11435,9 @@
|
|||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/picomatch": {
|
"node_modules/picomatch": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||||
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
|
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -11990,6 +12063,21 @@
|
|||||||
"react": ">= 0.14.0"
|
"react": ">= 0.14.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-use-measure": {
|
||||||
|
"version": "2.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.7.tgz",
|
||||||
|
"integrity": "sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.13",
|
||||||
|
"react-dom": ">=16.13"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/read-cache": {
|
"node_modules/read-cache": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||||
@@ -13307,14 +13395,14 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/tinyglobby": {
|
"node_modules/tinyglobby": {
|
||||||
"version": "0.2.14",
|
"version": "0.2.15",
|
||||||
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
|
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
|
||||||
"integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==",
|
"integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fdir": "^6.4.4",
|
"fdir": "^6.5.0",
|
||||||
"picomatch": "^4.0.2"
|
"picomatch": "^4.0.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12.0.0"
|
"node": ">=12.0.0"
|
||||||
@@ -13837,19 +13925,19 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "7.0.0",
|
"version": "7.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-7.1.5.tgz",
|
||||||
"integrity": "sha512-ixXJB1YRgDIw2OszKQS9WxGHKwLdCsbQNkpJN171udl6szi/rIySHL6/Os3s2+oE4P/FLD4dxg4mD7Wust+u5g==",
|
"integrity": "sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.25.0",
|
"esbuild": "^0.25.0",
|
||||||
"fdir": "^6.4.6",
|
"fdir": "^6.5.0",
|
||||||
"picomatch": "^4.0.2",
|
"picomatch": "^4.0.3",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "^8.5.6",
|
||||||
"rollup": "^4.40.0",
|
"rollup": "^4.43.0",
|
||||||
"tinyglobby": "^0.2.14"
|
"tinyglobby": "^0.2.15"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"vite": "bin/vite.js"
|
"vite": "bin/vite.js"
|
||||||
|
|||||||
4
frontend/package.json
generated
4
frontend/package.json
generated
@@ -38,8 +38,9 @@
|
|||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"framer-motion": "^11.18.2",
|
"framer-motion": "^11.18.2",
|
||||||
"fuse.js": "^7.1.0",
|
"fuse.js": "^7.1.0",
|
||||||
"lucide-react": "^0.453.0",
|
"lucide-react": "^0.542.0",
|
||||||
"mini-svg-data-uri": "^1.4.4",
|
"mini-svg-data-uri": "^1.4.4",
|
||||||
|
"motion": "^12.23.12",
|
||||||
"next": "15.5.2",
|
"next": "15.5.2",
|
||||||
"next-themes": "^0.4.4",
|
"next-themes": "^0.4.4",
|
||||||
"nuqs": "^2.4.1",
|
"nuqs": "^2.4.1",
|
||||||
@@ -53,6 +54,7 @@
|
|||||||
"react-dom": "19.0.0",
|
"react-dom": "19.0.0",
|
||||||
"react-icons": "^5.5.0",
|
"react-icons": "^5.5.0",
|
||||||
"react-simple-typewriter": "^5.0.1",
|
"react-simple-typewriter": "^5.0.1",
|
||||||
|
"react-use-measure": "^2.1.7",
|
||||||
"sharp": "^0.33.5",
|
"sharp": "^0.33.5",
|
||||||
"simple-icons": "^13.21.0",
|
"simple-icons": "^13.21.0",
|
||||||
"sonner": "^1.7.4",
|
"sonner": "^1.7.4",
|
||||||
|
|||||||
35
frontend/public/json/leantime.json
Normal file
35
frontend/public/json/leantime.json
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"name": "Leantime",
|
||||||
|
"slug": "leantime",
|
||||||
|
"categories": [
|
||||||
|
12
|
||||||
|
],
|
||||||
|
"date_created": "2025-09-06",
|
||||||
|
"type": "ct",
|
||||||
|
"updateable": true,
|
||||||
|
"privileged": false,
|
||||||
|
"interface_port": 80,
|
||||||
|
"documentation": "https://docs.leantime.io/",
|
||||||
|
"config_path": "/opt/Leantime/config/.env",
|
||||||
|
"website": "https://leantime.io",
|
||||||
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/leantime.webp",
|
||||||
|
"description": "Leantime is a goals focused project management system for non-project managers. Building with ADHD, Autism, and dyslexia in mind. ",
|
||||||
|
"install_methods": [
|
||||||
|
{
|
||||||
|
"type": "default",
|
||||||
|
"script": "ct/leantime.sh",
|
||||||
|
"resources": {
|
||||||
|
"cpu": 2,
|
||||||
|
"ram": 2048,
|
||||||
|
"hdd": 20,
|
||||||
|
"os": "Debian",
|
||||||
|
"version": "12"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default_credentials": {
|
||||||
|
"username": null,
|
||||||
|
"password": null
|
||||||
|
},
|
||||||
|
"notes": []
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
"privileged": false,
|
"privileged": false,
|
||||||
"interface_port": 8000,
|
"interface_port": 8000,
|
||||||
"documentation": "https://maxdorninger.github.io/MediaManager/introduction.html",
|
"documentation": "https://maxdorninger.github.io/MediaManager/introduction.html",
|
||||||
"config_path": "/opt/mm_data/config.toml",
|
"config_path": "/opt/mm/config/config.toml",
|
||||||
"website": "https://github.com/maxdorninger/MediaManager",
|
"website": "https://github.com/maxdorninger/MediaManager",
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/mediamanager.webp",
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/mediamanager.webp",
|
||||||
"description": "A modern selfhosted media management system for your media library",
|
"description": "A modern selfhosted media management system for your media library",
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"default_credentials": {
|
"default_credentials": {
|
||||||
"username": "admin",
|
"username": null,
|
||||||
"password": null
|
"password": null
|
||||||
},
|
},
|
||||||
"notes": [
|
"notes": [
|
||||||
|
|||||||
40
frontend/public/json/resiliosync.json
Normal file
40
frontend/public/json/resiliosync.json
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"name": "Resilio Sync",
|
||||||
|
"slug": "resiliosync",
|
||||||
|
"categories": [
|
||||||
|
11
|
||||||
|
],
|
||||||
|
"date_created": "2025-09-06",
|
||||||
|
"type": "ct",
|
||||||
|
"updateable": true,
|
||||||
|
"privileged": false,
|
||||||
|
"config_path": "/etc/resilio-sync/config.json",
|
||||||
|
"interface_port": 8888,
|
||||||
|
"documentation": "https://help.resilio.com/",
|
||||||
|
"website": "https://www.resilio.com/sync",
|
||||||
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/resilio-sync.webp",
|
||||||
|
"description": "Fast, reliable, and simple file sync and share solution, powered by P2P technology. Sync files across all your devices without storing them in the cloud.",
|
||||||
|
"install_methods": [
|
||||||
|
{
|
||||||
|
"type": "default",
|
||||||
|
"script": "ct/resilio-sync.sh",
|
||||||
|
"resources": {
|
||||||
|
"cpu": 2,
|
||||||
|
"ram": 2048,
|
||||||
|
"hdd": 8,
|
||||||
|
"os": "debian",
|
||||||
|
"version": "12"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default_credentials": {
|
||||||
|
"username": null,
|
||||||
|
"password": null
|
||||||
|
},
|
||||||
|
"notes": [
|
||||||
|
{
|
||||||
|
"text": "After free registration, you will receive a license keyfile to your email address. Upload it into any LXC directory and select on first run.",
|
||||||
|
"type": "info"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -48,7 +48,11 @@
|
|||||||
"type": "info"
|
"type": "info"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": "Login credentials: `cat ~/rustdesk.creds`",
|
"text": "To set admin password on Debian, type `cd /var/lib/rustdesk-api && rustdesk-api reset-admin-pwd <yournewpasswordhere>` inside LXC.",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "To see admin password on Alpine, type `cat ~/rustdesk.creds` inside LXC.",
|
||||||
"type": "info"
|
"type": "info"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "Swizzin",
|
"name": "Swizzin",
|
||||||
"slug": "swizzin",
|
"slug": "swizzin",
|
||||||
"categories": [
|
"categories": [
|
||||||
15
|
13
|
||||||
],
|
],
|
||||||
"date_created": "2025-08-19",
|
"date_created": "2025-08-19",
|
||||||
"type": "ct",
|
"type": "ct",
|
||||||
|
|||||||
@@ -1,4 +1,299 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"name": "authelia/authelia",
|
||||||
|
"version": "v4.39.9",
|
||||||
|
"date": "2025-09-09T22:48:24Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "MediaBrowser/Emby.Releases",
|
||||||
|
"version": "4.9.1.2",
|
||||||
|
"date": "2025-06-26T22:08:00Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "jenkinsci/jenkins",
|
||||||
|
"version": "jenkins-2.527",
|
||||||
|
"date": "2025-09-09T19:58:28Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "kyantech/Palmr",
|
||||||
|
"version": "v3.2.1-beta",
|
||||||
|
"date": "2025-09-09T19:47:13Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Part-DB/Part-DB-server",
|
||||||
|
"version": "v2.1.2",
|
||||||
|
"date": "2025-09-09T19:34:11Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hargata/lubelog",
|
||||||
|
"version": "v1.5.1",
|
||||||
|
"date": "2025-09-09T16:56:49Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "open-webui/open-webui",
|
||||||
|
"version": "v0.6.27",
|
||||||
|
"date": "2025-09-09T14:34:27Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "chrisvel/tududi",
|
||||||
|
"version": "v0.81",
|
||||||
|
"date": "2025-09-09T14:06:41Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "firefly-iii/firefly-iii",
|
||||||
|
"version": "v6.3.2",
|
||||||
|
"date": "2025-08-19T04:08:36Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "element-hq/synapse",
|
||||||
|
"version": "v1.138.0",
|
||||||
|
"date": "2025-09-09T11:25:50Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "traefik/traefik",
|
||||||
|
"version": "v3.5.2",
|
||||||
|
"date": "2025-09-09T10:28:12Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "docker/compose",
|
||||||
|
"version": "v2.39.3",
|
||||||
|
"date": "2025-09-09T08:27:27Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "OctoPrint/OctoPrint",
|
||||||
|
"version": "1.11.3",
|
||||||
|
"date": "2025-09-09T08:03:31Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "readeck/readeck",
|
||||||
|
"version": "0.20.2",
|
||||||
|
"date": "2025-09-09T06:09:25Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jackett/Jackett",
|
||||||
|
"version": "v0.22.2444",
|
||||||
|
"date": "2025-09-09T06:00:01Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "TandoorRecipes/recipes",
|
||||||
|
"version": "2.1.2",
|
||||||
|
"date": "2025-09-09T05:55:58Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "gotson/komga",
|
||||||
|
"version": "1.23.4",
|
||||||
|
"date": "2025-09-09T02:47:05Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Tautulli/Tautulli",
|
||||||
|
"version": "v2.16.0",
|
||||||
|
"date": "2025-09-09T01:05:45Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "jeedom/core",
|
||||||
|
"version": "4.4.20",
|
||||||
|
"date": "2025-09-09T00:27:11Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "steveiliop56/tinyauth",
|
||||||
|
"version": "v3.6.2",
|
||||||
|
"date": "2025-07-17T12:08:03Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "YunoHost/yunohost",
|
||||||
|
"version": "debian/12.1.20",
|
||||||
|
"date": "2025-09-08T23:47:21Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mongodb/mongo",
|
||||||
|
"version": "r8.0.14-rc1",
|
||||||
|
"date": "2025-09-08T22:50:53Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "diced/zipline",
|
||||||
|
"version": "v4.3.1",
|
||||||
|
"date": "2025-09-08T22:26:23Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cross-seed/cross-seed",
|
||||||
|
"version": "v6.13.3",
|
||||||
|
"date": "2025-09-08T21:45:15Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "HabitRPG/habitica",
|
||||||
|
"version": "v5.40.2",
|
||||||
|
"date": "2025-09-08T20:59:44Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "keycloak/keycloak",
|
||||||
|
"version": "26.0.15",
|
||||||
|
"date": "2025-08-27T12:12:03Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "booklore-app/booklore",
|
||||||
|
"version": "v1.2.1",
|
||||||
|
"date": "2025-09-08T19:31:07Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fallenbagel/jellyseerr",
|
||||||
|
"version": "preview-OIDC",
|
||||||
|
"date": "2025-09-08T18:08:15Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mattermost/mattermost",
|
||||||
|
"version": "server/public/v0.1.18",
|
||||||
|
"date": "2025-09-08T18:04:10Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "immich-app/immich",
|
||||||
|
"version": "v1.141.1",
|
||||||
|
"date": "2025-09-08T17:15:33Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "msgbyte/tianji",
|
||||||
|
"version": "v1.24.27",
|
||||||
|
"date": "2025-09-08T16:23:37Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Paymenter/Paymenter",
|
||||||
|
"version": "v1.3.1",
|
||||||
|
"date": "2025-09-08T15:26:01Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "n8n-io/n8n",
|
||||||
|
"version": "n8n@1.109.2",
|
||||||
|
"date": "2025-09-03T07:50:21Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "apache/tomcat",
|
||||||
|
"version": "10.1.46",
|
||||||
|
"date": "2025-09-08T14:29:54Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "home-assistant/operating-system",
|
||||||
|
"version": "16.2",
|
||||||
|
"date": "2025-09-08T14:03:25Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "zitadel/zitadel",
|
||||||
|
"version": "v4.1.3",
|
||||||
|
"date": "2025-09-08T13:36:08Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "theonedev/onedev",
|
||||||
|
"version": "v12.0.10",
|
||||||
|
"date": "2025-09-08T13:20:16Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "evcc-io/evcc",
|
||||||
|
"version": "0.207.6",
|
||||||
|
"date": "2025-09-08T11:52:00Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "autobrr/autobrr",
|
||||||
|
"version": "v1.66.1",
|
||||||
|
"date": "2025-09-08T10:49:03Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "meilisearch/meilisearch",
|
||||||
|
"version": "latest",
|
||||||
|
"date": "2025-09-08T10:03:11Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "syncthing/syncthing",
|
||||||
|
"version": "v2.0.8",
|
||||||
|
"date": "2025-09-08T08:07:18Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "nzbgetcom/nzbget",
|
||||||
|
"version": "v25.3",
|
||||||
|
"date": "2025-09-01T09:47:06Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "webmin/webmin",
|
||||||
|
"version": "2.501",
|
||||||
|
"date": "2025-09-08T04:50:25Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "paperless-ngx/paperless-ngx",
|
||||||
|
"version": "v2.18.4",
|
||||||
|
"date": "2025-09-07T23:57:32Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "9001/copyparty",
|
||||||
|
"version": "v1.19.8",
|
||||||
|
"date": "2025-09-07T23:36:42Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "minio/minio",
|
||||||
|
"version": "RELEASE.2025-09-07T16-13-09Z",
|
||||||
|
"date": "2025-09-07T18:53:04Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "karakeep-app/karakeep",
|
||||||
|
"version": "sdk/v0.27.0",
|
||||||
|
"date": "2025-09-07T17:49:04Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dgtlmoon/changedetection.io",
|
||||||
|
"version": "0.50.12",
|
||||||
|
"date": "2025-09-07T14:16:07Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "runtipi/runtipi",
|
||||||
|
"version": "v4.4.0",
|
||||||
|
"date": "2025-09-02T19:26:18Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "semaphoreui/semaphore",
|
||||||
|
"version": "v2.17.0-beta1",
|
||||||
|
"date": "2025-09-07T08:56:50Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Radarr/Radarr",
|
||||||
|
"version": "v5.27.5.10198",
|
||||||
|
"date": "2025-09-03T12:08:43Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Prowlarr/Prowlarr",
|
||||||
|
"version": "v2.0.5.5160",
|
||||||
|
"date": "2025-08-23T21:23:11Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pocketbase/pocketbase",
|
||||||
|
"version": "v0.30.0",
|
||||||
|
"date": "2025-09-07T05:25:44Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Lidarr/Lidarr",
|
||||||
|
"version": "v2.13.3.4711",
|
||||||
|
"date": "2025-08-28T20:06:24Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "rcourtman/Pulse",
|
||||||
|
"version": "v4.14.0",
|
||||||
|
"date": "2025-09-05T18:28:28Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "bunkerity/bunkerweb",
|
||||||
|
"version": "v1.6.4",
|
||||||
|
"date": "2025-08-18T20:22:07Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fuma-nama/fumadocs",
|
||||||
|
"version": "create-fumadocs-app@15.7.10",
|
||||||
|
"date": "2025-09-06T10:13:43Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Luligu/matterbridge",
|
||||||
|
"version": "3.2.6",
|
||||||
|
"date": "2025-09-06T07:50:15Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "forgejo/forgejo",
|
||||||
|
"version": "v12.0.3",
|
||||||
|
"date": "2025-09-06T07:01:44Z"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "moghtech/komodo",
|
"name": "moghtech/komodo",
|
||||||
"version": "v1.19.3",
|
"version": "v1.19.3",
|
||||||
@@ -9,16 +304,6 @@
|
|||||||
"version": "v1.36.1",
|
"version": "v1.36.1",
|
||||||
"date": "2025-09-05T21:14:40Z"
|
"date": "2025-09-05T21:14:40Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "booklore-app/booklore",
|
|
||||||
"version": "v1.2.0",
|
|
||||||
"date": "2025-09-05T20:43:03Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "immich-app/immich",
|
|
||||||
"version": "v1.141.1",
|
|
||||||
"date": "2025-09-05T19:44:39Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "gtsteffaniak/filebrowser",
|
"name": "gtsteffaniak/filebrowser",
|
||||||
"version": "v0.8.4-beta",
|
"version": "v0.8.4-beta",
|
||||||
@@ -29,16 +314,6 @@
|
|||||||
"version": "v1.3.2",
|
"version": "v1.3.2",
|
||||||
"date": "2025-09-05T18:44:15Z"
|
"date": "2025-09-05T18:44:15Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "diced/zipline",
|
|
||||||
"version": "v4.3.0",
|
|
||||||
"date": "2025-09-05T18:43:28Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "rcourtman/Pulse",
|
|
||||||
"version": "v4.14.0",
|
|
||||||
"date": "2025-09-05T18:28:28Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "henrygd/beszel",
|
"name": "henrygd/beszel",
|
||||||
"version": "v0.12.7",
|
"version": "v0.12.7",
|
||||||
@@ -49,46 +324,16 @@
|
|||||||
"version": "v5.14.2",
|
"version": "v5.14.2",
|
||||||
"date": "2025-09-05T17:24:12Z"
|
"date": "2025-09-05T17:24:12Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "fuma-nama/fumadocs",
|
|
||||||
"version": "create-fumadocs-app@15.7.9",
|
|
||||||
"date": "2025-09-05T14:33:41Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "wizarrrr/wizarr",
|
"name": "wizarrrr/wizarr",
|
||||||
"version": "2025.9.0",
|
"version": "2025.9.0",
|
||||||
"date": "2025-09-05T14:21:34Z"
|
"date": "2025-09-05T14:21:34Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "cross-seed/cross-seed",
|
|
||||||
"version": "v6.13.2",
|
|
||||||
"date": "2025-08-19T18:18:40Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "chrisvel/tududi",
|
|
||||||
"version": "v0.80",
|
|
||||||
"date": "2025-07-24T14:12:39Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "home-assistant/core",
|
"name": "home-assistant/core",
|
||||||
"version": "2025.9.1",
|
"version": "2025.9.1",
|
||||||
"date": "2025-09-05T11:15:21Z"
|
"date": "2025-09-05T11:15:21Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "syncthing/syncthing",
|
|
||||||
"version": "v2.0.7",
|
|
||||||
"date": "2025-09-05T10:18:24Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "zitadel/zitadel",
|
|
||||||
"version": "v4.1.2",
|
|
||||||
"date": "2025-09-05T08:23:30Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Jackett/Jackett",
|
|
||||||
"version": "v0.22.2429",
|
|
||||||
"date": "2025-09-05T06:05:30Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "CrazyWolf13/streamlink-webui",
|
"name": "CrazyWolf13/streamlink-webui",
|
||||||
"version": "0.6",
|
"version": "0.6",
|
||||||
@@ -99,16 +344,6 @@
|
|||||||
"version": "2.0.0-beta.2-temp",
|
"version": "2.0.0-beta.2-temp",
|
||||||
"date": "2025-03-28T08:45:58Z"
|
"date": "2025-03-28T08:45:58Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "jeedom/core",
|
|
||||||
"version": "4.4.19",
|
|
||||||
"date": "2025-09-05T00:27:15Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "steveiliop56/tinyauth",
|
|
||||||
"version": "v3.6.2",
|
|
||||||
"date": "2025-07-17T12:08:03Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "wazuh/wazuh",
|
"name": "wazuh/wazuh",
|
||||||
"version": "coverity-w36-4.13.0",
|
"version": "coverity-w36-4.13.0",
|
||||||
@@ -129,66 +364,26 @@
|
|||||||
"version": "v1.0.0-beta17",
|
"version": "v1.0.0-beta17",
|
||||||
"date": "2025-09-04T21:30:14Z"
|
"date": "2025-09-04T21:30:14Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "TandoorRecipes/recipes",
|
|
||||||
"version": "2.1.0",
|
|
||||||
"date": "2025-09-04T20:24:47Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "mongodb/mongo",
|
|
||||||
"version": "r7.0.24",
|
|
||||||
"date": "2025-09-04T19:50:49Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "Cleanuparr/Cleanuparr",
|
"name": "Cleanuparr/Cleanuparr",
|
||||||
"version": "v2.2.3",
|
"version": "v2.2.3",
|
||||||
"date": "2025-09-04T19:24:39Z"
|
"date": "2025-09-04T19:24:39Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "HabitRPG/habitica",
|
|
||||||
"version": "v5.40.1",
|
|
||||||
"date": "2025-09-04T19:10:45Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "runtipi/runtipi",
|
|
||||||
"version": "nightly",
|
|
||||||
"date": "2025-09-04T18:29:10Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "AdguardTeam/AdGuardHome",
|
"name": "AdguardTeam/AdGuardHome",
|
||||||
"version": "v0.107.65",
|
"version": "v0.107.65",
|
||||||
"date": "2025-08-20T14:02:28Z"
|
"date": "2025-08-20T14:02:28Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "webmin/webmin",
|
|
||||||
"version": "2.500",
|
|
||||||
"date": "2025-09-04T17:44:27Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "ollama/ollama",
|
"name": "ollama/ollama",
|
||||||
"version": "v0.11.10",
|
"version": "v0.11.10",
|
||||||
"date": "2025-09-04T17:27:40Z"
|
"date": "2025-09-04T17:27:40Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "MediaBrowser/Emby.Releases",
|
|
||||||
"version": "4.9.1.2",
|
|
||||||
"date": "2025-06-26T22:08:00Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "NodeBB/NodeBB",
|
"name": "NodeBB/NodeBB",
|
||||||
"version": "v4.5.1",
|
"version": "v4.5.1",
|
||||||
"date": "2025-09-04T16:02:49Z"
|
"date": "2025-09-04T16:02:49Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "keycloak/keycloak",
|
|
||||||
"version": "26.0.15",
|
|
||||||
"date": "2025-08-27T12:12:03Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "semaphoreui/semaphore",
|
|
||||||
"version": "v2.16.19",
|
|
||||||
"date": "2025-09-04T14:22:02Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "raydak-labs/configarr",
|
"name": "raydak-labs/configarr",
|
||||||
"version": "v1.15.1",
|
"version": "v1.15.1",
|
||||||
@@ -249,41 +444,21 @@
|
|||||||
"version": "10.0.19",
|
"version": "10.0.19",
|
||||||
"date": "2025-07-16T09:45:14Z"
|
"date": "2025-07-16T09:45:14Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "Radarr/Radarr",
|
|
||||||
"version": "v5.27.5.10198",
|
|
||||||
"date": "2025-09-03T12:08:43Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "neo4j/neo4j",
|
"name": "neo4j/neo4j",
|
||||||
"version": "5.26.12",
|
"version": "5.26.12",
|
||||||
"date": "2025-09-03T12:03:22Z"
|
"date": "2025-09-03T12:03:22Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "n8n-io/n8n",
|
|
||||||
"version": "n8n@1.109.2",
|
|
||||||
"date": "2025-09-03T07:50:21Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "Checkmk/checkmk",
|
"name": "Checkmk/checkmk",
|
||||||
"version": "v2.4.0p11",
|
"version": "v2.4.0p11",
|
||||||
"date": "2025-09-03T09:58:14Z"
|
"date": "2025-09-03T09:58:14Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "mattermost/mattermost",
|
|
||||||
"version": "server/public/v0.1.17",
|
|
||||||
"date": "2025-09-02T21:38:40Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "cockpit-project/cockpit",
|
"name": "cockpit-project/cockpit",
|
||||||
"version": "346",
|
"version": "346",
|
||||||
"date": "2025-09-03T09:13:05Z"
|
"date": "2025-09-03T09:13:05Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "jenkinsci/jenkins",
|
|
||||||
"version": "jenkins-2.526",
|
|
||||||
"date": "2025-09-02T18:44:42Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "apache/cassandra",
|
"name": "apache/cassandra",
|
||||||
"version": "cassandra-4.1.10",
|
"version": "cassandra-4.1.10",
|
||||||
@@ -294,31 +469,16 @@
|
|||||||
"version": "v4.5.3",
|
"version": "v4.5.3",
|
||||||
"date": "2025-09-02T23:52:26Z"
|
"date": "2025-09-02T23:52:26Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "Luligu/matterbridge",
|
|
||||||
"version": "3.2.5",
|
|
||||||
"date": "2025-09-02T17:25:13Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "netbox-community/netbox",
|
"name": "netbox-community/netbox",
|
||||||
"version": "v4.4.0",
|
"version": "v4.4.0",
|
||||||
"date": "2025-09-02T17:04:25Z"
|
"date": "2025-09-02T17:04:25Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "element-hq/synapse",
|
|
||||||
"version": "v1.137.0",
|
|
||||||
"date": "2025-08-26T09:51:47Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "rabbitmq/rabbitmq-server",
|
"name": "rabbitmq/rabbitmq-server",
|
||||||
"version": "v4.1.4",
|
"version": "v4.1.4",
|
||||||
"date": "2025-09-02T14:26:24Z"
|
"date": "2025-09-02T14:26:24Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "apache/tomcat",
|
|
||||||
"version": "10.1.45",
|
|
||||||
"date": "2025-09-02T12:46:34Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "Dolibarr/dolibarr",
|
"name": "Dolibarr/dolibarr",
|
||||||
"version": "22.0.1",
|
"version": "22.0.1",
|
||||||
@@ -329,26 +489,11 @@
|
|||||||
"version": "4.7.0",
|
"version": "4.7.0",
|
||||||
"date": "2025-09-02T06:02:43Z"
|
"date": "2025-09-02T06:02:43Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "firefly-iii/firefly-iii",
|
|
||||||
"version": "v6.3.2",
|
|
||||||
"date": "2025-08-19T04:08:36Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "paperless-ngx/paperless-ngx",
|
|
||||||
"version": "v2.18.3",
|
|
||||||
"date": "2025-09-02T01:16:49Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "ErsatzTV/ErsatzTV",
|
"name": "ErsatzTV/ErsatzTV",
|
||||||
"version": "v25.5.0",
|
"version": "v25.5.0",
|
||||||
"date": "2025-09-02T01:00:11Z"
|
"date": "2025-09-02T01:00:11Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "authelia/authelia",
|
|
||||||
"version": "v4.39.8",
|
|
||||||
"date": "2025-09-02T00:44:45Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "postgres/postgres",
|
"name": "postgres/postgres",
|
||||||
"version": "REL_18_RC1",
|
"version": "REL_18_RC1",
|
||||||
@@ -369,11 +514,6 @@
|
|||||||
"version": "v0.87.3",
|
"version": "v0.87.3",
|
||||||
"date": "2025-09-01T16:25:43Z"
|
"date": "2025-09-01T16:25:43Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "home-assistant/operating-system",
|
|
||||||
"version": "16.1",
|
|
||||||
"date": "2025-08-13T07:58:10Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "seanmorley15/AdventureLog",
|
"name": "seanmorley15/AdventureLog",
|
||||||
"version": "v0.11.0",
|
"version": "v0.11.0",
|
||||||
@@ -384,16 +524,6 @@
|
|||||||
"version": "rrc_steady_12.2.0-17245430286.patch1",
|
"version": "rrc_steady_12.2.0-17245430286.patch1",
|
||||||
"date": "2025-09-01T14:19:14Z"
|
"date": "2025-09-01T14:19:14Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "fallenbagel/jellyseerr",
|
|
||||||
"version": "preview-issue-description",
|
|
||||||
"date": "2025-09-01T12:21:58Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "nzbgetcom/nzbget",
|
|
||||||
"version": "v25.3",
|
|
||||||
"date": "2025-09-01T09:47:06Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "grokability/snipe-it",
|
"name": "grokability/snipe-it",
|
||||||
"version": "v8.3.1",
|
"version": "v8.3.1",
|
||||||
@@ -404,56 +534,16 @@
|
|||||||
"version": "v1.7.0",
|
"version": "v1.7.0",
|
||||||
"date": "2025-09-01T10:10:34Z"
|
"date": "2025-09-01T10:10:34Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "readeck/readeck",
|
|
||||||
"version": "0.20.1",
|
|
||||||
"date": "2025-09-01T07:35:48Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "YunoHost/yunohost",
|
|
||||||
"version": "debian/12.1.17.1",
|
|
||||||
"date": "2025-08-31T21:38:21Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "karakeep-app/karakeep",
|
|
||||||
"version": "ios/v1.8.0-1",
|
|
||||||
"date": "2025-08-31T16:06:00Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "LibreTranslate/LibreTranslate",
|
"name": "LibreTranslate/LibreTranslate",
|
||||||
"version": "v1.7.3",
|
"version": "v1.7.3",
|
||||||
"date": "2025-08-31T15:59:43Z"
|
"date": "2025-08-31T15:59:43Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "Part-DB/Part-DB-server",
|
|
||||||
"version": "v2.0.2",
|
|
||||||
"date": "2025-08-31T13:52:49Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "forgejo/forgejo",
|
|
||||||
"version": "v12.0.2",
|
|
||||||
"date": "2025-08-31T13:15:47Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Lidarr/Lidarr",
|
|
||||||
"version": "v2.13.3.4711",
|
|
||||||
"date": "2025-08-28T20:06:24Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "jhuckaby/Cronicle",
|
"name": "jhuckaby/Cronicle",
|
||||||
"version": "v0.9.91",
|
"version": "v0.9.91",
|
||||||
"date": "2025-08-30T21:49:57Z"
|
"date": "2025-08-30T21:49:57Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "bunkerity/bunkerweb",
|
|
||||||
"version": "v1.6.4",
|
|
||||||
"date": "2025-08-18T20:22:07Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "msgbyte/tianji",
|
|
||||||
"version": "v1.24.26",
|
|
||||||
"date": "2025-08-29T20:26:08Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "silverbulletmd/silverbullet",
|
"name": "silverbulletmd/silverbullet",
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
@@ -469,21 +559,11 @@
|
|||||||
"version": "v3007.7",
|
"version": "v3007.7",
|
||||||
"date": "2025-08-29T01:19:08Z"
|
"date": "2025-08-29T01:19:08Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "9001/copyparty",
|
|
||||||
"version": "v1.19.7",
|
|
||||||
"date": "2025-08-28T20:42:58Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "linkwarden/linkwarden",
|
"name": "linkwarden/linkwarden",
|
||||||
"version": "v2.12.2",
|
"version": "v2.12.2",
|
||||||
"date": "2025-08-28T20:34:30Z"
|
"date": "2025-08-28T20:34:30Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "dgtlmoon/changedetection.io",
|
|
||||||
"version": "0.50.11",
|
|
||||||
"date": "2025-08-28T20:12:30Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "benjaminjonard/koillection",
|
"name": "benjaminjonard/koillection",
|
||||||
"version": "1.7.0",
|
"version": "1.7.0",
|
||||||
@@ -509,21 +589,11 @@
|
|||||||
"version": "v3.4.1",
|
"version": "v3.4.1",
|
||||||
"date": "2025-08-28T13:56:00Z"
|
"date": "2025-08-28T13:56:00Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "open-webui/open-webui",
|
|
||||||
"version": "v0.6.26",
|
|
||||||
"date": "2025-08-28T10:40:30Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "garethgeorge/backrest",
|
"name": "garethgeorge/backrest",
|
||||||
"version": "v1.9.2",
|
"version": "v1.9.2",
|
||||||
"date": "2025-08-28T07:06:14Z"
|
"date": "2025-08-28T07:06:14Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "gotson/komga",
|
|
||||||
"version": "1.23.3",
|
|
||||||
"date": "2025-08-28T02:50:06Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "pocket-id/pocket-id",
|
"name": "pocket-id/pocket-id",
|
||||||
"version": "v1.10.0",
|
"version": "v1.10.0",
|
||||||
@@ -539,31 +609,6 @@
|
|||||||
"version": "v11.2.1",
|
"version": "v11.2.1",
|
||||||
"date": "2025-08-27T15:19:02Z"
|
"date": "2025-08-27T15:19:02Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "Paymenter/Paymenter",
|
|
||||||
"version": "v1.2.11",
|
|
||||||
"date": "2025-08-27T11:23:09Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "traefik/traefik",
|
|
||||||
"version": "v3.5.1",
|
|
||||||
"date": "2025-08-27T09:21:19Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "theonedev/onedev",
|
|
||||||
"version": "v12.0.8",
|
|
||||||
"date": "2025-08-27T06:22:32Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "meilisearch/meilisearch",
|
|
||||||
"version": "latest",
|
|
||||||
"date": "2025-08-26T14:14:42Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "evcc-io/evcc",
|
|
||||||
"version": "0.207.5",
|
|
||||||
"date": "2025-08-26T06:57:07Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "documenso/documenso",
|
"name": "documenso/documenso",
|
||||||
"version": "v1.12.2-rc.6",
|
"version": "v1.12.2-rc.6",
|
||||||
@@ -614,11 +659,6 @@
|
|||||||
"version": "2.1",
|
"version": "2.1",
|
||||||
"date": "2025-08-24T15:42:19Z"
|
"date": "2025-08-24T15:42:19Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "Prowlarr/Prowlarr",
|
|
||||||
"version": "v2.0.5.5160",
|
|
||||||
"date": "2025-08-23T21:23:11Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "janeczku/calibre-web",
|
"name": "janeczku/calibre-web",
|
||||||
"version": "0.6.25",
|
"version": "0.6.25",
|
||||||
@@ -634,11 +674,6 @@
|
|||||||
"version": "v0.306.0-rc.0",
|
"version": "v0.306.0-rc.0",
|
||||||
"date": "2025-08-21T13:31:03Z"
|
"date": "2025-08-21T13:31:03Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "pocketbase/pocketbase",
|
|
||||||
"version": "v0.29.3",
|
|
||||||
"date": "2025-08-23T06:37:44Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "caddyserver/caddy",
|
"name": "caddyserver/caddy",
|
||||||
"version": "v2.10.2",
|
"version": "v2.10.2",
|
||||||
@@ -674,16 +709,6 @@
|
|||||||
"version": "v6.9.1",
|
"version": "v6.9.1",
|
||||||
"date": "2025-08-22T04:04:12Z"
|
"date": "2025-08-22T04:04:12Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "hargata/lubelog",
|
|
||||||
"version": "v1.5.0",
|
|
||||||
"date": "2025-08-21T17:33:22Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "kyantech/Palmr",
|
|
||||||
"version": "v3.2.0-beta",
|
|
||||||
"date": "2025-08-21T16:51:45Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "cloudflare/cloudflared",
|
"name": "cloudflare/cloudflared",
|
||||||
"version": "2025.8.1",
|
"version": "2025.8.1",
|
||||||
@@ -819,11 +844,6 @@
|
|||||||
"version": "2.38.0",
|
"version": "2.38.0",
|
||||||
"date": "2025-08-08T21:47:19Z"
|
"date": "2025-08-08T21:47:19Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "docker/compose",
|
|
||||||
"version": "v2.39.2",
|
|
||||||
"date": "2025-08-08T16:06:06Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "apache/tika",
|
"name": "apache/tika",
|
||||||
"version": "3.2.2",
|
"version": "3.2.2",
|
||||||
@@ -849,11 +869,6 @@
|
|||||||
"version": "v1.28.3",
|
"version": "v1.28.3",
|
||||||
"date": "2025-08-06T12:32:02Z"
|
"date": "2025-08-06T12:32:02Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "autobrr/autobrr",
|
|
||||||
"version": "v1.65.0",
|
|
||||||
"date": "2025-08-05T21:12:35Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "WordPress/WordPress",
|
"name": "WordPress/WordPress",
|
||||||
"version": "4.7.30",
|
"version": "4.7.30",
|
||||||
@@ -869,11 +884,6 @@
|
|||||||
"version": "v2.0.116",
|
"version": "v2.0.116",
|
||||||
"date": "2025-08-05T04:45:21Z"
|
"date": "2025-08-05T04:45:21Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "Tautulli/Tautulli",
|
|
||||||
"version": "v2.15.3",
|
|
||||||
"date": "2025-08-03T17:27:16Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "linuxserver/Heimdall",
|
"name": "linuxserver/Heimdall",
|
||||||
"version": "v2.7.4",
|
"version": "v2.7.4",
|
||||||
@@ -954,11 +964,6 @@
|
|||||||
"version": "2.9.0",
|
"version": "2.9.0",
|
||||||
"date": "2025-07-25T14:20:25Z"
|
"date": "2025-07-25T14:20:25Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "minio/minio",
|
|
||||||
"version": "RELEASE.2025-07-23T15-54-02Z",
|
|
||||||
"date": "2025-07-23T20:35:39Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "TasmoAdmin/TasmoAdmin",
|
"name": "TasmoAdmin/TasmoAdmin",
|
||||||
"version": "v4.3.1",
|
"version": "v4.3.1",
|
||||||
@@ -1119,11 +1124,6 @@
|
|||||||
"version": "v2.0.0.4645",
|
"version": "v2.0.0.4645",
|
||||||
"date": "2017-03-07T18:56:06Z"
|
"date": "2017-03-07T18:56:06Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "OctoPrint/OctoPrint",
|
|
||||||
"version": "1.11.2",
|
|
||||||
"date": "2025-06-10T11:07:14Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "glanceapp/glance",
|
"name": "glanceapp/glance",
|
||||||
"version": "v0.8.4",
|
"version": "v0.8.4",
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ const DataFetcher: React.FC = () => {
|
|||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [itemsPerPage, setItemsPerPage] = useState(25);
|
const [itemsPerPage, setItemsPerPage] = useState(25);
|
||||||
const [sortConfig, setSortConfig] = useState<{ key: string; direction: "ascending" | "descending" } | null>(null);
|
const [sortConfig, setSortConfig] = useState<{ key: string; direction: "ascending" | "descending" } | null>(null);
|
||||||
|
const nf = new Intl.NumberFormat("en-US", { maximumFractionDigits: 0 });
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchSummary = async () => {
|
const fetchSummary = async () => {
|
||||||
@@ -129,19 +130,24 @@ const DataFetcher: React.FC = () => {
|
|||||||
<p className="text-lg font-bold mt-4"> </p>
|
<p className="text-lg font-bold mt-4"> </p>
|
||||||
<div className="mb-4 flex justify-between items-center">
|
<div className="mb-4 flex justify-between items-center">
|
||||||
<p className="text-lg font-bold">
|
<p className="text-lg font-bold">
|
||||||
{summary?.total_entries}
|
{nf.format(
|
||||||
|
summary?.total_entries ?? 0,
|
||||||
|
)}
|
||||||
{" "}
|
{" "}
|
||||||
results found
|
results found
|
||||||
</p>
|
</p>
|
||||||
<p className="text-lg font">
|
<p className="text-lg font">
|
||||||
Status Legend: 🔄 installing
|
Status Legend: 🔄 installing
|
||||||
{summary?.status_count.installing ?? 0}
|
{" "}
|
||||||
|
{nf.format(summary?.status_count.installing ?? 0)}
|
||||||
{" "}
|
{" "}
|
||||||
| ✔️ completed
|
| ✔️ completed
|
||||||
{summary?.status_count.done ?? 0}
|
{" "}
|
||||||
|
{nf.format(summary?.status_count.done ?? 0)}
|
||||||
{" "}
|
{" "}
|
||||||
| ❌ failed
|
| ❌ failed
|
||||||
{summary?.status_count.failed ?? 0}
|
{" "}
|
||||||
|
{nf.format(summary?.status_count.failed ?? 0)}
|
||||||
{" "}
|
{" "}
|
||||||
| ❓ unknown
|
| ❓ unknown
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import type { VariantProps } from "class-variance-authority";
|
||||||
|
|
||||||
|
import { cva } from "class-variance-authority";
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import type { ButtonProps as ButtonPrimitiveProps } from "@/components/animate-ui/primitives/buttons/button";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Button as ButtonPrimitive,
|
||||||
|
|
||||||
|
} from "@/components/animate-ui/primitives/buttons/button";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
const buttonVariants = cva(
|
||||||
|
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[box-shadow,_color,_background-color,_border-color,_outline-color,_text-decoration-color,_fill,_stroke] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
||||||
|
{
|
||||||
|
variants: {
|
||||||
|
variant: {
|
||||||
|
default:
|
||||||
|
"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
|
||||||
|
accent: "bg-accent text-accent-foreground shadow-xs hover:bg-accent/90",
|
||||||
|
destructive:
|
||||||
|
"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
||||||
|
outline:
|
||||||
|
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
||||||
|
secondary:
|
||||||
|
"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
|
||||||
|
ghost:
|
||||||
|
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
||||||
|
link: "text-primary underline-offset-4 hover:underline",
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
"default": "h-9 px-4 py-2 has-[>svg]:px-3",
|
||||||
|
"sm": "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
|
||||||
|
"lg": "h-10 rounded-md px-6 has-[>svg]:px-4",
|
||||||
|
"icon": "size-9",
|
||||||
|
"icon-sm": "size-8 rounded-md",
|
||||||
|
"icon-lg": "size-10 rounded-md",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
variant: "default",
|
||||||
|
size: "default",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
type ButtonProps = ButtonPrimitiveProps & VariantProps<typeof buttonVariants>;
|
||||||
|
|
||||||
|
function Button({ className, variant, size, ...props }: ButtonProps) {
|
||||||
|
return (
|
||||||
|
<ButtonPrimitive
|
||||||
|
className={cn(buttonVariants({ variant, size, className }))}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Button, type ButtonProps, buttonVariants };
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
import type { VariantProps } from "class-variance-authority";
|
||||||
|
|
||||||
|
import { cva } from "class-variance-authority";
|
||||||
|
import { StarIcon } from "lucide-react";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
import type { ButtonProps as ButtonPrimitiveProps } from "@/components/animate-ui/primitives/buttons/button";
|
||||||
|
import type { GithubStarsProps } from "@/components/animate-ui/primitives/animate/github-stars";
|
||||||
|
|
||||||
|
import {
|
||||||
|
GithubStars,
|
||||||
|
GithubStarsIcon,
|
||||||
|
GithubStarsLogo,
|
||||||
|
GithubStarsNumber,
|
||||||
|
GithubStarsParticles,
|
||||||
|
} from "@/components/animate-ui/primitives/animate/github-stars";
|
||||||
|
import { Button as ButtonPrimitive } from "@/components/animate-ui/primitives/buttons/button";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
const buttonVariants = cva(
|
||||||
|
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[box-shadow,_color,_background-color,_border-color,_outline-color,_text-decoration-color,_fill,_stroke] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
||||||
|
{
|
||||||
|
variants: {
|
||||||
|
variant: {
|
||||||
|
default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
|
||||||
|
accent: "bg-accent text-accent-foreground shadow-xs hover:bg-accent/90",
|
||||||
|
outline:
|
||||||
|
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
||||||
|
ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
||||||
|
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
|
||||||
|
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
variant: "default",
|
||||||
|
size: "default",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const buttonStarVariants = cva("", {
|
||||||
|
variants: {
|
||||||
|
variant: {
|
||||||
|
default: "fill-neutral-700 stroke-neutral-700 dark:fill-neutral-300 dark:stroke-neutral-300",
|
||||||
|
accent: "fill-neutral-300 stroke-neutral-300 dark:fill-neutral-700 dark:stroke-neutral-700",
|
||||||
|
outline: "fill-neutral-300 stroke-neutral-300 dark:fill-neutral-700 dark:stroke-neutral-700",
|
||||||
|
ghost: "fill-neutral-300 stroke-neutral-300 dark:fill-neutral-700 dark:stroke-neutral-700",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
variant: "default",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
type GitHubStarsButtonProps = Omit<ButtonPrimitiveProps & GithubStarsProps, "asChild" | "children">
|
||||||
|
& VariantProps<typeof buttonVariants>;
|
||||||
|
|
||||||
|
function GitHubStarsButton({
|
||||||
|
className,
|
||||||
|
username,
|
||||||
|
repo,
|
||||||
|
value,
|
||||||
|
delay,
|
||||||
|
inView,
|
||||||
|
inViewMargin,
|
||||||
|
inViewOnce,
|
||||||
|
variant,
|
||||||
|
size,
|
||||||
|
...props
|
||||||
|
}: GitHubStarsButtonProps) {
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
data-umami-event="github-stars"
|
||||||
|
href={`https://github.com/${username}/${repo}`}
|
||||||
|
>
|
||||||
|
<GithubStars
|
||||||
|
asChild
|
||||||
|
username={username}
|
||||||
|
repo={repo}
|
||||||
|
value={value}
|
||||||
|
delay={delay}
|
||||||
|
inView={inView}
|
||||||
|
inViewMargin={inViewMargin}
|
||||||
|
inViewOnce={inViewOnce}
|
||||||
|
>
|
||||||
|
<ButtonPrimitive className={cn(buttonVariants({ variant, size, className }))} {...props}>
|
||||||
|
<GithubStarsLogo />
|
||||||
|
<GithubStarsNumber />
|
||||||
|
<GithubStarsParticles className="text-yellow-500">
|
||||||
|
<GithubStarsIcon
|
||||||
|
icon={StarIcon}
|
||||||
|
data-variant={variant}
|
||||||
|
className={cn(buttonStarVariants({ variant }))}
|
||||||
|
activeClassName="text-yellow-500"
|
||||||
|
size={18}
|
||||||
|
/>
|
||||||
|
</GithubStarsParticles>
|
||||||
|
</ButtonPrimitive>
|
||||||
|
</GithubStars>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { GitHubStarsButton, type GitHubStarsButtonProps };
|
||||||
@@ -0,0 +1,206 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import type { HTMLMotionProps } from "motion/react";
|
||||||
|
|
||||||
|
import { motion } from "motion/react";
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import type { SlidingNumberProps } from "@/components/animate-ui/primitives/texts/sliding-number";
|
||||||
|
import type { ParticlesEffectProps } from "@/components/animate-ui/primitives/effects/particles";
|
||||||
|
import type { WithAsChild } from "@/components/animate-ui/primitives/animate/slot";
|
||||||
|
import type { UseIsInViewOptions } from "@/hooks/use-is-in-view";
|
||||||
|
|
||||||
|
import { Particles, ParticlesEffect } from "@/components/animate-ui/primitives/effects/particles";
|
||||||
|
import { SlidingNumber } from "@/components/animate-ui/primitives/texts/sliding-number";
|
||||||
|
import { Slot } from "@/components/animate-ui/primitives/animate/slot";
|
||||||
|
import { getStrictContext } from "@/lib/get-strict-context";
|
||||||
|
import { useIsInView } from "@/hooks/use-is-in-view";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
type GithubStarsContextType = {
|
||||||
|
stars: number;
|
||||||
|
setStars: (stars: number) => void;
|
||||||
|
currentStars: number;
|
||||||
|
setCurrentStars: (stars: number) => void;
|
||||||
|
isCompleted: boolean;
|
||||||
|
isLoading: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const [GithubStarsProvider, useGithubStars] = getStrictContext<GithubStarsContextType>("GithubStarsContext");
|
||||||
|
|
||||||
|
type GithubStarsProps = WithAsChild<
|
||||||
|
{
|
||||||
|
children: React.ReactNode;
|
||||||
|
username?: string;
|
||||||
|
repo?: string;
|
||||||
|
value?: number;
|
||||||
|
delay?: number;
|
||||||
|
} & UseIsInViewOptions
|
||||||
|
& HTMLMotionProps<"div">
|
||||||
|
>;
|
||||||
|
|
||||||
|
function GithubStars({
|
||||||
|
ref,
|
||||||
|
children,
|
||||||
|
username,
|
||||||
|
repo,
|
||||||
|
value,
|
||||||
|
delay = 0,
|
||||||
|
inView = false,
|
||||||
|
inViewMargin = "0px",
|
||||||
|
inViewOnce = true,
|
||||||
|
asChild = false,
|
||||||
|
...props
|
||||||
|
}: GithubStarsProps) {
|
||||||
|
const { ref: localRef, isInView } = useIsInView(ref as React.Ref<HTMLDivElement>, {
|
||||||
|
inView,
|
||||||
|
inViewOnce,
|
||||||
|
inViewMargin,
|
||||||
|
});
|
||||||
|
|
||||||
|
const [stars, setStars] = React.useState(value ?? 0);
|
||||||
|
const [currentStars, setCurrentStars] = React.useState(0);
|
||||||
|
const [isLoading, setIsLoading] = React.useState(true);
|
||||||
|
const isCompleted = React.useMemo(() => currentStars === stars, [currentStars, stars]);
|
||||||
|
|
||||||
|
const Component = asChild ? Slot : motion.div;
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (value !== undefined && username && repo)
|
||||||
|
return;
|
||||||
|
if (!isInView) {
|
||||||
|
setStars(0);
|
||||||
|
setIsLoading(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
fetch(`https://api.github.com/repos/${username}/${repo}`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then((data) => {
|
||||||
|
if (data && typeof data.stargazers_count === "number") {
|
||||||
|
setStars(data.stargazers_count);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(console.error)
|
||||||
|
.finally(() => setIsLoading(false));
|
||||||
|
}, delay);
|
||||||
|
|
||||||
|
return () => clearTimeout(timeout);
|
||||||
|
}, [username, repo, value, isInView, delay]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<GithubStarsProvider
|
||||||
|
value={{
|
||||||
|
stars,
|
||||||
|
currentStars,
|
||||||
|
isCompleted,
|
||||||
|
isLoading,
|
||||||
|
setStars,
|
||||||
|
setCurrentStars,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{!isLoading && (
|
||||||
|
<Component ref={localRef} {...props}>
|
||||||
|
{children}
|
||||||
|
</Component>
|
||||||
|
)}
|
||||||
|
</GithubStarsProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
type GithubStarsNumberProps = Omit<SlidingNumberProps, "number" | "fromNumber">;
|
||||||
|
|
||||||
|
function GithubStarsNumber({ padStart = true, ...props }: GithubStarsNumberProps) {
|
||||||
|
const { stars, setCurrentStars } = useGithubStars();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SlidingNumber number={stars} fromNumber={0} onNumberChange={setCurrentStars} padStart={padStart} {...props} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
type GithubStarsIconProps<T extends React.ElementType> = {
|
||||||
|
icon: React.ReactElement<T>;
|
||||||
|
color?: string;
|
||||||
|
activeClassName?: string;
|
||||||
|
} & React.ComponentProps<T>;
|
||||||
|
|
||||||
|
function GithubStarsIcon<T extends React.ElementType>({
|
||||||
|
icon: Icon,
|
||||||
|
color = "currentColor",
|
||||||
|
activeClassName,
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: GithubStarsIconProps<T>) {
|
||||||
|
const { stars, currentStars, isCompleted } = useGithubStars();
|
||||||
|
const fillPercentage = (currentStars / stars) * 100;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ position: "relative" }}>
|
||||||
|
<Icon aria-hidden="true" className={cn(className)} {...props} />
|
||||||
|
<Icon
|
||||||
|
aria-hidden="true"
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
fill: color,
|
||||||
|
stroke: color,
|
||||||
|
clipPath: `inset(${100 - (isCompleted ? fillPercentage : fillPercentage - 10)}% 0 0 0)`,
|
||||||
|
}}
|
||||||
|
className={cn(className, activeClassName)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
type GithubStarsParticlesProps = ParticlesEffectProps & {
|
||||||
|
children: React.ReactElement;
|
||||||
|
size?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
function GithubStarsParticles({ children, size = 4, style, ...props }: GithubStarsParticlesProps) {
|
||||||
|
const { isCompleted } = useGithubStars();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Particles animate={isCompleted}>
|
||||||
|
{children}
|
||||||
|
<ParticlesEffect
|
||||||
|
style={{
|
||||||
|
backgroundColor: "currentcolor",
|
||||||
|
borderRadius: "50%",
|
||||||
|
width: size,
|
||||||
|
height: size,
|
||||||
|
...style,
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</Particles>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
type GithubStarsLogoProps = React.SVGProps<SVGSVGElement>;
|
||||||
|
|
||||||
|
function GithubStarsLogo(props: GithubStarsLogoProps) {
|
||||||
|
return (
|
||||||
|
<svg role="img" viewBox="0 0 24 24" fill="currentColor" aria-label="GitHub" {...props}>
|
||||||
|
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"></path>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
GithubStars,
|
||||||
|
type GithubStarsContextType,
|
||||||
|
GithubStarsIcon,
|
||||||
|
type GithubStarsIconProps,
|
||||||
|
GithubStarsLogo,
|
||||||
|
type GithubStarsLogoProps,
|
||||||
|
GithubStarsNumber,
|
||||||
|
type GithubStarsNumberProps,
|
||||||
|
GithubStarsParticles,
|
||||||
|
type GithubStarsParticlesProps,
|
||||||
|
type GithubStarsProps,
|
||||||
|
useGithubStars,
|
||||||
|
};
|
||||||
101
frontend/src/components/animate-ui/primitives/animate/slot.tsx
Normal file
101
frontend/src/components/animate-ui/primitives/animate/slot.tsx
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import type { HTMLMotionProps } from "motion/react";
|
||||||
|
|
||||||
|
import { isMotionComponent, motion } from "motion/react";
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
type AnyProps = Record<string, unknown>;
|
||||||
|
|
||||||
|
type DOMMotionProps<T extends HTMLElement = HTMLElement> = Omit<
|
||||||
|
HTMLMotionProps<keyof HTMLElementTagNameMap>,
|
||||||
|
"ref"
|
||||||
|
> & { ref?: React.Ref<T> };
|
||||||
|
|
||||||
|
type WithAsChild<Base extends object>
|
||||||
|
= | (Base & { asChild: true; children: React.ReactElement })
|
||||||
|
| (Base & { asChild?: false | undefined });
|
||||||
|
|
||||||
|
type SlotProps<T extends HTMLElement = HTMLElement> = {
|
||||||
|
children?: any;
|
||||||
|
} & DOMMotionProps<T>;
|
||||||
|
|
||||||
|
function mergeRefs<T>(
|
||||||
|
...refs: (React.Ref<T> | undefined)[]
|
||||||
|
): React.RefCallback<T> {
|
||||||
|
return (node) => {
|
||||||
|
refs.forEach((ref) => {
|
||||||
|
if (!ref)
|
||||||
|
return;
|
||||||
|
if (typeof ref === "function") {
|
||||||
|
ref(node);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(ref as React.RefObject<T | null>).current = node;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mergeProps<T extends HTMLElement>(
|
||||||
|
childProps: AnyProps,
|
||||||
|
slotProps: DOMMotionProps<T>,
|
||||||
|
): AnyProps {
|
||||||
|
const merged: AnyProps = { ...childProps, ...slotProps };
|
||||||
|
|
||||||
|
if (childProps.className || slotProps.className) {
|
||||||
|
merged.className = cn(
|
||||||
|
childProps.className as string,
|
||||||
|
slotProps.className as string,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (childProps.style || slotProps.style) {
|
||||||
|
merged.style = {
|
||||||
|
...(childProps.style as React.CSSProperties),
|
||||||
|
...(slotProps.style as React.CSSProperties),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return merged;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Slot<T extends HTMLElement = HTMLElement>({
|
||||||
|
children,
|
||||||
|
ref,
|
||||||
|
...props
|
||||||
|
}: SlotProps<T>) {
|
||||||
|
const isAlreadyMotion
|
||||||
|
= typeof children.type === "object"
|
||||||
|
&& children.type !== null
|
||||||
|
&& isMotionComponent(children.type);
|
||||||
|
|
||||||
|
const Base = React.useMemo(
|
||||||
|
() =>
|
||||||
|
isAlreadyMotion
|
||||||
|
? (children.type as React.ElementType)
|
||||||
|
: motion.create(children.type as React.ElementType),
|
||||||
|
[isAlreadyMotion, children.type],
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!React.isValidElement(children))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
const { ref: childRef, ...childProps } = children.props as AnyProps;
|
||||||
|
|
||||||
|
const mergedProps = mergeProps(childProps, props);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Base {...mergedProps} ref={mergeRefs(childRef as React.Ref<T>, ref)} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
type AnyProps,
|
||||||
|
type DOMMotionProps,
|
||||||
|
Slot,
|
||||||
|
type SlotProps,
|
||||||
|
type WithAsChild,
|
||||||
|
};
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import type { HTMLMotionProps } from "motion/react";
|
||||||
|
|
||||||
|
import { motion } from "motion/react";
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import type { WithAsChild } from "@/components/animate-ui/primitives/animate/slot";
|
||||||
|
|
||||||
|
import { Slot } from "@/components/animate-ui/primitives/animate/slot";
|
||||||
|
|
||||||
|
type ButtonProps = WithAsChild<
|
||||||
|
HTMLMotionProps<"button"> & {
|
||||||
|
hoverScale?: number;
|
||||||
|
tapScale?: number;
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
|
||||||
|
function Button({
|
||||||
|
hoverScale = 1.05,
|
||||||
|
tapScale = 0.95,
|
||||||
|
asChild = false,
|
||||||
|
...props
|
||||||
|
}: ButtonProps) {
|
||||||
|
const Component = asChild ? Slot : motion.button;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Component
|
||||||
|
whileTap={{ scale: tapScale }}
|
||||||
|
whileHover={{ scale: hoverScale }}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Button, type ButtonProps };
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import type { HTMLMotionProps } from "motion/react";
|
||||||
|
|
||||||
|
import { AnimatePresence, motion } from "motion/react";
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import type { WithAsChild } from "@/components/animate-ui/primitives/animate/slot";
|
||||||
|
import type { UseIsInViewOptions } from "@/hooks/use-is-in-view";
|
||||||
|
|
||||||
|
import { Slot } from "@/components/animate-ui/primitives/animate/slot";
|
||||||
|
import { getStrictContext } from "@/lib/get-strict-context";
|
||||||
|
import {
|
||||||
|
useIsInView,
|
||||||
|
|
||||||
|
} from "@/hooks/use-is-in-view";
|
||||||
|
|
||||||
|
type Side = "top" | "bottom" | "left" | "right";
|
||||||
|
type Align = "start" | "center" | "end";
|
||||||
|
|
||||||
|
type ParticlesContextType = {
|
||||||
|
animate: boolean;
|
||||||
|
isInView: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const [ParticlesProvider, useParticles]
|
||||||
|
= getStrictContext<ParticlesContextType>("ParticlesContext");
|
||||||
|
|
||||||
|
type ParticlesProps = WithAsChild<
|
||||||
|
Omit<HTMLMotionProps<"div">, "children"> & {
|
||||||
|
animate?: boolean;
|
||||||
|
children: React.ReactNode;
|
||||||
|
} & UseIsInViewOptions
|
||||||
|
>;
|
||||||
|
|
||||||
|
function Particles({
|
||||||
|
ref,
|
||||||
|
animate = true,
|
||||||
|
asChild = false,
|
||||||
|
inView = false,
|
||||||
|
inViewMargin = "0px",
|
||||||
|
inViewOnce = true,
|
||||||
|
children,
|
||||||
|
style,
|
||||||
|
...props
|
||||||
|
}: ParticlesProps) {
|
||||||
|
const { ref: localRef, isInView } = useIsInView(
|
||||||
|
ref as React.Ref<HTMLDivElement>,
|
||||||
|
{ inView, inViewOnce, inViewMargin },
|
||||||
|
);
|
||||||
|
|
||||||
|
const Component = asChild ? Slot : motion.div;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ParticlesProvider value={{ animate, isInView }}>
|
||||||
|
<Component
|
||||||
|
ref={localRef}
|
||||||
|
style={{ position: "relative", ...style }}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Component>
|
||||||
|
</ParticlesProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
type ParticlesEffectProps = Omit<HTMLMotionProps<"div">, "children"> & {
|
||||||
|
side?: Side;
|
||||||
|
align?: Align;
|
||||||
|
count?: number;
|
||||||
|
radius?: number;
|
||||||
|
spread?: number;
|
||||||
|
duration?: number;
|
||||||
|
holdDelay?: number;
|
||||||
|
sideOffset?: number;
|
||||||
|
alignOffset?: number;
|
||||||
|
delay?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
function ParticlesEffect({
|
||||||
|
side = "top",
|
||||||
|
align = "center",
|
||||||
|
count = 6,
|
||||||
|
radius = 30,
|
||||||
|
spread = 360,
|
||||||
|
duration = 0.8,
|
||||||
|
holdDelay = 0.05,
|
||||||
|
sideOffset = 0,
|
||||||
|
alignOffset = 0,
|
||||||
|
delay = 0,
|
||||||
|
transition,
|
||||||
|
style,
|
||||||
|
...props
|
||||||
|
}: ParticlesEffectProps) {
|
||||||
|
const { animate, isInView } = useParticles();
|
||||||
|
|
||||||
|
const isVertical = side === "top" || side === "bottom";
|
||||||
|
const alignPct = align === "start" ? "0%" : align === "end" ? "100%" : "50%";
|
||||||
|
|
||||||
|
const top = isVertical
|
||||||
|
? side === "top"
|
||||||
|
? `calc(0% - ${sideOffset}px)`
|
||||||
|
: `calc(100% + ${sideOffset}px)`
|
||||||
|
: `calc(${alignPct} + ${alignOffset}px)`;
|
||||||
|
|
||||||
|
const left = isVertical
|
||||||
|
? `calc(${alignPct} + ${alignOffset}px)`
|
||||||
|
: side === "left"
|
||||||
|
? `calc(0% - ${sideOffset}px)`
|
||||||
|
: `calc(100% + ${sideOffset}px)`;
|
||||||
|
|
||||||
|
const containerStyle: React.CSSProperties = {
|
||||||
|
position: "absolute",
|
||||||
|
top,
|
||||||
|
left,
|
||||||
|
transform: "translate(-50%, -50%)",
|
||||||
|
};
|
||||||
|
|
||||||
|
const angleStep = (spread * (Math.PI / 180)) / Math.max(1, count - 1);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AnimatePresence>
|
||||||
|
{animate
|
||||||
|
&& isInView
|
||||||
|
&& Array.from({ length: count }).map((_, i) => {
|
||||||
|
const angle = i * angleStep;
|
||||||
|
const x = Math.cos(angle) * radius;
|
||||||
|
const y = Math.sin(angle) * radius;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<motion.div
|
||||||
|
key={i}
|
||||||
|
style={{ ...containerStyle, ...style }}
|
||||||
|
initial={{ scale: 0, opacity: 0 }}
|
||||||
|
animate={{
|
||||||
|
x: `${x}px`,
|
||||||
|
y: `${y}px`,
|
||||||
|
scale: [0, 1, 0],
|
||||||
|
opacity: [0, 1, 0],
|
||||||
|
}}
|
||||||
|
transition={{
|
||||||
|
duration,
|
||||||
|
delay: delay + i * holdDelay,
|
||||||
|
ease: "easeOut",
|
||||||
|
...transition,
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</AnimatePresence>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
Particles,
|
||||||
|
ParticlesEffect,
|
||||||
|
type ParticlesEffectProps,
|
||||||
|
type ParticlesProps,
|
||||||
|
};
|
||||||
@@ -0,0 +1,338 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import type { MotionValue, SpringOptions } from "motion/react";
|
||||||
|
|
||||||
|
import {
|
||||||
|
motion,
|
||||||
|
|
||||||
|
useMotionValue,
|
||||||
|
useSpring,
|
||||||
|
useTransform,
|
||||||
|
} from "motion/react";
|
||||||
|
import useMeasure from "react-use-measure";
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import type { UseIsInViewOptions } from "@/hooks/use-is-in-view";
|
||||||
|
|
||||||
|
import {
|
||||||
|
useIsInView,
|
||||||
|
|
||||||
|
} from "@/hooks/use-is-in-view";
|
||||||
|
|
||||||
|
type SlidingNumberRollerProps = {
|
||||||
|
prevValue: number;
|
||||||
|
value: number;
|
||||||
|
place: number;
|
||||||
|
transition: SpringOptions;
|
||||||
|
delay?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
function SlidingNumberRoller({
|
||||||
|
prevValue,
|
||||||
|
value,
|
||||||
|
place,
|
||||||
|
transition,
|
||||||
|
delay = 0,
|
||||||
|
}: SlidingNumberRollerProps) {
|
||||||
|
const startNumber = Math.floor(prevValue / place) % 10;
|
||||||
|
const targetNumber = Math.floor(value / place) % 10;
|
||||||
|
const animatedValue = useSpring(startNumber, transition);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const timeoutId = setTimeout(() => {
|
||||||
|
animatedValue.set(targetNumber);
|
||||||
|
}, delay);
|
||||||
|
return () => clearTimeout(timeoutId);
|
||||||
|
}, [targetNumber, animatedValue, delay]);
|
||||||
|
|
||||||
|
const [measureRef, { height }] = useMeasure();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
ref={measureRef}
|
||||||
|
data-slot="sliding-number-roller"
|
||||||
|
style={{
|
||||||
|
position: "relative",
|
||||||
|
display: "inline-block",
|
||||||
|
width: "1ch",
|
||||||
|
overflowX: "visible",
|
||||||
|
overflowY: "clip",
|
||||||
|
lineHeight: 1,
|
||||||
|
fontVariantNumeric: "tabular-nums",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span style={{ visibility: "hidden" }}>0</span>
|
||||||
|
{Array.from({ length: 10 }, (_, i) => (
|
||||||
|
<SlidingNumberDisplay
|
||||||
|
key={i}
|
||||||
|
motionValue={animatedValue}
|
||||||
|
number={i}
|
||||||
|
height={height}
|
||||||
|
transition={transition}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
type SlidingNumberDisplayProps = {
|
||||||
|
motionValue: MotionValue<number>;
|
||||||
|
number: number;
|
||||||
|
height: number;
|
||||||
|
transition: SpringOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
function SlidingNumberDisplay({
|
||||||
|
motionValue,
|
||||||
|
number,
|
||||||
|
height,
|
||||||
|
transition,
|
||||||
|
}: SlidingNumberDisplayProps) {
|
||||||
|
const y = useTransform(motionValue, (latest) => {
|
||||||
|
if (!height)
|
||||||
|
return 0;
|
||||||
|
const currentNumber = latest % 10;
|
||||||
|
const offset = (10 + number - currentNumber) % 10;
|
||||||
|
let translateY = offset * height;
|
||||||
|
if (offset > 5)
|
||||||
|
translateY -= 10 * height;
|
||||||
|
return translateY;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!height) {
|
||||||
|
return (
|
||||||
|
<span style={{ visibility: "hidden", position: "absolute" }}>
|
||||||
|
{number}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<motion.span
|
||||||
|
data-slot="sliding-number-display"
|
||||||
|
style={{
|
||||||
|
y,
|
||||||
|
position: "absolute",
|
||||||
|
inset: 0,
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
}}
|
||||||
|
transition={{ ...transition, type: "spring" }}
|
||||||
|
>
|
||||||
|
{number}
|
||||||
|
</motion.span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
type SlidingNumberProps = Omit<React.ComponentProps<"span">, "children"> & {
|
||||||
|
number: number;
|
||||||
|
fromNumber?: number;
|
||||||
|
onNumberChange?: (number: number) => void;
|
||||||
|
padStart?: boolean;
|
||||||
|
decimalSeparator?: string;
|
||||||
|
decimalPlaces?: number;
|
||||||
|
thousandSeparator?: string;
|
||||||
|
transition?: SpringOptions;
|
||||||
|
delay?: number;
|
||||||
|
} & UseIsInViewOptions;
|
||||||
|
|
||||||
|
function SlidingNumber({
|
||||||
|
ref,
|
||||||
|
number,
|
||||||
|
fromNumber,
|
||||||
|
onNumberChange,
|
||||||
|
inView = false,
|
||||||
|
inViewMargin = "0px",
|
||||||
|
inViewOnce = true,
|
||||||
|
padStart = false,
|
||||||
|
decimalSeparator = ".",
|
||||||
|
decimalPlaces = 0,
|
||||||
|
thousandSeparator,
|
||||||
|
transition = { stiffness: 200, damping: 20, mass: 0.4 },
|
||||||
|
delay = 0,
|
||||||
|
...props
|
||||||
|
}: SlidingNumberProps) {
|
||||||
|
const { ref: localRef, isInView } = useIsInView(
|
||||||
|
ref as React.Ref<HTMLElement>,
|
||||||
|
{
|
||||||
|
inView,
|
||||||
|
inViewOnce,
|
||||||
|
inViewMargin,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const prevNumberRef = React.useRef<number>(0);
|
||||||
|
|
||||||
|
const hasAnimated = fromNumber !== undefined;
|
||||||
|
const motionVal = useMotionValue(fromNumber ?? 0);
|
||||||
|
const springVal = useSpring(motionVal, { stiffness: 90, damping: 50 });
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (!hasAnimated)
|
||||||
|
return;
|
||||||
|
const timeoutId = setTimeout(() => {
|
||||||
|
if (isInView)
|
||||||
|
motionVal.set(number);
|
||||||
|
}, delay);
|
||||||
|
return () => clearTimeout(timeoutId);
|
||||||
|
}, [hasAnimated, isInView, number, motionVal, delay]);
|
||||||
|
|
||||||
|
const [effectiveNumber, setEffectiveNumber] = React.useState(0);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (hasAnimated) {
|
||||||
|
const inferredDecimals
|
||||||
|
= typeof decimalPlaces === "number" && decimalPlaces >= 0
|
||||||
|
? decimalPlaces
|
||||||
|
: (() => {
|
||||||
|
const s = String(number);
|
||||||
|
const idx = s.indexOf(".");
|
||||||
|
return idx >= 0 ? s.length - idx - 1 : 0;
|
||||||
|
})();
|
||||||
|
|
||||||
|
const factor = 10 ** inferredDecimals;
|
||||||
|
|
||||||
|
const unsubscribe = springVal.on("change", (latest: number) => {
|
||||||
|
const newValue
|
||||||
|
= inferredDecimals > 0
|
||||||
|
? Math.round(latest * factor) / factor
|
||||||
|
: Math.round(latest);
|
||||||
|
|
||||||
|
if (effectiveNumber !== newValue) {
|
||||||
|
setEffectiveNumber(newValue);
|
||||||
|
onNumberChange?.(newValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return () => unsubscribe();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setEffectiveNumber(!isInView ? 0 : Math.abs(Number(number)));
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
hasAnimated,
|
||||||
|
springVal,
|
||||||
|
isInView,
|
||||||
|
number,
|
||||||
|
decimalPlaces,
|
||||||
|
onNumberChange,
|
||||||
|
effectiveNumber,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const formatNumber = React.useCallback(
|
||||||
|
(num: number) =>
|
||||||
|
decimalPlaces != null ? num.toFixed(decimalPlaces) : num.toString(),
|
||||||
|
[decimalPlaces],
|
||||||
|
);
|
||||||
|
|
||||||
|
const numberStr = formatNumber(effectiveNumber);
|
||||||
|
const [newIntStrRaw, newDecStrRaw = ""] = numberStr.split(".");
|
||||||
|
|
||||||
|
const finalIntLength = padStart
|
||||||
|
? Math.max(
|
||||||
|
Math.floor(Math.abs(number)).toString().length,
|
||||||
|
newIntStrRaw.length,
|
||||||
|
)
|
||||||
|
: newIntStrRaw.length;
|
||||||
|
|
||||||
|
const newIntStr = padStart
|
||||||
|
? newIntStrRaw.padStart(finalIntLength, "0")
|
||||||
|
: newIntStrRaw;
|
||||||
|
|
||||||
|
const prevFormatted = formatNumber(prevNumberRef.current);
|
||||||
|
const [prevIntStrRaw = "", prevDecStrRaw = ""] = prevFormatted.split(".");
|
||||||
|
const prevIntStr = padStart
|
||||||
|
? prevIntStrRaw.padStart(finalIntLength, "0")
|
||||||
|
: prevIntStrRaw;
|
||||||
|
|
||||||
|
const adjustedPrevInt = React.useMemo(() => {
|
||||||
|
return prevIntStr.length > finalIntLength
|
||||||
|
? prevIntStr.slice(-finalIntLength)
|
||||||
|
: prevIntStr.padStart(finalIntLength, "0");
|
||||||
|
}, [prevIntStr, finalIntLength]);
|
||||||
|
|
||||||
|
const adjustedPrevDec = React.useMemo(() => {
|
||||||
|
if (!newDecStrRaw)
|
||||||
|
return "";
|
||||||
|
return prevDecStrRaw.length > newDecStrRaw.length
|
||||||
|
? prevDecStrRaw.slice(0, newDecStrRaw.length)
|
||||||
|
: prevDecStrRaw.padEnd(newDecStrRaw.length, "0");
|
||||||
|
}, [prevDecStrRaw, newDecStrRaw]);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (isInView)
|
||||||
|
prevNumberRef.current = effectiveNumber;
|
||||||
|
}, [effectiveNumber, isInView]);
|
||||||
|
|
||||||
|
const intPlaces = React.useMemo(
|
||||||
|
() =>
|
||||||
|
Array.from({ length: finalIntLength }, (_, i) =>
|
||||||
|
10 ** (finalIntLength - i - 1)),
|
||||||
|
[finalIntLength],
|
||||||
|
);
|
||||||
|
const decPlaces = React.useMemo(
|
||||||
|
() =>
|
||||||
|
newDecStrRaw
|
||||||
|
? Array.from({ length: newDecStrRaw.length }, (_, i) =>
|
||||||
|
10 ** (newDecStrRaw.length - i - 1))
|
||||||
|
: [],
|
||||||
|
[newDecStrRaw],
|
||||||
|
);
|
||||||
|
|
||||||
|
const newDecValue = newDecStrRaw ? Number.parseInt(newDecStrRaw, 10) : 0;
|
||||||
|
const prevDecValue = adjustedPrevDec ? Number.parseInt(adjustedPrevDec, 10) : 0;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
ref={localRef}
|
||||||
|
data-slot="sliding-number"
|
||||||
|
style={{
|
||||||
|
display: "inline-flex",
|
||||||
|
alignItems: "center",
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{isInView && Number(number) < 0 && (
|
||||||
|
<span style={{ marginRight: "0.25rem" }}>-</span>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{intPlaces.map((place, idx) => {
|
||||||
|
const digitsToRight = intPlaces.length - idx - 1;
|
||||||
|
const isSeparatorPosition
|
||||||
|
= typeof thousandSeparator !== "undefined"
|
||||||
|
&& digitsToRight > 0
|
||||||
|
&& digitsToRight % 3 === 0;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment key={`int-${place}`}>
|
||||||
|
<SlidingNumberRoller
|
||||||
|
prevValue={Number.parseInt(adjustedPrevInt, 10)}
|
||||||
|
value={Number.parseInt(newIntStr ?? "0", 10)}
|
||||||
|
place={place}
|
||||||
|
transition={transition}
|
||||||
|
/>
|
||||||
|
{isSeparatorPosition && <span>{thousandSeparator}</span>}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
|
{newDecStrRaw && (
|
||||||
|
<>
|
||||||
|
<span>{decimalSeparator}</span>
|
||||||
|
{decPlaces.map(place => (
|
||||||
|
<SlidingNumberRoller
|
||||||
|
key={`dec-${place}`}
|
||||||
|
prevValue={prevDecValue}
|
||||||
|
value={newDecValue}
|
||||||
|
place={place}
|
||||||
|
transition={transition}
|
||||||
|
delay={delay}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { SlidingNumber, type SlidingNumberProps };
|
||||||
@@ -4,10 +4,10 @@ import Image from "next/image";
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
||||||
import { navbarLinks } from "@/config/site-config";
|
import { navbarLinks } from "@/config/site-config";
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
|
|
||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/tooltip";
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/tooltip";
|
||||||
import StarOnGithubButton from "./ui/star-on-github-button";
|
import { GitHubStarsButton } from "./animate-ui/components/buttons/github-stars";
|
||||||
|
import { Button } from "./animate-ui/components/buttons/button";
|
||||||
import { ThemeToggle } from "./ui/theme-toggle";
|
import { ThemeToggle } from "./ui/theme-toggle";
|
||||||
import CommandMenu from "./command-menu";
|
import CommandMenu from "./command-menu";
|
||||||
|
|
||||||
@@ -39,31 +39,18 @@ function Navbar() {
|
|||||||
href="/"
|
href="/"
|
||||||
className="flex cursor-pointer w-full justify-center sm:justify-start flex-row-reverse items-center gap-2 font-semibold sm:flex-row"
|
className="flex cursor-pointer w-full justify-center sm:justify-start flex-row-reverse items-center gap-2 font-semibold sm:flex-row"
|
||||||
>
|
>
|
||||||
<Image
|
<Image height={18} unoptimized width={18} alt="logo" src="/ProxmoxVE/logo.png" className="" />
|
||||||
height={18}
|
|
||||||
unoptimized
|
|
||||||
width={18}
|
|
||||||
alt="logo"
|
|
||||||
src="/ProxmoxVE/logo.png"
|
|
||||||
className=""
|
|
||||||
/>
|
|
||||||
<span className="hidden md:block">Proxmox VE Helper-Scripts</span>
|
<span className="hidden md:block">Proxmox VE Helper-Scripts</span>
|
||||||
</Link>
|
</Link>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<CommandMenu />
|
<CommandMenu />
|
||||||
<StarOnGithubButton />
|
<GitHubStarsButton username="community-scripts" repo="ProxmoxVE" />
|
||||||
{navbarLinks.map(({ href, event, icon, text, mobileHidden }) => (
|
{navbarLinks.map(({ href, event, icon, text, mobileHidden }) => (
|
||||||
<TooltipProvider key={event}>
|
<TooltipProvider key={event}>
|
||||||
<Tooltip delayDuration={100}>
|
<Tooltip delayDuration={100}>
|
||||||
<TooltipTrigger
|
<TooltipTrigger className={mobileHidden ? "hidden lg:block" : ""}>
|
||||||
className={mobileHidden ? "hidden lg:block" : ""}
|
|
||||||
>
|
|
||||||
<Button variant="ghost" size="icon" asChild>
|
<Button variant="ghost" size="icon" asChild>
|
||||||
<Link
|
<Link target="_blank" href={href} data-umami-event={event}>
|
||||||
target="_blank"
|
|
||||||
href={href}
|
|
||||||
data-umami-event={event}
|
|
||||||
>
|
|
||||||
{icon}
|
{icon}
|
||||||
<span className="sr-only">{text}</span>
|
<span className="sr-only">{text}</span>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
27
frontend/src/hooks/use-is-in-view.tsx
Normal file
27
frontend/src/hooks/use-is-in-view.tsx
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import type { UseInViewOptions } from "motion/react";
|
||||||
|
|
||||||
|
import { useInView } from "motion/react";
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
type UseIsInViewOptions = {
|
||||||
|
inView?: boolean;
|
||||||
|
inViewOnce?: boolean;
|
||||||
|
inViewMargin?: UseInViewOptions["margin"];
|
||||||
|
};
|
||||||
|
|
||||||
|
function useIsInView<T extends HTMLElement = HTMLElement>(
|
||||||
|
ref: React.Ref<T>,
|
||||||
|
options: UseIsInViewOptions = {},
|
||||||
|
) {
|
||||||
|
const { inView, inViewOnce = false, inViewMargin = "0px" } = options;
|
||||||
|
const localRef = React.useRef<T>(null);
|
||||||
|
React.useImperativeHandle(ref, () => localRef.current as T);
|
||||||
|
const inViewResult = useInView(localRef, {
|
||||||
|
once: inViewOnce,
|
||||||
|
margin: inViewMargin,
|
||||||
|
});
|
||||||
|
const isInView = !inView || inViewResult;
|
||||||
|
return { ref: localRef, isInView };
|
||||||
|
}
|
||||||
|
|
||||||
|
export { useIsInView, type UseIsInViewOptions };
|
||||||
36
frontend/src/lib/get-strict-context.tsx
Normal file
36
frontend/src/lib/get-strict-context.tsx
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
function getStrictContext<T>(
|
||||||
|
name?: string,
|
||||||
|
): readonly [
|
||||||
|
({
|
||||||
|
value,
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
value: T;
|
||||||
|
children?: React.ReactNode;
|
||||||
|
}) => React.JSX.Element,
|
||||||
|
() => T,
|
||||||
|
] {
|
||||||
|
const Context = React.createContext<T | undefined>(undefined);
|
||||||
|
|
||||||
|
const Provider = ({
|
||||||
|
value,
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
value: T;
|
||||||
|
children?: React.ReactNode;
|
||||||
|
}) => <Context.Provider value={value}>{children}</Context.Provider>;
|
||||||
|
|
||||||
|
const useSafeContext = () => {
|
||||||
|
const ctx = React.useContext(Context);
|
||||||
|
if (ctx === undefined) {
|
||||||
|
throw new Error(`useContext must be used within ${name ?? "a Provider"}`);
|
||||||
|
}
|
||||||
|
return ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
return [Provider, useSafeContext] as const;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { getStrictContext };
|
||||||
@@ -285,7 +285,7 @@ GEO_DIR="${INSTALL_DIR}/geodata"
|
|||||||
mkdir -p "$INSTALL_DIR"
|
mkdir -p "$INSTALL_DIR"
|
||||||
mkdir -p {"${APP_DIR}","${UPLOAD_DIR}","${GEO_DIR}","${INSTALL_DIR}"/cache}
|
mkdir -p {"${APP_DIR}","${UPLOAD_DIR}","${GEO_DIR}","${INSTALL_DIR}"/cache}
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "immich" "immich-app/immich" "tarball" "v1.140.1" "$SRC_DIR"
|
fetch_and_deploy_gh_release "immich" "immich-app/immich" "tarball" "v1.141.1" "$SRC_DIR"
|
||||||
|
|
||||||
msg_info "Installing ${APPLICATION} (more patience please)"
|
msg_info "Installing ${APPLICATION} (more patience please)"
|
||||||
|
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ Wants=network.target karakeep-browser.service meilisearch.service
|
|||||||
After=network.target karakeep-browser.service meilisearch.service
|
After=network.target karakeep-browser.service meilisearch.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ExecStart=/usr/bin/node dist/index.mjs
|
ExecStart=/usr/bin/node dist/index.js
|
||||||
WorkingDirectory=/opt/karakeep/apps/workers
|
WorkingDirectory=/opt/karakeep/apps/workers
|
||||||
EnvironmentFile=/etc/karakeep/karakeep.env
|
EnvironmentFile=/etc/karakeep/karakeep.env
|
||||||
Restart=always
|
Restart=always
|
||||||
|
|||||||
78
install/leantime-install.sh
Normal file
78
install/leantime-install.sh
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2025 community-scripts ORG
|
||||||
|
# Author: Stroopwafe1
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://leantime.io
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
PHP_VERSION="8.4" PHP_MODULE="mysql" PHP_APACHE="YES" PHP_FPM="YES" setup_php
|
||||||
|
setup_mariadb
|
||||||
|
|
||||||
|
msg_info "Setting up Database"
|
||||||
|
DB_NAME=leantime
|
||||||
|
DB_USER=leantime
|
||||||
|
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
||||||
|
$STD mysql -u root -e "CREATE DATABASE $DB_NAME;"
|
||||||
|
$STD mysql -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED WITH mysql_native_password AS PASSWORD('$DB_PASS');"
|
||||||
|
$STD mysql -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
|
||||||
|
{
|
||||||
|
echo "Leantime Credentials"
|
||||||
|
echo "Database User: $DB_USER"
|
||||||
|
echo "Database Password: $DB_PASS"
|
||||||
|
echo "Database Name: $DB_NAME"
|
||||||
|
} >>~/leantime.creds
|
||||||
|
msg_ok "Set up Database"
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "leantime" "Leantime/leantime" "prebuild" "latest" "/opt/leantime" Leantime*.tar.gz
|
||||||
|
|
||||||
|
msg_info "Setup Leantime"
|
||||||
|
chown -R www-data:www-data "/opt/leantime"
|
||||||
|
chmod -R 750 "/opt/leantime"
|
||||||
|
cat <<EOF >/etc/apache2/sites-enabled/000-default.conf
|
||||||
|
<VirtualHost *:80>
|
||||||
|
ServerAdmin webmaster@localhost
|
||||||
|
DocumentRoot /opt/leantime/public
|
||||||
|
DirectoryIndex index.php index.html index.cgi index.pl index.xhtml
|
||||||
|
Options +ExecCGI
|
||||||
|
|
||||||
|
<Directory /opt/leantime/>
|
||||||
|
Options FollowSymLinks
|
||||||
|
Require all granted
|
||||||
|
AllowOverride All
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
<Location />
|
||||||
|
Require all granted
|
||||||
|
</Location>
|
||||||
|
|
||||||
|
ErrorLog /var/log/apache2/error.log
|
||||||
|
CustomLog /var/log/apache2/access.log combined
|
||||||
|
</VirtualHost>
|
||||||
|
EOF
|
||||||
|
mv "/opt/leantime/config/sample.env" "/opt/leantime/config/.env"
|
||||||
|
sed -i -e "s|^LEAN_DB_DATABASE.*|LEAN_DB_DATABASE = '$DB_NAME'|" \
|
||||||
|
-e "s|^LEAN_DB_USER.*|LEAN_DB_USER = '$DB_USER'|" \
|
||||||
|
-e "s|^LEAN_DB_PASSWORD.*|LEAN_DB_PASSWORD = '$DB_PASS'|" \
|
||||||
|
-e "s|^LEAN_SESSION_PASSWORD.*|LEAN_SESSION_PASSWORD = '$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)'|" \
|
||||||
|
"/opt/leantime/config/.env"
|
||||||
|
$STD a2enmod -q proxy_fcgi setenvif rewrite
|
||||||
|
$STD a2enconf -q "php8.4-fpm"
|
||||||
|
sed -i -e "s/^;extension.\(curl\|fileinfo\|gd\|intl\|ldap\|mbstring\|exif\|mysqli\|odbc\|openssl\|pdo_mysql\)/extension=\1/g" "/etc/php/8.4/apache2/php.ini"
|
||||||
|
systemctl restart apache2
|
||||||
|
msg_ok "Setup leantime"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
|
||||||
|
msg_info "Cleaning up"
|
||||||
|
$STD apt-get -y autoremove
|
||||||
|
$STD apt-get -y autoclean
|
||||||
|
msg_ok "Cleaned"
|
||||||
@@ -15,12 +15,10 @@ update_os
|
|||||||
|
|
||||||
msg_info "Installing Mosquitto MQTT Broker"
|
msg_info "Installing Mosquitto MQTT Broker"
|
||||||
source /etc/os-release
|
source /etc/os-release
|
||||||
curl -fsSL http://repo.mosquitto.org/debian/mosquitto-repo.gpg >/usr/share/keyrings/mosquitto-repo.gpg.key
|
|
||||||
chmod go+r /usr/share/keyrings/mosquitto-repo.gpg.key
|
|
||||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/mosquitto-repo.gpg.key] http://repo.mosquitto.org/debian ${VERSION_CODENAME} main" >/etc/apt/sources.list.d/mosquitto.list
|
|
||||||
$STD apt-get update
|
$STD apt-get update
|
||||||
$STD apt-get -y install mosquitto
|
$STD apt-get -y install mosquitto
|
||||||
$STD apt-get -y install mosquitto-clients
|
$STD apt-get -y install mosquitto-clients
|
||||||
|
|
||||||
cat <<EOF >/etc/mosquitto/conf.d/default.conf
|
cat <<EOF >/etc/mosquitto/conf.d/default.conf
|
||||||
allow_anonymous false
|
allow_anonymous false
|
||||||
persistence true
|
persistence true
|
||||||
|
|||||||
@@ -30,11 +30,12 @@ fi
|
|||||||
|
|
||||||
mkdir -p /etc/pulse
|
mkdir -p /etc/pulse
|
||||||
fetch_and_deploy_gh_release "pulse" "rcourtman/Pulse" "prebuild" "latest" "/opt/pulse" "*-linux-amd64.tar.gz"
|
fetch_and_deploy_gh_release "pulse" "rcourtman/Pulse" "prebuild" "latest" "/opt/pulse" "*-linux-amd64.tar.gz"
|
||||||
|
ln -sf /opt/pulse/bin/pulse /usr/local/bin/pulse
|
||||||
chown -R pulse:pulse /etc/pulse /opt/pulse
|
chown -R pulse:pulse /etc/pulse /opt/pulse
|
||||||
msg_ok "Installed Pulse"
|
msg_ok "Installed Pulse"
|
||||||
|
|
||||||
msg_info "Creating Service"
|
msg_info "Creating Service"
|
||||||
cat <<EOF >/etc/systemd/system/pulse-backend.service
|
cat <<EOF >/etc/systemd/system/pulse.service
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Pulse Monitoring Server
|
Description=Pulse Monitoring Server
|
||||||
After=network.target
|
After=network.target
|
||||||
@@ -55,7 +56,7 @@ Environment="PULSE_DATA_DIR=/etc/pulse"
|
|||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
EOF
|
EOF
|
||||||
systemctl enable -q --now pulse-backend
|
systemctl enable -q --now pulse
|
||||||
msg_ok "Created Service"
|
msg_ok "Created Service"
|
||||||
|
|
||||||
motd_ssh
|
motd_ssh
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ fetch_and_deploy_gh_release "recyclarr" "recyclarr/recyclarr" "prebuild" "latest
|
|||||||
|
|
||||||
msg_info "Configuring Recyclarr"
|
msg_info "Configuring Recyclarr"
|
||||||
mkdir -p /root/.config/recyclarr
|
mkdir -p /root/.config/recyclarr
|
||||||
recyclarr config create
|
$STD recyclarr config create
|
||||||
msg_ok "Configured Recyclarr"
|
msg_ok "Configured Recyclarr"
|
||||||
|
|
||||||
motd_ssh
|
motd_ssh
|
||||||
|
|||||||
35
install/resiliosync-install.sh
Normal file
35
install/resiliosync-install.sh
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2025 community-scripts ORG
|
||||||
|
# Author: David Bennett (dbinit)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://www.resilio.com/sync
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
msg_info "Setting up Resilio Sync Repository"
|
||||||
|
curl -fsSL "https://linux-packages.resilio.com/resilio-sync/key.asc" >/etc/apt/trusted.gpg.d/resilio-sync.asc
|
||||||
|
echo "deb [signed-by=/etc/apt/trusted.gpg.d/resilio-sync.asc] http://linux-packages.resilio.com/resilio-sync/deb resilio-sync non-free" >/etc/apt/sources.list.d/resilio-sync.list
|
||||||
|
$STD apt-get update
|
||||||
|
msg_ok "Resilio Sync Repository Setup"
|
||||||
|
|
||||||
|
msg_info "Installing Resilio Sync"
|
||||||
|
$STD apt-get install -y resilio-sync
|
||||||
|
sed -i "s/127.0.0.1:8888/0.0.0.0:8888/g" /etc/resilio-sync/config.json
|
||||||
|
systemctl enable -q resilio-sync
|
||||||
|
systemctl restart resilio-sync
|
||||||
|
msg_ok "Installed Resilio Sync"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
|
||||||
|
msg_info "Cleaning up"
|
||||||
|
$STD apt-get -y autoremove
|
||||||
|
$STD apt-get -y autoclean
|
||||||
|
msg_ok "Cleaned"
|
||||||
@@ -18,18 +18,6 @@ fetch_and_deploy_gh_release "rustdesk-hbbs" "rustdesk/rustdesk-server" "binary"
|
|||||||
fetch_and_deploy_gh_release "rustdesk-utils" "rustdesk/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-utils*amd64.deb"
|
fetch_and_deploy_gh_release "rustdesk-utils" "rustdesk/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-utils*amd64.deb"
|
||||||
fetch_and_deploy_gh_release "rustdesk-api" "lejianwen/rustdesk-api" "binary" "latest" "/opt/rustdesk" "rustdesk-api-server*amd64.deb"
|
fetch_and_deploy_gh_release "rustdesk-api" "lejianwen/rustdesk-api" "binary" "latest" "/opt/rustdesk" "rustdesk-api-server*amd64.deb"
|
||||||
|
|
||||||
msg_info "Configuring RustDesk Server"
|
|
||||||
ADMINPASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
|
||||||
cd /var/lib/rustdesk-api
|
|
||||||
$STD rustdesk-api reset-admin-pwd $ADMINPASS
|
|
||||||
{
|
|
||||||
echo "RustDesk WebUI"
|
|
||||||
echo ""
|
|
||||||
echo "Username: admin"
|
|
||||||
echo "Password: $ADMINPASS"
|
|
||||||
} >>~/rustdesk.creds
|
|
||||||
msg_ok "Configured RustDesk Server"
|
|
||||||
|
|
||||||
motd_ssh
|
motd_ssh
|
||||||
customize
|
customize
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ msg_info "Creating Python virtual environment"
|
|||||||
sudo -H -u searxng bash -c '
|
sudo -H -u searxng bash -c '
|
||||||
python3 -m venv /usr/local/searxng/searx-pyenv &&
|
python3 -m venv /usr/local/searxng/searx-pyenv &&
|
||||||
. /usr/local/searxng/searx-pyenv/bin/activate &&
|
. /usr/local/searxng/searx-pyenv/bin/activate &&
|
||||||
pip install -U pip setuptools wheel pyyaml &&
|
pip install -U pip setuptools wheel pyyaml lxml &&
|
||||||
pip install --use-pep517 --no-build-isolation -e /usr/local/searxng/searxng-src
|
pip install --use-pep517 --no-build-isolation -e /usr/local/searxng/searxng-src
|
||||||
'
|
'
|
||||||
msg_ok "Python environment ready"
|
msg_ok "Python environment ready"
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ $STD apt-get install -y \
|
|||||||
yq
|
yq
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
NODE_VERSION="20" setup_nodejs
|
NODE_VERSION="22" setup_nodejs
|
||||||
fetch_and_deploy_gh_release "tududi" "chrisvel/tududi" "tarball" "v0.80" "/opt/tududi"
|
fetch_and_deploy_gh_release "tududi" "chrisvel/tududi" "tarball" "latest" "/opt/tududi"
|
||||||
|
|
||||||
msg_info "Configuring Tududi"
|
msg_info "Configuring Tududi"
|
||||||
cd /opt/tududi
|
cd /opt/tududi
|
||||||
@@ -37,15 +37,16 @@ DB_LOCATION="/opt/tududi-db"
|
|||||||
UPLOAD_DIR="/opt/tududi-uploads"
|
UPLOAD_DIR="/opt/tududi-uploads"
|
||||||
mkdir -p {"$DB_LOCATION","$UPLOAD_DIR"}
|
mkdir -p {"$DB_LOCATION","$UPLOAD_DIR"}
|
||||||
SECRET="$(openssl rand -hex 64)"
|
SECRET="$(openssl rand -hex 64)"
|
||||||
sed -e 's/^GOOGLE/# &/' \
|
cat <<EOF >/opt/tududi/backend/.env
|
||||||
-e '/TUDUDI_SESSION/s/^# //' \
|
TUDUDI_SESSION_SECRET=${SECRET}
|
||||||
-e '/NODE_ENV/s/^# //' \
|
TUDUDI_ALLOWED_ORIGINS=<your tududi IP or FQDN>
|
||||||
-e "s/your_session_secret_here/$SECRET/" \
|
NODE_ENV=production
|
||||||
-e 's/development/production/' \
|
DB_FILE=${DB_LOCATION}/production.sqlite3
|
||||||
-e "\$a\DB_FILE=$DB_LOCATION/production.sqlite3" \
|
TUDUDI_UPLOAD_PATH=${UPLOAD_DIR}
|
||||||
-e "\$a\TUDUDI_UPLOAD_PATH=$UPLOAD_DIR" \
|
DISABLE_TELEGRAM=true
|
||||||
/opt/tududi/backend/.env.example >/opt/tududi/backend/.env
|
DIABLE_SCHEDULER=false
|
||||||
export DB_FILE="$DB_LOCATION/production.sqlite3"
|
EOF
|
||||||
|
export DB_FILE="${DB_LOCATION}/production.sqlite3"
|
||||||
$STD npm run db:init
|
$STD npm run db:init
|
||||||
msg_ok "Created env and database"
|
msg_ok "Created env and database"
|
||||||
|
|
||||||
@@ -57,9 +58,9 @@ After=network.target
|
|||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
WorkingDirectory=/opt/tududi
|
WorkingDirectory=/opt/tududi/backend
|
||||||
EnvironmentFile=/opt/tududi/backend/.env
|
EnvironmentFile=/opt/tududi/backend/.env
|
||||||
ExecStart=/usr/bin/npm run start
|
ExecStart=/usr/bin/bash /opt/tududi/backend/cmd/start.sh
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ setting_up_container
|
|||||||
network_check
|
network_check
|
||||||
update_os
|
update_os
|
||||||
|
|
||||||
|
msg_info "Installing Dependencies"
|
||||||
|
$STD apt-get install -y git
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
msg_info "Installing WireGuard"
|
msg_info "Installing WireGuard"
|
||||||
$STD apt-get install -y wireguard wireguard-tools net-tools iptables
|
$STD apt-get install -y wireguard wireguard-tools net-tools iptables
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confnew" install -y iptables-persistent &>/dev/null
|
DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confnew" install -y iptables-persistent &>/dev/null
|
||||||
@@ -21,7 +25,7 @@ msg_ok "Installed WireGuard"
|
|||||||
|
|
||||||
read -r -p "${TAB3}Would you like to add WGDashboard? <y/N> " prompt
|
read -r -p "${TAB3}Would you like to add WGDashboard? <y/N> " prompt
|
||||||
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
fetch_and_deploy_gh_release "wgdashboard" "donaldzou/WGDashboard" "tarball" "latest" "/etc/wgdashboard"
|
git clone -q https://github.com/donaldzou/WGDashboard.git /etc/wgdashboard
|
||||||
|
|
||||||
msg_info "Installing WGDashboard"
|
msg_info "Installing WGDashboard"
|
||||||
cd /etc/wgdashboard/src
|
cd /etc/wgdashboard/src
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ elif command -v wget >/dev/null 2>&1; then
|
|||||||
fi
|
fi
|
||||||
# This function enables error handling in the script by setting options and defining a trap for the ERR signal.
|
# This function enables error handling in the script by setting options and defining a trap for the ERR signal.
|
||||||
catch_errors() {
|
catch_errors() {
|
||||||
set -Eeuo pipefail
|
set -Eeo pipefail
|
||||||
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,41 +200,32 @@ ssh_check() {
|
|||||||
|
|
||||||
base_settings() {
|
base_settings() {
|
||||||
# Default Settings
|
# Default Settings
|
||||||
CT_TYPE="1"
|
CT_TYPE=${var_unprivileged:-"1"}
|
||||||
DISK_SIZE="4"
|
DISK_SIZE=${var_disk:-"4"}
|
||||||
CORE_COUNT="1"
|
CORE_COUNT=${var_cpu:-"1"}
|
||||||
RAM_SIZE="1024"
|
RAM_SIZE=${var_ram:-"1024"}
|
||||||
VERBOSE="${1:-no}"
|
VERBOSE=${var_verbose:-"${1:-no}"}
|
||||||
PW=""
|
PW=${var_pw:-""}
|
||||||
CT_ID=$NEXTID
|
CT_ID=${var_ctid:-$NEXTID}
|
||||||
HN=$NSAPP
|
HN=${var_hostname:-$NSAPP}
|
||||||
BRG="vmbr0"
|
BRG=${var_brg:-"vmbr0"}
|
||||||
NET="dhcp"
|
NET=${var_net:-"dhcp"}
|
||||||
IPV6_METHOD="none"
|
IPV6_METHOD=${var_ipv6_method:-"none"}
|
||||||
IPV6_STATIC=""
|
IPV6_STATIC=${var_ipv6_static:-""}
|
||||||
GATE=""
|
GATE=${var_gateway:-""}
|
||||||
APT_CACHER=""
|
APT_CACHER=${var_apt_cacher:-""}
|
||||||
APT_CACHER_IP=""
|
APT_CACHER_IP=${var_apt_cacher_ip:-""}
|
||||||
MTU=""
|
MTU=${var_mtu:-""}
|
||||||
SD=""
|
SD=${var_storage:-""}
|
||||||
NS=""
|
NS=${var_ns:-""}
|
||||||
MAC=""
|
MAC=${var_mac:-""}
|
||||||
VLAN=""
|
VLAN=${var_vlan:-""}
|
||||||
SSH="no"
|
SSH=${var_ssh:-"no"}
|
||||||
SSH_AUTHORIZED_KEY=""
|
SSH_AUTHORIZED_KEY=${var_ssh_authorized_key:-""}
|
||||||
TAGS="community-script;"
|
UDHCPC_FIX=${var_udhcpc_fix:-""}
|
||||||
ENABLE_FUSE="${1:-no}"
|
TAGS="community-script;${var_tags:-}"
|
||||||
ENABLE_TUN="${1:-no}"
|
ENABLE_FUSE=${var_fuse:-"${1:-no}"}
|
||||||
|
ENABLE_TUN=${var_tun:-"${1:-no}"}
|
||||||
# Override default settings with variables from ct script
|
|
||||||
CT_TYPE=${var_unprivileged:-$CT_TYPE}
|
|
||||||
DISK_SIZE=${var_disk:-$DISK_SIZE}
|
|
||||||
CORE_COUNT=${var_cpu:-$CORE_COUNT}
|
|
||||||
RAM_SIZE=${var_ram:-$RAM_SIZE}
|
|
||||||
VERB=${var_verbose:-$VERBOSE}
|
|
||||||
TAGS="${TAGS}${var_tags:-}"
|
|
||||||
ENABLE_FUSE="${var_fuse:-$ENABLE_FUSE}"
|
|
||||||
ENABLE_TUN="${var_tun:-$ENABLE_TUN}"
|
|
||||||
|
|
||||||
# Since these 2 are only defined outside of default_settings function, we add a temporary fallback. TODO: To align everything, we should add these as constant variables (e.g. OSTYPE and OSVERSION), but that would currently require updating the default_settings function for all existing scripts
|
# Since these 2 are only defined outside of default_settings function, we add a temporary fallback. TODO: To align everything, we should add these as constant variables (e.g. OSTYPE and OSVERSION), but that would currently require updating the default_settings function for all existing scripts
|
||||||
if [ -z "$var_os" ]; then
|
if [ -z "$var_os" ]; then
|
||||||
@@ -244,6 +235,7 @@ base_settings() {
|
|||||||
var_version="12"
|
var_version="12"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
write_config() {
|
write_config() {
|
||||||
mkdir -p /opt/community-scripts
|
mkdir -p /opt/community-scripts
|
||||||
# This function writes the configuration to a file.
|
# This function writes the configuration to a file.
|
||||||
@@ -354,7 +346,7 @@ echo_default() {
|
|||||||
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}"
|
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}"
|
||||||
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}"
|
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}"
|
||||||
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}"
|
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}"
|
||||||
if [ "$VERB" == "yes" ]; then
|
if [ "$VERBOSE" == "yes" ]; then
|
||||||
echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}Enabled${CL}"
|
echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}Enabled${CL}"
|
||||||
fi
|
fi
|
||||||
echo -e "${CREATING}${BOLD}${BL}Creating a ${APP} LXC using the above default settings${CL}"
|
echo -e "${CREATING}${BOLD}${BL}Creating a ${APP} LXC using the above default settings${CL}"
|
||||||
|
|||||||
@@ -514,7 +514,42 @@ post_routines_common() {
|
|||||||
yes)
|
yes)
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58
|
whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58
|
||||||
msg_info "Disabling subscription nag"
|
msg_info "Disabling subscription nag"
|
||||||
echo "DPkg::Post-Invoke { \"if [ -s /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js ] && ! grep -q -F 'NoMoreNagging' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; then echo 'Removing subscription nag from UI...'; sed -i '/data\.status/{s/\\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; fi\" };" >/etc/apt/apt.conf.d/no-nag-script
|
# Create external script, this is needed because DPkg::Post-Invoke is fidly with quote interpretation
|
||||||
|
cat >/usr/local/bin/pve-remove-nag.sh <<'EOF'
|
||||||
|
#!/bin/sh
|
||||||
|
WEB_JS=/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js
|
||||||
|
if [ -s "$WEB_JS" ] && ! grep -q NoMoreNagging "$WEB_JS"; then
|
||||||
|
echo "Patching Web UI nag..."
|
||||||
|
sed -i -e "/data\.status/ s/!//" -e "/data\.status/ s/active/NoMoreNagging/" "$WEB_JS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
MOBILE_TPL=/usr/share/pve-yew-mobile-gui/index.html.tpl
|
||||||
|
MARKER="<!-- MANAGED BLOCK FOR MOBILE NAG -->"
|
||||||
|
if [ -f "$MOBILE_TPL" ] && ! grep -q "$MARKER" "$MOBILE_TPL"; then
|
||||||
|
echo "Patching Mobile UI nag..."
|
||||||
|
printf "%s\n" \
|
||||||
|
"$MARKER" \
|
||||||
|
"<script>" \
|
||||||
|
" function watchAndRemoveDialog() {" \
|
||||||
|
" const observer = new MutationObserver(() => {" \
|
||||||
|
" const dialog = document.querySelector('dialog[aria-label=\"No valid subscription\"]');" \
|
||||||
|
" if (dialog) { dialog.remove(); console.log('Removed dialog: No valid subscription'); observer.disconnect(); }" \
|
||||||
|
" });" \
|
||||||
|
" observer.observe(document.body, { childList: true, subtree: true });" \
|
||||||
|
" }" \
|
||||||
|
" setTimeout(watchAndRemoveDialog, 100);" \
|
||||||
|
"</script>" \
|
||||||
|
"" >> "$MOBILE_TPL"
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod 755 /usr/local/bin/pve-remove-nag.sh
|
||||||
|
|
||||||
|
cat >/etc/apt/apt.conf.d/no-nag-script <<'EOF'
|
||||||
|
DPkg::Post-Invoke { "/usr/local/bin/pve-remove-nag.sh"; };
|
||||||
|
EOF
|
||||||
|
chmod 644 /etc/apt/apt.conf.d/no-nag-script
|
||||||
|
|
||||||
msg_ok "Disabled subscription nag (Delete browser cache)"
|
msg_ok "Disabled subscription nag (Delete browser cache)"
|
||||||
;;
|
;;
|
||||||
no)
|
no)
|
||||||
|
|||||||
Reference in New Issue
Block a user