Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7251938294 |
No files matched your search
@@ -1,12 +1,8 @@
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
node_modules
|
||||
**/node_modules
|
||||
npm-debug.log
|
||||
README.md
|
||||
.next
|
||||
.turbo
|
||||
.git
|
||||
dev
|
||||
.build
|
||||
e2e
|
||||
dev
|
||||
@@ -4,20 +4,6 @@
|
||||
# This file will be committed to version control, so make sure not to have any secrets in it.
|
||||
# If you are cloning this repo, create a copy of this file named `.env` and populate it with your secrets.
|
||||
|
||||
# The below secret is not used anywhere but required for Auth.js (Would encrypt JWTs and Mail hashes, both not used)
|
||||
AUTH_SECRET="supersecret"
|
||||
|
||||
# The below secret is used to encrypt integration secrets in the database.
|
||||
# It should be a 32-byte string, generated by running `openssl rand -hex 32` on Unix
|
||||
# or starting the project without any (which will show a randomly generated one).
|
||||
SECRET_ENCRYPTION_KEY=0000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
# Cron job API key is generated every time the container starts as it is required for communication between nextjs-api and tasks-api
|
||||
# export CRON_JOB_API_KEY=$(openssl rand -base64 32)
|
||||
# CRON_JOB_API_KEY="your-generated-api-key"
|
||||
|
||||
LOG_LEVEL='info'
|
||||
|
||||
# This is how you can use the sqlite driver:
|
||||
DB_DRIVER='better-sqlite3'
|
||||
DB_URL='FULL_PATH_TO_YOUR_SQLITE_DB_FILE'
|
||||
@@ -34,19 +20,14 @@ DB_URL='FULL_PATH_TO_YOUR_SQLITE_DB_FILE'
|
||||
# DB_PASSWORD='password'
|
||||
# DB_NAME='name-of-database'
|
||||
|
||||
# The following is an example on how to use the node-postgres driver:
|
||||
# DB_DRIVER='node-postgres'
|
||||
# DB_URL='postgres://user:password@host:port/database'
|
||||
# @see https://next-auth.js.org/configuration/options#nextauth_url
|
||||
AUTH_URL='http://localhost:3000'
|
||||
|
||||
# The below path can be used to store trusted certificates, it is not required and can be left empty.
|
||||
# If it is empty, it will default to `/appdata/trusted-certificates` in production.
|
||||
# If it is used, please use the full path to the directory where the certificates are stored.
|
||||
# LOCAL_CERTIFICATE_PATH='FULL_PATH_TO_CERTIFICATES'
|
||||
# You can generate the secret via 'openssl rand -base64 32' on Unix
|
||||
# @see https://next-auth.js.org/configuration/options#secret
|
||||
AUTH_SECRET='supersecret'
|
||||
|
||||
TURBO_TELEMETRY_DISABLED=1
|
||||
|
||||
# Enable kubernetes tool
|
||||
# ENABLE_KUBERNETES=true
|
||||
|
||||
# Enable mock integration
|
||||
UNSAFE_ENABLE_MOCK_INTEGRATION=true
|
||||
# Configure logging to use winston logger
|
||||
NODE_OPTIONS='-r @homarr/log/override'
|
||||
@@ -1 +0,0 @@
|
||||
* text=auto eol=lf
|
||||
@@ -1,153 +1,37 @@
|
||||
name: 🐞 Bug Report
|
||||
description: Report that something is broken, not working as intended or causes side-effects
|
||||
description: Create a bug report to help us improve
|
||||
title: "bug: "
|
||||
labels: ["needs triage"]
|
||||
labels: ["🐞❔ unconfirmed bug"]
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Provide environment information
|
||||
description: |
|
||||
Run this command in your project root and paste the results in a code block:
|
||||
```bash
|
||||
npx envinfo --system --binaries
|
||||
```
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of the bug, as well as what you expected to happen when encountering it.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
- type: input
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Describe how to reproduce your bug. Steps, code snippets, reproduction repos etc.
|
||||
label: Link to reproduction
|
||||
description: Please provide a link to a reproduction of the bug. Issues without a reproduction repo may be ignored.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Impact
|
||||
description: How big is the impact of this bug? Does it make Homarr unusable? Is there any workaround that you're aware of?
|
||||
label: To reproduce
|
||||
description: Describe how to reproduce your bug. Steps, code snippets, reproduction repos etc.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional information
|
||||
description: Add any other information related to the bug here, screenshots if applicable.
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: What version of Homarr are you running?
|
||||
options:
|
||||
# The below comment is used to insert a new version with on-release.yml
|
||||
#NEXT_VERSION#
|
||||
- 1.56.1
|
||||
- 1.56.0
|
||||
- 1.55.0
|
||||
- 1.54.0
|
||||
- 1.53.0
|
||||
- 1.52.0
|
||||
- 1.51.0
|
||||
- 1.50.1
|
||||
- 1.50.0
|
||||
- 1.49.1
|
||||
- 1.49.0
|
||||
- 1.48.0
|
||||
- 1.47.0
|
||||
- 1.46.0
|
||||
- 1.45.3
|
||||
- 1.45.2
|
||||
- 1.45.1
|
||||
- 1.45.0
|
||||
- 1.44.0
|
||||
- 1.43.1
|
||||
- 1.43.0
|
||||
- 1.42.1
|
||||
- 1.42.0
|
||||
- 1.41.0
|
||||
- 1.40.0
|
||||
- 1.39.0
|
||||
- 1.38.0
|
||||
- 1.37.0
|
||||
- 1.36.1
|
||||
- 1.36.0
|
||||
- 1.35.1
|
||||
- 1.35.0
|
||||
- 1.34.0
|
||||
- 1.33.0
|
||||
- 1.32.0
|
||||
- 1.31.0
|
||||
- 1.30.1
|
||||
- 1.30.0
|
||||
- 1.29.0
|
||||
- 1.28.1
|
||||
- 1.28.0
|
||||
- 1.27.0
|
||||
- 1.26.0
|
||||
- 1.25.0
|
||||
- 1.24.0
|
||||
- 1.23.0
|
||||
- 1.22.0
|
||||
- 1.21.0
|
||||
- 1.20.0
|
||||
- 1.19.1
|
||||
- 1.19.0
|
||||
- 1.18.0
|
||||
- 1.17.0
|
||||
- 1.16.0
|
||||
- 1.15.0
|
||||
- 1.14.0
|
||||
- 1.13.1
|
||||
- 1.13.0
|
||||
- 1.12.0
|
||||
- 1.11.0
|
||||
- 1.10.0
|
||||
- 1.9.0
|
||||
- 1.8.0
|
||||
- 1.7.0
|
||||
- 1.6.0
|
||||
- 1.5.0
|
||||
- 1.4.0
|
||||
- 1.3.1
|
||||
- 1.3.0
|
||||
- 1.2.0
|
||||
- 1.1.0
|
||||
- 1.0.1
|
||||
- 1.0.0
|
||||
- 1.0.0-beta
|
||||
- Other (describe in "additional information")
|
||||
default: 0
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: installationMethod
|
||||
attributes:
|
||||
label: Installation method
|
||||
description: How do you run Homarr? Post docker-compose, configs or screenshots if applicable.
|
||||
options:
|
||||
- Docker Run
|
||||
- Docker Compose
|
||||
- Portainer
|
||||
- Helm
|
||||
- QNAP
|
||||
- Saltbox
|
||||
- EasyPanel
|
||||
- Unraid Apps
|
||||
- TrueNAS Apps
|
||||
- Synology
|
||||
- HomeAssistant Addon
|
||||
- From Source
|
||||
- Other (describe in "additional information")
|
||||
default: 0
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: browser
|
||||
attributes:
|
||||
label: Browser
|
||||
description: If relevant, what browser do you use?
|
||||
options:
|
||||
- Firefox
|
||||
- Edge (Chromium)
|
||||
- Edge (Proprietary)
|
||||
- Chrome
|
||||
- Safari
|
||||
- Vivaldi
|
||||
- Brave
|
||||
- Samsung Internet
|
||||
- Other (describe in "additional information")
|
||||
default: 0
|
||||
validations:
|
||||
required: false
|
||||
@@ -2,16 +2,26 @@
|
||||
# See here: https://github.com/vercel/next.js/blob/canary/.github/ISSUE_TEMPLATE/3.feature_request.yml
|
||||
|
||||
name: 🛠 Feature Request
|
||||
description: Request a new feature that you would like to have implemented
|
||||
description: Create a feature request for the core packages
|
||||
title: "feat: "
|
||||
labels: ["needs triage"]
|
||||
labels: ["✨ enhancement"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thank you for taking the time to file a feature request. Please fill out this form as completely as possible.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the feature you'd like to request
|
||||
description: Please describe the feature as clear and concise as possible. Remember to add context as to why you believe this feature is needed.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the solution you'd like to see
|
||||
description: Please describe the solution you would like to see. Adding example usage is a good way to provide context.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional information
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
name: 🛠 Integration request
|
||||
description: Request support for a new integration (eg. Sonarr, Radarr)
|
||||
title: "feat: "
|
||||
labels: ["needs triage"]
|
||||
body:
|
||||
- type: input
|
||||
attributes:
|
||||
label: Project Website
|
||||
description: Post the link to the website of the application. Paste the official link.
|
||||
placeholder: ex. https://sonarr.tv/
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe what data should be consumed by Homarr
|
||||
description: Please describe what data Homarr should fetch from the integration. Specify in what interval data should be fetched and whether the user can also perform write operations (eg. deleting a movie or adding a user).
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional information
|
||||
description: Add any other information related to the integration.
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Public API available?
|
||||
description: Is there a public API available, that we can consume in Homarr?
|
||||
options:
|
||||
- Yes, available on a website
|
||||
- Yes, available in the application itself
|
||||
- No
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Are you willing to contribute this yourself?
|
||||
options:
|
||||
- Yes
|
||||
- No
|
||||
validations:
|
||||
required: true
|
||||
@@ -1,30 +0,0 @@
|
||||
name: 🛠 Widget request
|
||||
description: Request a new widget (eg. Clock, Calendar, ...)
|
||||
title: "feat: "
|
||||
labels: ["needs triage"]
|
||||
body:
|
||||
- type: input
|
||||
attributes:
|
||||
label: Compatible integrations
|
||||
description: Post a list of the integrations that should be compatible with this widget. Divide using comma. Leave empty if no integration is needed.
|
||||
placeholder: ex. Sonarr, Radarr, Lidarr, Readarr, Nextcloud
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe what data should be displayed
|
||||
description: Please describe what data Homarr should display. Describe how elements should be intractable and what actions the user can perform.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional information
|
||||
description: Add any other information related to the widget.
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Are you willing to contribute this yourself?
|
||||
options:
|
||||
- Yes
|
||||
- No
|
||||
validations:
|
||||
required: true
|
||||
@@ -1,64 +0,0 @@
|
||||
name: Extract Build Artifact
|
||||
description: Extracts artifacts from an existing Docker image to be used for from source installation
|
||||
inputs:
|
||||
digest:
|
||||
description: Digest of Docker image to use
|
||||
required: true
|
||||
architecture:
|
||||
description: Name of architecture, will be used to build artifact content (amd64 or arm64)
|
||||
required: true
|
||||
release-tag:
|
||||
description: Tag of the release to which the artifact will be attached
|
||||
required: true
|
||||
repository:
|
||||
description: Repository to which the release belongs, e.g. owner/repo
|
||||
required: true
|
||||
token:
|
||||
description: GitHub token with permissions to upload release assets
|
||||
required: true
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Prebuilt debian dependencies
|
||||
uses: homarr-labs/homarr/.github/actions/prebuilt-debian@dev
|
||||
id: prebuilt-debian
|
||||
with:
|
||||
architecture: ${{ inputs.architecture }}
|
||||
- name: Start docker container for ${{ inputs.architecture }}
|
||||
run: |
|
||||
docker run --name homarr \
|
||||
-e "SECRET_ENCRYPTION_KEY=0000000000000000000000000000000000000000000000000000000000000000" \
|
||||
--detach --rm ${{ inputs.digest }}
|
||||
shell: bash
|
||||
- name: Prepare extraction
|
||||
run: |
|
||||
docker exec homarr cp /etc/nginx/templates/nginx.conf /app && \
|
||||
mkdir -p ${{ runner.temp }}/extraction/${{ inputs.architecture }}
|
||||
shell: bash
|
||||
- name: Extract source from ${{ inputs.architecture }} container (alpine)
|
||||
run: |
|
||||
docker exec homarr tar -czf extraction-alpine.tar.gz -C /app . && \
|
||||
docker cp homarr:/app/extraction-alpine.tar.gz ${{ runner.temp }}/extraction/${{ inputs.architecture }}/build-alpine-${{ inputs.architecture }}.tar.gz && \
|
||||
docker exec homarr rm /app/extraction-alpine.tar.gz
|
||||
shell: bash
|
||||
- name: Extract source from ${{ inputs.architecture }} container (debian)
|
||||
run: |
|
||||
docker cp ${{ steps.prebuilt-debian.outputs.path }}/. homarr:/app/build && \
|
||||
docker cp ${{ steps.prebuilt-debian.outputs.path }}/. homarr:/app/node_modules/better-sqlite3/build/Release && \
|
||||
docker exec homarr tar -czf extraction-debian.tar.gz -C /app . && \
|
||||
docker cp homarr:/app/extraction-debian.tar.gz ${{ runner.temp }}/extraction/${{ inputs.architecture }}/build-debian-${{ inputs.architecture }}.tar.gz
|
||||
shell: bash
|
||||
- name: Stop ${{ inputs.architecture }} container
|
||||
if: always()
|
||||
run: docker container remove --force --volumes homarr
|
||||
shell: bash
|
||||
- name: Add build archive to release (alpine)
|
||||
env:
|
||||
GH_TOKEN: ${{ inputs.token }}
|
||||
run: gh release upload --repo ${{ inputs.repository }} ${{ inputs.release-tag }} ${{ runner.temp }}/extraction/${{ inputs.architecture }}/build-alpine-${{ inputs.architecture }}.tar.gz --clobber
|
||||
shell: bash
|
||||
- name: Add build archive to release (debian)
|
||||
env:
|
||||
GH_TOKEN: ${{ inputs.token }}
|
||||
run: gh release upload --repo ${{ inputs.repository }} ${{ inputs.release-tag }} ${{ runner.temp }}/extraction/${{ inputs.architecture }}/build-debian-${{ inputs.architecture }}.tar.gz --clobber
|
||||
shell: bash
|
||||
@@ -1,42 +0,0 @@
|
||||
name: Prebuilt dependencies for debian
|
||||
description: Provides prebuilt dependencies for debian based docker images
|
||||
inputs:
|
||||
architecture:
|
||||
description: Name of architecture, will be used to build docker image (e.g. amd64, arm64)
|
||||
required: true
|
||||
outputs:
|
||||
path:
|
||||
description: Path to extracted prebuilt dependencies
|
||||
value: ${{ runner.temp }}/prebuilts
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build docker image for ${{ inputs.architecture }}
|
||||
id: build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
push: false
|
||||
load: true
|
||||
context: ./deployments/prebuilt-debian
|
||||
platforms: linux/${{ inputs.architecture }}
|
||||
tags: prebuilt-debian
|
||||
- name: Start docker container for ${{ inputs.architecture }}
|
||||
run: |
|
||||
docker run --name prebuilt-debian \
|
||||
--detach --rm prebuilt-debian
|
||||
shell: bash
|
||||
- name: Extract prebuilt dependencies from ${{ inputs.architecture }} container
|
||||
run: |
|
||||
mkdir -p ${{ runner.temp }}/prebuilts && \
|
||||
docker cp prebuilt-debian:/app/node_modules/better-sqlite3/build/Release/better_sqlite3.node ${{ runner.temp }}/prebuilts/better_sqlite3.node
|
||||
shell: bash
|
||||
- name: Stop ${{ inputs.architecture }} container
|
||||
if: always()
|
||||
run: docker container remove --force --volumes prebuilt-debian
|
||||
shell: bash
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
**Thank you for your contribution. Please ensure that your pull request meets the following pull request:**
|
||||
|
||||
- [ ] Builds without warnings or errors (`pnpm build`, autofix with `pnpm format:fix`)
|
||||
- [ ] Pull request targets `dev` branch
|
||||
- [ ] Builds without warnings or errors (``pnpm buid``, autofix with ``pnpm format:fix``)
|
||||
- [ ] Pull request targets ``dev`` branch
|
||||
- [ ] Commits follow the [conventional commits guideline](https://www.conventionalcommits.org/en/v1.0.0/)
|
||||
- [ ] No shorthand variable names are used (eg. `x`, `y`, `i` or any abbrevation)
|
||||
- [ ] Documentation is up to date. Create a pull request [here](https://github.com/homarr-labs/documentation/).
|
||||
- [ ] No shorthand variable names are used (eg. ``x``, ``y``, ``i`` or any abbrevation)
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": ["config:recommended"],
|
||||
"packageRules": [
|
||||
{
|
||||
"matchPackagePatterns": ["^@homarr/"],
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"updateInternalDeps": true,
|
||||
"rangeStrategy": "bump",
|
||||
"automerge": false,
|
||||
"baseBranches": ["dev"],
|
||||
"dependencyDashboard": false
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
{
|
||||
$schema: "https://docs.renovatebot.com/renovate-schema.json",
|
||||
extends: ["config:recommended"],
|
||||
packageRules: [
|
||||
{
|
||||
matchPackageNames: ["^@homarr/"],
|
||||
enabled: false,
|
||||
},
|
||||
// Reenable once https://github.com/privatenumber/tsx/issues/737 is fixed
|
||||
{
|
||||
matchPackageNames: ["tsx"],
|
||||
enabled: false,
|
||||
},
|
||||
{
|
||||
matchUpdateTypes: ["minor", "patch", "pin", "digest"],
|
||||
automerge: true,
|
||||
},
|
||||
{
|
||||
// disallow automerge for onlyBuiltDependencies
|
||||
matchPackageNames: [
|
||||
"@tree-sitter-grammars/tree-sitter-yaml",
|
||||
"bcrypt",
|
||||
"better-sqlite3",
|
||||
"cpu-features",
|
||||
"esbuild",
|
||||
"sharp",
|
||||
"ssh2",
|
||||
"tree-sitter",
|
||||
"tree-sitter-json",
|
||||
],
|
||||
automerge: false,
|
||||
},
|
||||
],
|
||||
updateInternalDeps: true,
|
||||
rangeStrategy: "bump",
|
||||
automerge: false,
|
||||
baseBranches: ["dev"],
|
||||
dependencyDashboard: false,
|
||||
// prevent special characters in branch names (otherwise git errors occur on windows)
|
||||
branchNameStrict: true,
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
name: "[Dependency Updates] Auto Approve"
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
approve-automatic-prs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 2
|
||||
if: github.actor_id == 158783068 || github.actor_id == 190541745 || github.actor_id == 210161987 # Id of renovate bot and crowdin bot see https://api.github.com/users/homarr-renovate%5Bbot%5D and https://api.github.com/users/homarr-crowdin%5Bbot%5D and https://api.github.com/users/homarr-update-contributors%5Bbot%5D
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
- name: Obtain token
|
||||
id: obtainToken
|
||||
uses: actions/create-github-app-token@v2
|
||||
with:
|
||||
private-key: ${{ secrets.RENOVATE_APPROVE_PRIVATE_KEY }}
|
||||
app-id: ${{ secrets.RENOVATE_APPROVE_APP_ID }}
|
||||
permission-pull-requests: write # required to approve pull request
|
||||
|
||||
- name: Install GitHub CLI
|
||||
run: sudo apt-get install -y gh
|
||||
- name: Approve automatic PRs
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
|
||||
run: |
|
||||
gh pr review ${{github.event.pull_request.number}} --approve --body "Automatically approved by GitHub Action"
|
||||
@@ -0,0 +1,31 @@
|
||||
name: Build apps and migration script
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: ["*"]
|
||||
push:
|
||||
branches: ["main"]
|
||||
merge_group:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 3
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup
|
||||
uses: ./tooling/github/setup
|
||||
|
||||
- name: Copy env
|
||||
shell: bash
|
||||
run: cp .env.example .env
|
||||
|
||||
- name: Build
|
||||
run: pnpm build
|
||||
@@ -1,6 +1,4 @@
|
||||
name: "[Quality] Code Analysis"
|
||||
permissions:
|
||||
contents: read
|
||||
name: Code quality analysis
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -10,7 +8,7 @@ on:
|
||||
merge_group:
|
||||
|
||||
concurrency:
|
||||
group: "${{ github.workflow }}-${{ github.ref }}"
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
|
||||
|
||||
# You can leverage Vercel Remote Caching with Turbo to speed up your builds
|
||||
@@ -23,9 +21,8 @@ env:
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup
|
||||
uses: ./tooling/github/setup
|
||||
@@ -39,9 +36,8 @@ jobs:
|
||||
|
||||
format:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup
|
||||
uses: ./tooling/github/setup
|
||||
@@ -51,9 +47,8 @@ jobs:
|
||||
|
||||
typecheck:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup
|
||||
uses: ./tooling/github/setup
|
||||
@@ -63,56 +58,11 @@ jobs:
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup
|
||||
uses: ./tooling/github/setup
|
||||
|
||||
- name: Test
|
||||
run: pnpm test
|
||||
|
||||
- name: "Report Coverage"
|
||||
# Set if: always() to also generate the report if tests are failing
|
||||
# Only works if you set `reportOnFailure: true` in your vite config as specified above
|
||||
if: always()
|
||||
uses: davelosert/vitest-coverage-report-action@v2
|
||||
|
||||
e2e:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Setup
|
||||
uses: ./tooling/github/setup
|
||||
- name: Build docker image
|
||||
id: build-docker-image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
platforms: linux/amd64
|
||||
context: .
|
||||
push: false
|
||||
tags: homarr-e2e
|
||||
network: host
|
||||
env:
|
||||
SKIP_ENV_VALIDATION: true
|
||||
- name: Install playwright browsers
|
||||
run: pnpm exec playwright install chromium
|
||||
- name: Run E2E Tests
|
||||
shell: bash
|
||||
run: pnpm test:e2e
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Setup
|
||||
uses: ./tooling/github/setup
|
||||
- name: Copy env
|
||||
shell: bash
|
||||
run: cp .env.example .env
|
||||
- name: Build
|
||||
run: pnpm build
|
||||
@@ -1,20 +0,0 @@
|
||||
name: "[Conventions] Semantic PRs"
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
permissions:
|
||||
pull-requests: read
|
||||
|
||||
jobs:
|
||||
validate-pull-request-title:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 1
|
||||
steps:
|
||||
- uses: amannn/action-semantic-pull-request@v6
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,55 +0,0 @@
|
||||
name: "[Crowdin] Download translations"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 0 * * *" # every day at midnight
|
||||
|
||||
permissions:
|
||||
contents: write # required to push changes
|
||||
|
||||
jobs:
|
||||
download-crowdin-translations:
|
||||
timeout-minutes: 5
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Obtain token
|
||||
id: obtainToken
|
||||
uses: actions/create-github-app-token@v2
|
||||
with:
|
||||
private-key: ${{ secrets.CROWDIN_APP_PRIVATE_KEY }}
|
||||
app-id: ${{ secrets.CROWDIN_APP_ID }}
|
||||
permission-contents: write # required to commit to crowdin branch
|
||||
permission-pull-requests: write # required to create pull request
|
||||
|
||||
- name: Download Crowdin translations
|
||||
id: crowdin-download
|
||||
uses: crowdin/github-action@v2
|
||||
with:
|
||||
upload_sources: false
|
||||
upload_translations: false
|
||||
download_translations: true
|
||||
localization_branch_name: crowdin
|
||||
create_pull_request: true
|
||||
pull_request_title: "chore(lang): updated translations from crowdin"
|
||||
pull_request_body: "New Crowdin translations by [Crowdin GH Action](https://github.com/crowdin/github-action)"
|
||||
commit_message: "chore(lang): update translations from crowdin"
|
||||
pull_request_base_branch_name: "dev"
|
||||
github_user_name: "Crowdin Homarr"
|
||||
github_user_email: "190541745+homarr-crowdin[bot]@users.noreply.github.com"
|
||||
skip_untranslated_strings: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
|
||||
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
|
||||
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
||||
|
||||
- name: Enable auto-merge
|
||||
if: steps.crowdin-download.outputs.pull_request_number != '' && steps.crowdin-download.outputs.pull_request_number != null
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
|
||||
run: |
|
||||
gh pr merge ${{steps.crowdin-download.outputs.pull_request_number}} --auto --squash --delete-branch --subject "chore(lang): updated translations from crowdin"
|
||||
@@ -1,31 +0,0 @@
|
||||
name: "[Crowdin] Upload translations"
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- "packages/translation/src/lang/**"
|
||||
branches: [dev]
|
||||
|
||||
jobs:
|
||||
upload-crowdin-translations:
|
||||
# Don't run this action if the downloaded translations are being pushed
|
||||
if: "!contains(github.event.head_commit.message, 'chore(lang)')"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Upload Crowdin translations
|
||||
uses: crowdin/github-action@v2
|
||||
with:
|
||||
upload_sources: true
|
||||
upload_translations: true
|
||||
download_translations: false
|
||||
env:
|
||||
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
|
||||
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
||||
@@ -1,279 +0,0 @@
|
||||
name: "[Deployment] Release"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- beta
|
||||
- dev
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
send-notifications:
|
||||
type: boolean
|
||||
required: false
|
||||
default: true
|
||||
description: Send notifications
|
||||
|
||||
permissions:
|
||||
contents: write # Required to update package.json version
|
||||
packages: write # Required for pushing to GHCR
|
||||
|
||||
env:
|
||||
SKIP_ENV_VALIDATION: true
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
GHCR_REPO: ghcr.io/${{ github.repository }}
|
||||
TURBO_TELEMETRY_DISABLED: 1
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref_name }}
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: Create tag and release
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
env:
|
||||
SKIP_RELEASE: ${{ github.event_name == 'workflow_dispatch' || github.ref_name == 'dev' }}
|
||||
outputs:
|
||||
version: ${{ steps.read-semver.outputs.version || steps.version-fallback.outputs.version }}
|
||||
git_ref: ${{ steps.read-git-ref.outputs.ref || github.ref }}
|
||||
skipped: ${{ env.SKIP_RELEASE }}
|
||||
steps:
|
||||
- run: echo "Skipping release for workflow_dispatch event"
|
||||
if: env.SKIP_RELEASE == 'true'
|
||||
# The below generated version fallback represents a normalized branch name, for example "feature/branch-name" -> "feature-branch-name"
|
||||
- run: echo "version="$(echo ${{github.ref_name}} | sed 's/[^a-zA-Z0-9\-]/-/g') >> "$GITHUB_OUTPUT"
|
||||
id: version-fallback
|
||||
if: env.SKIP_RELEASE == 'true' && github.ref_name != 'main' && github.ref_name != 'beta'
|
||||
|
||||
- name: Obtain token
|
||||
if: env.SKIP_RELEASE == 'false'
|
||||
id: obtainToken
|
||||
uses: actions/create-github-app-token@v2
|
||||
with:
|
||||
private-key: ${{ secrets.RENOVATE_MERGE_PRIVATE_KEY }}
|
||||
app-id: ${{ secrets.RENOVATE_MERGE_APP_ID }}
|
||||
permission-contents: write # required to commit package.json & changelog changes, merge them to dev and publish the release
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
if: env.SKIP_RELEASE == 'false'
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: pnpm/action-setup@v4
|
||||
if: env.SKIP_RELEASE == 'false'
|
||||
- uses: actions/setup-node@v6
|
||||
if: env.SKIP_RELEASE == 'false'
|
||||
with:
|
||||
node-version: 24.14.0
|
||||
cache: "pnpm"
|
||||
- run: npm i -g pnpm
|
||||
if: env.SKIP_RELEASE == 'false'
|
||||
- name: Install dependencies
|
||||
if: env.SKIP_RELEASE == 'false'
|
||||
run: |
|
||||
pnpm install
|
||||
- name: Run Semantic Release
|
||||
if: env.SKIP_RELEASE == 'false'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
|
||||
GIT_AUTHOR_NAME: "Releases Homarr"
|
||||
GIT_AUTHOR_EMAIL: "175486441+homarr-releases[bot]@users.noreply.github.com"
|
||||
GIT_COMMITTER_NAME: "Releases Homarr"
|
||||
GIT_COMMITTER_EMAIL: "175486441+homarr-releases[bot]@users.noreply.github.com"
|
||||
run: |
|
||||
pnpm release
|
||||
- name: Read semver output
|
||||
# We read the last tag either from the created release or from the current branch, this is to rerun the deployment job for the currently released version when it failed
|
||||
if: env.SKIP_RELEASE == 'false' || github.ref_name == 'main' || github.ref_name == 'beta'
|
||||
id: read-semver
|
||||
run: |
|
||||
git fetch --tags
|
||||
echo "version=$(git describe --tags --abbrev=0)" >> "$GITHUB_OUTPUT"
|
||||
- name: Read git ref
|
||||
if: env.SKIP_RELEASE == 'false'
|
||||
id: read-git-ref
|
||||
run: |
|
||||
echo "ref=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
|
||||
- name: Update dev branch
|
||||
if: env.SKIP_RELEASE == 'false'
|
||||
continue-on-error: true # Prevent pipeline from failing when merge fails
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
|
||||
run: |
|
||||
git config user.name "Releases Homarr"
|
||||
git config user.email "175486441+homarr-releases[bot]@users.noreply.github.com"
|
||||
git remote set-url origin https://x-access-token:${{ steps.obtainToken.outputs.token }}@github.com/${{ github.repository }}.git
|
||||
git fetch origin dev
|
||||
git checkout dev
|
||||
git pull origin dev
|
||||
git rebase ${{ github.ref_name }}
|
||||
git push origin dev
|
||||
build-amd64:
|
||||
name: Build docker image for amd64
|
||||
needs: release
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
outputs:
|
||||
digest: ${{ steps.build.outputs.digest }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ needs.release.outputs.git_ref }}
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: "${{ env.GHCR_REPO }}"
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build and push by digest
|
||||
id: build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
network: host
|
||||
platforms: linux/amd64
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
outputs: type=image,"name=${{ env.GHCR_REPO }}",push-by-digest=true,name-canonical=true,push=true
|
||||
env:
|
||||
SKIP_ENV_VALIDATION: true
|
||||
build-arm64:
|
||||
name: Build docker image for arm64
|
||||
needs: release
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 20
|
||||
outputs:
|
||||
digest: ${{ steps.build.outputs.digest }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ needs.release.outputs.git_ref }}
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: "${{ env.GHCR_REPO }}"
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build and push by digest
|
||||
id: build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
network: host
|
||||
platforms: linux/arm64
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
outputs: type=image,"name=${{ env.GHCR_REPO }}",push-by-digest=true,name-canonical=true,push=true
|
||||
env:
|
||||
SKIP_ENV_VALIDATION: true
|
||||
extract-asset-amd64:
|
||||
name: Extract amd64 asset from docker image
|
||||
needs: [release, build-amd64]
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 2
|
||||
steps:
|
||||
- name: Extract amd64
|
||||
if: needs.release.outputs.skipped == 'false'
|
||||
uses: homarr-labs/homarr/.github/actions/extract-build-artifact@dev
|
||||
with:
|
||||
digest: "${{ env.GHCR_REPO }}@${{ needs.build-amd64.outputs.digest }}"
|
||||
architecture: amd64
|
||||
release-tag: ${{ needs.release.outputs.version }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
repository: ${{ github.repository }}
|
||||
|
||||
extract-asset-arm64:
|
||||
name: Extract arm64 asset from docker image
|
||||
needs: [release, build-arm64]
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 2
|
||||
steps:
|
||||
- name: Extract arm64
|
||||
if: needs.release.outputs.skipped == 'false'
|
||||
uses: homarr-labs/homarr/.github/actions/extract-build-artifact@dev
|
||||
with:
|
||||
digest: "${{ env.GHCR_REPO }}@${{ needs.build-arm64.outputs.digest }}"
|
||||
architecture: arm64
|
||||
release-tag: ${{ needs.release.outputs.version }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
repository: ${{ github.repository }}
|
||||
publish:
|
||||
name: Complete deployment and notify
|
||||
needs: [release, build-amd64, build-arm64, extract-asset-amd64, extract-asset-arm64]
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
env:
|
||||
NEXT_VERSION: ${{ needs.release.outputs.version }}
|
||||
DEPLOY_LATEST: ${{ github.ref_name == 'main' }}
|
||||
DEPLOY_BETA: ${{ github.ref_name == 'beta' }}
|
||||
steps:
|
||||
- name: Obtain token
|
||||
if: needs.release.outputs.skipped == 'false'
|
||||
id: obtainToken
|
||||
uses: actions/create-github-app-token@v2
|
||||
with:
|
||||
private-key: ${{ secrets.RENOVATE_MERGE_PRIVATE_KEY }}
|
||||
app-id: ${{ secrets.RENOVATE_MERGE_APP_ID }}
|
||||
permission-contents: write # required to publish the release
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Publish beta
|
||||
if: env.DEPLOY_BETA == 'true'
|
||||
run: |
|
||||
docker buildx imagetools create -t ${{ env.GHCR_REPO }}:beta \
|
||||
${{ env.GHCR_REPO }}@${{ needs.build-amd64.outputs.digest }} \
|
||||
${{ env.GHCR_REPO }}@${{ needs.build-arm64.outputs.digest }}
|
||||
|
||||
- name: Publish latest
|
||||
if: env.DEPLOY_LATEST == 'true'
|
||||
run: |
|
||||
docker buildx imagetools create -t ${{ env.GHCR_REPO }}:latest \
|
||||
${{ env.GHCR_REPO }}@${{ needs.build-amd64.outputs.digest }} \
|
||||
${{ env.GHCR_REPO }}@${{ needs.build-arm64.outputs.digest }}
|
||||
|
||||
- name: Publish version
|
||||
run: |
|
||||
docker buildx imagetools create -t ${{ env.GHCR_REPO }}:${{ env.NEXT_VERSION }} \
|
||||
${{ env.GHCR_REPO }}@${{ needs.build-amd64.outputs.digest }} \
|
||||
${{ env.GHCR_REPO }}@${{ needs.build-arm64.outputs.digest }}
|
||||
|
||||
- name: Publish release
|
||||
if: needs.release.outputs.skipped == 'false'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
|
||||
run: |
|
||||
gh release edit --repo ${{ github.repository }} ${{ needs.release.outputs.version }} --draft=false
|
||||
|
||||
- name: Discord notification
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
uses: Ilshidur/action-discord@master
|
||||
with:
|
||||
args: "Successfully deployed images for branch **${{ github.ref_name }}**. Tagged as **${{env.NEXT_VERSION}}**."
|
||||
@@ -1,105 +0,0 @@
|
||||
name: "[Deployment] Automatic Weekly Release"
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 19 * * 5" # https://crontab.guru/#0_19_*_*_5
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
send-notifications:
|
||||
type: boolean
|
||||
required: false
|
||||
default: true
|
||||
description: Send notifications
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
create-and-merge-pr:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 2
|
||||
steps:
|
||||
- name: Discord notification
|
||||
if: ${{ github.events.inputs.send-notifications }}
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
uses: Ilshidur/action-discord@master
|
||||
with:
|
||||
args: "Automatic release has been triggered: [run ${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})"
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Get Next Version
|
||||
id: semver
|
||||
uses: ietf-tools/semver-action@v1
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
branch: dev
|
||||
- name: Create pull request
|
||||
run: 'gh pr create --title "chore(release): automatic release ${{ steps.semver.outputs.next }}" --body "**This is an automatic release**.<br/>Manual action may be required for major bumps.<br/>Detected change to be ``${{ steps.semver.outputs.bump }}``<br/>Bump version from ``${{ steps.semver.outputs.current }}`` to ``${{ steps.semver.outputs.next }}``" --base main --head dev --label automerge'
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
- name: Discord notification
|
||||
if: ${{ github.events.inputs.send-notifications }}
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
uses: Ilshidur/action-discord@master
|
||||
with:
|
||||
args: "Created a release PR ${{ steps.create-pull-request.outputs.url }} for version ${{ steps.semver.outputs.next }} (new behaviour: ${{ steps.semver.outputs.bump }})"
|
||||
- name: Obtain token
|
||||
id: obtainApprovalToken
|
||||
uses: actions/create-github-app-token@v2
|
||||
with:
|
||||
private-key: ${{ secrets.RENOVATE_APPROVE_PRIVATE_KEY }}
|
||||
app-id: ${{ secrets.RENOVATE_APPROVE_APP_ID }}
|
||||
permission-pull-requests: write
|
||||
- name: Approve PR
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainApprovalToken.outputs.token }}
|
||||
run: |
|
||||
gh pr review --approve --body "Automatically approved by GitHub Action"
|
||||
- name: Obtain token
|
||||
id: obtainMergeToken
|
||||
uses: actions/create-github-app-token@v2
|
||||
with:
|
||||
private-key: ${{ secrets.RENOVATE_MERGE_PRIVATE_KEY }}
|
||||
app-id: ${{ secrets.RENOVATE_MERGE_APP_ID }}
|
||||
permission-contents: write # write to main branch (due to merge)
|
||||
permission-pull-requests: write # merge pull request
|
||||
- id: automerge
|
||||
if: ${{ steps.semver.outputs.bump != 'major' }}
|
||||
name: automerge
|
||||
uses: "pascalgn/automerge-action@v0.16.4"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainMergeToken.outputs.token }}
|
||||
MERGE_METHOD: merge # we prefer merge commits for merging to master
|
||||
MERGE_COMMIT_MESSAGE: "chore(release): automatic release ${{ steps.semver.outputs.next }}"
|
||||
MERGE_DELETE_BRANCH: false # never set to true!
|
||||
PULL_REQUEST: "${{ steps.create-pull-request.outputs.pr_number }}"
|
||||
MERGE_RETRIES: 20 # 20 retries * MERGE_RETRY_SLEEP until step fails
|
||||
MERGE_RETRY_SLEEP: 10000 # 10 seconds * MERGE_RETRIES until step fails
|
||||
MERGE_REQUIRED_APPROVALS: 0 # do not require approvals
|
||||
|
||||
- name: Merged Discord notification
|
||||
if: ${{ steps.automerge.outputs.mergeResult == 'merged' && github.events.inputs.send-notifications }}
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
uses: Ilshidur/action-discord@master
|
||||
with:
|
||||
args: "Merged PR ${{ steps.create-pull-request.outputs.url }} for release ${{ steps.semver.outputs.next }}"
|
||||
- name: Major Bump Discord notification
|
||||
if: ${{ steps.semver.outputs.bump == 'major' && github.events.inputs.send-notifications }}
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
uses: Ilshidur/action-discord@master
|
||||
with:
|
||||
args: "The release PR must be manually merged because the next version is a major version: ${{ steps.create-pull-request.outputs.url }} for release ${{ steps.semver.outputs.next }}"
|
||||
- name: Discord Fail Notification
|
||||
if: failure() && github.events.inputs.send-notifications
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
uses: Ilshidur/action-discord@master
|
||||
with:
|
||||
args: "The automatic release workflow [run ${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) has failed"
|
||||
@@ -0,0 +1,89 @@
|
||||
name: Docker image
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- closed
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch: {}
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
|
||||
env:
|
||||
TURBO_TELEMETRY_DISABLED: 1
|
||||
|
||||
concurrency: production
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
name: Deploy docker image
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [20]
|
||||
steps:
|
||||
- name: Discord notification
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
uses: Ilshidur/action-discord@master
|
||||
with:
|
||||
args: "Deployment of an image has been triggered"
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: 8
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: "pnpm"
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
- name: Build artifacts
|
||||
run: pnpm build
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Bump version and push tag
|
||||
id: githubTagAction
|
||||
uses: anothrNick/github-tag-action@1.67.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
WITH_V: false
|
||||
DRY_RUN: true
|
||||
- name: Discord notification
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
uses: Ilshidur/action-discord@master
|
||||
with:
|
||||
args: "Image has been tagged as ${{ steps.githubTagAction.outputs.new_tag }}"
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
type=raw,value=latest
|
||||
type=raw,value=${{ steps.githubTagAction.outputs.new_tag }}
|
||||
- name: Build and push
|
||||
id: buildPushAction
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64,linux/riscv64,linux/arm/v7,linux/arm/v6
|
||||
context: .
|
||||
push: false
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
network: host
|
||||
- name: Discord notification
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
uses: Ilshidur/action-discord@master
|
||||
with:
|
||||
args: "Image built with ID ${{ steps.buildPushAction.outputs.imageid }}"
|
||||
@@ -1,45 +0,0 @@
|
||||
name: "[Deployments] Validate prebuilt debian dependencies"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: ["*"]
|
||||
paths: [".github/actions/prebuilt-debian/**", "deployments/prebuilt-debian/**"]
|
||||
|
||||
jobs:
|
||||
prebuilt-debian-validate-amd64:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Validate prebuilt dependencies for amd64
|
||||
id: validate-amd64
|
||||
uses: ./.github/actions/prebuilt-debian
|
||||
with:
|
||||
architecture: amd64
|
||||
|
||||
- name: Check extracted files for amd64
|
||||
run: |
|
||||
if [ ! -f "${{ steps.validate-amd64.outputs.path }}/better_sqlite3.node" ]; then
|
||||
echo "better_sqlite3.node not found for amd64!"
|
||||
exit 1
|
||||
fi
|
||||
prebuilt-debian-validate-arm64:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Validate prebuilt dependencies for arm64
|
||||
id: validate-arm64
|
||||
uses: ./.github/actions/prebuilt-debian
|
||||
with:
|
||||
architecture: arm64
|
||||
|
||||
- name: Check extracted files for arm64
|
||||
run: |
|
||||
if [ ! -f "${{ steps.validate-arm64.outputs.path }}/better_sqlite3.node" ]; then
|
||||
echo "better_sqlite3.node not found for arm64!"
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,19 +0,0 @@
|
||||
name: "[Renovate] Validate configuration"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: ["*"]
|
||||
paths: [".github/renovate.json5"]
|
||||
|
||||
jobs:
|
||||
renovate-validate:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 2
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- run: |
|
||||
npx --yes --package renovate -- \
|
||||
renovate-config-validator --strict .github/renovate.json5
|
||||
@@ -1,87 +0,0 @@
|
||||
permissions: {}
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [released]
|
||||
|
||||
jobs:
|
||||
trigger-docs-release:
|
||||
name: Trigger Documentation Release
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 2
|
||||
steps:
|
||||
- name: Obtain token
|
||||
id: obtainToken
|
||||
uses: actions/create-github-app-token@v2
|
||||
with:
|
||||
private-key: ${{ secrets.HOMARR_DOCS_RELEASE_APP_PRIVATE_KEY }}
|
||||
app-id: ${{ vars.HOMARR_DOCS_RELEASE_APP_ID }}
|
||||
owner: homarr-labs
|
||||
repositories: |
|
||||
documentation
|
||||
permission-contents: write # required to dispatch repository workflow
|
||||
- name: Trigger documentation release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
|
||||
SOURCE_TAG: ${{ github.event.release.tag_name }}
|
||||
run: |
|
||||
curl -X POST \
|
||||
-H "Authorization: token $GITHUB_TOKEN" \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
https://api.github.com/repos/homarr-labs/documentation/dispatches \
|
||||
-d @- <<EOF
|
||||
{
|
||||
"event_type": "trigger-release",
|
||||
"client_payload": {
|
||||
"tag": "${SOURCE_TAG}"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
update-bug-report-template:
|
||||
name: Update Bug Report Template
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- name: Obtain token
|
||||
id: obtainToken
|
||||
uses: actions/create-github-app-token@v2
|
||||
with:
|
||||
private-key: ${{ secrets.RENOVATE_MERGE_PRIVATE_KEY }}
|
||||
app-id: ${{ secrets.RENOVATE_MERGE_APP_ID }}
|
||||
permission-contents: write # required to commit to branch
|
||||
permission-pull-requests: write # required to create pr & enable automerge
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
token: ${{ steps.obtainToken.outputs.token }}
|
||||
ref: dev
|
||||
- name: Setup
|
||||
uses: ./tooling/github/setup
|
||||
- run: pnpm run scripts:update-bug-report-template
|
||||
env:
|
||||
NEXT_VERSION: ${{ github.event.release.tag_name }}
|
||||
|
||||
- name: Create Pull Request
|
||||
id: create-pull-request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
with:
|
||||
add-paths: .github/ISSUE_TEMPLATE/bug_report.yml
|
||||
commit-message: "chore: update bug report template"
|
||||
author: Releases Homarr <175486441+homarr-releases[bot]@users.noreply.github.com>
|
||||
token: ${{ steps.obtainToken.outputs.token }}
|
||||
branch: update-bug-report-template
|
||||
base: dev
|
||||
title: "chore: update bug report template"
|
||||
delete-branch: true
|
||||
body: |
|
||||
This PR automatically updates the bug report template of Homarr in the .github/ISSUE_TEMPLATE/bug_report.yml
|
||||
|
||||
- name: Install GitHub CLI
|
||||
run: sudo apt-get install -y gh
|
||||
|
||||
- name: Enable auto-merge
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
|
||||
run: |
|
||||
gh pr merge ${{steps.create-pull-request.outputs.pull-request-number}} --auto --squash
|
||||
@@ -1,27 +0,0 @@
|
||||
permissions:
|
||||
statuses: write
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
|
||||
jobs:
|
||||
skip-stability-days:
|
||||
if: ${{ !startsWith(github.head_ref, 'renovate/') }}
|
||||
name: Skip Stability Days
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 1
|
||||
steps:
|
||||
- name: Add status check
|
||||
env:
|
||||
GH_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
run: |
|
||||
gh api \
|
||||
--method POST \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
/repos/${{github.repository}}/statuses/${{github.event.pull_request.head.sha}} \
|
||||
-f 'state=success' \
|
||||
-f 'target_url=https://docs.renovatebot.com/configuration-options#minimumreleaseage' \
|
||||
-f 'description=Skipped for non renovate branches' \
|
||||
-f 'context=renovate/stability-days'
|
||||
@@ -1,74 +0,0 @@
|
||||
name: Update Contributors
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 12 * * FRI" # At 12:00 on Friday.
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
CROWDIN_TOKEN: "${{ secrets.CROWDIN_UPDATE_CONTRIBUTORS_TOKEN }}"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
jobs:
|
||||
update-contributors:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 2
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [22]
|
||||
steps:
|
||||
- name: Obtain token
|
||||
id: obtainToken
|
||||
uses: actions/create-github-app-token@v2
|
||||
with:
|
||||
private-key: ${{ secrets.HOMARR_UPDATE_CONTRIBUTORS_PRIVATE_KEY }}
|
||||
app-id: ${{ vars.HOMARR_UPDATE_CONTRIBUTORS_APP_ID }}
|
||||
permission-contents: write # required to commit to branch
|
||||
permission-pull-requests: write # required to create pr & enable automerge
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: "pnpm"
|
||||
|
||||
- name: Run update script
|
||||
run: node ./scripts/update-contributors.mjs
|
||||
|
||||
- name: Commit changes
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
|
||||
run: |
|
||||
git config --global user.email "210161987+homarr-update-contributors[bot]@users.noreply.github.com"
|
||||
git config --global user.name "Homarr Update Contributors"
|
||||
git add .
|
||||
git commit -m "chore: update contributors"
|
||||
|
||||
- name: Create Pull Request
|
||||
id: create-pull-request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
with:
|
||||
token: ${{ steps.obtainToken.outputs.token }}
|
||||
branch: update-contributors
|
||||
base: dev
|
||||
title: "chore: update contributors"
|
||||
delete-branch: true
|
||||
body: |
|
||||
This PR updates the contributors list in the static-data directory.
|
||||
|
||||
- name: Install GitHub CLI
|
||||
run: sudo apt-get install -y gh
|
||||
|
||||
- name: Enable auto-merge
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
|
||||
run: |
|
||||
gh pr merge ${{steps.create-pull-request.outputs.pull-request-number}} --auto --squash
|
||||
@@ -1,65 +0,0 @@
|
||||
name: Update integration list
|
||||
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
push:
|
||||
paths:
|
||||
- packages/definitions/src/integration.ts
|
||||
branches:
|
||||
- dev
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
update-readme:
|
||||
concurrency:
|
||||
group: update-integration
|
||||
cancel-in-progress: false
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- name: Obtain token
|
||||
id: obtainToken
|
||||
uses: actions/create-github-app-token@v2
|
||||
with:
|
||||
private-key: ${{ secrets.HOMARR_UPDATE_CONTRIBUTORS_PRIVATE_KEY }}
|
||||
app-id: ${{ vars.HOMARR_UPDATE_CONTRIBUTORS_APP_ID }}
|
||||
permission-contents: write # required to commit to branch
|
||||
permission-pull-requests: write # required to create pr & enable automerge
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
|
||||
- name: Setup
|
||||
uses: ./tooling/github/setup
|
||||
- run: pnpm run scripts:update-readme-integrations
|
||||
- name: Commit changes
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
|
||||
run: |
|
||||
git config --global user.email "210161987+homarr-update-contributors[bot]@users.noreply.github.com"
|
||||
git config --global user.name "Homarr Update Contributors"
|
||||
git add .
|
||||
git commit -m "chore: update integrations list readme"
|
||||
|
||||
- name: Create Pull Request
|
||||
id: create-pull-request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
with:
|
||||
token: ${{ steps.obtainToken.outputs.token }}
|
||||
branch: update-integrations-readme
|
||||
base: dev
|
||||
title: "chore: update integrations list readme"
|
||||
delete-branch: true
|
||||
body: |
|
||||
This PR automatically updates the list of integrations of Homarr in the README.md
|
||||
|
||||
- name: Install GitHub CLI
|
||||
run: sudo apt-get install -y gh
|
||||
|
||||
- name: Enable auto-merge
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
|
||||
run: |
|
||||
gh pr merge ${{steps.create-pull-request.outputs.pull-request-number}} --auto --squash
|
||||
@@ -14,8 +14,8 @@ coverage
|
||||
out/
|
||||
next-env.d.ts
|
||||
|
||||
# artifacts
|
||||
packages/db/migrations/*/migrate.cjs
|
||||
# nest.js
|
||||
apps/nestjs/dist
|
||||
|
||||
# nitro
|
||||
.nitro/
|
||||
@@ -48,23 +48,7 @@ yarn-error.log*
|
||||
.turbo
|
||||
|
||||
# database
|
||||
*.sqlite
|
||||
db.sqlite
|
||||
|
||||
# logs
|
||||
*.log
|
||||
|
||||
apps/tasks/tasks.cjs
|
||||
apps/tasks/tasks.css
|
||||
apps/websocket/wssServer.cjs
|
||||
apps/websocket/wssServer.css
|
||||
apps/nextjs/.million/
|
||||
packages/cli/cli.cjs
|
||||
|
||||
# e2e mounts
|
||||
e2e/shared/tmp
|
||||
|
||||
#personal backgrounds
|
||||
apps/nextjs/public/images/background.png
|
||||
|
||||
# next-intl
|
||||
en.d.json.ts
|
||||
*.log
|
||||
@@ -3,4 +3,3 @@
|
||||
# @link https://docs.expo.dev/guides/monorepos/#common-issues
|
||||
node-linker=hoisted
|
||||
strict-peer-dependencies=false
|
||||
engine-strict=true
|
||||
@@ -1,52 +0,0 @@
|
||||
{
|
||||
"branches": [
|
||||
"main",
|
||||
{
|
||||
"name": "beta",
|
||||
"prerelease": true,
|
||||
"channel": "beta"
|
||||
}
|
||||
],
|
||||
"plugins": [
|
||||
[
|
||||
"@semantic-release/commit-analyzer",
|
||||
{
|
||||
"preset": "conventionalcommits"
|
||||
}
|
||||
],
|
||||
[
|
||||
"@semantic-release/release-notes-generator",
|
||||
{
|
||||
"preset": "conventionalcommits"
|
||||
}
|
||||
],
|
||||
[
|
||||
"@semantic-release/changelog",
|
||||
{
|
||||
"changelogFile": "CHANGELOG.md"
|
||||
}
|
||||
],
|
||||
[
|
||||
"@semantic-release/npm",
|
||||
{
|
||||
"npmPublish": false
|
||||
}
|
||||
],
|
||||
[
|
||||
"@semantic-release/git",
|
||||
{
|
||||
"assets": ["package.json", "CHANGELOG.md"],
|
||||
"message": "chore(release): ${nextRelease.version} [skip ci]"
|
||||
}
|
||||
],
|
||||
[
|
||||
"@semantic-release/github",
|
||||
{
|
||||
"successComment": false,
|
||||
"failComment": false,
|
||||
"draftRelease": true,
|
||||
"releaseBodyTemplate": "<%= _.truncate(nextRelease.notes, { 'length': 124000, 'omission': '' }) %>"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="All Tests" type="JavaScriptTestRunnerVitest" nameIsGenerated="true">
|
||||
<node-interpreter value="project" />
|
||||
<vitest-package value="$PROJECT_DIR$/node_modules/vitest" />
|
||||
<working-dir value="$PROJECT_DIR$" />
|
||||
<vitest-options value="--exclude e2e --coverage.enabled" />
|
||||
<envs>
|
||||
<env name="NODE_ENV" value="development" />
|
||||
<env name="CI" value="true" />
|
||||
</envs>
|
||||
<scope-kind value="ALL" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,13 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="db:migration:mysql:generate" type="js.build_tools.npm">
|
||||
<package-json value="$PROJECT_DIR$/package.json" />
|
||||
<command value="run" />
|
||||
<scripts>
|
||||
<script value="db:migration:mysql:generate" />
|
||||
</scripts>
|
||||
<node-interpreter value="project" />
|
||||
<package-manager value="pnpm" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,13 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="db:migration:postgresql:generate" type="js.build_tools.npm">
|
||||
<package-json value="$PROJECT_DIR$/package.json" />
|
||||
<command value="run" />
|
||||
<scripts>
|
||||
<script value="db:migration:postgresql:generate" />
|
||||
</scripts>
|
||||
<node-interpreter value="project" />
|
||||
<package-manager value="pnpm" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,13 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="db:migration:sqlite:generate" type="js.build_tools.npm">
|
||||
<package-json value="$PROJECT_DIR$/package.json" />
|
||||
<command value="run" />
|
||||
<scripts>
|
||||
<script value="db:migration:sqlite:generate" />
|
||||
</scripts>
|
||||
<node-interpreter value="project" />
|
||||
<package-manager value="pnpm" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,13 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="db:push" type="js.build_tools.npm">
|
||||
<package-json value="$PROJECT_DIR$/package.json" />
|
||||
<command value="run" />
|
||||
<scripts>
|
||||
<script value="db:push" />
|
||||
</scripts>
|
||||
<node-interpreter value="project" />
|
||||
<package-manager value="pnpm" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,13 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="db:studio" type="js.build_tools.npm">
|
||||
<package-json value="$PROJECT_DIR$/package.json" />
|
||||
<command value="run" />
|
||||
<scripts>
|
||||
<script value="db:studio" />
|
||||
</scripts>
|
||||
<node-interpreter value="project" />
|
||||
<package-manager value="pnpm" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,13 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="dev" type="js.build_tools.npm" nameIsGenerated="true">
|
||||
<package-json value="$PROJECT_DIR$/package.json" />
|
||||
<command value="run" />
|
||||
<scripts>
|
||||
<script value="dev" />
|
||||
</scripts>
|
||||
<node-interpreter value="project" />
|
||||
<package-manager value="pnpm" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,13 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="docker:dev" type="js.build_tools.npm">
|
||||
<package-json value="$PROJECT_DIR$/package.json" />
|
||||
<command value="run" />
|
||||
<scripts>
|
||||
<script value="docker:dev" />
|
||||
</scripts>
|
||||
<node-interpreter value="project" />
|
||||
<package-manager value="pnpm" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,13 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="format" type="js.build_tools.npm">
|
||||
<package-json value="$PROJECT_DIR$/package.json" />
|
||||
<command value="run" />
|
||||
<scripts>
|
||||
<script value="format" />
|
||||
</scripts>
|
||||
<node-interpreter value="project" />
|
||||
<package-manager value="pnpm" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,13 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="format:fix" type="js.build_tools.npm">
|
||||
<package-json value="$PROJECT_DIR$/package.json" />
|
||||
<command value="run" />
|
||||
<scripts>
|
||||
<script value="format:fix" />
|
||||
</scripts>
|
||||
<node-interpreter value="project" />
|
||||
<package-manager value="pnpm" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,13 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="test" type="js.build_tools.npm">
|
||||
<package-json value="$PROJECT_DIR$/package.json" />
|
||||
<command value="run" />
|
||||
<scripts>
|
||||
<script value="test" />
|
||||
</scripts>
|
||||
<node-interpreter value="project" />
|
||||
<package-manager value="pnpm" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,13 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="test:ui" type="js.build_tools.npm">
|
||||
<package-json value="$PROJECT_DIR$/package.json" />
|
||||
<command value="run" />
|
||||
<scripts>
|
||||
<script value="test:ui" />
|
||||
</scripts>
|
||||
<node-interpreter value="project" />
|
||||
<package-manager value="pnpm" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,13 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="typecheck" type="js.build_tools.npm">
|
||||
<package-json value="$PROJECT_DIR$/package.json" />
|
||||
<command value="run" />
|
||||
<scripts>
|
||||
<script value="typecheck" />
|
||||
</scripts>
|
||||
<node-interpreter value="project" />
|
||||
<package-manager value="pnpm" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -2,8 +2,6 @@
|
||||
"recommendations": [
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
"yoavbls.pretty-ts-errors",
|
||||
"million.million-lint",
|
||||
"lokalise.i18n-ally"
|
||||
"yoavbls.pretty-ts-errors"
|
||||
]
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
# .vscode/i18n-ally-custom-framework.yml
|
||||
|
||||
# An array of strings which contain Language Ids defined by VS Code
|
||||
# You can check available language ids here: https://code.visualstudio.com/docs/languages/identifiers
|
||||
languageIds:
|
||||
- javascript
|
||||
- typescript
|
||||
- javascriptreact
|
||||
- typescriptreact
|
||||
|
||||
# An array of RegExes to find the key usage. **The key should be captured in the first match group**.
|
||||
# You should unescape RegEx strings in order to fit in the YAML file
|
||||
# To help with this, you can use https://www.freeformatter.com/json-escape.html
|
||||
usageMatchRegex:
|
||||
# For direct t("your.i18n.keys") usage
|
||||
- "[^\\w\\d]t\\(['\"`]({key})['\"`]"
|
||||
# For variable t assigned from getScopedI18n or useScopedI18n
|
||||
- "\\bt\\(['\"`]({key})['\"`]\\)"
|
||||
|
||||
# A RegEx to set a custom scope range. This scope will be used as a prefix when detecting keys
|
||||
# and works like how the i18next framework identifies the namespace scope from the
|
||||
# useTranslation() hook.
|
||||
# You should unescape RegEx strings in order to fit in the YAML file
|
||||
# To help with this, you can use https://www.freeformatter.com/json-escape.html
|
||||
scopeRangeRegex: "(?:const|let|var)\\s+t\\s*=\\s*(?:await\\s+)?(?:getScopedI18n|useScopedI18n)\\(\\s*['\"](.*?)['\"]\\)"
|
||||
|
||||
# An array of strings containing refactor templates.
|
||||
# The "$1" will be replaced by the keypath specified.
|
||||
# Optional: uncomment the following two lines to use
|
||||
|
||||
# refactorTemplates:
|
||||
# - i18n.get("$1")
|
||||
|
||||
|
||||
# If set to true, only enables this custom framework (will disable all built-in frameworks)
|
||||
monopoly: true
|
||||
@@ -4,41 +4,11 @@
|
||||
"mode": "auto"
|
||||
}
|
||||
],
|
||||
"eslint.experimental.useFlatConfig": true,
|
||||
"typescript.tsdk": "node_modules\\typescript\\lib",
|
||||
"js/ts.implicitProjectConfig.experimentalDecorators": true,
|
||||
"prettier.configPath": "./tooling/prettier/index.mjs",
|
||||
"cSpell.words": [
|
||||
"ajnart",
|
||||
"cqmin",
|
||||
"gridstack",
|
||||
"homarr",
|
||||
"jellyfin",
|
||||
"llen",
|
||||
"lpop",
|
||||
"lpush",
|
||||
"lrange",
|
||||
"ltrim",
|
||||
"mantine",
|
||||
"manuel-rw",
|
||||
"Meierschlumpf",
|
||||
"overseerr",
|
||||
"Sabnzbd",
|
||||
"SeDemal",
|
||||
"Sonarr",
|
||||
"sslverify",
|
||||
"superjson",
|
||||
"tabler",
|
||||
"trpc",
|
||||
"Umami"
|
||||
],
|
||||
"i18n-ally.dirStructure": "auto",
|
||||
"i18n-ally.displayLanguage": "en",
|
||||
"i18n-ally.enabledFrameworks": [
|
||||
"custom"
|
||||
],
|
||||
"i18n-ally.localesPaths": [
|
||||
"packages/translation/src/lang",
|
||||
],
|
||||
"i18n-ally.keystyle": "nested",
|
||||
"homarr",
|
||||
"trpc"
|
||||
]
|
||||
}
|
||||
@@ -1,9 +1 @@
|
||||
# ── CODEOWNERS ───────────────────────────────────────
|
||||
* @homarr-labs/maintainers
|
||||
|
||||
# Exempt Renovate‑managed files (no owners)
|
||||
package.json
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
Dockerfile
|
||||
docker-compose.yml
|
||||
@@ -1,71 +1,77 @@
|
||||
FROM node:24.14.0-alpine AS base
|
||||
FROM node:20.12.2-alpine AS base
|
||||
|
||||
FROM base AS builder
|
||||
RUN apk add --no-cache libc6-compat
|
||||
RUN apk update
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN npm i -g turbo
|
||||
RUN turbo prune @homarr/nextjs --docker --out-dir ./next-out
|
||||
RUN turbo prune @homarr/tasks --docker --out-dir ./tasks-out
|
||||
RUN turbo prune @homarr/websocket --docker --out-dir ./websocket-out
|
||||
RUN turbo prune @homarr/db --docker --out-dir ./migration-out
|
||||
|
||||
# Add lockfile and package.json's of isolated subworkspace
|
||||
FROM base AS installer
|
||||
RUN apk add --no-cache libc6-compat curl bash
|
||||
RUN apk update
|
||||
COPY . .
|
||||
WORKDIR /app
|
||||
|
||||
RUN corepack enable pnpm && pnpm install --recursive --frozen-lockfile
|
||||
# First install the dependencies (as they change less often)
|
||||
COPY .gitignore .gitignore
|
||||
|
||||
# Copy static data as it is not part of the build
|
||||
COPY static-data ./static-data
|
||||
ARG SKIP_ENV_VALIDATION='true'
|
||||
ARG CI='true'
|
||||
ARG DISABLE_REDIS_LOGS='true'
|
||||
COPY --from=builder /app/tasks-out/json/ .
|
||||
COPY --from=builder /app/tasks-out/pnpm-lock.yaml ./pnpm-lock.yaml
|
||||
RUN corepack enable pnpm && pnpm install
|
||||
|
||||
RUN corepack enable pnpm && pnpm build
|
||||
COPY --from=builder /app/websocket-out/json/ .
|
||||
COPY --from=builder /app/websocket-out/pnpm-lock.yaml ./pnpm-lock.yaml
|
||||
RUN corepack enable pnpm && pnpm install
|
||||
|
||||
COPY --from=builder /app/migration-out/json/ .
|
||||
COPY --from=builder /app/migration-out/pnpm-lock.yaml ./pnpm-lock.yaml
|
||||
RUN corepack enable pnpm && pnpm install
|
||||
|
||||
COPY --from=builder /app/next-out/json/ .
|
||||
COPY --from=builder /app/next-out/pnpm-lock.yaml ./pnpm-lock.yaml
|
||||
RUN corepack enable pnpm && pnpm install sharp -w
|
||||
|
||||
# Build the project
|
||||
COPY --from=builder /app/tasks-out/full/ .
|
||||
COPY --from=builder /app/websocket-out/full/ .
|
||||
COPY --from=builder /app/next-out/full/ .
|
||||
COPY --from=builder /app/migration-out/full/ .
|
||||
ARG SKIP_ENV_VALIDATION=true
|
||||
RUN corepack enable pnpm && pnpm turbo run build
|
||||
|
||||
FROM base AS runner
|
||||
WORKDIR /app
|
||||
|
||||
# gettext is required for envsubst, openssl for generating AUTH_SECRET, su-exec for running application as non-root
|
||||
RUN apk add --no-cache redis nginx bash gettext su-exec openssl
|
||||
RUN mkdir /appdata
|
||||
VOLUME /appdata
|
||||
|
||||
# Enable homarr cli
|
||||
COPY --from=builder /app/packages/cli/cli.cjs /app/apps/cli/cli.cjs
|
||||
RUN echo $'#!/bin/bash\ncd /app/apps/cli && node ./cli.cjs "$@"' > /usr/bin/homarr
|
||||
RUN chmod +x /usr/bin/homarr
|
||||
RUN apk add --no-cache redis
|
||||
|
||||
# Don't run production as root
|
||||
RUN mkdir -p /var/cache/nginx && \
|
||||
mkdir -p /var/log/nginx && \
|
||||
mkdir -p /var/lib/nginx && \
|
||||
touch /run/nginx/nginx.pid && \
|
||||
mkdir -p /etc/nginx/templates /etc/nginx/ssl/certs
|
||||
RUN addgroup --system --gid 1001 nodejs
|
||||
RUN adduser --system --uid 1001 nextjs
|
||||
USER nextjs
|
||||
|
||||
COPY --from=builder /app/apps/nextjs/next.config.ts .
|
||||
COPY --from=builder /app/apps/nextjs/package.json .
|
||||
COPY --from=installer /app/apps/nextjs/next.config.mjs .
|
||||
COPY --from=installer /app/apps/nextjs/package.json .
|
||||
|
||||
COPY --from=builder /app/apps/tasks/tasks.cjs ./apps/tasks/tasks.cjs
|
||||
COPY --from=builder /app/apps/websocket/wssServer.cjs ./apps/websocket/wssServer.cjs
|
||||
COPY --from=builder /app/node_modules/better-sqlite3/build/Release/better_sqlite3.node /app/build/better_sqlite3.node
|
||||
COPY --from=installer --chown=nextjs:nodejs /app/apps/tasks/tasks.cjs ./apps/tasks/tasks.cjs
|
||||
COPY --from=installer --chown=nextjs:nodejs /app/apps/websocket/wssServer.cjs ./apps/websocket/wssServer.cjs
|
||||
COPY --from=installer --chown=nextjs:nodejs /app/node_modules/better-sqlite3/build/Release/better_sqlite3.node /app/build/better_sqlite3.node
|
||||
|
||||
COPY --from=builder /app/packages/db/migrations ./db/migrations
|
||||
COPY --from=installer --chown=nextjs:nodejs /app/packages/db/migrations ./db/migrations
|
||||
COPY --from=installer --chown=nextjs:nodejs /app/packages/db/migrate.cjs ./db/migrate.cjs
|
||||
|
||||
# Automatically leverage output traces to reduce image size
|
||||
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
||||
COPY --from=builder /app/apps/nextjs/.next/standalone ./
|
||||
COPY --from=builder /app/apps/nextjs/.next/static ./apps/nextjs/.next/static
|
||||
COPY --from=builder /app/apps/nextjs/public ./apps/nextjs/public
|
||||
COPY scripts/run.sh ./run.sh
|
||||
COPY --chmod=755 scripts/entrypoint.sh ./entrypoint.sh
|
||||
COPY packages/redis/redis.conf /app/redis.conf
|
||||
COPY nginx.conf /etc/nginx/templates/nginx.conf
|
||||
COPY --from=installer --chown=nextjs:nodejs /app/apps/nextjs/.next/standalone ./
|
||||
COPY --from=installer --chown=nextjs:nodejs /app/apps/nextjs/.next/static ./apps/nextjs/.next/static
|
||||
COPY --from=installer --chown=nextjs:nodejs /app/apps/nextjs/public ./apps/nextjs/public
|
||||
COPY --chown=nextjs:nodejs scripts/run.sh ./run.sh
|
||||
|
||||
ENV DB_URL='/app/db/db.sqlite'
|
||||
|
||||
ENV DB_URL='/appdata/db/db.sqlite'
|
||||
ENV DB_DIALECT='sqlite'
|
||||
ENV DB_DRIVER='better-sqlite3'
|
||||
ENV AUTH_PROVIDERS='credentials'
|
||||
ENV REDIS_IS_EXTERNAL='false'
|
||||
ENV NODE_ENV='production'
|
||||
|
||||
ENTRYPOINT [ "/app/entrypoint.sh" ]
|
||||
CMD ["sh", "run.sh"]
|
||||
@@ -1,201 +1,21 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
MIT License
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
Copyright (c) 2023 Julius Marminge
|
||||
|
||||
1. Definitions.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright (c) 2024 Meier Lukas, Thomas Camlong and Homarr Labs
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,5 @@
|
||||
# THIS PROJECT IS STILL UNSTABLE AND WE DO NOT PROVIDE ANY SUPPORT FOR ISSUES THAT OCCURE.
|
||||
## PLEASE DO NOT OPEN ANY ISSUES OR DISCUSSIONS
|
||||
### EVERYTHING IS SUBJECT TO CHANGE
|
||||
|
||||
Please use [this](https://github.com/ajnart/homarr) version of Homarr when you want to use it
|
||||
@@ -1,29 +0,0 @@
|
||||
# Security Policy
|
||||
|
||||
This policy is relevant if you found potential vulnerabilities in an audit.
|
||||
We consider something as a vulnerability if it...
|
||||
|
||||
1. puts users or user data at risk
|
||||
2. enables third parties to gain control or access (e.g. [RATs](https://en.wikipedia.org/wiki/Remote_desktop_software#RAT), [privilege escalation](https://en.wikipedia.org/wiki/Privilege_escalation), ...)
|
||||
3. abuses the system in an unintended way (e.g. crypto mining, proxy, ...)
|
||||
|
||||
## Supported Versions
|
||||
|
||||
We only fix security issues in the [latest stable version](https://github.com/homarr-labs/homarr/releases/latest). Meaning security issues in prior versions will not be fixed and users have to upgrade to the latest version to receive them.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
We use [GitHub's system for reporting vulnerabilities](https://docs.github.com/en/enterprise-cloud@latest/code-security/security-advisories/working-with-repository-security-advisories/creating-a-repository-security-advisory).
|
||||
Click [**here to report an advisory**](https://github.com/homarr-labs/homarr/security/advisories/new). Our team will get notified and will get back to you within 1-6 business days.
|
||||
|
||||
As a general guideline; please provide as much detail as possible and provide reproduction steps / documentation regarding the re-creation.
|
||||
You may also provide a fork with a fix for the vulnerability.
|
||||
See https://cheatsheetseries.owasp.org/cheatsheets/Vulnerability_Disclosure_Cheat_Sheet.html for guidelines regarding disclosure.
|
||||
|
||||
If you're unable / unwilling (or it's not safe) to disclose vulnerabilites via GitHub, please report them with the subject "Security advisory - CVEXXX" to our email homarr-labs@proton.me.
|
||||
Please never disclose security vulnerabilits on your own publicly - we'd like to search for a dimplomatic solution that is also safe for our users.
|
||||
|
||||
In your initial contact with us, please provide details according to the [OWASP guidelines for initial reports](https://cheatsheetseries.owasp.org/cheatsheets/Vulnerability_Disclosure_Cheat_Sheet.html#initial-report).
|
||||
|
||||
Thank you!
|
||||
We're looking forward to your report
|
||||
@@ -1,13 +0,0 @@
|
||||
import baseConfig from "@homarr/eslint-config/base";
|
||||
import nextjsConfig from "@homarr/eslint-config/nextjs";
|
||||
import reactConfig from "@homarr/eslint-config/react";
|
||||
|
||||
/** @type {import('typescript-eslint').Config} */
|
||||
export default [
|
||||
{
|
||||
ignores: [".next/**"],
|
||||
},
|
||||
...baseConfig,
|
||||
...reactConfig,
|
||||
...nextjsConfig,
|
||||
];
|
||||
@@ -0,0 +1,31 @@
|
||||
// Importing env files here to validate on build
|
||||
import "./src/env.mjs";
|
||||
import "@homarr/auth/env.mjs";
|
||||
|
||||
/** @type {import("next").NextConfig} */
|
||||
const config = {
|
||||
output: "standalone",
|
||||
reactStrictMode: true,
|
||||
/** We already do linting and typechecking as separate tasks in CI */
|
||||
eslint: { ignoreDuringBuilds: true },
|
||||
typescript: { ignoreBuildErrors: true },
|
||||
experimental: {
|
||||
optimizePackageImports: [
|
||||
"@mantine/core",
|
||||
"@mantine/hooks",
|
||||
"@tabler/icons-react",
|
||||
],
|
||||
},
|
||||
transpilePackages: [
|
||||
"@homarr/ui",
|
||||
"@homarr/notifications",
|
||||
"@homarr/modals",
|
||||
"@homarr/spotlight",
|
||||
"@homarr/widgets",
|
||||
],
|
||||
images: {
|
||||
domains: ["cdn.jsdelivr.net"],
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -1,81 +0,0 @@
|
||||
// Importing env files here to validate on build
|
||||
import "@homarr/auth/env";
|
||||
import "@homarr/core/infrastructure/db/env";
|
||||
import "@homarr/common/env";
|
||||
import "@homarr/core/infrastructure/logs/env";
|
||||
import "@homarr/docker/env";
|
||||
|
||||
import type { NextConfig } from "next";
|
||||
import MillionLint from "@million/lint";
|
||||
import createNextIntlPlugin from "next-intl/plugin";
|
||||
|
||||
// Package path does not work... so we need to use relative path
|
||||
const withNextIntl = createNextIntlPlugin({
|
||||
experimental: {
|
||||
createMessagesDeclaration: "../../packages/translation/src/lang/en.json",
|
||||
},
|
||||
requestConfig: "../../packages/translation/src/request.ts",
|
||||
});
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
output: "standalone",
|
||||
reactStrictMode: true,
|
||||
// react compiler breaks mantine-react-table, so disabled for now
|
||||
//reactCompiler: true,
|
||||
/** We already do typechecking as separate tasks in CI */
|
||||
typescript: { ignoreBuildErrors: true },
|
||||
/**
|
||||
* dockerode is required in the external server packages because of https://github.com/homarr-labs/homarr/issues/612
|
||||
* isomorphic-dompurify and jsdom are required, see https://github.com/kkomelin/isomorphic-dompurify/issues/356
|
||||
*/
|
||||
serverExternalPackages: ["dockerode", "isomorphic-dompurify", "jsdom"],
|
||||
experimental: {
|
||||
optimizePackageImports: ["@mantine/core", "@mantine/hooks", "@tabler/icons-react"],
|
||||
turbopackFileSystemCacheForDev: true,
|
||||
},
|
||||
transpilePackages: ["@homarr/ui", "@homarr/notifications", "@homarr/modals", "@homarr/spotlight", "@homarr/widgets"],
|
||||
images: {
|
||||
localPatterns: [
|
||||
{
|
||||
pathname: "/**",
|
||||
search: "",
|
||||
},
|
||||
],
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/require-await,no-restricted-syntax
|
||||
async headers() {
|
||||
return [
|
||||
{
|
||||
source: "/(.*)", // Apply CSP to all routes
|
||||
headers: [
|
||||
{
|
||||
key: "Content-Security-Policy",
|
||||
// worker-src / media-src with blob: is necessary for video.js, see https://github.com/homarr-labs/homarr/issues/3912 and https://stackoverflow.com/questions/65792855/problem-with-video-js-and-content-security-policy-csp
|
||||
value: `
|
||||
default-src 'self';
|
||||
script-src * 'unsafe-inline' 'unsafe-eval';
|
||||
worker-src * blob:;
|
||||
base-uri 'self';
|
||||
connect-src *;
|
||||
style-src * 'unsafe-inline';
|
||||
frame-ancestors *;
|
||||
frame-src *;
|
||||
form-action 'self';
|
||||
img-src * data:;
|
||||
font-src * data:;
|
||||
media-src * data: blob:;
|
||||
`
|
||||
.replace(/\s{2,}/g, " ")
|
||||
.trim(),
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
|
||||
// Skip transform is used because of webpack loader, without it for example 'Tooltip.Floating' will not work and show an error
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const withMillionLint = MillionLint.next({ rsc: true, skipTransform: true, telemetry: false });
|
||||
|
||||
export default withNextIntl(nextConfig);
|
||||
@@ -7,102 +7,77 @@
|
||||
"build": "pnpm with-env next build",
|
||||
"clean": "git clean -xdf .next .turbo node_modules",
|
||||
"dev": "pnpm with-env next dev",
|
||||
"lint": "dotenv -v SKIP_ENV_VALIDATION=1 next lint",
|
||||
"format": "prettier --check . --ignore-path ../../.gitignore",
|
||||
"lint": "eslint",
|
||||
"start": "pnpm with-env next start",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"with-env": "dotenv -e ../../.env --"
|
||||
},
|
||||
"prettier": "@homarr/prettier-config",
|
||||
"dependencies": {
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
"@dnd-kit/modifiers": "^9.0.0",
|
||||
"@dnd-kit/sortable": "^10.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"@homarr/analytics": "workspace:^0.1.0",
|
||||
"@homarr/api": "workspace:^0.1.0",
|
||||
"@homarr/auth": "workspace:^0.1.0",
|
||||
"@homarr/boards": "workspace:^0.1.0",
|
||||
"@homarr/common": "workspace:^0.1.0",
|
||||
"@homarr/core": "workspace:^0.1.0",
|
||||
"@homarr/cron-job-status": "workspace:^0.1.0",
|
||||
"@homarr/db": "workspace:^0.1.0",
|
||||
"@homarr/definitions": "workspace:^0.1.0",
|
||||
"@homarr/docker": "workspace:^0.1.0",
|
||||
"@homarr/form": "workspace:^0.1.0",
|
||||
"@homarr/forms-collection": "workspace:^0.1.0",
|
||||
"@homarr/gridstack": "^1.12.0",
|
||||
"@homarr/icons": "workspace:^0.1.0",
|
||||
"@homarr/image-proxy": "workspace:^0.1.0",
|
||||
"@homarr/integrations": "workspace:^0.1.0",
|
||||
"@homarr/gridstack": "^1.0.0",
|
||||
"@homarr/log": "workspace:^",
|
||||
"@homarr/modals": "workspace:^0.1.0",
|
||||
"@homarr/modals-collection": "workspace:^0.1.0",
|
||||
"@homarr/notifications": "workspace:^0.1.0",
|
||||
"@homarr/old-import": "workspace:^0.1.0",
|
||||
"@homarr/old-schema": "workspace:^0.1.0",
|
||||
"@homarr/redis": "workspace:^0.1.0",
|
||||
"@homarr/server-settings": "workspace:^0.1.0",
|
||||
"@homarr/settings": "workspace:^0.1.0",
|
||||
"@homarr/spotlight": "workspace:^0.1.0",
|
||||
"@homarr/translation": "workspace:^0.1.0",
|
||||
"@homarr/ui": "workspace:^0.1.0",
|
||||
"@homarr/validation": "workspace:^0.1.0",
|
||||
"@homarr/widgets": "workspace:^0.1.0",
|
||||
"@mantine/colors-generator": "^8.3.18",
|
||||
"@mantine/core": "^8.3.18",
|
||||
"@mantine/dropzone": "^8.3.18",
|
||||
"@mantine/hooks": "^8.3.18",
|
||||
"@mantine/modals": "^8.3.18",
|
||||
"@mantine/tiptap": "^8.3.18",
|
||||
"@million/lint": "1.0.14",
|
||||
"@tabler/icons-react": "^3.40.0",
|
||||
"@tanstack/react-query": "^5.91.2",
|
||||
"@tanstack/react-query-devtools": "^5.91.3",
|
||||
"@tanstack/react-query-next-experimental": "^5.91.0",
|
||||
"@trpc/client": "^11.14.1",
|
||||
"@trpc/next": "^11.14.1",
|
||||
"@trpc/react-query": "^11.14.1",
|
||||
"@trpc/server": "^11.14.1",
|
||||
"@mantine/colors-generator": "^7.9.0",
|
||||
"@mantine/hooks": "^7.9.0",
|
||||
"@mantine/modals": "^7.9.0",
|
||||
"@mantine/tiptap": "^7.9.0",
|
||||
"@t3-oss/env-nextjs": "^0.10.1",
|
||||
"@tanstack/react-query": "^5.34.1",
|
||||
"@tanstack/react-query-devtools": "^5.34.1",
|
||||
"@tanstack/react-query-next-experimental": "5.34.1",
|
||||
"@trpc/client": "11.0.0-rc.364",
|
||||
"@trpc/next": "next",
|
||||
"@trpc/react-query": "next",
|
||||
"@trpc/server": "next",
|
||||
"@xterm/addon-canvas": "^0.7.0",
|
||||
"@xterm/addon-fit": "0.11.0",
|
||||
"@xterm/xterm": "^6.0.0",
|
||||
"babel-plugin-react-compiler": "^1.0.0",
|
||||
"chroma-js": "^3.2.0",
|
||||
"clsx": "^2.1.1",
|
||||
"dayjs": "^1.11.20",
|
||||
"dotenv": "^17.3.1",
|
||||
"flag-icons": "^7.5.0",
|
||||
"glob": "^13.0.6",
|
||||
"isomorphic-dompurify": "^3.6.0",
|
||||
"jotai": "^2.18.1",
|
||||
"mantine-react-table": "2.0.0-beta.9",
|
||||
"next": "16.2.1",
|
||||
"postcss-preset-mantine": "^1.18.0",
|
||||
"prismjs": "^1.30.0",
|
||||
"react": "19.2.4",
|
||||
"react-dom": "19.2.4",
|
||||
"react-error-boundary": "^6.1.1",
|
||||
"react-simple-code-editor": "^0.14.1",
|
||||
"sass": "^1.98.0",
|
||||
"superjson": "2.2.6",
|
||||
"swagger-ui-react": "^5.32.1",
|
||||
"use-deep-compare-effect": "^1.8.1",
|
||||
"zod": "^4.2.1"
|
||||
"@xterm/addon-fit": "0.10.0",
|
||||
"@xterm/xterm": "^5.5.0",
|
||||
"chroma-js": "^2.4.2",
|
||||
"dayjs": "^1.11.11",
|
||||
"dotenv": "^16.4.5",
|
||||
"glob": "^10.3.12",
|
||||
"jotai": "^2.8.0",
|
||||
"next": "^14.2.3",
|
||||
"postcss-preset-mantine": "^1.15.0",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
"sass": "^1.76.0",
|
||||
"superjson": "2.2.1",
|
||||
"use-deep-compare-effect": "^1.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||
"@homarr/prettier-config": "workspace:^0.1.0",
|
||||
"@homarr/tsconfig": "workspace:^0.1.0",
|
||||
"@types/chroma-js": "3.1.2",
|
||||
"@types/node": "^24.12.0",
|
||||
"@types/prismjs": "^1.26.6",
|
||||
"@types/react": "19.2.14",
|
||||
"@types/react-dom": "19.2.3",
|
||||
"@types/swagger-ui-react": "^5.18.0",
|
||||
"concurrently": "^9.2.1",
|
||||
"eslint": "^9.39.4",
|
||||
"node-loader": "^2.1.0",
|
||||
"prettier": "^3.8.1",
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
"@types/chroma-js": "2.4.4",
|
||||
"@types/node": "^20.12.8",
|
||||
"@types/react": "^18.3.1",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"concurrently": "^8.2.2",
|
||||
"eslint": "^8.57.0",
|
||||
"prettier": "^3.2.5",
|
||||
"tsx": "4.9.0",
|
||||
"typescript": "^5.4.5"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"extends": [
|
||||
"@homarr/eslint-config/base",
|
||||
"@homarr/eslint-config/nextjs",
|
||||
"@homarr/eslint-config/react"
|
||||
]
|
||||
},
|
||||
"prettier": "@homarr/prettier-config"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 575 289.83" width="575" height="289.83"><defs><path d="M575 24.91C573.44 12.15 563.97 1.98 551.91 0C499.05 0 76.18 0 23.32 0C10.11 2.17 0 14.16 0 28.61C0 51.84 0 237.64 0 260.86C0 276.86 12.37 289.83 27.64 289.83C79.63 289.83 495.6 289.83 547.59 289.83C561.65 289.83 573.26 278.82 575 264.57C575 216.64 575 48.87 575 24.91Z" id="d1pwhf9wy2"></path><path d="M69.35 58.24L114.98 58.24L114.98 233.89L69.35 233.89L69.35 58.24Z" id="g5jjnq26yS"></path><path d="M201.2 139.15C197.28 112.38 195.1 97.5 194.67 94.53C192.76 80.2 190.94 67.73 189.2 57.09C185.25 57.09 165.54 57.09 130.04 57.09L130.04 232.74L170.01 232.74L170.15 116.76L186.97 232.74L215.44 232.74L231.39 114.18L231.54 232.74L271.38 232.74L271.38 57.09L211.77 57.09L201.2 139.15Z" id="i3Prh1JpXt"></path><path d="M346.71 93.63C347.21 95.87 347.47 100.95 347.47 108.89C347.47 115.7 347.47 170.18 347.47 176.99C347.47 188.68 346.71 195.84 345.2 198.48C343.68 201.12 339.64 202.43 333.09 202.43C333.09 190.9 333.09 98.66 333.09 87.13C338.06 87.13 341.45 87.66 343.25 88.7C345.05 89.75 346.21 91.39 346.71 93.63ZM367.32 230.95C372.75 229.76 377.31 227.66 381.01 224.67C384.7 221.67 387.29 217.52 388.77 212.21C390.26 206.91 391.14 196.38 391.14 180.63C391.14 174.47 391.14 125.12 391.14 118.95C391.14 102.33 390.49 91.19 389.48 85.53C388.46 79.86 385.93 74.71 381.88 70.09C377.82 65.47 371.9 62.15 364.12 60.13C356.33 58.11 343.63 57.09 321.54 57.09C319.27 57.09 307.93 57.09 287.5 57.09L287.5 232.74L342.78 232.74C355.52 232.34 363.7 231.75 367.32 230.95Z" id="a4ov9rRGQm"></path><path d="M464.76 204.7C463.92 206.93 460.24 208.06 457.46 208.06C454.74 208.06 452.93 206.98 452.01 204.81C451.09 202.65 450.64 197.72 450.64 190C450.64 185.36 450.64 148.22 450.64 143.58C450.64 135.58 451.04 130.59 451.85 128.6C452.65 126.63 454.41 125.63 457.13 125.63C459.91 125.63 463.64 126.76 464.6 129.03C465.55 131.3 466.03 136.15 466.03 143.58C466.03 146.58 466.03 161.58 466.03 188.59C465.74 197.84 465.32 203.21 464.76 204.7ZM406.68 231.21L447.76 231.21C449.47 224.5 450.41 220.77 450.6 220.02C454.32 224.52 458.41 227.9 462.9 230.14C467.37 232.39 474.06 233.51 479.24 233.51C486.45 233.51 492.67 231.62 497.92 227.83C503.16 224.05 506.5 219.57 507.92 214.42C509.34 209.26 510.05 201.42 510.05 190.88C510.05 185.95 510.05 146.53 510.05 141.6C510.05 131 509.81 124.08 509.34 120.83C508.87 117.58 507.47 114.27 505.14 110.88C502.81 107.49 499.42 104.86 494.98 102.98C490.54 101.1 485.3 100.16 479.26 100.16C474.01 100.16 467.29 101.21 462.81 103.28C458.34 105.35 454.28 108.49 450.64 112.7C450.64 108.89 450.64 89.85 450.64 55.56L406.68 55.56L406.68 231.21Z" id="fk968BpsX"></path></defs><g><g><g><use xlink:href="#d1pwhf9wy2" opacity="1" fill="#f6c700" fill-opacity="1"></use><g><use xlink:href="#d1pwhf9wy2" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="0"></use></g></g><g><use xlink:href="#g5jjnq26yS" opacity="1" fill="#000000" fill-opacity="1"></use><g><use xlink:href="#g5jjnq26yS" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="0"></use></g></g><g><use xlink:href="#i3Prh1JpXt" opacity="1" fill="#000000" fill-opacity="1"></use><g><use xlink:href="#i3Prh1JpXt" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="0"></use></g></g><g><use xlink:href="#a4ov9rRGQm" opacity="1" fill="#000000" fill-opacity="1"></use><g><use xlink:href="#a4ov9rRGQm" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="0"></use></g></g><g><use xlink:href="#fk968BpsX" opacity="1" fill="#000000" fill-opacity="1"></use><g><use xlink:href="#fk968BpsX" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="0"></use></g></g></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 3.9 KiB |
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="708.767" height="179.332">
|
||||
<path fill="#d51007" d="m158.431 165.498-8.354-22.708s-13.575 15.14-33.932 15.14c-18.013 0-30.802-15.662-30.802-40.721 0-32.106 16.182-43.591 32.107-43.591 22.969 0 30.277 14.878 36.543 33.934l8.354 26.103c8.351 25.318 24.013 45.678 69.17 45.678 32.37 0 54.295-9.918 54.295-36.02 0-21.143-12.009-32.107-34.458-37.328l-16.705-3.654c-11.484-2.61-14.877-7.309-14.877-15.14 0-8.875 7.046-14.096 18.533-14.096 12.529 0 19.315 4.699 20.36 15.923l26.102-3.133c-2.088-23.492-18.271-33.15-44.896-33.15-23.491 0-46.462 8.875-46.462 37.327 0 17.75 8.614 28.975 30.277 34.195l17.752 4.175c13.312 3.133 17.748 8.614 17.748 16.185 0 9.656-9.396 13.572-27.146 13.572-26.364 0-37.325-13.834-43.591-32.89l-8.614-26.101c-10.961-33.934-28.452-46.463-63.169-46.463-38.37 0-58.731 24.275-58.731 65.517 0 39.677 20.361 61.08 56.906 61.08 29.492 0 43.59-13.834 43.59-13.834zM46.726 153.229c-2.61.784-5.221 1.306-8.614 1.306-6.265 0-10.703-2.87-10.703-10.442V1.827H0v148.792c0 19.577 13.575 27.672 29.497 27.672 5.221 0 10.181-.785 16.446-2.349l.783-22.713zm330.185-4.176c-6.787 4.701-12.529 7.051-20.36 7.051-9.92 0-15.401-5.221-15.401-18.012V77.006h36.023V55.603H341.41V26.625l-27.669 3.394v25.583h-17.49v21.403h17.49v66.826c0 24.02 13.834 35.5 36.284 35.5 12.269 0 23.232-2.346 31.847-7.305l-4.961-22.973zm23.807 9.396c0 10.705 8.354 19.318 19.056 19.318 11.226 0 19.578-8.613 19.578-19.318 0-10.963-8.353-19.313-19.578-19.313-10.702 0-19.056 8.35-19.056 19.313zm67.009-81.443v99.195h27.409V77.006h30.803V55.603h-30.803V44.638c0-16.444 7.049-21.665 18.534-21.665 8.092 0 13.574 1.825 19.839 5.221l4.437-22.974C530.638 1.827 522.023 0 511.582 0c-22.973 0-43.855 10.963-43.855 43.593v12.01h-17.489v21.403h17.489zm167.427 2.352c-3.133-19.578-15.923-26.629-32.63-26.629-16.706 0-31.062 7.571-37.329 26.104l-3.393-23.23h-22.188v120.598h27.409v-68.129c0-23.235 12.008-32.11 24.799-32.11 13.312 0 18.795 8.875 18.795 23.232V176.2h27.147v-68.39c0-22.974 12.269-31.849 25.061-31.849 13.052 0 18.532 8.875 18.532 23.232v77.006h27.409v-86.66c0-25.843-15.14-36.81-35.24-36.81-16.965 0-32.107 7.571-38.372 26.629z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.2 KiB |
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg width="1024" height="1024" version="1.1" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<clipPath id="a">
|
||||
<circle cx="512" cy="512" r="410" fill="#989898" stroke-width="3.5906"/>
|
||||
</clipPath>
|
||||
<clipPath id="b">
|
||||
<path d="m512 636l0-565 -330 565 330 0z" fill="#000"/>
|
||||
<path d="m512 388l0 565 330-565 -330 0z" fill="#000"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g id="lidarr-group-logo" transform="translate(5e-6 .26738)">
|
||||
<circle id="lidarr-black-circle" cx="512" cy="512" r="410" stroke-width="1.8"/>
|
||||
<path id="lidarr-honeycomb-a" d="m852.12 33.49l23.46 14.44 23.22-14.44 0-28.87 -23.22-14.44 -23.46 14.44 0 28.87zm-46.44-28.87l-23.22-14.44 -23.2 14.44 0 28.87 23.2 14.44 23.22-14.44 0-28.87 23.22-14.44 23.22 14.44m-46.44 28.87l23.22 14.44 23.22-14.44m-46.44 57.49l0 28.87 23.22 14.44 23.22-14.44 0-28.87 -23.22-14.18 -23.22 14.18 -23.22-14.18 -23.2 14.18m92.86 28.87l23.46 14.44 23.22-14.44 0-28.87 -23.22-14.18 -23.46 14.18m23.46-43.05l0 28.87m-46.68-28.87l0 28.87m69.9-72.18l23.22-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.2-14.44 23.22 14.44 0 28.87 23.22 14.44 0 28.87 -23.22 14.18 0 28.87 23.22 14.44 0 28.87 -23.22 14.44 0 28.87 23.22 14.44 0 28.87 -23.22 14.16 0 28.87 23.22 14.44 0 28.87 -23.22 14.44 0 28.87 23.22 14.44 0 28.87 -23.22 14.16 0 28.87 23.22 14.44 0 28.87 -23.22 14.45 0 28.87 23.22 14.44 0 28.87 -23.22 14.16 0 28.87 23.22 14.44 0 28.87 -23.22 14.44 0 28.87 23.22 14.44 0 28.87 -23.22 14.16 0 28.87 23.22 14.44 0 28.87 -23.22 14.44 0 28.87 23.22 14.44 0 28.87 -23.22 14.18 0 28.87 23.22 14.44 0 28.87 -23.22 14.44 -23.22-14.44 -23.2 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.46 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.2 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.46 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.2 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.2 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.46 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.22 14.44 -23.2-14.44 -23.22 14.44 -23.22-14.44 -23.46 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 0-28.87 -23.22-14.44 0-28.87 23.22-14.18 0-28.87 -23.22-14.44 0-28.87 23.22-14.44 0-28.87 -23.22-14.44 0-28.87 23.22-14.16 0-28.87 -23.22-14.44 0-28.87 23.22-14.44 0-28.87 -23.22-14.44 0-28.87 23.22-14.16 0-28.87 -23.22-14.44 0-28.87 23.22-14.45 0-28.87 -23.22-14.44 0-28.87 23.22-14.16 0-28.87 -23.22-14.44 0-28.87 23.22-14.44 0-28.87 -23.22-14.44 0-28.87 23.22-14.16 0-28.87 -23.22-14.44 0-28.87 23.22-14.44 0-28.87 -23.22-14.44 0-28.87 23.22-14.18 0-28.87 -23.22-14.44 0-28.87 23.22-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.46-14.44 23.22 14.44 23.22-14.44 23.2 14.44 23.22-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.46-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.2-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.2-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.46-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.22-14.44 23.22 14.44m-46.44 0l0 28.87 23.22 14.44 23.22-14.44m-46.44 57.49l0 28.87 23.22 14.44 23.22-14.44 0-28.87 -23.22-14.18 -23.22 14.18 -23.22-14.18 -23.22 14.18m116.08-43.05l0 28.87m-46.42-28.87l0 28.87m23.22 100.79l0 28.87 23.2 14.44 23.22-14.44 0-28.87 -23.22-14.44 -23.2 14.44 -23.22-14.44 -23.22 14.44 0 28.87 23.22 14.44 23.22-14.44m46.42-86.61l-23.22 14.44 0 28.87m-23.2-43.31l23.2 14.44m-46.42 0l0 28.87m0 57.74l0 28.87 23.22 14.16 23.2-14.16 0-28.87m46.44-86.61l0 28.87 23.22 14.44 23.46-14.44 0-28.87m-46.68 28.87l-23.22 14.44m-23.22 72.18l23.22 14.16 23.22-14.16 0-28.87 -23.22-14.44m46.44-28.87l0 28.87 23.46 14.44 23.22-14.44 0-28.87 -23.22-14.44m0 57.74l0 28.87 23.22 14.16 23.22-14.16 0-28.87 -23.22-14.44m-69.9 14.44l23.22-14.44m-185.74-201.84l0 28.87 23.22 14.44 23.22-14.44m-139.56-28.87l0 28.87 23.22 14.44 23.22-14.44 0-28.87m0 28.87l23.46 14.44 23.22-14.44m-46.68 57.49l0 28.87 23.46 14.44 23.22-14.44 0-28.87 -23.22-14.18 -23.46 14.18 -23.22-14.18 -23.22 14.18 0 28.87 23.22 14.44 23.22-14.44m-23.22-71.92l0 28.87m93.12-28.87l0 28.87m-46.44-28.87l0 28.87m-116.32-72.18l0 28.87 23.2 14.44 23.22-14.44m-92.86-28.87l0 28.87 23.22 14.44 23.22-14.44m-23.22 43.31l-23.22 14.18 0 28.87 23.22 14.44 23.22-14.44 0-28.87 -23.22-14.18zm69.64 14.18l-23.22-14.18 -23.2 14.18m-23.22-43.05l0 28.87m46.42-28.87l0 28.87m23.22 43.05l-23.22 14.44 0 28.87 23.22 14.44 23.22-14.44 0-28.87m-92.86 0l0 28.87 23.22 14.44 23.2-14.44m-46.42 86.61l23.22 14.16 23.2-14.16 0-28.87 -23.2-14.44 -23.22 14.44 0 28.87 -23.22 14.16 0 28.87 23.22 14.44 23.22-14.44 0-28.87m23.2-43.03l23.22-14.44 0-28.87m-46.42-57.74l23.2 14.44m-23.2 72.18l0-28.87m116.32-43.31l0 28.87 23.22 14.44 23.22-14.44 0-28.87 -23.22-14.44m-93.12 86.61l23.22 14.44 23.22-14.44 0-28.87 -23.22-14.44m46.68 0l-23.46 14.44m23.46 72.18l23.22 14.16 23.22-14.16 0-28.87 -23.22-14.44 -23.22 14.44 0 28.87 -23.46 14.16 0 28.87 -23.22 14.44 0 28.87 23.22 14.44 23.46-14.44 0-28.87 -23.46-14.44m-69.66-43.03l23.22 14.16 23.22-14.16 0-28.87m23.22-14.44l23.46 14.44m23.22-14.44l0-28.87m0 86.34l0 28.87 23.22 14.44 23.22-14.44 0-28.87 -23.22-14.16m-69.9 100.77l0 28.87 23.46 14.44 23.22-14.44 0-28.87 -23.22-14.44m23.22 43.31l23.22 14.44 23.22-14.44 0-28.87 -23.22-14.44 -23.22 14.44m-23.22-43.31l23.22-14.44m23.22 14.44l0 28.87m-93.12-28.87l-23.22-14.44 -23.22 14.44 0 28.87 23.22 14.44 23.22-14.44m-23.22-43.31l0-28.87m-69.64 72.18l-23.22 14.44 0 28.87 23.22 14.44 23.22-14.44 0-28.87 -23.22-14.44zm23.22 4Line truncated
|
||||
<ellipse cx="512" cy="512" rx="460" ry="460" style="fill:none;stroke-width:99;stroke:#e5e5e5"/>
|
||||
<ellipse cx="512" cy="512" rx="270" ry="270" style="fill:#e5e5e5;stroke-width:76;stroke:#e5e5e5"/>
|
||||
<ellipse ry="410" rx="410" cy="512" cx="512" style="fill-opacity:null;fill:none;stroke-width:12;stroke:#009252"/>
|
||||
<path d="m512 636l0-565 -330 565 330 0z" fill="#000"/>
|
||||
<path d="m512 388l0 565 330-565 -330 0z" fill="#000"/>
|
||||
<path id="lidarr-honeycomb-b" d="m852.12 33.49l23.46 14.44 23.22-14.44 0-28.87 -23.22-14.44 -23.46 14.44 0 28.87zm-46.44-28.87l-23.22-14.44 -23.2 14.44 0 28.87 23.2 14.44 23.22-14.44 0-28.87 23.22-14.44 23.22 14.44m-46.44 28.87l23.22 14.44 23.22-14.44m-46.44 57.49l0 28.87 23.22 14.44 23.22-14.44 0-28.87 -23.22-14.18 -23.22 14.18 -23.22-14.18 -23.2 14.18m92.86 28.87l23.46 14.44 23.22-14.44 0-28.87 -23.22-14.18 -23.46 14.18m23.46-43.05l0 28.87m-46.68-28.87l0 28.87m69.9-72.18l23.22-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.2-14.44 23.22 14.44 0 28.87 23.22 14.44 0 28.87 -23.22 14.18 0 28.87 23.22 14.44 0 28.87 -23.22 14.44 0 28.87 23.22 14.44 0 28.87 -23.22 14.16 0 28.87 23.22 14.44 0 28.87 -23.22 14.44 0 28.87 23.22 14.44 0 28.87 -23.22 14.16 0 28.87 23.22 14.44 0 28.87 -23.22 14.45 0 28.87 23.22 14.44 0 28.87 -23.22 14.16 0 28.87 23.22 14.44 0 28.87 -23.22 14.44 0 28.87 23.22 14.44 0 28.87 -23.22 14.16 0 28.87 23.22 14.44 0 28.87 -23.22 14.44 0 28.87 23.22 14.44 0 28.87 -23.22 14.18 0 28.87 23.22 14.44 0 28.87 -23.22 14.44 -23.22-14.44 -23.2 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.46 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.2 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.46 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.2 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.2 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.46 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.22 14.44 -23.2-14.44 -23.22 14.44 -23.22-14.44 -23.46 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 -23.22 14.44 -23.22-14.44 0-28.87 -23.22-14.44 0-28.87 23.22-14.18 0-28.87 -23.22-14.44 0-28.87 23.22-14.44 0-28.87 -23.22-14.44 0-28.87 23.22-14.16 0-28.87 -23.22-14.44 0-28.87 23.22-14.44 0-28.87 -23.22-14.44 0-28.87 23.22-14.16 0-28.87 -23.22-14.44 0-28.87 23.22-14.45 0-28.87 -23.22-14.44 0-28.87 23.22-14.16 0-28.87 -23.22-14.44 0-28.87 23.22-14.44 0-28.87 -23.22-14.44 0-28.87 23.22-14.16 0-28.87 -23.22-14.44 0-28.87 23.22-14.44 0-28.87 -23.22-14.44 0-28.87 23.22-14.18 0-28.87 -23.22-14.44 0-28.87 23.22-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.46-14.44 23.22 14.44 23.22-14.44 23.2 14.44 23.22-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.46-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.2-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.2-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.46-14.44 23.22 14.44 23.22-14.44 23.22 14.44 23.22-14.44 23.22 14.44m-46.44 0l0 28.87 23.22 14.44 23.22-14.44m-46.44 57.49l0 28.87 23.22 14.44 23.22-14.44 0-28.87 -23.22-14.18 -23.22 14.18 -23.22-14.18 -23.22 14.18m116.08-43.05l0 28.87m-46.42-28.87l0 28.87m23.22 100.79l0 28.87 23.2 14.44 23.22-14.44 0-28.87 -23.22-14.44 -23.2 14.44 -23.22-14.44 -23.22 14.44 0 28.87 23.22 14.44 23.22-14.44m46.42-86.61l-23.22 14.44 0 28.87m-23.2-43.31l23.2 14.44m-46.42 0l0 28.87m0 57.74l0 28.87 23.22 14.16 23.2-14.16 0-28.87m46.44-86.61l0 28.87 23.22 14.44 23.46-14.44 0-28.87m-46.68 28.87l-23.22 14.44m-23.22 72.18l23.22 14.16 23.22-14.16 0-28.87 -23.22-14.44m46.44-28.87l0 28.87 23.46 14.44 23.22-14.44 0-28.87 -23.22-14.44m0 57.74l0 28.87 23.22 14.16 23.22-14.16 0-28.87 -23.22-14.44m-69.9 14.44l23.22-14.44m-185.74-201.84l0 28.87 23.22 14.44 23.22-14.44m-139.56-28.87l0 28.87 23.22 14.44 23.22-14.44 0-28.87m0 28.87l23.46 14.44 23.22-14.44m-46.68 57.49l0 28.87 23.46 14.44 23.22-14.44 0-28.87 -23.22-14.18 -23.46 14.18 -23.22-14.18 -23.22 14.18 0 28.87 23.22 14.44 23.22-14.44m-23.22-71.92l0 28.87m93.12-28.87l0 28.87m-46.44-28.87l0 28.87m-116.32-72.18l0 28.87 23.2 14.44 23.22-14.44m-92.86-28.87l0 28.87 23.22 14.44 23.22-14.44m-23.22 43.31l-23.22 14.18 0 28.87 23.22 14.44 23.22-14.44 0-28.87 -23.22-14.18zm69.64 14.18l-23.22-14.18 -23.2 14.18m-23.22-43.05l0 28.87m46.42-28.87l0 28.87m23.22 43.05l-23.22 14.44 0 28.87 23.22 14.44 23.22-14.44 0-28.87m-92.86 0l0 28.87 23.22 14.44 23.2-14.44m-46.42 86.61l23.22 14.16 23.2-14.16 0-28.87 -23.2-14.44 -23.22 14.44 0 28.87 -23.22 14.16 0 28.87 23.22 14.44 23.22-14.44 0-28.87m23.2-43.03l23.22-14.44 0-28.87m-46.42-57.74l23.2 14.44m-23.2 72.18l0-28.87m116.32-43.31l0 28.87 23.22 14.44 23.22-14.44 0-28.87 -23.22-14.44m-93.12 86.61l23.22 14.44 23.22-14.44 0-28.87 -23.22-14.44m46.68 0l-23.46 14.44m23.46 72.18l23.22 14.16 23.22-14.16 0-28.87 -23.22-14.44 -23.22 14.44 0 28.87 -23.46 14.16 0 28.87 -23.22 14.44 0 28.87 23.22 14.44 23.46-14.44 0-28.87 -23.46-14.44m-69.66-43.03l23.22 14.16 23.22-14.16 0-28.87m23.22-14.44l23.46 14.44m23.22-14.44l0-28.87m0 86.34l0 28.87 23.22 14.44 23.22-14.44 0-28.87 -23.22-14.16m-69.9 100.77l0 28.87 23.46 14.44 23.22-14.44 0-28.87 -23.22-14.44m23.22 43.31l23.22 14.44 23.22-14.44 0-28.87 -23.22-14.44 -23.22 14.44m-23.22-43.31l23.22-14.44m23.22 14.44l0 28.87m-93.12-28.87l-23.22-14.44 -23.22 14.44 0 28.87 23.22 14.44 23.22-14.44m-23.22-43.31l0-28.87m-69.64 72.18l-23.22 14.44 0 28.87 23.22 14.44 23.22-14.44 0-28.87 -23.22-14.44zm23.22 4Line truncated
|
||||
<path d="m512 636l0-565 -330 565 330 0z" style="fill:none;stroke-width:16;stroke:#009252;"/>
|
||||
<path d="m512 388l0 565 330-565 -330 0z" style="fill:none;stroke-width:16;stroke:#009252;"/>
|
||||
<ellipse cx="512" cy="512" rx="150" ry="150" style="fill-opacity:null;fill:#009252;stroke-opacity:null;stroke-width:null;stroke:null"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 54 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 139.3 512.2 233.5"><path d="M256 139.3c-53 0-97.9 35.8-112.1 84.4-12.2-25.5-38.2-43.4-68.2-43.4C34.2 180.2 0 214.4 0 256s34.2 75.8 75.8 75.8c30 0 55.9-17.9 68.2-43.4 14.1 48.6 59.1 84.4 112.1 84.4S354 337 368.2 288.4c12.2 25.5 38.2 43.4 68.2 43.4 41.6 0 75.8-34.2 75.8-75.8s-34.2-75.8-75.8-75.8c-30 0-55.9 17.9-68.2 43.4-14.3-48.5-59.2-84.3-112.2-84.3m0 45c39.9 0 71.7 31.8 71.7 71.7s-31.8 71.7-71.7 71.7-71.7-31.8-71.7-71.7 31.8-71.7 71.7-71.7m-180.2 41c17.2 0 30.7 13.5 30.7 30.7S93 286.7 75.8 286.7 45.1 273.2 45.1 256s13.4-30.7 30.7-30.7m360.4 0c17.2 0 30.7 13.5 30.7 30.7s-13.5 30.7-30.7 30.7-30.7-13.5-30.7-30.7 13.5-30.7 30.7-30.7" style="fill:#3784c9"/></svg>
|
||||
|
Before Width: | Height: | Size: 739 B |
@@ -1 +0,0 @@
|
||||
<svg height="1024" viewBox="0 0 1024 1024" width="1024" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><path id="a" d="m0 0h1024v1024h-1024z"/><clipPath id="b"><use clip-rule="evenodd" xlink:href="#a"/></clipPath></defs><g clip-path="url(#b)"><use fill="none" xlink:href="#a"/><g transform="translate(70 21.00012)"><path d="m105.302 154.943 7.522 714.549c-60.173 7.522-105.30242-22.565-105.30242-82.737l-7.52158-594.205c0-188.03894 172.996-233.1684 278.298-157.9526l534.032 308.3846c75.216 52.651 90.259 150.431 52.651 218.125-7.521-52.651-30.086-82.737-75.216-112.823l-601.726-338.471c-45.129-30.0862-82.737-22.5646-82.737 45.13z" fill="#24292e"/><path d="m0 376.079c45.1295 15.043 90.259 7.521 127.867-15.043l616.769-361.036c37.608 52.651 30.087 105.302-15.043 135.388l-518.989 300.863c-75.216 37.608-172.9961 0-210.604-60.172z" fill="#24292e" transform="translate(60.17249 531.0214)"/><path d="m0 413.687 368.557-210.604-361.03543-203.083z" fill="#ffc230" transform="translate(240.6902 282.8092)"/></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB |
@@ -1 +0,0 @@
|
||||
<svg version="1.1" viewBox="0 0 1000 1000" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(.97895 0 0 .97895 -2.2026 -2.2026)"><g stroke="#443c3c" stroke-width="1.5"><circle cx="513" cy="513" r="510" fill="#eee"/><circle cx="513" cy="513" r="440" fill="#443c3c"/><circle cx="513" cy="513" r="387" fill="#8e2222"/></g><g stroke-width="1.5"><circle cx="513" cy="513" r="378" fill="#eee" stroke="#8e2222"/><circle cx="511.67" cy="514.33" r="265" fill="#443c3c" stroke="#443c3c"/></g><g stroke="#8e2222"><path d="m176.71 682.24-5.71-356.67c0.634-53.106 17.5-47.829 30.454-49.405 198.58 10.83 270.91 71.252 275.35 73.499 13.323 5.018 20.937 31.782 20.302 31.123 0.634 0.658 4.441 420.6 3.807 419.94 3.172 22.455-13.323 21.002-13.958 20.343-124.99-98.152-297.56-122.85-298.19-123.51-12.055-0.795-12.055-15.326-12.055-15.326zm670.08 0.82 5.711-357.54c-0.635-53.236-17.501-47.946-30.456-49.526-198.6 10.857-270.93 71.426-275.38 73.679-13.325 5.03-20.939 31.859-20.304 31.199-0.635 0.66-4.442 421.63-3.807 420.97-3.173 22.51 13.325 21.053 13.959 20.393 125-98.392 297.58-123.15 298.22-123.81 12.056-0.797 12.056-15.363 12.056-15.363z" fill="#eee" stroke-width="10"/><path d="m174.14 739.57-5.802-356.67c0.645-53.106 17.782-47.829 30.945-49.405 201.79 10.83 275.28 71.252 279.8 73.499 13.539 5.018 21.275 31.782 20.63 31.123 0.645 0.658 4.513 420.6 3.868 419.94 3.224 22.455-13.539 21.002-14.183 20.343-127-98.152-302.36-122.85-303.01-123.51-12.249-0.795-12.249-15.326-12.249-15.326zm675.22 0.49 5.803-357.54c-0.645-53.236-17.784-47.946-30.948-49.526-201.81 10.857-275.31 71.426-279.82 73.679-13.54 5.03-21.277 31.859-20.632 31.199-0.645 0.66-4.513 421.63-3.869 420.97-3.224 22.51 13.54 21.053 14.184 20.393 127.02-98.392 302.39-123.15 303.03-123.81 12.25-0.797 12.25-15.363 12.25-15.363z" fill="#8e2222" stroke-width="5"/></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 1.8 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><g clip-rule="evenodd"><path fill="#eee" fill-rule="evenodd" d="M47.978 24c0 6.602-2.331 12.26-6.993 16.974a3.773 3.773 0 0 1-.52.509 20.53 20.53 0 0 1-2.435 2.047C33.988 46.51 29.318 48 24.022 48c-5.304 0-9.966-1.49-13.986-4.47a21.726 21.726 0 0 1-2.988-2.556c-3.622-3.6-5.846-7.783-6.672-12.548-.162-.93-.27-1.874-.32-2.833a38.27 38.27 0 0 1 0-3.197c0-.052.014-.104.044-.155.346-5.887 2.662-10.973 6.948-15.259C11.762 2.327 17.42 0 24.022 0c6.624 0 12.279 2.327 16.963 6.982 4.662 4.743 6.993 10.416 6.993 17.018z"/><path fill="#3a3f51" fill-rule="evenodd" d="m43.098 9.405-4.957 4.957c-2.899 2.899-3.153 5.422-3.153 9.87 0 3.97.63 7.602 3.585 10.556 2.156 2.157 4.204 4.194 4.204 4.194a27.962 27.962 0 0 1-1.792 1.992 3.773 3.773 0 0 1-.52.509 20.05 20.05 0 0 1-1.749 1.538l-3.883-3.884c-3.452-3.452-6.196-3.784-10.756-3.784-4.375 0-7.352.403-10.556 3.607a2715.831 2715.831 0 0 0-4.105 4.116 21.196 21.196 0 0 1-2.368-2.102 27.739 27.739 0 0 1-1.737-1.903s2.168-2.18 4.238-4.25c3.066-3.065 3.563-6.62 3.563-10.589 0-3.872-.636-7.485-3.452-10.301C7.705 11.975 5 9.284 5 9.284a25.954 25.954 0 0 1 2.047-2.302A29.761 29.761 0 0 1 9.04 5.201l4.504 4.503c2.877 2.877 6.565 3.618 10.533 3.618 4.087 0 7.763-.791 10.756-3.784 1.84-1.841 4.27-4.26 4.27-4.26a25.168 25.168 0 0 1 1.882 1.704c.767.782 1.471 1.59 2.113 2.423z"/><path fill="#0cf" fill-rule="evenodd" d="M17.438 25.228a6.986 6.986 0 0 1-.1-1.228c0-.155.005-.303.012-.443 0-.014.004-.029.011-.044.096-1.63.738-3.039 1.925-4.227 1.306-1.29 2.874-1.936 4.703-1.936 1.837 0 3.404.645 4.703 1.936 1.29 1.313 1.936 2.884 1.936 4.714s-.645 3.397-1.936 4.703c-.045.051-.093.1-.144.143a6.056 6.056 0 0 1-.675.565c-1.121.826-2.416 1.239-3.884 1.239s-2.759-.413-3.873-1.24a5.818 5.818 0 0 1-.83-.707c-1.003-.996-1.619-2.155-1.848-3.475z"/><path fill="none" stroke="#0cf" stroke-miterlimit="1" stroke-width=".4426" d="m34.943 13.223-3.32 3.242M6.834 7.198l9.044 9.012M34.6 34.855l6.154 6.369m.41-34.056-6.22 6.056M7.18 41.107l6.053-6.063"/><path fill="none" stroke="#0cf" stroke-miterlimit="1" stroke-width="1.5491" d="m34.943 13.223-3.75 3.806m-18.12-3.617 3.806 3.795m-3.662 17.854 3.706-3.851m13.705-.309 3.99 3.971"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.2 KiB |
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="100px" height="54px" viewBox="0 0 100 54" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Logo tvdb</title>
|
||||
<g id="Logo-tvdb" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<path d="M0,5.09590006 C0,1.81024006 2.9636,-0.441498938 6.46228,0.0733078623 L6.46228,0.0733078623 L52.10124,6.03470006 C54.15254,6.33652006 55.78724,8.54666006 55.78724,10.9536001 L55.78724,10.9536001 L55.78654,17.1835001 C51.94104,19.7605001 49.42044,24.0737001 49.42044,28.9596001 C49.42044,33.8924001 51.87974,38.1680001 55.78724,40.7361001 L55.78724,40.7361001 L55.78724,43.4756001 C55.78724,45.8825001 54.15254,48.0927001 52.10124,48.3945001 L52.10124,48.3945001 L11.60314,53.9266001 C8.10444,54.4417001 5.14084,52.1897001 5.14084,48.9040001 L5.14084,48.9040001 Z M19.68044,10.8218001 L13.66114,10.8218001 L13.66114,18.7064001 L9.84244,18.7064001 L9.84244,23.2621001 L13.66114,23.2621001 L13.66114,32.0227001 C13.4846091,37.5274601 15.6467584,39.9923503 20.6149401,40.0386142 L25.25134,40.0387001 L25.25134,35.4830001 L22.87064,35.4830001 C20.17484,35.3516001 19.59134,34.5631001 19.68074,31.0149001 L19.68074,23.2617001 L27.08014,23.2617001 L33.93424,40.0384001 L40.40294,40.0384001 L49.83694,18.7061001 L43.45734,18.7061001 L37.34794,33.3806001 L31.77694,18.7064001 L19.68044,18.7064001 L19.68044,10.8218001 Z" id="Combined-Shape" fill="#6CD591" fill-rule="nonzero"></path>
|
||||
<path d="M88.60974,18.2771001 C92.51784,18.2771001 95.12314,19.2407001 97.09994,21.4310001 C98.71734,23.1831001 99.57074,25.7677001 99.57074,28.6584001 C99.57074,32.8634001 97.86394,36.1487001 94.76414,38.0323001 C92.74234,39.2590001 90.99054,39.6094001 87.03734,39.6094001 L77.24404,39.6094001 L77.24404,10.3925001 L83.26404,10.3925001 L83.26404,18.2771001 L88.60974,18.2771001 Z M83.26404,35.0537001 L87.71094,35.0537001 C91.26004,35.0537001 93.41634,32.6884001 93.41634,28.8334001 C93.41634,24.8035001 91.52964,22.8324001 87.71094,22.8324001 L83.26404,22.8324001 L83.26404,35.0537001 Z" id="Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
<path d="M68.01354,10.3925001 L74.03354,10.3925001 L74.03354,39.6094001 L63.65594,39.6094001 C59.43354,39.6094001 57.41174,38.9962001 55.25524,37.1126001 C53.05394,35.1416001 51.93124,32.3384001 51.93124,28.7898001 C51.93124,25.1102001 53.14404,22.3070001 55.70494,20.2481001 C57.32204,18.9342001 59.52364,18.2771001 62.35354,18.2771001 L68.01384,18.2771001 L68.01384,10.3925001 L68.01354,10.3925001 Z M68.01354,22.8327001 L63.65594,22.8327001 C60.15224,22.8327001 58.04064,25.0667001 58.04064,28.7898001 C58.04064,32.6884001 60.19654,35.0537001 63.65594,35.0537001 L68.01354,35.0537001 L68.01354,22.8327001 Z" id="Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.8 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 190.24 81.52"><defs><style>.cls-1{fill:url(#linear-gradient);}</style><linearGradient id="linear-gradient" y1="40.76" x2="190.24" y2="40.76" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#90cea1"/><stop offset="0.56" stop-color="#3cbec9"/><stop offset="1" stop-color="#00b3e5"/></linearGradient></defs><title>Asset 2</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M105.67,36.06h66.9A17.67,17.67,0,0,0,190.24,18.4h0A17.67,17.67,0,0,0,172.57.73h-66.9A17.67,17.67,0,0,0,88,18.4h0A17.67,17.67,0,0,0,105.67,36.06Zm-88,45h76.9A17.67,17.67,0,0,0,112.24,63.4h0A17.67,17.67,0,0,0,94.57,45.73H17.67A17.67,17.67,0,0,0,0,63.4H0A17.67,17.67,0,0,0,17.67,81.06ZM10.41,35.42h7.8V6.92h10.1V0H.31v6.9h10.1Zm28.1,0h7.8V8.25h.1l9,27.15h6l9.3-27.15h.1V35.4h7.8V0H66.76l-8.2,23.1h-.1L50.31,0H38.51ZM152.43,55.67a15.07,15.07,0,0,0-4.52-5.52,18.57,18.57,0,0,0-6.68-3.08,33.54,33.54,0,0,0-8.07-1h-11.7v35.4h12.75a24.58,24.58,0,0,0,7.55-1.15A19.34,19.34,0,0,0,148.11,77a16.27,16.27,0,0,0,4.37-5.5,16.91,16.91,0,0,0,1.63-7.58A18.5,18.5,0,0,0,152.43,55.67ZM145,68.6A8.8,8.8,0,0,1,142.36,72a10.7,10.7,0,0,1-4,1.82,21.57,21.57,0,0,1-5,.55h-4.05v-21h4.6a17,17,0,0,1,4.67.63,11.66,11.66,0,0,1,3.88,1.87A9.14,9.14,0,0,1,145,59a9.87,9.87,0,0,1,1,4.52A11.89,11.89,0,0,1,145,68.6Zm44.63-.13a8,8,0,0,0-1.58-2.62A8.38,8.38,0,0,0,185.63,64a10.31,10.31,0,0,0-3.17-1v-.1a9.22,9.22,0,0,0,4.42-2.82,7.43,7.43,0,0,0,1.68-5,8.42,8.42,0,0,0-1.15-4.65,8.09,8.09,0,0,0-3-2.72,12.56,12.56,0,0,0-4.18-1.3,32.84,32.84,0,0,0-4.62-.33h-13.2v35.4h14.5a22.41,22.41,0,0,0,4.72-.5,13.53,13.53,0,0,0,4.28-1.65,9.42,9.42,0,0,0,3.1-3,8.52,8.52,0,0,0,1.2-4.68A9.39,9.39,0,0,0,189.66,68.47ZM170.21,52.72h5.3a10,10,0,0,1,1.85.18,6.18,6.18,0,0,1,1.7.57,3.39,3.39,0,0,1,1.22,1.13,3.22,3.22,0,0,1,.48,1.82,3.63,3.63,0,0,1-.43,1.8,3.4,3.4,0,0,1-1.12,1.2,4.92,4.92,0,0,1-1.58.65,7.51,7.51,0,0,1-1.77.2h-5.65Zm11.72,20a3.9,3.9,0,0,1-1.22,1.3,4.64,4.64,0,0,1-1.68.7,8.18,8.18,0,0,1-1.82.2h-7v-8h5.9a15.35,15.35,0,0,1,2,.15,8.47,8.47,0,0,1,2.05.55,4,4,0,0,1,1.57,1.18,3.11,3.11,0,0,1,.63,2A3.71,3.71,0,0,1,181.93,72.72Z"/></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.2 KiB |
@@ -1 +0,0 @@
|
||||
<svg viewBox="0 0 90 90" xmlns="http://www.w3.org/2000/svg"><g fill="none"><path fill="#31BEEC" d="M90 38.197v19.137L48.942 80.999V61.864z"/><path d="M41.086 61.863V81L0 57.333V38.197l18.566 10.687c.02.016.043.03.067.04l22.453 12.94Z" fill="#0095D5"/><path fill="#AEADAE" d="m61.621 45.506-16.607 9.576-16.622-9.576 16.622-9.575z"/><path fill="#0095D5" d="M86.086 31.416 69.464 40.99 48.942 29.15V10z"/><path fill="#31BEEC" d="M41.086 10v19.15l-20.55 11.827-16.621-9.561z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 484 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><defs><linearGradient id="a" x1="100%" x2="0" y1="0" y2="100%" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ff8d30"/><stop offset="1" stop-color="#e32929"/></linearGradient></defs><circle cx="50%" cy="50%" r="50%" fill="url(#a)"/><path fill="#fff" d="M246.6 200.8h18.7v110.6h-18.7zm-182.3 0H83v110.7H64.3zm91.1 123.9h18.7V367h-18.7zm-45.7-47.5h18.7v68.5h-18.7zm91.2 0h18.6v68.4h-18.6zm228.2-76.5h18.7v110.7h-18.7zM338 145.5h18.7v42.3H338zm45.7 21.2h18.7v68.2h-18.7zm-91.5 0h18.7v68.1h-18.7z"/></svg>
|
||||
|
Before Width: | Height: | Size: 577 B |
@@ -1,47 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="64mm"
|
||||
height="64mm"
|
||||
viewBox="0 0 64 64"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.2-alpha1 (b6a15bbbed, 2022-02-23)"
|
||||
sodipodi:docname="vgmdb.svg"
|
||||
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">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.1089995"
|
||||
inkscape:cx="96.017091"
|
||||
inkscape:cy="132.29021"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="1912"
|
||||
inkscape:window-y="456"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs2" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
style="fill:#000000;stroke-width:0.21854"
|
||||
d="m 24.915135,62.650271 c 0.887879,-1.778597 2.041345,-3.66055 2.243584,-3.66055 0.373389,0 3.112623,2.34553 4.058216,3.474939 l 0.933036,1.114407 h -3.849247 -3.849246 z m 12.769897,0.133716 c 0.188983,-1.699691 0.540579,-9.438559 0.541952,-11.928786 l 0.0013,-2.561742 1.233546,-0.358603 c 1.858993,-0.540424 4.864719,-0.351614 6.306093,0.396126 2.102595,1.090761 3.373658,3.018391 3.382575,5.129841 0.0167,3.956206 -2.25508,7.722455 -5.608397,9.297806 -1.304436,0.612809 -1.766356,0.710219 -3.720191,0.784508 l -2.230831,0.08482 0.09384,-0.843972 z M 15.28167,58.692354 C 13.855849,58.372721 13.307133,58.098082 12.027965,57.063833 10.767623,56.044804 9.571224,54.160633 8.9251418,52.177293 8.4791686,50.808245 8.4074221,50.178438 8.4306037,47.836119 8.5286648,37.927793 11.975024,28.061437 18.601259,18.719217 c 1.935825,-2.729288 2.971061,-3.715223 4.909347,-4.675547 2.754154,-1.364545 6.425257,-1.245307 7.097695,0.230534 0.528157,1.159175 -0.351225,2.928281 -5.658254,11.38306 -3.70676,5.905347 -6.114927,9.18009 -8.52131,11.587702 l -1.747431,1.748322 0.748093,2.185403 c 1.052426,3.074452 2.737855,6.406887 3.730724,7.376398 l 0.831803,0.812233 1.792285,-1.012255 c 0.985756,-0.556742 3.87521,-2.58299 6.421008,-4.502779 l 4.628722,-3.490523 -0.152738,4.29269 c -0.08401,2.36098 -0.222472,4.480622 -0.3077,4.710314 -0.332428,0.895893 -8.050465,7.1666 -10.09734,8.203831 -2.185833,1.107645 -5.028822,1.564407 -6.994493,1.123754 z m 12.832756,-0.03877 c -0.369353,-0.206871 -0.546974,-0.44325 -0.453135,-0.603036 0.708434,-1.206309 4.008342,-5.172791 4.307161,-5.177197 0.225634,-0.0033 -0.01427,3.110825 -0.312679,4.058824 -0.487124,1.547514 -2.288476,2.42313 -3.541347,1.721409 z M 54.400377,47.270961 c -2.064993,-1.073365 -4.152108,-1.442529 -8.74161,-1.546198 -3.114822,-0.07036 -4.685696,-0.01346 -5.837847,0.211437 l -1.576311,0.307699 -0.101497,-0.893553 C 38.087288,44.858893 37.933571,42.73579 37.801516,40.63234 l -0.240099,-3.824455 0.497396,-0.409308 c 3.74237,-3.079615 11.651909,-7.818064 15.417757,-9.236475 2.486857,-0.936679 2.235049,-2.072647 2.235049,10.082864 0,5.829561 -0.07376,10.585246 -0.163906,10.568187 -0.09015,-0.01705 -0.606449,-0.261044 -1.147336,-0.542192 z M 23.409747,36.75325 c 0.981959,-3.570355 4.756318,-11.031164 6.826933,-13.49486 0.464503,-0.552684 0.586271,-0.604153 0.775553,-0.327811 0.553602,0.808232 1.251919,4.110924 1.621318,7.668016 l 0.126807,1.221076 -3.079512,1.795215 c -1.693731,0.987367 -3.814306,2.281815 -4.71239,2.876551 -0.898084,0.594738 -1.666906,1.081339 -1.708492,1.081339 -0.04159,0 0.02582,-0.368786 0.149783,-0.819526 z m 13.184647,-7.110817 c -0.04629,-0.145705 -0.341909,-1.543377 -0.656926,-3.10594 -0.315019,-1.562562 -0.864147,-3.967401 -1.220285,-5.344086 l -0.647526,-2.503063 1.150575,-1.176622 c 0.632814,-0.647143 2.643448,-2.301196 4.468071,-3.675673 3.438183,-2.589963 4.301443,-3.419286 4.80161,-4.6128516 0.714642,-1.7053778 -0.03157,-3.7643498 -1.67217,-4.613896 -0.898369,-0.4651992 -1.181912,-0.4997701 -3.278104,-0.3996832 -2.190425,0.1045861 -4.050576,0.523224 -8.85088,1.9919437 l -1.092702,0.334327 0.546351,-0.4412242 c 6.292255,-5.0815261 14.525967,-6.98424479 19.646997,-4.540202 2.438424,1.163752 4.050578,3.1575295 5.198539,6.4291158 l 0.605044,1.7243152 0.0047,7.3023343 0.0047,7.302333 -2.622483,0.481857 c -4.702423,0.864027 -9.663403,2.365904 -14.706862,4.452327 -1.118146,0.462565 -1.619586,0.580467 -1.67861,0.394688 z"
|
||||
id="path6625" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.6 KiB |
@@ -1,141 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="18.035334mm"
|
||||
height="17.500378mm"
|
||||
viewBox="0 0 18.035334 17.500378"
|
||||
version="1.1"
|
||||
id="svg13826"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="cm.svg">
|
||||
<defs
|
||||
id="defs13820" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="8"
|
||||
inkscape:cx="-2.090004"
|
||||
inkscape:cy="33.752239"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="771"
|
||||
inkscape:window-x="1"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<metadata
|
||||
id="metadata13823">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-0.99262638,-1.174181)">
|
||||
<g
|
||||
id="g70"
|
||||
transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)">
|
||||
<path
|
||||
inkscape:export-ydpi="250.55"
|
||||
inkscape:export-xdpi="250.55"
|
||||
inkscape:export-filename="new.png"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3055"
|
||||
d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z"
|
||||
style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path3054-2-9"
|
||||
d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g3349"
|
||||
transform="translate(0.11778981,0.45794291)">
|
||||
<path
|
||||
inkscape:export-ydpi="376.57999"
|
||||
inkscape:export-xdpi="376.57999"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 8.236948,6.2914262 5.825001,0"
|
||||
id="path876" />
|
||||
<path
|
||||
inkscape:export-ydpi="376.57999"
|
||||
inkscape:export-xdpi="376.57999"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 5.723058,6.2914262 1.45834,0"
|
||||
id="path880" />
|
||||
<a
|
||||
id="a3346">
|
||||
<path
|
||||
id="path884"
|
||||
d="m 10.353619,8.4080928 3.70833,0"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
||||
inkscape:export-xdpi="376.57999"
|
||||
inkscape:export-ydpi="376.57999" />
|
||||
</a>
|
||||
<path
|
||||
inkscape:export-ydpi="376.57999"
|
||||
inkscape:export-xdpi="376.57999"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 7.839728,8.4080928 1.4583305,0"
|
||||
id="path888" />
|
||||
<path
|
||||
inkscape:export-ydpi="376.57999"
|
||||
inkscape:export-xdpi="376.57999"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 10.353619,10.52476 3.70833,0"
|
||||
id="path892" />
|
||||
<path
|
||||
inkscape:export-ydpi="376.57999"
|
||||
inkscape:export-xdpi="376.57999"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 7.839728,10.52476 1.4583305,0"
|
||||
id="path896" />
|
||||
<path
|
||||
inkscape:export-ydpi="376.57999"
|
||||
inkscape:export-xdpi="376.57999"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 8.236948,12.641428 5.825001,0"
|
||||
id="path900" />
|
||||
<path
|
||||
inkscape:export-ydpi="376.57999"
|
||||
inkscape:export-xdpi="376.57999"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 5.723058,12.641428 1.45834,0"
|
||||
id="path904" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 7.6 KiB |
@@ -1,84 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="18.035334mm"
|
||||
height="17.500378mm"
|
||||
viewBox="0 0 18.035334 17.500378"
|
||||
version="1.1"
|
||||
id="svg13826"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="ing.svg">
|
||||
<defs
|
||||
id="defs13820" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="8"
|
||||
inkscape:cx="-2.090004"
|
||||
inkscape:cy="28.752239"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="775"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<metadata
|
||||
id="metadata13823">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-0.99262638,-1.174181)">
|
||||
<g
|
||||
id="g70"
|
||||
transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)">
|
||||
<path
|
||||
inkscape:export-ydpi="250.55"
|
||||
inkscape:export-xdpi="250.55"
|
||||
inkscape:export-filename="new.png"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3055"
|
||||
d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z"
|
||||
style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path3054-2-9"
|
||||
d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<path
|
||||
id="path7709"
|
||||
pointer-events="none"
|
||||
d="m 12.75799,13.997178 -2.270701,0 -4.9209009,-6.1558617 -1.42366,0 0,-2.0149069 2.31473,0 4.9230119,6.1558536 1.37752,0 0,-1.593474 3.119869,2.599882 -3.119869,2.601983 z m -2.47616,-4.7552751 1.09864,-1.3754256 1.37752,0 0,1.593475 3.119869,-2.5998829 -3.119869,-2.601983 0,1.593483 -2.270701,0 -1.4571904,1.8241102 z m -3.5979219,1.3649431 -1.11752,1.400578 -1.42366,0 0,2.014915 2.31473,0 1.4781699,-1.849278 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.20966817" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.2 KiB |
@@ -1,85 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="18.035334mm"
|
||||
height="17.500378mm"
|
||||
viewBox="0 0 18.035334 17.500378"
|
||||
version="1.1"
|
||||
id="svg13826"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="ns.svg">
|
||||
<defs
|
||||
id="defs13820" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="8"
|
||||
inkscape:cx="-2.090004"
|
||||
inkscape:cy="23.752239"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="775"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<metadata
|
||||
id="metadata13823">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-0.99262638,-1.174181)">
|
||||
<g
|
||||
id="g70"
|
||||
transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)">
|
||||
<path
|
||||
inkscape:export-ydpi="250.55"
|
||||
inkscape:export-xdpi="250.55"
|
||||
inkscape:export-filename="new.png"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3055"
|
||||
d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z"
|
||||
style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path3054-2-9"
|
||||
d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<rect
|
||||
y="6.5793304"
|
||||
x="6.1734986"
|
||||
height="6.6900792"
|
||||
width="7.6735892"
|
||||
id="rect8790"
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.40000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:0.80000001, 0.4;stroke-dashoffset:3.44000006;stroke-opacity:1" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.0 KiB |
@@ -1,84 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="18.035334mm"
|
||||
height="17.500378mm"
|
||||
viewBox="0 0 18.035334 17.500378"
|
||||
version="1.1"
|
||||
id="svg13826"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="node.svg">
|
||||
<defs
|
||||
id="defs13820" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="8"
|
||||
inkscape:cx="16.847496"
|
||||
inkscape:cy="33.752239"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="775"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<metadata
|
||||
id="metadata13823">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-0.99262638,-1.174181)">
|
||||
<g
|
||||
id="g70"
|
||||
transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)">
|
||||
<path
|
||||
inkscape:export-ydpi="250.55"
|
||||
inkscape:export-xdpi="250.55"
|
||||
inkscape:export-filename="new.png"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3055"
|
||||
d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z"
|
||||
style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path3054-2-9"
|
||||
d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccscccccccccccccccc"
|
||||
id="path1994"
|
||||
d="M 9.9921803,5.0101759 C 9.8538505,5.0057759 5.9970805,6.902049 5.9466504,6.999295 c -0.12117,0.233682 -0.9989,4.281827 -0.94731,4.369074 0.03,0.05065 0.66219,0.851861 1.40458,1.780327 l 1.3498201,1.688014 2.2211901,9.31e-4 2.2216404,9.31e-4 1.41321,-1.765731 1.41365,-1.765228 -0.49479,-2.1685759 C 14.256441,7.946271 14.012981,6.950423 13.988111,6.926433 13.918611,6.859553 10.067151,5.0126389 9.9921803,5.0102179 Z m 0.1961407,0.947753 0.90893,0.2635771 -0.90893,0.263576 -0.9089209,-0.263576 z m -0.9089209,0.36452 0.8511209,0.2532261 -0.004,1.183289 -0.8468109,-0.469347 z m 1.8178509,0 0,0.9671681 -0.84679,0.469347 -0.004,-1.183289 z M 8.8997705,7.937127 9.8087101,8.2007027 8.8997705,8.4642797 7.9908504,8.2007027 Z m 2.2087005,0 0.90894,0.2635757 -0.90894,0.263577 -0.90893,-0.263577 z m -3.1176206,0.3645197 0.8511202,0.252792 -0.004,1.1832908 -0.8468199,-0.468915 z m 1.8178597,0 0,0.9671678 -0.8468098,0.468915 -0.004,-1.1832908 z m 0.3908309,0 0.85113,0.252792 -0.004,1.1832908 -0.84682,-0.468915 z m 1.81787,0 0,0.9671678 -0.84682,0.468915 -0.004,-1.1832908 z m -3.4496605,1.515028 c 0.2706299,0.0096 0.0611,0.2819093 0.3684101,0.4279353 0.3277495,0.155764 0.3953995,-0.235354 0.6013395,0.06341 0.20599,0.298766 -0.18339,0.223239 -0.15443,0.584957 0.029,0.361718 0.40165,0.224858 0.24589,0.552606 -0.15575,0.327746 -0.28532,-0.04764 -0.5840895,0.158317 -0.2987401,0.205957 0.006,0.460208 -0.35546,0.489192 -0.3617401,0.02898 -0.1015001,-0.270447 -0.42924,-0.426208 -0.32775,-0.155765 -0.3953801,0.234921 -0.6013402,-0.06385 -0.2059599,-0.298767 0.1838299,-0.22281 0.15485,-0.584528 -0.029,-0.361718 -0.4016499,-0.224859 -0.24587,-0.552604 0.1557501,-0.327749 0.2848801,0.04764 0.5836502,-0.15832 0.2987898,-0.205956 -0.006,-0.4602083 0.3559099,-0.4891903 0.022499,-0.0018 0.0424,-0.0023 0.0604,-0.0018 z m 2.3359605,0.3627943 c 0.48335,0.01358 0.0146,0.467218 0.45596,0.664766 0.44144,0.197548 0.46714,-0.454103 0.79937,-0.102669 0.33221,0.351432 -0.31997,0.34064 -0.14753,0.792455 0.17243,0.451813 0.65163,0.0092 0.63802,0.49264 -0.0137,0.483411 -0.46723,0.01456 -0.66477,0.455977 -0.19755,0.441412 0.4541,0.467143 0.10266,0.799357 -0.35141,0.332212 -0.34021,-0.319974 -0.79202,-0.147534 -0.45183,0.172437 -0.009,0.65161 -0.49265,0.638019 -0.48339,-0.01358 -0.0146,-0.467216 -0.45596,-0.664764 -0.4414105,-0.197551 -0.4675805,0.454102 -0.7997909,0.102669 -0.3322097,-0.351431 0.3199804,-0.340209 0.14754,-0.792025 -0.17245,-0.451815 -0.6516296,-0.0092 -0.6380295,-0.492642 0.013699,-0.483408 0.4672095,-0.01499 0.6647795,-0.456405 0.1975204,-0.441414 -0.45411,-0.467143 -0.10269,-0.799357 0.3514505,-0.332213 0.3406505,0.319971 0.7924609,0.147534 0.45184,-0.17244 0.009,-0.651611 0.49265,-0.638021 z m -2.3148207,0.253655 c -0.2936499,9e-5 -0.5316098,0.238249 -0.5314498,0.531898 7.99e-5,0.293481 0.2379701,0.531377 0.5314498,0.531467 0.2936602,1.59e-4 0.5318202,-0.23781 0.5319,-0.531467 1.601e-4,-0.293825 -0.2380699,-0.532057 -0.5319,-0.531898 z m 2.2643607,0.480564 c -0.58689,-1.96e-4 -1.0627109,0.475614 -1.0625209,1.062502 5e-5,0.586719 0.4758009,1.062267 1.0625209,1.062071 0.58654,-5.8e-5 1.06201,-0.475531 1.06206,-1.062071 1.9e-4,-0.586708 -0.47535,-1.062444 -1.06206,-1.062502 z"
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#eeeeee;stroke-width:0;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:11.23642349;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 8.1 KiB |
@@ -1,103 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="18.035334mm"
|
||||
height="17.500378mm"
|
||||
viewBox="0 0 18.035334 17.500378"
|
||||
version="1.1"
|
||||
id="svg13826"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="pod.svg">
|
||||
<defs
|
||||
id="defs13820" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="8"
|
||||
inkscape:cx="-2.090004"
|
||||
inkscape:cy="33.752239"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="775"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<metadata
|
||||
id="metadata13823">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-0.99262638,-1.174181)">
|
||||
<g
|
||||
id="g70"
|
||||
transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)">
|
||||
<path
|
||||
inkscape:export-ydpi="250.55"
|
||||
inkscape:export-xdpi="250.55"
|
||||
inkscape:export-filename="new.png"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3055"
|
||||
d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z"
|
||||
style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path3054-2-9"
|
||||
d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g3341"
|
||||
transform="translate(0.12766661,0.35147801)">
|
||||
<path
|
||||
inkscape:export-ydpi="376.57999"
|
||||
inkscape:export-xdpi="376.57999"
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10"
|
||||
inkscape:connector-curvature="0"
|
||||
d="M 6.2617914,7.036086 9.8826317,5.986087 13.503462,7.036086 9.8826317,8.086087 Z"
|
||||
id="path910" />
|
||||
<path
|
||||
inkscape:export-ydpi="376.57999"
|
||||
inkscape:export-xdpi="376.57999"
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 6.2617914,7.43817 0,3.852778 3.3736103,1.868749 0.0167,-4.713193 z"
|
||||
id="path912" />
|
||||
<path
|
||||
inkscape:export-ydpi="376.57999"
|
||||
inkscape:export-xdpi="376.57999"
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 13.503462,7.43817 0,3.852778 -3.37361,1.868749 -0.0167,-4.713193 z"
|
||||
id="path914" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.8 KiB |
@@ -1,128 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="18.035334mm"
|
||||
height="17.500378mm"
|
||||
viewBox="0 0 18.035334 17.500378"
|
||||
version="1.1"
|
||||
id="svg13826"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="secret.svg">
|
||||
<defs
|
||||
id="defs13820" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="8"
|
||||
inkscape:cx="-2.090004"
|
||||
inkscape:cy="28.752239"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="775"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<metadata
|
||||
id="metadata13823">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-0.99262638,-1.174181)">
|
||||
<g
|
||||
id="g70"
|
||||
transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)">
|
||||
<path
|
||||
inkscape:export-ydpi="250.55"
|
||||
inkscape:export-xdpi="250.55"
|
||||
inkscape:export-filename="new.png"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3055"
|
||||
d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z"
|
||||
style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path3054-2-9"
|
||||
d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g3347"
|
||||
transform="translate(0.05710921,0.77487342)">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 10.414299,8.0912253 3.708331,0"
|
||||
id="path922" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79400003;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 8.2976282,5.9745582 5.8250018,0"
|
||||
id="path930" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 5.7837382,5.9745582 1.45834,0"
|
||||
id="path934" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:#326ce5;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 7.7183782,8.4321603 0,0 c 0,-1.1667021 1.0110897,-2.1125011 2.2583305,-2.1125011 1.2472403,0 2.2583303,0.945799 2.2583303,2.1125011 l -1.05624,0 0,0 c 0,-0.583351 -0.5382,-1.0562501 -1.2020903,-1.0562501 -0.6638904,0 -1.2020808,0.4728991 -1.2020808,1.0562501 z"
|
||||
id="path936" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 10.414299,10.207893 3.708331,0"
|
||||
id="path942" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 8.2976282,12.32456 5.8250018,0"
|
||||
id="path950" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 5.7837382,12.32456 1.45834,0"
|
||||
id="path954" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:#326ce5;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 7.1622182,8.3691063 5.6166608,0 0,3.6583337 -5.6166608,0 z"
|
||||
id="path956" />
|
||||
<circle
|
||||
r="0.55515254"
|
||||
cy="10.198272"
|
||||
cx="9.9705448"
|
||||
id="path7280"
|
||||
style="opacity:1;fill:#326ce5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.26478875;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:0.52957746, 0.26478873;stroke-dashoffset:5.01860619;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 7.5 KiB |
@@ -1,117 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="18.035334mm"
|
||||
height="17.500378mm"
|
||||
viewBox="0 0 18.035334 17.500378"
|
||||
version="1.1"
|
||||
id="svg13826"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="svc.svg">
|
||||
<defs
|
||||
id="defs13820" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="8"
|
||||
inkscape:cx="-2.090004"
|
||||
inkscape:cy="28.752239"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="775"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<metadata
|
||||
id="metadata13823">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-0.99262638,-1.174181)">
|
||||
<g
|
||||
id="g70"
|
||||
transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)">
|
||||
<path
|
||||
inkscape:export-ydpi="250.55"
|
||||
inkscape:export-xdpi="250.55"
|
||||
inkscape:export-filename="new.png"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3055"
|
||||
d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z"
|
||||
style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path3054-2-9"
|
||||
d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g3345"
|
||||
transform="translate(0.09238801,0.66897746)">
|
||||
<path
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 4.4949896,11.260826 2.9083311,0 0,2.041667 -2.9083311,0 z"
|
||||
id="path964" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 8.4637407,11.260826 2.9083303,0 0,2.041667 -2.9083303,0 z"
|
||||
id="path966" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 12.432491,11.260826 2.90833,0 0,2.041667 -2.90833,0 z"
|
||||
id="path968" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 7.6137407,5.2082921 4.6083303,0 0,2.041667 -4.6083303,0 z"
|
||||
id="path970" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 9.9179005,7.2499601 0,2.005449 -3.966671,0 0,2.0028859"
|
||||
id="path978" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.52899998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 9.9179005,7.2499601 0,2.005449 3.9666705,0 0,2.0028859"
|
||||
id="path986" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 9.9095538,7.2512251 0,2.005449 0.0167,0 0,2.0028859"
|
||||
id="path982" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.7 KiB |
@@ -1,97 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="18.035334mm"
|
||||
height="17.500378mm"
|
||||
viewBox="0 0 18.035334 17.500378"
|
||||
version="1.1"
|
||||
id="svg13826"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="pv.svg">
|
||||
<defs
|
||||
id="defs13820" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="8"
|
||||
inkscape:cx="-12.090004"
|
||||
inkscape:cy="28.752239"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="775"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<metadata
|
||||
id="metadata13823">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-0.99262638,-1.174181)">
|
||||
<g
|
||||
id="g70"
|
||||
transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)">
|
||||
<path
|
||||
inkscape:export-ydpi="250.55"
|
||||
inkscape:export-xdpi="250.55"
|
||||
inkscape:export-filename="new.png"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3055"
|
||||
d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z"
|
||||
style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path3054-2-9"
|
||||
d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g3341"
|
||||
transform="translate(-0.18983289,0.49258906)">
|
||||
<path
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 5.5709614,7.9105849 0,0 c 0,0.621121 2.0725401,1.124639 4.6291706,1.124639 2.556609,0 4.629159,-0.503518 4.629159,-1.124639 l 0,3.0423911 c 0,0.62112 -2.07255,1.124638 -4.629159,1.124638 -2.5566305,0 -4.6291706,-0.503518 -4.6291706,-1.124638 z"
|
||||
id="path1114" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 5.5709614,7.9105849 0,0 c 0,-0.621119 2.0725401,-1.124637 4.6291706,-1.124637 2.556609,0 4.629159,0.503518 4.629159,1.124637 l 0,0 c 0,0.621121 -2.07255,1.124639 -4.629159,1.124639 -2.5566305,0 -4.6291706,-0.503518 -4.6291706,-1.124639 z"
|
||||
id="path1116" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#326ce5;stroke-width:0.26458332;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 14.829291,7.9105849 0,0 c 0,0.621121 -2.07255,1.124639 -4.629159,1.124639 -2.5566205,0 -4.6291706,-0.503518 -4.6291706,-1.124639 l 0,0 c 0,-0.621119 2.0725501,-1.124637 4.6291706,-1.124637 2.556609,0 4.629159,0.503518 4.629159,1.124637 l 0,3.0423911 c 0,0.62112 -2.07255,1.124638 -4.629159,1.124638 -2.5566205,0 -4.6291706,-0.503518 -4.6291706,-1.124638 l 0,-3.0423911"
|
||||
id="path1120" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 595 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 11 KiB |
@@ -1,5 +0,0 @@
|
||||
import definition from "../../boards/(content)/(home)/_definition";
|
||||
|
||||
const { layout } = definition;
|
||||
|
||||
export default layout;
|
||||
@@ -1,7 +0,0 @@
|
||||
import definition from "../../boards/(content)/(home)/_definition";
|
||||
|
||||
const { generateMetadataAsync: generateMetadata, page } = definition;
|
||||
|
||||
export default page;
|
||||
|
||||
export { generateMetadata };
|
||||
@@ -1,3 +0,0 @@
|
||||
import HomeBoardNotFoundPage from "../boards/(content)/not-found";
|
||||
|
||||
export default HomeBoardNotFoundPage;
|
||||
@@ -0,0 +1,14 @@
|
||||
import type { PropsWithChildren } from "react";
|
||||
import { AppShellMain } from "@mantine/core";
|
||||
|
||||
import { MainHeader } from "~/components/layout/header";
|
||||
import { ClientShell } from "~/components/layout/shell";
|
||||
|
||||
export default function MainLayout({ children }: PropsWithChildren) {
|
||||
return (
|
||||
<ClientShell hasNavigation={false}>
|
||||
<MainHeader />
|
||||
<AppShellMain>{children}</AppShellMain>
|
||||
</ClientShell>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Stack, Title } from "@mantine/core";
|
||||
|
||||
export default function HomePage() {
|
||||
return (
|
||||
<Stack>
|
||||
<Title>Home</Title>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import type { PropsWithChildren } from "react";
|
||||
|
||||
import { useSuspenseDayJsLocalization } from "@homarr/translation/dayjs";
|
||||
|
||||
export const DayJsLoader = ({ children }: PropsWithChildren) => {
|
||||
// Load the dayjs localization for the current locale with suspense
|
||||
useSuspenseDayJsLocalization();
|
||||
|
||||
return children;
|
||||
};
|
||||
@@ -1,77 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import type { PropsWithChildren } from "react";
|
||||
import type { MantineColorScheme, MantineColorSchemeManager } from "@mantine/core";
|
||||
import { createTheme, DirectionProvider, MantineProvider } from "@mantine/core";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { useSession } from "@homarr/auth/client";
|
||||
import { parseCookies, setClientCookie } from "@homarr/common";
|
||||
import type { ColorScheme } from "@homarr/definitions";
|
||||
import { colorSchemeCookieKey } from "@homarr/definitions";
|
||||
|
||||
export const CustomMantineProvider = ({
|
||||
children,
|
||||
defaultColorScheme,
|
||||
}: PropsWithChildren<{ defaultColorScheme: ColorScheme }>) => {
|
||||
const manager = useColorSchemeManager();
|
||||
return (
|
||||
<DirectionProvider>
|
||||
<MantineProvider
|
||||
defaultColorScheme={defaultColorScheme}
|
||||
colorSchemeManager={manager}
|
||||
theme={createTheme({
|
||||
primaryColor: "red",
|
||||
autoContrast: true,
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
</MantineProvider>
|
||||
</DirectionProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export function useColorSchemeManager(): MantineColorSchemeManager {
|
||||
const { data: session } = useSession();
|
||||
|
||||
const updateCookieValue = (value: Exclude<MantineColorScheme, "auto">) => {
|
||||
setClientCookie(colorSchemeCookieKey, value, { expires: dayjs().add(1, "year").toDate(), path: "/" });
|
||||
};
|
||||
|
||||
const { mutate: mutateColorScheme } = clientApi.user.changeColorScheme.useMutation({
|
||||
onSuccess: (_, variables) => {
|
||||
updateCookieValue(variables.colorScheme);
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
get: (defaultValue) => {
|
||||
if (typeof window === "undefined") {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
try {
|
||||
const cookies = parseCookies(document.cookie);
|
||||
return (cookies[colorSchemeCookieKey] as MantineColorScheme | undefined) ?? defaultValue;
|
||||
} catch {
|
||||
return defaultValue;
|
||||
}
|
||||
},
|
||||
|
||||
set: (value) => {
|
||||
if (value === "auto") return;
|
||||
try {
|
||||
if (session) {
|
||||
mutateColorScheme({ colorScheme: value });
|
||||
}
|
||||
updateCookieValue(value);
|
||||
} catch (error) {
|
||||
console.warn("[@mantine/core] Color scheme manager was unable to save color scheme.", error);
|
||||
}
|
||||
},
|
||||
subscribe: () => undefined,
|
||||
unsubscribe: () => undefined,
|
||||
clear: () => undefined,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import type { PropsWithChildren } from "react";
|
||||
|
||||
import { defaultLocale } from "@homarr/translation";
|
||||
import { I18nProviderClient } from "@homarr/translation/client";
|
||||
|
||||
export const NextInternationalProvider = ({
|
||||
children,
|
||||
locale,
|
||||
}: PropsWithChildren<{ locale: string }>) => {
|
||||
return (
|
||||
<I18nProviderClient locale={locale} fallback={defaultLocale}>
|
||||
{children}
|
||||
</I18nProviderClient>
|
||||
);
|
||||
};
|
||||
@@ -1,46 +1,17 @@
|
||||
"use client";
|
||||
|
||||
import { createContext, useContext, useEffect } from "react";
|
||||
import type { PropsWithChildren } from "react";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
import type { Session } from "@homarr/auth";
|
||||
import { SessionProvider, signIn } from "@homarr/auth/client";
|
||||
import { SessionProvider } from "@homarr/auth/client";
|
||||
|
||||
interface AuthProviderProps extends AuthContextProps {
|
||||
interface AuthProviderProps {
|
||||
session: Session | null;
|
||||
}
|
||||
|
||||
export const AuthProvider = ({ children, session, logoutUrl }: PropsWithChildren<AuthProviderProps>) => {
|
||||
useLoginRedirectOnSessionExpiry(session);
|
||||
|
||||
return (
|
||||
<SessionProvider session={session}>
|
||||
<AuthContext.Provider value={{ logoutUrl }}>{children}</AuthContext.Provider>
|
||||
</SessionProvider>
|
||||
);
|
||||
};
|
||||
|
||||
interface AuthContextProps {
|
||||
logoutUrl: string | undefined;
|
||||
}
|
||||
|
||||
const AuthContext = createContext<AuthContextProps | null>(null);
|
||||
|
||||
export const useAuthContext = () => {
|
||||
const context = useContext(AuthContext);
|
||||
|
||||
if (!context) throw new Error("useAuthContext must be used within an AuthProvider");
|
||||
|
||||
return context;
|
||||
};
|
||||
|
||||
const useLoginRedirectOnSessionExpiry = (session: Session | null) => {
|
||||
useEffect(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
if (!session) return () => {};
|
||||
//setTimeout doesn't allow for a number higher than 2147483647 (2³¹-1 , or roughly 24 days)
|
||||
const timeout = setTimeout(() => void signIn(), Math.min(dayjs(session.expires).diff(), 2147483647));
|
||||
return () => clearTimeout(timeout);
|
||||
}, [session]);
|
||||
export const AuthProvider = ({
|
||||
children,
|
||||
session,
|
||||
}: PropsWithChildren<AuthProviderProps>) => {
|
||||
return <SessionProvider session={session}>{children}</SessionProvider>;
|
||||
};
|
||||
@@ -7,45 +7,17 @@ import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
|
||||
import { ReactQueryStreamedHydration } from "@tanstack/react-query-next-experimental";
|
||||
import {
|
||||
createWSClient,
|
||||
httpBatchStreamLink,
|
||||
httpLink,
|
||||
isNonJsonSerializable,
|
||||
loggerLink,
|
||||
splitLink,
|
||||
unstable_httpBatchStreamLink,
|
||||
wsLink,
|
||||
} from "@trpc/client";
|
||||
import superjson from "superjson";
|
||||
import type { SuperJSONResult } from "superjson";
|
||||
|
||||
import type { AppRouter } from "@homarr/api";
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { createHeadersCallbackForSource, getTrpcUrl } from "@homarr/api/shared";
|
||||
import { env } from "@homarr/common/env";
|
||||
|
||||
const getWebSocketProtocol = () => {
|
||||
// window is not defined on server side
|
||||
if (typeof window === "undefined") {
|
||||
return "ws";
|
||||
}
|
||||
|
||||
return window.location.protocol === "https:" ? "wss" : "ws";
|
||||
};
|
||||
|
||||
const constructWebsocketUrl = () => {
|
||||
const fallback = `${getWebSocketProtocol()}://localhost:3001/websockets`;
|
||||
if (typeof window === "undefined") {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
if (env.NODE_ENV === "development") {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
return `${getWebSocketProtocol()}://${window.location.hostname}:${window.location.port}/websockets`;
|
||||
};
|
||||
|
||||
const wsClient = createWSClient({
|
||||
url: constructWebsocketUrl(),
|
||||
url: "ws://localhost:3001",
|
||||
});
|
||||
|
||||
export function TRPCReactProvider(props: PropsWithChildren) {
|
||||
@@ -65,39 +37,31 @@ export function TRPCReactProvider(props: PropsWithChildren) {
|
||||
links: [
|
||||
loggerLink({
|
||||
enabled: (opts) =>
|
||||
env.NODE_ENV === "development" || (opts.direction === "down" && opts.result instanceof Error),
|
||||
process.env.NODE_ENV === "development" ||
|
||||
(opts.direction === "down" && opts.result instanceof Error),
|
||||
}),
|
||||
splitLink({
|
||||
condition: ({ type }) => type === "subscription",
|
||||
true: wsLink<AppRouter>({
|
||||
client: wsClient,
|
||||
transformer: superjson,
|
||||
}),
|
||||
false: splitLink({
|
||||
condition: ({ input }) => isNonJsonSerializable(input),
|
||||
true: httpLink({
|
||||
/**
|
||||
* We don't want to transform the data here as we want to use form data
|
||||
*/
|
||||
transformer: {
|
||||
serialize(object: unknown) {
|
||||
return object;
|
||||
},
|
||||
deserialize(data: SuperJSONResult) {
|
||||
return superjson.deserialize<unknown>(data);
|
||||
},
|
||||
},
|
||||
url: getTrpcUrl(),
|
||||
headers: createHeadersCallbackForSource("nextjs-react (form-data)"),
|
||||
}),
|
||||
false: httpBatchStreamLink({
|
||||
(args) => {
|
||||
return ({ op, next }) => {
|
||||
console.log("op", op.type, op.input, op.path, op.id);
|
||||
if (op.type === "subscription") {
|
||||
const link = wsLink<AppRouter>({
|
||||
client: wsClient,
|
||||
transformer: superjson,
|
||||
});
|
||||
return link(args)({ op, next });
|
||||
}
|
||||
|
||||
return unstable_httpBatchStreamLink({
|
||||
transformer: superjson,
|
||||
url: getTrpcUrl(),
|
||||
maxURLLength: 2083, // Suggested by tRPC: https://trpc.io/docs/client/links/httpBatchLink#setting-a-maximum-url-length
|
||||
headers: createHeadersCallbackForSource("nextjs-react (json)"),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
url: `${getBaseUrl()}/api/trpc`,
|
||||
headers() {
|
||||
const headers = new Headers();
|
||||
headers.set("x-trpc-source", "nextjs-react");
|
||||
return headers;
|
||||
},
|
||||
})(args)({ op, next });
|
||||
};
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
@@ -105,9 +69,17 @@ export function TRPCReactProvider(props: PropsWithChildren) {
|
||||
return (
|
||||
<clientApi.Provider client={trpcClient} queryClient={queryClient}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<ReactQueryStreamedHydration transformer={superjson}>{props.children}</ReactQueryStreamedHydration>
|
||||
<ReactQueryStreamedHydration transformer={superjson}>
|
||||
{props.children}
|
||||
</ReactQueryStreamedHydration>
|
||||
<ReactQueryDevtools initialIsOpen={false} />
|
||||
</QueryClientProvider>
|
||||
</clientApi.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
function getBaseUrl() {
|
||||
if (typeof window !== "undefined") return window.location.origin;
|
||||
if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`;
|
||||
return `http://localhost:${process.env.PORT ?? 3000}`;
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Button, PasswordInput, Stack, TextInput } from "@mantine/core";
|
||||
import type { z } from "zod/v4";
|
||||
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { useZodForm } from "@homarr/form";
|
||||
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
import { CustomPasswordInput } from "@homarr/ui";
|
||||
import { userRegistrationSchema } from "@homarr/validation/user";
|
||||
|
||||
interface RegistrationFormProps {
|
||||
invite: {
|
||||
id: string;
|
||||
token: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const RegistrationForm = ({ invite }: RegistrationFormProps) => {
|
||||
const t = useScopedI18n("user");
|
||||
const router = useRouter();
|
||||
const { mutate, isPending } = clientApi.user.register.useMutation();
|
||||
const form = useZodForm(userRegistrationSchema, {
|
||||
initialValues: {
|
||||
username: "",
|
||||
password: "",
|
||||
confirmPassword: "",
|
||||
},
|
||||
});
|
||||
|
||||
const handleSubmit = (values: z.infer<typeof userRegistrationSchema>) => {
|
||||
mutate(
|
||||
{
|
||||
...values,
|
||||
inviteId: invite.id,
|
||||
token: invite.token,
|
||||
},
|
||||
{
|
||||
onSuccess() {
|
||||
showSuccessNotification({
|
||||
title: t("action.register.notification.success.title"),
|
||||
message: t("action.register.notification.success.message"),
|
||||
});
|
||||
router.push("/auth/login");
|
||||
},
|
||||
onError(error) {
|
||||
const message =
|
||||
error.data?.code === "CONFLICT"
|
||||
? t("error.usernameTaken")
|
||||
: t("action.register.notification.error.message");
|
||||
|
||||
showErrorNotification({
|
||||
title: t("action.register.notification.error.title"),
|
||||
message,
|
||||
});
|
||||
},
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack gap="xl">
|
||||
<form onSubmit={form.onSubmit(handleSubmit)}>
|
||||
<Stack gap="lg">
|
||||
<TextInput
|
||||
label={t("field.username.label")}
|
||||
id="username"
|
||||
autoComplete="username"
|
||||
{...form.getInputProps("username")}
|
||||
/>
|
||||
<CustomPasswordInput
|
||||
withPasswordRequirements
|
||||
label={t("field.password.label")}
|
||||
id="password"
|
||||
autoComplete="new-password"
|
||||
{...form.getInputProps("password")}
|
||||
/>
|
||||
|
||||
<PasswordInput
|
||||
label={t("field.passwordConfirm.label")}
|
||||
id="password-confirm"
|
||||
autoComplete="new-password"
|
||||
{...form.getInputProps("confirmPassword")}
|
||||
/>
|
||||
<Button type="submit" fullWidth loading={isPending}>
|
||||
{t("action.register.label")}
|
||||
</Button>
|
||||
</Stack>
|
||||
</form>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
@@ -1,72 +0,0 @@
|
||||
import { notFound } from "next/navigation";
|
||||
import { Card, Center, Stack, Text, Title } from "@mantine/core";
|
||||
|
||||
import { auth } from "@homarr/auth/next";
|
||||
import { isProviderEnabled } from "@homarr/auth/server";
|
||||
import { and, db, eq } from "@homarr/db";
|
||||
import { invites } from "@homarr/db/schema";
|
||||
import { getScopedI18n } from "@homarr/translation/server";
|
||||
|
||||
import { HomarrLogoWithTitle } from "~/components/layout/logo/homarr-logo";
|
||||
import { RegistrationForm } from "./_registration-form";
|
||||
|
||||
interface InviteUsagePageProps {
|
||||
params: Promise<{
|
||||
id: string;
|
||||
}>;
|
||||
searchParams: Promise<{
|
||||
token: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
export default async function InviteUsagePage(props: InviteUsagePageProps) {
|
||||
const searchParams = await props.searchParams;
|
||||
const params = await props.params;
|
||||
if (!isProviderEnabled("credentials")) notFound();
|
||||
|
||||
const session = await auth();
|
||||
if (session) notFound();
|
||||
|
||||
const invite = await db.query.invites.findFirst({
|
||||
where: and(eq(invites.id, params.id), eq(invites.token, searchParams.token)),
|
||||
columns: {
|
||||
id: true,
|
||||
token: true,
|
||||
expirationDate: true,
|
||||
},
|
||||
with: {
|
||||
creator: {
|
||||
columns: {
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!invite || invite.expirationDate < new Date()) notFound();
|
||||
|
||||
const t = await getScopedI18n("user.page.invite");
|
||||
|
||||
return (
|
||||
<Center>
|
||||
<Stack align="center" mt="xl">
|
||||
<HomarrLogoWithTitle size="lg" />
|
||||
<Stack gap={6} align="center">
|
||||
<Title order={3} fw={400} ta="center">
|
||||
{t("title")}
|
||||
</Title>
|
||||
<Text size="sm" c="gray.5" ta="center">
|
||||
{t("subtitle")}
|
||||
</Text>
|
||||
</Stack>
|
||||
<Card withBorder w={64 * 6} maw="90vw">
|
||||
<RegistrationForm invite={invite} />
|
||||
</Card>
|
||||
<Text size="xs" c="gray.5" ta="center">
|
||||
{/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */}
|
||||
{t("description", { username: invite.creator.name! })}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
@@ -1,214 +1,82 @@
|
||||
"use client";
|
||||
|
||||
import type { PropsWithChildren } from "react";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import { Anchor, Button, Card, Code, Collapse, Divider, PasswordInput, Stack, Text, TextInput } from "@mantine/core";
|
||||
import { useDisclosure } from "@mantine/hooks";
|
||||
import { z } from "zod/v4";
|
||||
import { useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import {
|
||||
Alert,
|
||||
Button,
|
||||
PasswordInput,
|
||||
rem,
|
||||
Stack,
|
||||
TextInput,
|
||||
} from "@mantine/core";
|
||||
import { IconAlertTriangle } from "@tabler/icons-react";
|
||||
|
||||
import { signIn } from "@homarr/auth/client";
|
||||
import { revalidatePathActionAsync } from "@homarr/common/client";
|
||||
import type { useForm } from "@homarr/form";
|
||||
import { useZodForm } from "@homarr/form";
|
||||
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
|
||||
import { useForm, zodResolver } from "@homarr/form";
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
import { sanitizeRedirectionUrl } from "@homarr/validation/redirection-url";
|
||||
import { userSignInSchema } from "@homarr/validation/user";
|
||||
import type { z } from "@homarr/validation";
|
||||
import { validation } from "@homarr/validation";
|
||||
|
||||
type Provider = "credentials" | "ldap" | "oidc";
|
||||
|
||||
interface LoginFormProps {
|
||||
providers: string[];
|
||||
oidcClientName: string;
|
||||
isOidcAutoLoginEnabled: boolean;
|
||||
callbackUrl: string;
|
||||
}
|
||||
|
||||
const extendedValidation = userSignInSchema.extend({ provider: z.enum(["credentials", "ldap"]) });
|
||||
|
||||
export const LoginForm = ({ providers, oidcClientName, isOidcAutoLoginEnabled, callbackUrl }: LoginFormProps) => {
|
||||
export const LoginForm = () => {
|
||||
const t = useScopedI18n("user");
|
||||
const searchParams = useSearchParams();
|
||||
const isError = searchParams.has("error");
|
||||
const router = useRouter();
|
||||
const [isPending, setIsPending] = useState(false);
|
||||
const form = useZodForm(extendedValidation, {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState<string>();
|
||||
const form = useForm<FormType>({
|
||||
validate: zodResolver(validation.user.signIn),
|
||||
initialValues: {
|
||||
name: "",
|
||||
password: "",
|
||||
provider: "credentials",
|
||||
},
|
||||
});
|
||||
|
||||
const credentialInputsVisible = providers.includes("credentials") || providers.includes("ldap");
|
||||
|
||||
const onSuccess = useCallback(
|
||||
async (provider: Provider, response: Awaited<ReturnType<typeof signIn>>) => {
|
||||
if (!response.ok || response.error) {
|
||||
// eslint-disable-next-line @typescript-eslint/only-throw-error
|
||||
throw response.error;
|
||||
}
|
||||
|
||||
if (provider === "oidc") {
|
||||
if (!response.url) {
|
||||
showErrorNotification({
|
||||
title: t("action.login.notification.error.title"),
|
||||
message: t("action.login.notification.error.message"),
|
||||
autoClose: 10000,
|
||||
});
|
||||
return;
|
||||
const handleSubmit = async (values: FormType) => {
|
||||
setIsLoading(true);
|
||||
setError(undefined);
|
||||
await signIn("credentials", {
|
||||
...values,
|
||||
redirect: false,
|
||||
callbackUrl: "/",
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response?.ok || response.error) {
|
||||
throw response?.error;
|
||||
}
|
||||
|
||||
router.push(response.url);
|
||||
return;
|
||||
}
|
||||
|
||||
showSuccessNotification({
|
||||
title: t("action.login.notification.success.title"),
|
||||
message: t("action.login.notification.success.message"),
|
||||
});
|
||||
|
||||
// Redirect to the callback URL if the response is defined and comes from a credentials provider (ldap or credentials). oidc is redirected automatically.
|
||||
await revalidatePathActionAsync("/");
|
||||
router.push(sanitizeRedirectionUrl(callbackUrl));
|
||||
},
|
||||
[t, router, callbackUrl],
|
||||
);
|
||||
|
||||
const onError = useCallback(() => {
|
||||
setIsPending(false);
|
||||
|
||||
showErrorNotification({
|
||||
title: t("action.login.notification.error.title"),
|
||||
message: t("action.login.notification.error.message"),
|
||||
autoClose: 10000,
|
||||
});
|
||||
}, [t]);
|
||||
|
||||
const signInAsync = useCallback(
|
||||
async (provider: Provider, options?: Parameters<typeof signIn>[1]) => {
|
||||
setIsPending(true);
|
||||
await signIn(provider, {
|
||||
...options,
|
||||
redirect: false,
|
||||
callbackUrl: new URL(callbackUrl, window.location.href).href,
|
||||
void router.push("/");
|
||||
})
|
||||
.then((response) => onSuccess(provider, response))
|
||||
.catch(onError);
|
||||
},
|
||||
[setIsPending, onSuccess, onError, callbackUrl],
|
||||
);
|
||||
|
||||
const isLoginInProgress = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (isError) return;
|
||||
if (isOidcAutoLoginEnabled && !isPending && !isLoginInProgress.current) {
|
||||
isLoginInProgress.current = true;
|
||||
void signInAsync("oidc");
|
||||
}
|
||||
}, [signInAsync, isOidcAutoLoginEnabled, isPending, isError]);
|
||||
.catch((error: Error | string) => {
|
||||
setIsLoading(false);
|
||||
setError(error.toString());
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack gap="xl">
|
||||
<Stack gap="lg">
|
||||
{credentialInputsVisible && (
|
||||
<>
|
||||
<form onSubmit={form.onSubmit((credentials) => void signInAsync(credentials.provider, credentials))}>
|
||||
<Stack gap="lg">
|
||||
<TextInput
|
||||
label={t("field.username.label")}
|
||||
id="username"
|
||||
autoComplete="username"
|
||||
{...form.getInputProps("name")}
|
||||
/>
|
||||
<PasswordInput
|
||||
label={t("field.password.label")}
|
||||
id="password"
|
||||
autoComplete="current-password"
|
||||
{...form.getInputProps("password")}
|
||||
/>
|
||||
|
||||
{providers.includes("credentials") && (
|
||||
<Stack gap="sm">
|
||||
<SubmitButton isPending={isPending} form={form} provider="credentials">
|
||||
{t("action.login.label")}
|
||||
</SubmitButton>
|
||||
<PasswordForgottenCollapse username={form.values.name} />
|
||||
</Stack>
|
||||
)}
|
||||
|
||||
{providers.includes("ldap") && (
|
||||
<SubmitButton isPending={isPending} form={form} provider="ldap">
|
||||
{t("action.login.labelWith", { provider: "LDAP" })}
|
||||
</SubmitButton>
|
||||
)}
|
||||
</Stack>
|
||||
</form>
|
||||
{providers.includes("oidc") && <Divider label="OIDC" labelPosition="center" />}
|
||||
</>
|
||||
)}
|
||||
|
||||
{providers.includes("oidc") && (
|
||||
<Button fullWidth variant="light" onClick={async () => await signInAsync("oidc")}>
|
||||
{t("action.login.labelWith", { provider: oidcClientName })}
|
||||
<form onSubmit={form.onSubmit((values) => void handleSubmit(values))}>
|
||||
<Stack gap="lg">
|
||||
<TextInput
|
||||
label={t("field.username.label")}
|
||||
{...form.getInputProps("name")}
|
||||
/>
|
||||
<PasswordInput
|
||||
label={t("field.password.label")}
|
||||
{...form.getInputProps("password")}
|
||||
/>
|
||||
<Button type="submit" fullWidth loading={isLoading}>
|
||||
{t("action.login")}
|
||||
</Button>
|
||||
)}
|
||||
</Stack>
|
||||
</Stack>
|
||||
</form>
|
||||
|
||||
{error && (
|
||||
<Alert icon={<IconAlertTriangle size={rem(16)} />} color="red">
|
||||
{error}
|
||||
</Alert>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
interface SubmitButtonProps {
|
||||
isPending: boolean;
|
||||
form: ReturnType<typeof useForm<FormType, (values: FormType) => FormType>>;
|
||||
provider: "credentials" | "ldap";
|
||||
}
|
||||
|
||||
const SubmitButton = ({ isPending, form, provider, children }: PropsWithChildren<SubmitButtonProps>) => {
|
||||
const isCurrentProviderActive = form.getValues().provider === provider;
|
||||
|
||||
return (
|
||||
<Button
|
||||
type="submit"
|
||||
name={provider}
|
||||
fullWidth
|
||||
onClick={() => form.setFieldValue("provider", provider)}
|
||||
loading={isPending && isCurrentProviderActive}
|
||||
disabled={isPending && !isCurrentProviderActive}
|
||||
>
|
||||
{children}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
interface PasswordForgottenCollapseProps {
|
||||
username: string;
|
||||
}
|
||||
const PasswordForgottenCollapse = ({ username }: PasswordForgottenCollapseProps) => {
|
||||
const [visible, { toggle }] = useDisclosure(false);
|
||||
const tForgotPassword = useScopedI18n("user.action.login.forgotPassword");
|
||||
|
||||
const commandUsername = username.trim().length >= 1 ? username.trim() : "<username>";
|
||||
|
||||
return (
|
||||
<>
|
||||
<Anchor type="button" component="button" onClick={toggle}>
|
||||
{tForgotPassword("label")}
|
||||
</Anchor>
|
||||
|
||||
<Collapse in={visible}>
|
||||
<Card>
|
||||
<Stack gap="xs">
|
||||
<Text size="sm">{tForgotPassword("description")}</Text>
|
||||
|
||||
<Code>homarr reset-password -u {commandUsername}</Code>
|
||||
</Stack>
|
||||
</Card>
|
||||
</Collapse>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
type FormType = z.infer<typeof extendedValidation>;
|
||||
type FormType = z.infer<typeof validation.user.signIn>;
|
||||
@@ -1,28 +1,11 @@
|
||||
import { redirect } from "next/navigation";
|
||||
import { Card, Center, Stack, Text, Title } from "@mantine/core";
|
||||
|
||||
import { env } from "@homarr/auth/env";
|
||||
import { auth } from "@homarr/auth/next";
|
||||
import { getScopedI18n } from "@homarr/translation/server";
|
||||
import { sanitizeRedirectionUrl } from "@homarr/validation/redirection-url";
|
||||
|
||||
import { HomarrLogoWithTitle } from "~/components/layout/logo/homarr-logo";
|
||||
import { LoginForm } from "./_login-form";
|
||||
|
||||
interface LoginProps {
|
||||
searchParams: Promise<{
|
||||
callbackUrl?: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
export default async function Login(props: LoginProps) {
|
||||
const searchParams = await props.searchParams;
|
||||
const session = await auth();
|
||||
|
||||
if (session) {
|
||||
redirect(sanitizeRedirectionUrl(searchParams.callbackUrl));
|
||||
}
|
||||
|
||||
export default async function Login() {
|
||||
const t = await getScopedI18n("user.page.login");
|
||||
|
||||
return (
|
||||
@@ -37,13 +20,8 @@ export default async function Login(props: LoginProps) {
|
||||
{t("subtitle")}
|
||||
</Text>
|
||||
</Stack>
|
||||
<Card withBorder w={64 * 6} maw="90vw">
|
||||
<LoginForm
|
||||
providers={env.AUTH_PROVIDERS}
|
||||
oidcClientName={env.AUTH_OIDC_CLIENT_NAME}
|
||||
isOidcAutoLoginEnabled={env.AUTH_OIDC_AUTO_LOGIN}
|
||||
callbackUrl={searchParams.callbackUrl ?? "/"}
|
||||
/>
|
||||
<Card bg="dark.8" w={64 * 6} maw="90vw">
|
||||
<LoginForm />
|
||||
</Card>
|
||||
</Stack>
|
||||
</Center>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { api } from "@homarr/api/server";
|
||||
import { createBoardContentPage } from "../_creator";
|
||||
|
||||
export default createBoardContentPage<{ locale: string }>({
|
||||
async getInitialBoardAsync() {
|
||||
return await api.board.getHomeBoard();
|
||||
async getInitialBoard() {
|
||||
return await api.board.getDefaultBoard();
|
||||
},
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
import definition from "./_definition";
|
||||
|
||||
const { generateMetadataAsync: generateMetadata, page } = definition;
|
||||
const { generateMetadata, page } = definition;
|
||||
|
||||
export default page;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { api } from "@homarr/api/server";
|
||||
|
||||
import { createBoardContentPage } from "../../_creator";
|
||||
import { createBoardContentPage } from "../_creator";
|
||||
|
||||
export default createBoardContentPage<{ locale: string; name: string }>({
|
||||
async getInitialBoardAsync({ name }) {
|
||||
async getInitialBoard({ name }) {
|
||||
return await api.board.getBoardByName({ name });
|
||||
},
|
||||
});
|
||||
@@ -1,18 +0,0 @@
|
||||
import { IconLayoutOff } from "@tabler/icons-react";
|
||||
|
||||
import { getScopedI18n } from "@homarr/translation/server";
|
||||
|
||||
import { BoardNotFound } from "~/components/board/not-found";
|
||||
|
||||
export default async function BoardNotFoundPage() {
|
||||
const tNotFound = await getScopedI18n("board.error.notFound");
|
||||
return (
|
||||
<BoardNotFound
|
||||
icon={IconLayoutOff}
|
||||
title={tNotFound("title")}
|
||||
description={tNotFound("description")}
|
||||
link={{ label: tNotFound("link"), href: "/manage/boards" }}
|
||||
notice={tNotFound("notice")}
|
||||
/>
|
||||
);
|
||||
}
|
||||