Compare commits
16 Commits
docs/split
...
fix/silo-w
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0c67455dc | ||
|
|
d95c850b7b | ||
|
|
fe50b1595e | ||
|
|
7bec3d5c3b | ||
|
|
145c29d7d6 | ||
|
|
8ba7b73aa8 | ||
|
|
1e4deea130 | ||
|
|
3923e2e4b9 | ||
|
|
9e29b76fbc | ||
|
|
88e025f1c6 | ||
|
|
772d3b3288 | ||
|
|
dfa2b73966 | ||
|
|
056b015e78 | ||
| 6649372f7b | |||
| 5db68dab25 | |||
|
|
c59c704da3 |
11
.gitea/runner/cleanup.service
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Kindred Create CI runner disk cleanup
|
||||
After=docker.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/opt/runner/cleanup.sh
|
||||
Environment=CLEANUP_THRESHOLD=85
|
||||
Environment=CACHE_MAX_AGE_DAYS=7
|
||||
StandardOutput=append:/var/log/runner-cleanup.log
|
||||
StandardError=append:/var/log/runner-cleanup.log
|
||||
220
.gitea/runner/cleanup.sh
Executable file
@@ -0,0 +1,220 @@
|
||||
#!/usr/bin/env bash
|
||||
# Runner disk cleanup script for Kindred Create CI/CD
|
||||
#
|
||||
# Designed to run as a cron job on the pubworker host:
|
||||
# */30 * * * * /path/to/cleanup.sh >> /var/log/runner-cleanup.log 2>&1
|
||||
#
|
||||
# Or install the systemd timer (see cleanup.timer / cleanup.service).
|
||||
#
|
||||
# What it cleans:
|
||||
# 1. Docker: stopped containers, dangling images, build cache
|
||||
# 2. act_runner action cache: keeps only the newest entry per key prefix
|
||||
# 3. act_runner workspaces: removes leftover build workspaces
|
||||
# 4. System: apt cache, old logs
|
||||
#
|
||||
# What it preserves:
|
||||
# - The current runner container and its image
|
||||
# - The most recent cache entry per prefix (so ccache hits still work)
|
||||
# - Everything outside of known CI paths
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Configuration -- adjust these to match your runner setup
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Disk usage threshold (percent) -- only run aggressive cleanup above this
|
||||
THRESHOLD=${CLEANUP_THRESHOLD:-85}
|
||||
|
||||
# act_runner cache directory (default location)
|
||||
CACHE_DIR=${CACHE_DIR:-/root/.cache/actcache}
|
||||
|
||||
# act_runner workspace directories
|
||||
WORKSPACES=(
|
||||
"/root/.cache/act"
|
||||
"/workspace"
|
||||
)
|
||||
|
||||
# Maximum age (days) for cache entries before unconditional deletion
|
||||
CACHE_MAX_AGE_DAYS=${CACHE_MAX_AGE_DAYS:-7}
|
||||
|
||||
# Maximum age (days) for Docker images not used by running containers
|
||||
DOCKER_IMAGE_MAX_AGE=${DOCKER_IMAGE_MAX_AGE:-48h}
|
||||
|
||||
# Log prefix
|
||||
LOG_PREFIX="[runner-cleanup]"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
log() { echo "$(date '+%Y-%m-%d %H:%M:%S') ${LOG_PREFIX} $*"; }
|
||||
|
||||
disk_usage_pct() {
|
||||
df --output=pcent / | tail -1 | tr -dc '0-9'
|
||||
}
|
||||
|
||||
bytes_to_human() {
|
||||
numfmt --to=iec-i --suffix=B "$1" 2>/dev/null || echo "${1}B"
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Phase 1: Check if cleanup is needed
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
usage=$(disk_usage_pct)
|
||||
log "Disk usage: ${usage}% (threshold: ${THRESHOLD}%)"
|
||||
|
||||
if [ "$usage" -lt "$THRESHOLD" ]; then
|
||||
log "Below threshold, running light cleanup only"
|
||||
AGGRESSIVE=false
|
||||
else
|
||||
log "Above threshold, running aggressive cleanup"
|
||||
AGGRESSIVE=true
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Phase 2: Docker cleanup (always runs, safe)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
log "--- Docker cleanup ---"
|
||||
|
||||
# Remove stopped containers
|
||||
stopped=$(docker ps -aq --filter status=exited --filter status=dead 2>/dev/null | wc -l)
|
||||
if [ "$stopped" -gt 0 ]; then
|
||||
docker rm $(docker ps -aq --filter status=exited --filter status=dead) 2>/dev/null || true
|
||||
log "Removed ${stopped} stopped containers"
|
||||
fi
|
||||
|
||||
# Remove dangling images (untagged layers)
|
||||
dangling=$(docker images -q --filter dangling=true 2>/dev/null | wc -l)
|
||||
if [ "$dangling" -gt 0 ]; then
|
||||
docker rmi $(docker images -q --filter dangling=true) 2>/dev/null || true
|
||||
log "Removed ${dangling} dangling images"
|
||||
fi
|
||||
|
||||
# Prune build cache
|
||||
docker builder prune -f --filter "until=${DOCKER_IMAGE_MAX_AGE}" 2>/dev/null || true
|
||||
log "Pruned Docker build cache older than ${DOCKER_IMAGE_MAX_AGE}"
|
||||
|
||||
if [ "$AGGRESSIVE" = true ]; then
|
||||
# Remove all images not used by running containers
|
||||
running_images=$(docker ps -q 2>/dev/null | xargs -r docker inspect --format='{{.Image}}' | sort -u)
|
||||
all_images=$(docker images -q 2>/dev/null | sort -u)
|
||||
for img in $all_images; do
|
||||
if ! echo "$running_images" | grep -q "$img"; then
|
||||
docker rmi -f "$img" 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
log "Removed unused Docker images (aggressive)"
|
||||
|
||||
# Prune volumes
|
||||
docker volume prune -f 2>/dev/null || true
|
||||
log "Pruned unused Docker volumes"
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Phase 3: act_runner action cache cleanup
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
log "--- Action cache cleanup ---"
|
||||
|
||||
if [ -d "$CACHE_DIR" ]; then
|
||||
before=$(du -sb "$CACHE_DIR" 2>/dev/null | cut -f1)
|
||||
|
||||
# Delete cache entries older than max age
|
||||
find "$CACHE_DIR" -type f -mtime "+${CACHE_MAX_AGE_DAYS}" -delete 2>/dev/null || true
|
||||
find "$CACHE_DIR" -type d -empty -delete 2>/dev/null || true
|
||||
|
||||
after=$(du -sb "$CACHE_DIR" 2>/dev/null | cut -f1)
|
||||
freed=$((before - after))
|
||||
log "Cache cleanup freed $(bytes_to_human $freed) (entries older than ${CACHE_MAX_AGE_DAYS}d)"
|
||||
else
|
||||
log "Cache directory not found: ${CACHE_DIR}"
|
||||
|
||||
# Try common alternative locations
|
||||
for alt in /var/lib/act_runner/.cache/actcache /home/*/.cache/actcache; do
|
||||
if [ -d "$alt" ]; then
|
||||
log "Found cache at: $alt (update CACHE_DIR config)"
|
||||
CACHE_DIR="$alt"
|
||||
find "$CACHE_DIR" -type f -mtime "+${CACHE_MAX_AGE_DAYS}" -delete 2>/dev/null || true
|
||||
find "$CACHE_DIR" -type d -empty -delete 2>/dev/null || true
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Phase 4: Workspace cleanup
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
log "--- Workspace cleanup ---"
|
||||
|
||||
for ws in "${WORKSPACES[@]}"; do
|
||||
if [ -d "$ws" ]; then
|
||||
# Remove workspace dirs not modified in the last 2 hours
|
||||
# (active builds should be touching files continuously)
|
||||
before=$(du -sb "$ws" 2>/dev/null | cut -f1)
|
||||
find "$ws" -mindepth 1 -maxdepth 1 -type d -mmin +120 -exec rm -rf {} + 2>/dev/null || true
|
||||
after=$(du -sb "$ws" 2>/dev/null | cut -f1)
|
||||
freed=$((before - after))
|
||||
if [ "$freed" -gt 0 ]; then
|
||||
log "Workspace $ws: freed $(bytes_to_human $freed)"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Phase 5: System cleanup
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
log "--- System cleanup ---"
|
||||
|
||||
# apt cache
|
||||
apt-get clean 2>/dev/null || true
|
||||
|
||||
# Truncate large log files (keep last 1000 lines)
|
||||
for logfile in /var/log/syslog /var/log/daemon.log /var/log/kern.log; do
|
||||
if [ -f "$logfile" ] && [ "$(stat -c%s "$logfile" 2>/dev/null)" -gt 104857600 ]; then
|
||||
tail -1000 "$logfile" > "${logfile}.tmp" && mv "${logfile}.tmp" "$logfile"
|
||||
log "Truncated $logfile (was >100MB)"
|
||||
fi
|
||||
done
|
||||
|
||||
# Journal logs older than 3 days
|
||||
journalctl --vacuum-time=3d 2>/dev/null || true
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Phase 6: Emergency cleanup (only if still critical)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
usage=$(disk_usage_pct)
|
||||
if [ "$usage" -gt 95 ]; then
|
||||
log "CRITICAL: Still at ${usage}% after cleanup"
|
||||
|
||||
# Nuclear option: remove ALL docker data except running containers
|
||||
docker system prune -af --volumes 2>/dev/null || true
|
||||
log "Ran docker system prune -af --volumes"
|
||||
|
||||
# Clear entire action cache
|
||||
if [ -d "$CACHE_DIR" ]; then
|
||||
rm -rf "${CACHE_DIR:?}/"*
|
||||
log "Cleared entire action cache"
|
||||
fi
|
||||
|
||||
usage=$(disk_usage_pct)
|
||||
log "After emergency cleanup: ${usage}%"
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Summary
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
usage=$(disk_usage_pct)
|
||||
log "Cleanup complete. Disk usage: ${usage}%"
|
||||
|
||||
# Report top space consumers for diagnostics
|
||||
log "Top 10 directories under /var:"
|
||||
du -sh /var/*/ 2>/dev/null | sort -rh | head -10 | while read -r line; do
|
||||
log " $line"
|
||||
done
|
||||
10
.gitea/runner/cleanup.timer
Normal file
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Run CI runner cleanup every 30 minutes
|
||||
|
||||
[Timer]
|
||||
OnBootSec=5min
|
||||
OnUnitActiveSec=30min
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
@@ -22,6 +22,17 @@ jobs:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
steps:
|
||||
- name: Free disk space
|
||||
run: |
|
||||
echo "=== Disk usage before cleanup ==="
|
||||
df -h /
|
||||
rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache 2>/dev/null || true
|
||||
rm -rf /usr/local/share/boost /usr/share/swift 2>/dev/null || true
|
||||
apt-get autoremove -y 2>/dev/null || true
|
||||
apt-get clean 2>/dev/null || true
|
||||
echo "=== Disk usage after cleanup ==="
|
||||
df -h /
|
||||
|
||||
- name: Install system prerequisites
|
||||
run: |
|
||||
apt-get update -qq
|
||||
@@ -46,12 +57,16 @@ jobs:
|
||||
export PATH="$HOME/.pixi/bin:$PATH"
|
||||
pixi --version
|
||||
|
||||
- name: Compute cache date key
|
||||
id: cache-date
|
||||
run: echo "date=$(date -u +%Y%m%d)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Restore ccache
|
||||
id: ccache-restore
|
||||
uses: https://github.com/actions/cache/restore@v4
|
||||
with:
|
||||
path: /tmp/ccache-kindred-create
|
||||
key: ccache-build-${{ github.ref_name }}-${{ github.run_id }}
|
||||
key: ccache-build-${{ github.ref_name }}-${{ steps.cache-date.outputs.date }}
|
||||
restore-keys: |
|
||||
ccache-build-${{ github.ref_name }}-
|
||||
ccache-build-main-
|
||||
@@ -60,6 +75,7 @@ jobs:
|
||||
run: |
|
||||
mkdir -p $CCACHE_DIR
|
||||
pixi run ccache -z
|
||||
pixi run ccache -p
|
||||
|
||||
- name: Configure (CMake)
|
||||
run: pixi run cmake --preset conda-linux-release
|
||||
@@ -71,11 +87,11 @@ jobs:
|
||||
run: pixi run ccache -s
|
||||
|
||||
- name: Save ccache
|
||||
if: always()
|
||||
if: always() && steps.ccache-restore.outputs.cache-hit != 'true'
|
||||
uses: https://github.com/actions/cache/save@v4
|
||||
with:
|
||||
path: /tmp/ccache-kindred-create
|
||||
key: ccache-build-${{ github.ref_name }}-${{ github.run_id }}
|
||||
key: ccache-build-${{ github.ref_name }}-${{ steps.cache-date.outputs.date }}
|
||||
|
||||
- name: Run C++ unit tests
|
||||
continue-on-error: true
|
||||
|
||||
@@ -31,6 +31,18 @@ jobs:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
steps:
|
||||
- name: Free disk space
|
||||
run: |
|
||||
echo "=== Disk usage before cleanup ==="
|
||||
df -h /
|
||||
# Remove pre-installed bloat common in runner images
|
||||
rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache 2>/dev/null || true
|
||||
rm -rf /usr/local/share/boost /usr/share/swift 2>/dev/null || true
|
||||
apt-get autoremove -y 2>/dev/null || true
|
||||
apt-get clean 2>/dev/null || true
|
||||
echo "=== Disk usage after cleanup ==="
|
||||
df -h /
|
||||
|
||||
- name: Install system prerequisites
|
||||
run: |
|
||||
apt-get update -qq
|
||||
@@ -55,20 +67,26 @@ jobs:
|
||||
export PATH="$HOME/.pixi/bin:$PATH"
|
||||
pixi --version
|
||||
|
||||
- name: Compute cache date key
|
||||
id: cache-date
|
||||
run: echo "date=$(date -u +%Y%m%d)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Restore ccache
|
||||
id: ccache-restore
|
||||
uses: https://github.com/actions/cache/restore@v4
|
||||
with:
|
||||
path: /tmp/ccache-kindred-create
|
||||
key: ccache-release-linux-${{ github.run_id }}
|
||||
key: ccache-release-linux-${{ steps.cache-date.outputs.date }}
|
||||
restore-keys: |
|
||||
ccache-release-linux-
|
||||
ccache-build-main-
|
||||
|
||||
- name: Prepare ccache
|
||||
run: |
|
||||
mkdir -p $CCACHE_DIR
|
||||
# Ensure ccache is accessible to rattler-build's subprocess
|
||||
export PATH="$(pixi run bash -c 'echo $PATH')"
|
||||
pixi run ccache -z
|
||||
pixi run ccache -p
|
||||
|
||||
- name: Build release package (AppImage)
|
||||
working-directory: package/rattler-build
|
||||
@@ -80,11 +98,19 @@ jobs:
|
||||
run: pixi run ccache -s
|
||||
|
||||
- name: Save ccache
|
||||
if: always()
|
||||
if: always() && steps.ccache-restore.outputs.cache-hit != 'true'
|
||||
uses: https://github.com/actions/cache/save@v4
|
||||
with:
|
||||
path: /tmp/ccache-kindred-create
|
||||
key: ccache-release-linux-${{ github.run_id }}
|
||||
key: ccache-release-linux-${{ steps.cache-date.outputs.date }}
|
||||
|
||||
- name: Clean up intermediate build files
|
||||
run: |
|
||||
# Remove pixi package cache and build work dirs to free space for .deb
|
||||
rm -rf package/rattler-build/.pixi/build 2>/dev/null || true
|
||||
find /root/.cache/rattler -type f -delete 2>/dev/null || true
|
||||
echo "=== Disk usage after cleanup ==="
|
||||
df -h /
|
||||
|
||||
- name: Build .deb package
|
||||
run: |
|
||||
@@ -105,7 +131,7 @@ jobs:
|
||||
with:
|
||||
name: release-linux
|
||||
path: |
|
||||
package/rattler-build/linux/*.AppImage
|
||||
package/rattler-build/linux/FreeCAD_*.AppImage
|
||||
package/rattler-build/linux/*.deb
|
||||
package/rattler-build/linux/*-SHA256.txt
|
||||
package/rattler-build/linux/*.sha256
|
||||
@@ -315,22 +341,69 @@ jobs:
|
||||
ls -lah release/
|
||||
|
||||
- name: Create release
|
||||
uses: https://gitea.com/actions/release-action@main
|
||||
with:
|
||||
files: release/*
|
||||
title: "Kindred Create ${{ env.BUILD_TAG }}"
|
||||
body: |
|
||||
## Kindred Create ${{ env.BUILD_TAG }}
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
GITEA_URL: ${{ github.server_url }}
|
||||
REPO: ${{ github.repository }}
|
||||
run: |
|
||||
TAG="${BUILD_TAG}"
|
||||
|
||||
### Downloads
|
||||
# Build JSON payload entirely in Python to avoid shell/Python type mismatches
|
||||
PAYLOAD=$(python3 -c "
|
||||
import json, re
|
||||
tag = '${TAG}'
|
||||
prerelease = bool(re.search(r'(rc|beta|alpha)', tag))
|
||||
body = '''## Kindred Create {tag}
|
||||
|
||||
| Platform | File |
|
||||
|----------|------|
|
||||
| Linux (AppImage) | `KindredCreate-*-Linux-x86_64.AppImage` |
|
||||
| Linux (Debian/Ubuntu) | `kindred-create_*.deb` |
|
||||
### Downloads
|
||||
|
||||
*macOS and Windows builds are not yet available.*
|
||||
| Platform | File |
|
||||
|----------|------|
|
||||
| Linux (AppImage) | \`KindredCreate-*-Linux-x86_64.AppImage\` |
|
||||
| Linux (Debian/Ubuntu) | \`kindred-create_*.deb\` |
|
||||
|
||||
SHA256 checksums are provided alongside each artifact.
|
||||
prerelease: ${{ contains(github.ref_name, 'rc') || contains(github.ref_name, 'beta') || contains(github.ref_name, 'alpha') }}
|
||||
api_key: ${{ secrets.RELEASE_TOKEN }}
|
||||
*macOS and Windows builds are not yet available.*
|
||||
|
||||
SHA256 checksums are provided alongside each artifact.'''.format(tag=tag)
|
||||
print(json.dumps({
|
||||
'tag_name': tag,
|
||||
'name': f'Kindred Create {tag}',
|
||||
'body': body,
|
||||
'prerelease': prerelease,
|
||||
}))
|
||||
")
|
||||
|
||||
# Delete existing release for this tag (if any) so we can recreate
|
||||
existing=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
"${GITEA_URL}/api/v1/repos/${REPO}/releases/tags/${TAG}")
|
||||
if [ "$existing" = "200" ]; then
|
||||
release_id=$(curl -s \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
"${GITEA_URL}/api/v1/repos/${REPO}/releases/tags/${TAG}" | \
|
||||
python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
|
||||
curl -s -X DELETE \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
"${GITEA_URL}/api/v1/repos/${REPO}/releases/${release_id}"
|
||||
echo "Deleted existing release ${release_id} for tag ${TAG}"
|
||||
fi
|
||||
|
||||
# Create release
|
||||
release_id=$(curl -s -X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$PAYLOAD" \
|
||||
"${GITEA_URL}/api/v1/repos/${REPO}/releases" | \
|
||||
python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
|
||||
echo "Created release ${release_id}"
|
||||
|
||||
# Upload assets
|
||||
for file in release/*; do
|
||||
filename=$(basename "$file")
|
||||
echo "Uploading ${filename}..."
|
||||
curl -s -X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-F "attachment=@${file}" \
|
||||
"${GITEA_URL}/api/v1/repos/${REPO}/releases/${release_id}/assets?name=${filename}"
|
||||
echo " done."
|
||||
done
|
||||
|
||||
2
.gitmodules
vendored
@@ -15,4 +15,4 @@
|
||||
url = https://git.kindred-systems.com/forbes/ztools.git
|
||||
[submodule "mods/silo"]
|
||||
path = mods/silo
|
||||
url = https://git.kindred-systems.com/kindred/silo.git
|
||||
url = https://git.kindred-systems.com/kindred/silo-mod.git
|
||||
|
||||
@@ -7,14 +7,14 @@ FreeCAD startup
|
||||
└─ src/Mod/Create/Init.py
|
||||
└─ setup_kindred_addons()
|
||||
├─ exec(mods/ztools/ztools/Init.py)
|
||||
└─ exec(mods/silo/pkg/freecad/Init.py)
|
||||
└─ exec(mods/silo/freecad/Init.py)
|
||||
|
||||
└─ src/Mod/Create/InitGui.py
|
||||
├─ setup_kindred_workbenches()
|
||||
│ ├─ exec(mods/ztools/ztools/InitGui.py)
|
||||
│ │ ├─ registers ZToolsWorkbench
|
||||
│ │ └─ installs _ZToolsPartDesignManipulator (global)
|
||||
│ └─ exec(mods/silo/pkg/freecad/InitGui.py)
|
||||
│ └─ exec(mods/silo/freecad/InitGui.py)
|
||||
│ └─ registers SiloWorkbench
|
||||
└─ Deferred setup (QTimer):
|
||||
├─ 1500ms: _setup_silo_auth_panel() → "Database Auth" dock
|
||||
@@ -43,16 +43,13 @@ mods/ztools/ [submodule] ztools workbench
|
||||
│ └── resources/ Icons, theme utilities
|
||||
└── CatppuccinMocha/ Theme preference pack (QSS)
|
||||
|
||||
mods/silo/ [submodule] Silo parts database
|
||||
├── cmd/ Go server entry points
|
||||
├── internal/ Go API, database, auth, storage packages
|
||||
├── pkg/freecad/ FreeCAD workbench (Python)
|
||||
│ ├── InitGui.py SiloWorkbench
|
||||
│ ├── silo_commands.py Commands + SiloClient API
|
||||
│ └── silo_origin.py FileOrigin backend for Silo
|
||||
├── pkg/calc/ LibreOffice Calc extension (Python)
|
||||
├── deployments/ Docker compose configuration
|
||||
└── migrations/ PostgreSQL schema migrations (001–010)
|
||||
mods/silo/ [submodule -> silo-mod.git] FreeCAD workbench
|
||||
├── silo-client/ [submodule -> silo-client.git] shared API client
|
||||
│ └── silo_client/ SiloClient, SiloSettings, CATEGORY_NAMES
|
||||
└── freecad/ FreeCAD workbench (Python)
|
||||
├── InitGui.py SiloWorkbench
|
||||
├── silo_commands.py Commands + FreeCADSiloSettings adapter
|
||||
└── silo_origin.py FileOrigin backend for Silo
|
||||
|
||||
src/Gui/Stylesheets/ QSS themes and SVG assets
|
||||
resources/preferences/ Canonical preference pack (KindredCreate)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
## Origin commands (C++)
|
||||
|
||||
The Origin abstraction (`src/Gui/FileOrigin.h`) provides a backend-agnostic interface for document storage. Commands delegate to the active `FileOrigin` implementation (currently `LocalFileOrigin` for local files, `SiloOrigin` via `mods/silo/pkg/freecad/silo_origin.py` for Silo-tracked documents).
|
||||
The Origin abstraction (`src/Gui/FileOrigin.h`) provides a backend-agnostic interface for document storage. Commands delegate to the active `FileOrigin` implementation (currently `LocalFileOrigin` for local files, `SiloOrigin` via `mods/silo/freecad/silo_origin.py` for Silo-tracked documents).
|
||||
|
||||
**Registered commands (5):**
|
||||
|
||||
@@ -71,7 +71,7 @@ These appear in the File menu and "Origin Tools" toolbar across all workbenches
|
||||
|
||||
**Server architecture:** Go REST API (38+ routes) + PostgreSQL + MinIO S3. Authentication via local (bcrypt), LDAP, or OIDC backends. See `mods/silo/docs/` for server documentation.
|
||||
|
||||
**LibreOffice Calc extension** (`mods/silo/pkg/calc/`): BOM management, item creation, and AI-assisted descriptions via OpenRouter API. Shares the same Silo REST API and auth token system.
|
||||
**LibreOffice Calc extension** ([silo-calc](https://git.kindred-systems.com/kindred/silo-calc.git)): BOM management, item creation, and AI-assisted descriptions via OpenRouter API. Shares the same Silo REST API and auth token system via the shared [silo-client](https://git.kindred-systems.com/kindred/silo-client.git) package.
|
||||
|
||||
---
|
||||
|
||||
@@ -95,7 +95,7 @@ Four copies must stay in sync:
|
||||
|
||||
`silo-bom.svg`, `silo-commit.svg`, `silo-info.svg`, `silo-pull.svg`, `silo-push.svg`
|
||||
|
||||
### Silo module icons (`mods/silo/pkg/freecad/resources/icons/`)
|
||||
### Silo module icons (`mods/silo/freecad/resources/icons/`)
|
||||
|
||||
10 SVGs loaded at runtime by the `_icon()` function in `silo_commands.py`:
|
||||
|
||||
|
||||
@@ -134,8 +134,10 @@ install(DIRECTORY ${CMAKE_SOURCE_DIR}/mods/ztools/ztools
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/mods/ztools/CatppuccinMocha
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/Mod/ztools)
|
||||
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/mods/silo/pkg/freecad/
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/mods/silo/freecad/
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/Mod/Silo)
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/mods/silo/silo-client/
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/Mod/silo-client)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -1,8 +1,117 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M8 6 L20 6 L24 10 L24 26 L8 26 Z" fill="none" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<path d="M20 6 L20 10 L24 10" fill="none" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<line x1="11" y1="14" x2="21" y2="14" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<line x1="11" y1="18" x2="21" y2="18" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<line x1="11" y1="22" x2="17" y2="22" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
sodipodi:docname="Document.svg"
|
||||
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect5"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0.8970359,0,1 @ F,0,0,1,0,0,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect4"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,2.25625,0,1 @ F,0,0,1,0,1.411235,0,1 @ F,0,0,1,0,1.2732549,0,1 @ F,0,0,1,0,2.25625,0,1 @ F,0,0,1,0,1.875,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="namedview4"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="32"
|
||||
inkscape:cx="10.90625"
|
||||
inkscape:cy="12.21875"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1371"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4" />
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<path
|
||||
d="m 10.246497,6 h 8.332515 a 3.4070227,3.4070227 22.5 0 1 2.409129,0.9978938 l 2.101779,2.101779 a 3.0739092,3.0739092 67.5 0 1 0.900327,2.1735822 l 0,12.470495 A 2.25625,2.25625 135 0 1 21.733997,26 H 9.8652468 a 1.875,1.875 45 0 1 -1.875,-1.875 V 8.25625 A 2.25625,2.25625 135 0 1 10.246497,6 Z"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path1"
|
||||
inkscape:path-effect="#path-effect4"
|
||||
inkscape:original-d="M 7.9902468,6 H 19.990247 l 4,4 V 26 H 7.9902468 Z" />
|
||||
<path
|
||||
d="m 19.707388,5.8623613 v 3.4443418 a 0.8970359,0.8970359 45 0 0 0.897036,0.8970359 h 3.385823"
|
||||
fill="none"
|
||||
stroke="#74c7ec"
|
||||
stroke-width="1.61701"
|
||||
id="path2"
|
||||
style="stroke:#89b4fa;stroke-width:1.5;stroke-dasharray:none;stroke-opacity:1"
|
||||
inkscape:path-effect="#path-effect5"
|
||||
inkscape:original-d="m 19.707388,5.8623613 v 4.3413777 h 4.282859" />
|
||||
<line
|
||||
x1="11"
|
||||
y1="14"
|
||||
x2="21"
|
||||
y2="14"
|
||||
stroke="#74c7ec"
|
||||
stroke-width="1.5"
|
||||
id="line2"
|
||||
style="stroke-linecap:round" />
|
||||
<line
|
||||
x1="11"
|
||||
y1="18"
|
||||
x2="21"
|
||||
y2="18"
|
||||
stroke="#74c7ec"
|
||||
stroke-width="1.5"
|
||||
id="line3"
|
||||
style="stroke-linecap:round" />
|
||||
<line
|
||||
x1="11"
|
||||
y1="22"
|
||||
x2="17"
|
||||
y2="22"
|
||||
stroke="#74c7ec"
|
||||
stroke-width="1.5"
|
||||
id="line4"
|
||||
style="stroke-linecap:round" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 534 B After Width: | Height: | Size: 3.4 KiB |
@@ -1,5 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<ellipse cx="16" cy="16" rx="10" ry="6" fill="none" stroke="#f9e2af" stroke-width="2"/>
|
||||
<circle cx="16" cy="16" r="3" fill="#fab387"/>
|
||||
<ellipse cx="16" cy="16" rx="10" ry="6" fill="none" stroke="#cdd6f4" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<circle cx="16" cy="16" r="3" fill="none" stroke="#cdd6f4" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 262 B After Width: | Height: | Size: 344 B |
@@ -1,5 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M8 12 L16 8 L24 12 L24 22 L16 26 L8 22 Z" fill="#f9e2af" fill-opacity="0.6" stroke="#fab387" stroke-width="1.5"/>
|
||||
<path d="M8 12 L16 16 L24 12 M16 16 L16 26" fill="none" stroke="#fab387" stroke-width="1.5"/>
|
||||
<path d="M5.5 9.5 16 4l10.5 5.5v13L16 28 5.5 22.5z" fill="#45475a" stroke="#89b4fa" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M5.5 9.5 16 15l10.5-5.5M16 15v13" fill="none" stroke="#89b4fa" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 344 B After Width: | Height: | Size: 419 B |
@@ -1,5 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M8 12 L16 8 L24 12 L24 22 L16 26 L8 22 Z" fill="none" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
<path d="M8 12 L16 16 L24 12 M16 16 L16 26" fill="none" stroke="#fab387" stroke-width="1.5" stroke-dasharray="2,2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 345 B |
@@ -1,7 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<rect x="8" y="10" width="16" height="12" fill="none" stroke="#f9e2af" stroke-width="2"/>
|
||||
<line x1="8" y1="10" x2="12" y2="6" stroke="#fab387" stroke-width="1.5"/>
|
||||
<line x1="24" y1="10" x2="28" y2="6" stroke="#fab387" stroke-width="1.5"/>
|
||||
<line x1="12" y1="6" x2="28" y2="6" stroke="#fab387" stroke-width="1.5"/>
|
||||
<path d="M5.5 9.5 16 4l10.5 5.5v13L16 28 5.5 22.5z" fill="#585b70" stroke="#cdd6f4" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M5.5 9.5 16 15l10.5-5.5M16 15v13" fill="none" stroke="#cdd6f4" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 444 B After Width: | Height: | Size: 419 B |
@@ -1,10 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<circle cx="8" cy="12" r="2" fill="#f9e2af"/>
|
||||
<circle cx="16" cy="8" r="2" fill="#f9e2af"/>
|
||||
<circle cx="24" cy="12" r="2" fill="#f9e2af"/>
|
||||
<circle cx="8" cy="22" r="2" fill="#fab387"/>
|
||||
<circle cx="16" cy="26" r="2" fill="#fab387"/>
|
||||
<circle cx="24" cy="22" r="2" fill="#fab387"/>
|
||||
<circle cx="16" cy="16" r="2" fill="#f9e2af"/>
|
||||
<circle cx="16" cy="4" r="1.5" fill="#cdd6f4"/>
|
||||
<circle cx="5.5" cy="9.5" r="1.5" fill="#cdd6f4"/>
|
||||
<circle cx="26.5" cy="9.5" r="1.5" fill="#cdd6f4"/>
|
||||
<circle cx="16" cy="15" r="1.5" fill="#cdd6f4"/>
|
||||
<circle cx="5.5" cy="22.5" r="1.5" fill="#cdd6f4"/>
|
||||
<circle cx="26.5" cy="22.5" r="1.5" fill="#cdd6f4"/>
|
||||
<circle cx="16" cy="28" r="1.5" fill="#cdd6f4"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 463 B After Width: | Height: | Size: 491 B |
@@ -1,5 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M8 12 L16 8 L24 12 L24 22 L16 26 L8 22 Z" fill="#f9e2af" stroke="#fab387" stroke-width="1.5"/>
|
||||
<path d="M8 12 L16 16 L24 12 M16 16 L16 26" fill="none" stroke="#313244" stroke-width="1"/>
|
||||
<path d="M5.5 9.5 16 4l10.5 5.5v13L16 28 5.5 22.5z" fill="#45475a" stroke="#cdd6f4" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M5.5 9.5 16 15l10.5-5.5M16 15v13" fill="none" stroke="#cdd6f4" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 323 B After Width: | Height: | Size: 419 B |
@@ -1,5 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M8 12 L16 8 L24 12 L24 22 L16 26 L8 22 Z" fill="none" stroke="#f9e2af" stroke-width="1.5"/>
|
||||
<path d="M8 12 L16 16 L24 12 M16 16 L16 26" fill="none" stroke="#fab387" stroke-width="1.5"/>
|
||||
<path d="M5.5 9.5 16 4l10.5 5.5v13L16 28 5.5 22.5z" fill="none" stroke="#cdd6f4" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M5.5 9.5 16 15l10.5-5.5M16 15v13" fill="none" stroke="#cdd6f4" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 322 B After Width: | Height: | Size: 416 B |
@@ -1,9 +1,62 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<circle cx="10" cy="10" r="4" fill="none" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<circle cx="22" cy="10" r="4" fill="none" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<circle cx="10" cy="22" r="4" fill="none" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<circle cx="22" cy="22" r="4" fill="none" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<line x1="14" y1="10" x2="18" y2="10" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<line x1="10" y1="14" x2="10" y2="18" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<circle
|
||||
cx="10"
|
||||
cy="10"
|
||||
r="4"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="circle1" />
|
||||
<circle
|
||||
cx="22"
|
||||
cy="10"
|
||||
r="4"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="circle2" />
|
||||
<circle
|
||||
cx="10"
|
||||
cy="22"
|
||||
r="4"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="circle3" />
|
||||
<circle
|
||||
cx="22"
|
||||
cy="22"
|
||||
r="4"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="circle4" />
|
||||
<line
|
||||
x1="14"
|
||||
y1="10"
|
||||
x2="18"
|
||||
y2="10"
|
||||
stroke="#cba6f7"
|
||||
stroke-width="1.5"
|
||||
id="line1" />
|
||||
<line
|
||||
x1="10"
|
||||
y1="14"
|
||||
x2="10"
|
||||
y2="18"
|
||||
stroke="#cba6f7"
|
||||
stroke-width="1.5"
|
||||
id="line2" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 607 B After Width: | Height: | Size: 1.0 KiB |
@@ -1,7 +1,52 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<rect x="6" y="6" width="10" height="10" rx="1" fill="none" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<rect x="10" y="10" width="10" height="10" rx="1" fill="#313244" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<rect x="14" y="14" width="10" height="10" rx="1" fill="#313244" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<circle cx="24" cy="8" r="4" fill="none" stroke="#a6e3a1" stroke-width="1.5"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<rect
|
||||
x="6"
|
||||
y="6"
|
||||
width="10"
|
||||
height="10"
|
||||
rx="1.5"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="rect2" />
|
||||
<rect
|
||||
x="10"
|
||||
y="10"
|
||||
width="10"
|
||||
height="10"
|
||||
rx="1.5"
|
||||
fill="#313244"
|
||||
stroke="#cba6f7"
|
||||
stroke-width="1.5"
|
||||
id="rect3" />
|
||||
<rect
|
||||
x="14"
|
||||
y="14"
|
||||
width="10"
|
||||
height="10"
|
||||
rx="1.5"
|
||||
fill="#313244"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="rect4" />
|
||||
<circle
|
||||
cx="24"
|
||||
cy="8"
|
||||
r="4"
|
||||
fill="none"
|
||||
stroke="#a6e3a1"
|
||||
stroke-width="1.5"
|
||||
id="circle1" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 514 B After Width: | Height: | Size: 910 B |
@@ -1,6 +1,35 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<rect x="8" y="8" width="10" height="10" rx="1" fill="none" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<path d="M18 18 L24 24" stroke="#74c7ec" stroke-width="2"/>
|
||||
<circle cx="24" cy="24" r="3" fill="#74c7ec"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<rect
|
||||
x="8"
|
||||
y="8"
|
||||
width="10"
|
||||
height="10"
|
||||
rx="1.5"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="rect2" />
|
||||
<path
|
||||
d="M 18,18 24,24"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path1" />
|
||||
<circle
|
||||
cx="24"
|
||||
cy="24"
|
||||
r="3"
|
||||
fill="#cba6f7"
|
||||
id="circle1" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 334 B After Width: | Height: | Size: 636 B |
@@ -1,7 +1,48 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<rect x="6" y="10" width="20" height="14" rx="2" fill="none" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<circle cx="12" cy="17" r="3" fill="none" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<circle cx="20" cy="17" r="3" fill="none" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<line x1="15" y1="17" x2="17" y2="17" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<rect
|
||||
x="6"
|
||||
y="10"
|
||||
width="20"
|
||||
height="14"
|
||||
rx="2"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="rect2" />
|
||||
<circle
|
||||
cx="12"
|
||||
cy="17"
|
||||
r="3"
|
||||
fill="none"
|
||||
stroke="#cba6f7"
|
||||
stroke-width="1.5"
|
||||
id="circle1" />
|
||||
<circle
|
||||
cx="20"
|
||||
cy="17"
|
||||
r="3"
|
||||
fill="none"
|
||||
stroke="#cba6f7"
|
||||
stroke-width="1.5"
|
||||
id="circle2" />
|
||||
<line
|
||||
x1="15"
|
||||
y1="17"
|
||||
x2="17"
|
||||
y2="17"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="line1" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 466 B After Width: | Height: | Size: 838 B |
@@ -1,7 +1,42 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<circle cx="10" cy="10" r="3" fill="none" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<circle cx="22" cy="10" r="3" fill="none" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<circle cx="10" cy="20" r="3" fill="none" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<path d="M24 18 L24 26 L18 22 Z" fill="#a6e3a1"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<circle
|
||||
cx="10"
|
||||
cy="10"
|
||||
r="3"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="circle1" />
|
||||
<circle
|
||||
cx="22"
|
||||
cy="10"
|
||||
r="3"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="circle2" />
|
||||
<circle
|
||||
cx="10"
|
||||
cy="20"
|
||||
r="3"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="circle3" />
|
||||
<path
|
||||
d="M 24,18 24,26 18,22 Z"
|
||||
fill="#a6e3a1"
|
||||
id="path1" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 421 B After Width: | Height: | Size: 764 B |
@@ -1,5 +1,34 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<rect x="6" y="6" width="12" height="12" rx="1" fill="none" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<rect x="14" y="14" width="12" height="12" rx="1" fill="#313244" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<rect
|
||||
x="6"
|
||||
y="6"
|
||||
width="12"
|
||||
height="12"
|
||||
rx="1.5"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="rect2" />
|
||||
<rect
|
||||
x="14"
|
||||
y="14"
|
||||
width="12"
|
||||
height="12"
|
||||
rx="1.5"
|
||||
fill="#313244"
|
||||
stroke="#cba6f7"
|
||||
stroke-width="1.5"
|
||||
id="rect3" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 328 B After Width: | Height: | Size: 616 B |
@@ -1,7 +1,42 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<circle cx="10" cy="16" r="5" fill="none" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<circle cx="22" cy="16" r="5" fill="none" stroke="#74c7ec" stroke-width="1.5"/>
|
||||
<path d="M13 12 L19 12 M19 12 L17 10 M19 12 L17 14" stroke="#a6e3a1" stroke-width="1.5"/>
|
||||
<path d="M19 20 L13 20 M13 20 L15 18 M13 20 L15 22" stroke="#f38ba8" stroke-width="1.5"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<circle
|
||||
cx="10"
|
||||
cy="16"
|
||||
r="5"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="circle1" />
|
||||
<circle
|
||||
cx="22"
|
||||
cy="16"
|
||||
r="5"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="circle2" />
|
||||
<path
|
||||
d="M 13,12 19,12 M 19,12 17,10 M 19,12 17,14"
|
||||
stroke="#a6e3a1"
|
||||
stroke-width="1.5"
|
||||
fill="none"
|
||||
id="path1" />
|
||||
<path
|
||||
d="M 19,20 13,20 M 13,20 15,18 M 13,20 15,22"
|
||||
stroke="#f38ba8"
|
||||
stroke-width="1.5"
|
||||
fill="none"
|
||||
id="path2" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 471 B After Width: | Height: | Size: 837 B |
@@ -1,14 +1,62 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
x="2"
|
||||
y="2"
|
||||
width="28"
|
||||
height="28"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<!-- Base sketch profile -->
|
||||
<path d="M6 24 L6 20 L14 18 L26 20 L26 24 L14 26 Z" fill="#45475a" stroke="#6c7086" stroke-width="1"/>
|
||||
<path
|
||||
d="M 6,24 6,20 14,18 26,20 26,24 14,26 Z"
|
||||
fill="#45475a"
|
||||
stroke="#6c7086"
|
||||
stroke-width="1"
|
||||
id="path1" />
|
||||
<!-- Extruded body -->
|
||||
<path d="M6 20 L6 10 L14 8 L26 10 L26 20 L14 22 Z" fill="#45475a" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<path d="M6 10 L14 12 L26 10" stroke="#89b4fa" stroke-width="1.5" fill="none"/>
|
||||
<path d="M14 12 L14 22" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<path
|
||||
d="M 6,20 6,10 14,8 26,10 26,20 14,22 Z"
|
||||
fill="#45475a"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path2" />
|
||||
<path
|
||||
d="M 6,10 14,12 26,10"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
fill="none"
|
||||
id="path3" />
|
||||
<path
|
||||
d="M 14,12 V 22"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path4" />
|
||||
<!-- Top face -->
|
||||
<path d="M6 10 L14 8 L26 10 L14 12 Z" fill="#74c7ec" fill-opacity="0.4"/>
|
||||
<path
|
||||
d="M 6,10 14,8 26,10 14,12 Z"
|
||||
fill="#74c7ec"
|
||||
fill-opacity="0.4"
|
||||
id="path5" />
|
||||
<!-- Extrude arrow -->
|
||||
<path d="M20 18 L20 6" stroke="#a6e3a1" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M17 9 L20 5 L23 9" stroke="#a6e3a1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
|
||||
<path
|
||||
d="M 20,18 V 6"
|
||||
stroke="#a6e3a1"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
id="path6" />
|
||||
<path
|
||||
d="M 17,9 20,5 23,9"
|
||||
stroke="#a6e3a1"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
fill="none"
|
||||
id="path7" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 878 B After Width: | Height: | Size: 1.3 KiB |
@@ -1,14 +1,67 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
x="2"
|
||||
y="2"
|
||||
width="28"
|
||||
height="28"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<!-- Solid block -->
|
||||
<path d="M4 22 L4 10 L16 6 L28 10 L28 22 L16 26 Z" fill="#45475a" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<path d="M4 10 L16 14 L28 10" stroke="#89b4fa" stroke-width="1.5" fill="none"/>
|
||||
<path d="M16 14 L16 26" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<path
|
||||
d="M 4,22 4,10 16,6 28,10 28,22 16,26 Z"
|
||||
fill="#45475a"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path1" />
|
||||
<path
|
||||
d="M 4,10 16,14 28,10"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
fill="none"
|
||||
id="path2" />
|
||||
<path
|
||||
d="M 16,14 V 26"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path3" />
|
||||
<!-- Pocket cut-out -->
|
||||
<path d="M10 12 L16 10 L22 12 L22 18 L16 20 L10 18 Z" fill="#1e1e2e" stroke="#f38ba8" stroke-width="1.5"/>
|
||||
<path d="M10 12 L16 14 L22 12" stroke="#f38ba8" stroke-width="1" fill="none"/>
|
||||
<path d="M16 14 L16 20" stroke="#f38ba8" stroke-width="1"/>
|
||||
<path
|
||||
d="M 10,12 16,10 22,12 22,18 16,20 10,18 Z"
|
||||
fill="#1e1e2e"
|
||||
stroke="#f38ba8"
|
||||
stroke-width="1.5"
|
||||
id="path4" />
|
||||
<path
|
||||
d="M 10,12 16,14 22,12"
|
||||
stroke="#f38ba8"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
id="path5" />
|
||||
<path
|
||||
d="M 16,14 V 20"
|
||||
stroke="#f38ba8"
|
||||
stroke-width="1"
|
||||
id="path6" />
|
||||
<!-- Cut arrow -->
|
||||
<path d="M16 8 L16 16" stroke="#f38ba8" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<path d="M14 13 L16 17 L18 13" stroke="#f38ba8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
|
||||
<path
|
||||
d="M 16,8 V 16"
|
||||
stroke="#f38ba8"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
id="path7" />
|
||||
<path
|
||||
d="M 14,13 16,17 18,13"
|
||||
stroke="#f38ba8"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
fill="none"
|
||||
id="path8" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 925 B After Width: | Height: | Size: 1.4 KiB |
@@ -1,6 +1,34 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="4" fill="#313244"/>
|
||||
<path d="M12 20 L8 20 A4 4 0 0 1 8 12 L12 12" fill="none" stroke="#585b70" stroke-width="2"/>
|
||||
<path d="M20 12 L24 12 A4 4 0 0 1 24 20 L20 20" fill="none" stroke="#585b70" stroke-width="2"/>
|
||||
<line x1="6" y1="26" x2="26" y2="6" stroke="#f38ba8" stroke-width="2"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<path
|
||||
d="M 12,20 H 8 A 4,4 0 0 1 8,12 h 4"
|
||||
fill="none"
|
||||
stroke="#585b70"
|
||||
stroke-width="1.5"
|
||||
id="path1" />
|
||||
<path
|
||||
d="M 20,12 h 4 A 4,4 0 0 1 24,20 h -4"
|
||||
fill="none"
|
||||
stroke="#585b70"
|
||||
stroke-width="1.5"
|
||||
id="path2" />
|
||||
<line
|
||||
x1="6"
|
||||
y1="26"
|
||||
x2="26"
|
||||
y2="6"
|
||||
stroke="#f38ba8"
|
||||
stroke-width="2"
|
||||
id="line1" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 391 B After Width: | Height: | Size: 680 B |
@@ -1,10 +1,60 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<!-- Document shape -->
|
||||
<path d="M9 5 L9 27 L23 27 L23 11 L17 5 Z" fill="#45475a" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<!-- Folded corner -->
|
||||
<path d="M17 5 L17 11 L23 11" fill="#313244" stroke="#89b4fa" stroke-width="1.5" stroke-linejoin="round"/>
|
||||
<!-- Plus sign for "new" -->
|
||||
<circle cx="22" cy="22" r="6" fill="#a6e3a1"/>
|
||||
<path d="M22 19 L22 25 M19 22 L25 22" stroke="#1e1e2e" stroke-width="2" stroke-linecap="round"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
x="2"
|
||||
y="2"
|
||||
width="28"
|
||||
height="28"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<path
|
||||
d="M 10,6 H 18 L 24,12 V 26 H 10 Z"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path1"
|
||||
style="stroke-linejoin:round" />
|
||||
<path
|
||||
d="M 18,6 V 12 H 24"
|
||||
fill="none"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path2"
|
||||
style="stroke-linejoin:round" />
|
||||
<line
|
||||
x1="12"
|
||||
y1="16"
|
||||
x2="20"
|
||||
y2="16"
|
||||
stroke="#74c7ec"
|
||||
stroke-width="1.5"
|
||||
id="line1"
|
||||
style="stroke-linecap:round" />
|
||||
<line
|
||||
x1="12"
|
||||
y1="20"
|
||||
x2="20"
|
||||
y2="20"
|
||||
stroke="#74c7ec"
|
||||
stroke-width="1.5"
|
||||
id="line2"
|
||||
style="stroke-linecap:round" />
|
||||
<circle
|
||||
cx="24"
|
||||
cy="24"
|
||||
r="5"
|
||||
fill="#a6e3a1"
|
||||
id="circle1" />
|
||||
<path
|
||||
d="M 24,21.5 V 26.5 M 21.5,24 H 26.5"
|
||||
stroke="#1e1e2e"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
id="path3" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 572 B After Width: | Height: | Size: 1.2 KiB |
@@ -1,14 +1,75 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
x="2"
|
||||
y="2"
|
||||
width="28"
|
||||
height="28"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<!-- Printer body -->
|
||||
<rect x="5" y="12" width="22" height="10" rx="2" fill="#45475a" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<rect
|
||||
x="5"
|
||||
y="12"
|
||||
width="22"
|
||||
height="10"
|
||||
rx="2"
|
||||
fill="#45475a"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="rect2" />
|
||||
<!-- Paper input (top) -->
|
||||
<rect x="9" y="6" width="14" height="8" rx="1" fill="#cdd6f4" stroke="#6c7086" stroke-width="1"/>
|
||||
<rect
|
||||
x="9"
|
||||
y="6"
|
||||
width="14"
|
||||
height="8"
|
||||
rx="1"
|
||||
fill="#cdd6f4"
|
||||
stroke="#6c7086"
|
||||
stroke-width="1"
|
||||
id="rect3" />
|
||||
<!-- Paper output (bottom) -->
|
||||
<rect x="9" y="20" width="14" height="8" rx="1" fill="#cdd6f4" stroke="#6c7086" stroke-width="1"/>
|
||||
<rect
|
||||
x="9"
|
||||
y="20"
|
||||
width="14"
|
||||
height="8"
|
||||
rx="1"
|
||||
fill="#cdd6f4"
|
||||
stroke="#6c7086"
|
||||
stroke-width="1"
|
||||
id="rect4" />
|
||||
<!-- Paper lines -->
|
||||
<line x1="11" y1="23" x2="21" y2="23" stroke="#585b70" stroke-width="1" stroke-linecap="round"/>
|
||||
<line x1="11" y1="25" x2="18" y2="25" stroke="#585b70" stroke-width="1" stroke-linecap="round"/>
|
||||
<line
|
||||
x1="11"
|
||||
y1="23"
|
||||
x2="21"
|
||||
y2="23"
|
||||
stroke="#585b70"
|
||||
stroke-width="1"
|
||||
stroke-linecap="round"
|
||||
id="line1" />
|
||||
<line
|
||||
x1="11"
|
||||
y1="25.5"
|
||||
x2="18"
|
||||
y2="25.5"
|
||||
stroke="#585b70"
|
||||
stroke-width="1"
|
||||
stroke-linecap="round"
|
||||
id="line2" />
|
||||
<!-- Printer status light -->
|
||||
<circle cx="23" cy="15" r="1.5" fill="#a6e3a1"/>
|
||||
<circle
|
||||
cx="23"
|
||||
cy="15"
|
||||
r="1.5"
|
||||
fill="#a6e3a1"
|
||||
id="circle1" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 830 B After Width: | Height: | Size: 1.3 KiB |
@@ -1,15 +1,63 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
x="2"
|
||||
y="2"
|
||||
width="28"
|
||||
height="28"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<!-- Floppy disk body -->
|
||||
<path d="M7 6 L7 26 L25 26 L25 10 L21 6 Z" fill="#45475a" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<path
|
||||
d="M 7,6 H 21 L 25,10 V 26 H 7 Z"
|
||||
fill="#45475a"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path1"
|
||||
style="stroke-linejoin:round" />
|
||||
<!-- Metal slider -->
|
||||
<rect x="10" y="6" width="10" height="8" rx="1" fill="#1e1e2e" stroke="#6c7086" stroke-width="1"/>
|
||||
<rect
|
||||
x="10"
|
||||
y="6"
|
||||
width="10"
|
||||
height="8"
|
||||
rx="1"
|
||||
fill="#1e1e2e"
|
||||
stroke="#6c7086"
|
||||
stroke-width="1"
|
||||
id="rect2" />
|
||||
<!-- Slider notch -->
|
||||
<rect x="17" y="7" width="2" height="6" fill="#313244"/>
|
||||
<rect
|
||||
x="17"
|
||||
y="7"
|
||||
width="2"
|
||||
height="6"
|
||||
fill="#313244"
|
||||
id="rect3" />
|
||||
<!-- Label area -->
|
||||
<rect x="9" y="17" width="14" height="7" rx="1" fill="#cdd6f4"/>
|
||||
<!-- Pencil icon for "save as" -->
|
||||
<g transform="translate(18, 14)">
|
||||
<path d="M6 2 L8 0 L10 2 L4 8 L2 8 L2 6 Z" fill="#f9e2af" stroke="#fab387" stroke-width="0.5"/>
|
||||
</g>
|
||||
<rect
|
||||
x="9"
|
||||
y="17"
|
||||
width="14"
|
||||
height="7"
|
||||
rx="1"
|
||||
fill="#cdd6f4"
|
||||
id="rect4" />
|
||||
<!-- Pencil badge for "save as" -->
|
||||
<circle
|
||||
cx="24"
|
||||
cy="24"
|
||||
r="5"
|
||||
fill="#f9e2af"
|
||||
id="circle1" />
|
||||
<path
|
||||
d="M 22,26 22,24 26,20 28,22 24,26 Z"
|
||||
fill="#1e1e2e"
|
||||
id="path2" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 738 B After Width: | Height: | Size: 1.1 KiB |
@@ -1,14 +1,71 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="2" y="2" width="28" height="28" rx="4" fill="#313244"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<rect
|
||||
x="2"
|
||||
y="2"
|
||||
width="28"
|
||||
height="28"
|
||||
rx="4"
|
||||
fill="#313244"
|
||||
id="rect1" />
|
||||
<!-- Floppy disk body -->
|
||||
<path d="M7 6 L7 26 L25 26 L25 10 L21 6 Z" fill="#45475a" stroke="#89b4fa" stroke-width="1.5"/>
|
||||
<path
|
||||
d="M 7,6 H 21 L 25,10 V 26 H 7 Z"
|
||||
fill="#45475a"
|
||||
stroke="#89b4fa"
|
||||
stroke-width="1.5"
|
||||
id="path1"
|
||||
style="stroke-linejoin:round" />
|
||||
<!-- Metal slider -->
|
||||
<rect x="10" y="6" width="10" height="8" rx="1" fill="#1e1e2e" stroke="#6c7086" stroke-width="1"/>
|
||||
<rect
|
||||
x="10"
|
||||
y="6"
|
||||
width="10"
|
||||
height="8"
|
||||
rx="1"
|
||||
fill="#1e1e2e"
|
||||
stroke="#6c7086"
|
||||
stroke-width="1"
|
||||
id="rect2" />
|
||||
<!-- Slider notch -->
|
||||
<rect x="17" y="7" width="2" height="6" fill="#313244"/>
|
||||
<rect
|
||||
x="17"
|
||||
y="7"
|
||||
width="2"
|
||||
height="6"
|
||||
fill="#313244"
|
||||
id="rect3" />
|
||||
<!-- Label area -->
|
||||
<rect x="9" y="17" width="14" height="7" rx="1" fill="#cdd6f4"/>
|
||||
<rect
|
||||
x="9"
|
||||
y="17"
|
||||
width="14"
|
||||
height="7"
|
||||
rx="1"
|
||||
fill="#cdd6f4"
|
||||
id="rect4" />
|
||||
<!-- Label lines -->
|
||||
<line x1="11" y1="19" x2="21" y2="19" stroke="#313244" stroke-width="1" stroke-linecap="round"/>
|
||||
<line x1="11" y1="22" x2="17" y2="22" stroke="#313244" stroke-width="1" stroke-linecap="round"/>
|
||||
<line
|
||||
x1="11"
|
||||
y1="19.5"
|
||||
x2="21"
|
||||
y2="19.5"
|
||||
stroke="#313244"
|
||||
stroke-width="1"
|
||||
stroke-linecap="round"
|
||||
id="line1" />
|
||||
<line
|
||||
x1="11"
|
||||
y1="22"
|
||||
x2="17"
|
||||
y2="22"
|
||||
stroke="#313244"
|
||||
stroke-width="1"
|
||||
stroke-linecap="round"
|
||||
id="line2" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 779 B After Width: | Height: | Size: 1.3 KiB |
@@ -1,3 +1,15 @@
|
||||
# Configure ccache to use a shared cache directory that persists across CI runs.
|
||||
# The workflow caches /tmp/ccache-kindred-create between builds.
|
||||
export CCACHE_DIR="${CCACHE_DIR:-/tmp/ccache-kindred-create}"
|
||||
export CCACHE_BASEDIR="${SRC_DIR:-$(pwd)}"
|
||||
export CCACHE_COMPRESS="${CCACHE_COMPRESS:-true}"
|
||||
export CCACHE_COMPRESSLEVEL="${CCACHE_COMPRESSLEVEL:-6}"
|
||||
export CCACHE_MAXSIZE="${CCACHE_MAXSIZE:-4G}"
|
||||
export CCACHE_SLOPPINESS="${CCACHE_SLOPPINESS:-include_file_ctime,include_file_mtime,pch_defines,time_macros}"
|
||||
mkdir -p "$CCACHE_DIR"
|
||||
echo "ccache config: CCACHE_DIR=$CCACHE_DIR CCACHE_BASEDIR=$CCACHE_BASEDIR"
|
||||
ccache -z || true
|
||||
|
||||
if [[ ${HOST} =~ .*linux.* ]]; then
|
||||
CMAKE_PRESET=conda-linux-release
|
||||
fi
|
||||
@@ -46,3 +58,6 @@ cmake --install build
|
||||
|
||||
mv ${PREFIX}/bin/FreeCAD ${PREFIX}/bin/freecad || true
|
||||
mv ${PREFIX}/bin/FreeCADCmd ${PREFIX}/bin/freecadcmd || true
|
||||
|
||||
echo "=== ccache statistics ==="
|
||||
ccache -s || true
|
||||
|
||||
@@ -59,6 +59,10 @@ sed -i "1s/.*/\nLIST OF PACKAGES:/" AppDir/packages.txt
|
||||
curl -LO https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-$(uname -m).AppImage
|
||||
chmod a+x appimagetool-$(uname -m).AppImage
|
||||
|
||||
# Extract appimagetool so it works in containers without FUSE
|
||||
./appimagetool-$(uname -m).AppImage --appimage-extract > /dev/null 2>&1
|
||||
APPIMAGETOOL=squashfs-root/AppRun
|
||||
|
||||
if [ "${UPLOAD_RELEASE}" == "true" ]; then
|
||||
case "${BUILD_TAG}" in
|
||||
*weekly*)
|
||||
@@ -76,7 +80,7 @@ fi
|
||||
echo -e "\nCreate the appimage"
|
||||
# export GPG_TTY=$(tty)
|
||||
chmod a+x ./AppDir/AppRun
|
||||
./appimagetool-$(uname -m).AppImage \
|
||||
${APPIMAGETOOL} \
|
||||
--comp zstd \
|
||||
--mksquashfs-opt -Xcompression-level \
|
||||
--mksquashfs-opt 22 \
|
||||
|
||||
@@ -18,6 +18,7 @@ requirements:
|
||||
- cmake
|
||||
- compilers>=1.10,<1.11
|
||||
- doxygen
|
||||
- icu>=75,<76
|
||||
- ninja
|
||||
- noqt5
|
||||
- python>=3.11,<3.12
|
||||
@@ -102,6 +103,7 @@ requirements:
|
||||
- fmt
|
||||
- freetype
|
||||
- hdf5
|
||||
- icu>=75,<76
|
||||
- lark
|
||||
- libboost-devel
|
||||
- matplotlib-base
|
||||
|
||||
@@ -25,6 +25,7 @@ freetype = "*"
|
||||
git = "*"
|
||||
graphviz = "*"
|
||||
hdf5 = "*"
|
||||
icu = ">=75,<76"
|
||||
ifcopenshell = "*"
|
||||
lark = "*"
|
||||
libboost-devel = "*"
|
||||
|
||||
2
src/3rdParty/OndselSolver
vendored
@@ -54,8 +54,9 @@ void OriginSelectorWidget::setupUi()
|
||||
{
|
||||
setPopupMode(QToolButton::InstantPopup);
|
||||
setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
setMinimumWidth(70);
|
||||
setMaximumWidth(120);
|
||||
setMinimumWidth(80);
|
||||
setMaximumWidth(160);
|
||||
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||||
|
||||
// Create menu
|
||||
m_menu = new QMenu(this);
|
||||
|
||||
@@ -33,7 +33,13 @@ install(
|
||||
# Install Silo addon
|
||||
install(
|
||||
DIRECTORY
|
||||
${CMAKE_SOURCE_DIR}/mods/silo/pkg/freecad/
|
||||
${CMAKE_SOURCE_DIR}/mods/silo/freecad/
|
||||
DESTINATION
|
||||
mods/silo/pkg/freecad
|
||||
mods/silo/freecad
|
||||
)
|
||||
install(
|
||||
DIRECTORY
|
||||
${CMAKE_SOURCE_DIR}/mods/silo/silo-client/
|
||||
DESTINATION
|
||||
mods/silo/silo-client
|
||||
)
|
||||
|
||||
@@ -16,7 +16,7 @@ def setup_kindred_addons():
|
||||
# Define built-in addons with their paths relative to mods/
|
||||
addons = [
|
||||
("ztools", "ztools/ztools"), # mods/ztools/ztools/
|
||||
("silo", "silo/pkg/freecad"), # mods/silo/pkg/freecad/
|
||||
("silo", "silo/freecad"), # mods/silo/freecad/
|
||||
]
|
||||
|
||||
for name, subpath in addons:
|
||||
|
||||
@@ -15,7 +15,7 @@ def setup_kindred_workbenches():
|
||||
|
||||
addons = [
|
||||
("ztools", "ztools/ztools"),
|
||||
("silo", "silo/pkg/freecad"),
|
||||
("silo", "silo/freecad"),
|
||||
]
|
||||
|
||||
for name, subpath in addons:
|
||||
|
||||