Compare commits
1 Commits
aa8e05f676
...
ci_test
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
52f3372701 |
2
.github/FUNDING.yml
vendored
@@ -1,2 +0,0 @@
|
|||||||
github: [Steve-Tech]
|
|
||||||
thanks_dev: u/gh/steve-tech
|
|
||||||
4
.github/workflows/flatpak.yml
vendored
@@ -8,10 +8,10 @@ jobs:
|
|||||||
flatpak:
|
flatpak:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: ghcr.io/flathub-infra/flatpak-github-actions:gnome-50
|
image: ghcr.io/flathub-infra/flatpak-github-actions:gnome-48
|
||||||
options: --privileged
|
options: --privileged
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
- name: Build Flatpak
|
- name: Build Flatpak
|
||||||
uses: flatpak/flatpak-github-actions/flatpak-builder@v6
|
uses: flatpak/flatpak-github-actions/flatpak-builder@v6
|
||||||
with:
|
with:
|
||||||
|
|||||||
4
.github/workflows/pyinstaller-linux.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
|||||||
pyinstaller-linux:
|
pyinstaller-linux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
# We shouldn't use actions/setup-python since PyGObject is compiled against the system Python
|
# We shouldn't use actions/setup-python since PyGObject is compiled against the system Python
|
||||||
- name: Install System Dependencies
|
- name: Install System Dependencies
|
||||||
uses: awalsh128/cache-apt-pkgs-action@latest
|
uses: awalsh128/cache-apt-pkgs-action@latest
|
||||||
@@ -24,7 +24,7 @@ jobs:
|
|||||||
run: LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu pyinstaller yafi.spec -- --onefile
|
run: LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu pyinstaller yafi.spec -- --onefile
|
||||||
working-directory: pyinstaller
|
working-directory: pyinstaller
|
||||||
- name: Upload PyInstaller Artifact
|
- name: Upload PyInstaller Artifact
|
||||||
uses: actions/upload-artifact@v6
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: pyinstaller/dist/YAFI
|
path: pyinstaller/dist/YAFI
|
||||||
name: yafi-linux-${{ github.sha }}
|
name: yafi-linux-${{ github.sha }}
|
||||||
|
|||||||
16
.github/workflows/pyinstaller-windows.yml
vendored
@@ -8,22 +8,22 @@ jobs:
|
|||||||
pyinstaller-windows:
|
pyinstaller-windows:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-python@v6
|
- uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.14'
|
python-version: '3.13'
|
||||||
cache: 'pip'
|
cache: 'pip'
|
||||||
|
|
||||||
- name: Cache GTK4
|
- name: Cache GTK4
|
||||||
id: cache-gtk4
|
id: cache-gtk4
|
||||||
uses: actions/cache@v5
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: C:\gtk
|
path: C:\gtk
|
||||||
key: Gvsbuild_2026.2.0
|
key: Gvsbuild_2025.8.0
|
||||||
|
|
||||||
- name: Download GTK4 Gvsbuild zip
|
- name: Download GTK4 Gvsbuild zip
|
||||||
if: steps.cache-gtk4.outputs.cache-hit != 'true'
|
if: steps.cache-gtk4.outputs.cache-hit != 'true'
|
||||||
run: Start-BitsTransfer -Source https://github.com/wingtk/gvsbuild/releases/download/2026.2.0/GTK4_Gvsbuild_2026.2.0_x64.zip -Destination Gvsbuild.zip
|
run: Start-BitsTransfer -Source https://github.com/wingtk/gvsbuild/releases/download/2025.9.0/GTK4_Gvsbuild_2025.9.0_x64.zip -Destination Gvsbuild.zip
|
||||||
|
|
||||||
- name: Extract Gvsbuild zip
|
- name: Extract Gvsbuild zip
|
||||||
if: steps.cache-gtk4.outputs.cache-hit != 'true'
|
if: steps.cache-gtk4.outputs.cache-hit != 'true'
|
||||||
@@ -46,7 +46,7 @@ jobs:
|
|||||||
working-directory: pyinstaller
|
working-directory: pyinstaller
|
||||||
|
|
||||||
- name: Upload PyInstaller Artifact (ZIP)
|
- name: Upload PyInstaller Artifact (ZIP)
|
||||||
uses: actions/upload-artifact@v6
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: pyinstaller/dist/YAFI/*
|
path: pyinstaller/dist/YAFI/*
|
||||||
name: yafi-windows-${{ github.sha }}
|
name: yafi-windows-${{ github.sha }}
|
||||||
@@ -56,7 +56,7 @@ jobs:
|
|||||||
working-directory: pyinstaller
|
working-directory: pyinstaller
|
||||||
|
|
||||||
- name: Upload PyInstaller Artifact (Standalone)
|
- name: Upload PyInstaller Artifact (Standalone)
|
||||||
uses: actions/upload-artifact@v6
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: pyinstaller/dist/YAFI.exe
|
path: pyinstaller/dist/YAFI.exe
|
||||||
name: yafi-windows-standalone-${{ github.sha }}
|
name: yafi-windows-standalone-${{ github.sha }}
|
||||||
|
|||||||
7
60-cros_ec_python.rules
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# CrOS_EC_Python udev rules
|
||||||
|
|
||||||
|
# LPC Access
|
||||||
|
KERNEL=="port", TAG+="uaccess"
|
||||||
|
|
||||||
|
# /dev/cros_ec Access
|
||||||
|
KERNEL=="cros_ec", TAG+="uaccess"
|
||||||
16
README.md
@@ -11,13 +11,9 @@ You can download the latest release from the [Releases page](https://github.com/
|
|||||||
|
|
||||||
There are builds for Flatpak, and PyInstaller for portable execution on Linux or Windows.
|
There are builds for Flatpak, and PyInstaller for portable execution on Linux or Windows.
|
||||||
|
|
||||||
YAFI is also available on [Flathub](https://flathub.org/en/apps/au.stevetech.yafi): `flatpak install flathub au.stevetech.yafi`.
|
|
||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
To allow YAFI to communicate with the EC, you will need to enable user access to the `/dev/cros_ec` device. You can do this by running `echo KERNEL==\"cros_ec\", TAG+=\"uaccess\" | sudo tee /etc/udev/rules.d/60-yafi.rules`, and then reload the rules with `sudo udevadm control --reload-rules && sudo udevadm trigger`.
|
To allow YAFI to communicate with the EC, you need to copy the [`60-cros_ec_python.rules`](60-cros_ec_python.rules) file to `/etc/udev/rules.d/` and reload the rules with `sudo udevadm control --reload-rules && sudo udevadm trigger`.
|
||||||
|
|
||||||
You can also do this by running `curl -Lfs yafi.stevetech.au/udev.sh | sudo sh` which will run the [`add-udev-rules.sh`](add-udev-rules.sh) script.
|
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
@@ -25,8 +21,6 @@ If your Laptop's BIOS supports Framework's EC driver, there is no need to instal
|
|||||||
|
|
||||||
Otherwise, YAFI supports the [PawnIO](https://pawnio.eu/) driver, and will be automatically used if installed and there is no Framework driver available. YAFI will need to be run as administrator to communicate with the driver.
|
Otherwise, YAFI supports the [PawnIO](https://pawnio.eu/) driver, and will be automatically used if installed and there is no Framework driver available. YAFI will need to be run as administrator to communicate with the driver.
|
||||||
|
|
||||||
Currently the PawnIO driver does not support Framework 13 mainboards with 11th, 12th, or 13th Gen Intel CPUs.
|
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
### Flatpak
|
### Flatpak
|
||||||
@@ -86,7 +80,7 @@ It is possible to run YAFI on Windows using [gvsbuild](https://github.com/wingtk
|
|||||||
|
|
||||||
### `[Errno 13] Permission denied: '/dev/cros_ec'`
|
### `[Errno 13] Permission denied: '/dev/cros_ec'`
|
||||||
|
|
||||||
This error occurs when the udev rules are not installed or not working. Make sure you have installed the udev rules as described in the [Linux Installation](#linux) section.
|
This error occurs when the udev rules are not installed or not working. Make sure you have copied the `60-cros_ec_python.rules` file to `/etc/udev/rules.d/` and reloaded the rules with `sudo udevadm control --reload-rules && sudo udevadm trigger`.
|
||||||
|
|
||||||
### `Could not auto detect device, check you have the required permissions, or specify manually.`
|
### `Could not auto detect device, check you have the required permissions, or specify manually.`
|
||||||
|
|
||||||
@@ -94,9 +88,3 @@ This error occurs when `/dev/cros_ec` is not found, and the `CrOS_EC_Python` lib
|
|||||||
You can either update your kernel to have a working `cros_ec_dev` driver, or run YAFI as root.
|
You can either update your kernel to have a working `cros_ec_dev` driver, or run YAFI as root.
|
||||||
|
|
||||||
It can also occur if you do not have a CrOS EC, like on non Framework laptops.
|
It can also occur if you do not have a CrOS EC, like on non Framework laptops.
|
||||||
|
|
||||||
## Disclaimer
|
|
||||||
|
|
||||||
YAFI is not affiliated with Framework Computer Inc. in any way.
|
|
||||||
|
|
||||||
YAFI is licensed under the [GPL-2.0-or-later license](COPYING), and comes with no warranty or guarantee of any kind. Use at your own risk.
|
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
echo Installing udev rules for YAFI to /etc/udev/rules.d/60-yafi.rules
|
|
||||||
echo KERNEL==\"cros_ec\", TAG+=\"uaccess\" > /etc/udev/rules.d/60-yafi.rules
|
|
||||||
udevadm control --reload-rules
|
|
||||||
udevadm trigger
|
|
||||||
echo udev rules installed successfully.
|
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
{
|
{
|
||||||
"id" : "au.stevetech.yafi",
|
"id" : "au.stevetech.yafi",
|
||||||
"runtime" : "org.gnome.Platform",
|
"runtime" : "org.gnome.Platform",
|
||||||
"runtime-version" : "49",
|
"runtime-version" : "48",
|
||||||
"sdk" : "org.gnome.Sdk",
|
"sdk" : "org.gnome.Sdk",
|
||||||
"command" : "yafi",
|
"command" : "yafi",
|
||||||
"finish-args" : [
|
"finish-args" : [
|
||||||
"--device=all",
|
"--device=all",
|
||||||
"--socket=fallback-x11",
|
"--socket=fallback-x11",
|
||||||
"--socket=wayland",
|
"--socket=wayland"
|
||||||
"--share=ipc"
|
|
||||||
],
|
],
|
||||||
"cleanup" : [
|
"cleanup" : [
|
||||||
"/include",
|
"/include",
|
||||||
@@ -22,7 +21,6 @@
|
|||||||
"*.a"
|
"*.a"
|
||||||
],
|
],
|
||||||
"modules" : [
|
"modules" : [
|
||||||
"python3-cros_ec_python.json",
|
|
||||||
{
|
{
|
||||||
"name" : "yafi",
|
"name" : "yafi",
|
||||||
"builddir" : true,
|
"builddir" : true,
|
||||||
@@ -33,6 +31,18 @@
|
|||||||
"path" : "."
|
"path" : "."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cros_ec_python",
|
||||||
|
"buildsystem": "simple",
|
||||||
|
"build-options": {
|
||||||
|
"build-args": [
|
||||||
|
"--share=network"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"build-commands": [
|
||||||
|
"pip3 install --prefix=${FLATPAK_DEST} --no-cache-dir \"cros_ec_python>=0.2.0\""
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ Comment=Yet Another Framework Interface
|
|||||||
Terminal=false
|
Terminal=false
|
||||||
Type=Application
|
Type=Application
|
||||||
Categories=Utility;
|
Categories=Utility;
|
||||||
Keywords=Framework;EC;Embedded Controller;
|
Keywords=GTK;
|
||||||
StartupNotify=true
|
StartupNotify=true
|
||||||
DBusActivatable=true
|
DBusActivatable=true
|
||||||
|
|||||||
@@ -7,25 +7,11 @@
|
|||||||
<name>Yet Another Framework Interface</name>
|
<name>Yet Another Framework Interface</name>
|
||||||
<summary>YAFI is another GUI for the Framework Laptop Embedded Controller</summary>
|
<summary>YAFI is another GUI for the Framework Laptop Embedded Controller</summary>
|
||||||
<description>
|
<description>
|
||||||
<p>It is written in Python with a GTK4 Adwaita theme, and uses the CrOS_EC_Python library to communicate with the EC.</p>
|
<p>It is written in Python with a GTK4 Adwaita theme, and uses the `CrOS_EC_Python` library to communicate with the EC.</p>
|
||||||
<p>YAFI has the capability for the following features:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Fan control and temperature monitoring</li>
|
|
||||||
<li>LED control</li>
|
|
||||||
<li>Battery statistics</li>
|
|
||||||
<li>Battery limiting</li>
|
|
||||||
<li>Hardware information</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>You will need to install the udev rules to allow non-root access to the EC device. See the README for more information.</p>
|
|
||||||
|
|
||||||
<p>Alternatively, you can run <code>curl -Lfs yafi.stevetech.au/udev.sh | sudo sh</code> to install the udev rules.</p>
|
|
||||||
|
|
||||||
<p>YAFI is not affiliated with Framework Computer Inc. in any way.</p>
|
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<developer id="au.stevetech">
|
<developer id="au.stevetech">
|
||||||
<name translate="no">Stephen Horvath</name>
|
<name>Stephen Horvath</name>
|
||||||
</developer>
|
</developer>
|
||||||
|
|
||||||
<!-- Required: Should be a link to the upstream homepage for the component -->
|
<!-- Required: Should be a link to the upstream homepage for the component -->
|
||||||
@@ -56,92 +42,35 @@
|
|||||||
|
|
||||||
<!-- Applications should set a brand color in both light and dark variants like so -->
|
<!-- Applications should set a brand color in both light and dark variants like so -->
|
||||||
<branding>
|
<branding>
|
||||||
<color type="primary" scheme_preference="light">#7c916f</color>
|
<color type="primary" scheme_preference="light">#ff00ff</color>
|
||||||
<color type="primary" scheme_preference="dark">#282000</color>
|
<color type="primary" scheme_preference="dark">#993d3d</color>
|
||||||
</branding>
|
</branding>
|
||||||
|
|
||||||
<screenshots>
|
<screenshots>
|
||||||
<screenshot type="default">
|
<screenshot type="default">
|
||||||
<image>https://raw.githubusercontent.com/Steve-Tech/YAFI/refs/heads/main/docs/1-thermals.png</image>
|
<image>https://github.com/Steve-Tech/YAFI/blob/main/docs/1-thermals.png</image>
|
||||||
<caption>Fan Control and Temperature Monitoring</caption>
|
<caption>Fan Control and Temperature Monitoring</caption>
|
||||||
</screenshot>
|
</screenshot>
|
||||||
<screenshot>
|
<screenshot>
|
||||||
<image>https://raw.githubusercontent.com/Steve-Tech/YAFI/refs/heads/main/docs/2-leds.png</image>
|
<image>https://github.com/Steve-Tech/YAFI/blob/main/docs/2-leds.png</image>
|
||||||
<caption>LED Control</caption>
|
<caption>LED Control</caption>
|
||||||
</screenshot>
|
</screenshot>
|
||||||
<screenshot>
|
<screenshot>
|
||||||
<image>https://raw.githubusercontent.com/Steve-Tech/YAFI/refs/heads/main/docs/3-battery.png</image>
|
<image>https://github.com/Steve-Tech/YAFI/blob/main/docs/3-battery.png</image>
|
||||||
<caption>Battery Statistics</caption>
|
<caption>Battery Statistics</caption>
|
||||||
</screenshot>
|
</screenshot>
|
||||||
<screenshot>
|
<screenshot>
|
||||||
<image>https://raw.githubusercontent.com/Steve-Tech/YAFI/refs/heads/main/docs/4-battery-limit.png</image>
|
<image>https://github.com/Steve-Tech/YAFI/blob/main/docs/4-battery-limit.png</image>
|
||||||
<caption>Battery Limiting</caption>
|
<caption>Battery Limiting</caption>
|
||||||
</screenshot>
|
</screenshot>
|
||||||
<screenshot>
|
<screenshot>
|
||||||
<image>https://raw.githubusercontent.com/Steve-Tech/YAFI/refs/heads/main/docs/4a-battery-ext.png</image>
|
<image>https://github.com/Steve-Tech/YAFI/blob/main/docs/4a-battery-ext.png</image>
|
||||||
<caption>Battery Extender</caption>
|
<caption>Battery Extender</caption>
|
||||||
</screenshot>
|
</screenshot>
|
||||||
<screenshot>
|
<screenshot>
|
||||||
<image>https://raw.githubusercontent.com/Steve-Tech/YAFI/refs/heads/main/docs/5-hardware.png</image>
|
<image>https://github.com/Steve-Tech/YAFI/blob/main/docs/5-hardware.png</image>
|
||||||
<caption>Hardware Info</caption>
|
<caption>Hardware Info</caption>
|
||||||
</screenshot>
|
</screenshot>
|
||||||
</screenshots>
|
</screenshots>
|
||||||
|
|
||||||
<releases>
|
|
||||||
<release version="0.7" date="2025-12-25">
|
|
||||||
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.7</url>
|
|
||||||
<description>
|
|
||||||
<p>YAFI now supports modifying fan set points.</p>
|
|
||||||
</description>
|
|
||||||
</release>
|
|
||||||
<release version="0.6" date="2025-09-28">
|
|
||||||
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.6</url>
|
|
||||||
<description>
|
|
||||||
<p>The following changes have been made:</p>
|
|
||||||
<ul>
|
|
||||||
<li>YAFI now has a new logo!</li>
|
|
||||||
<li>The advanced LED settings now detect available LEDs.</li>
|
|
||||||
<li>The ALS and lid open sensor has been added.</li>
|
|
||||||
<li>Stuttering has been reduced when opening the about dialog.</li>
|
|
||||||
</ul>
|
|
||||||
</description>
|
|
||||||
</release>
|
|
||||||
<release version="0.5" date="2025-09-16">
|
|
||||||
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.5</url>
|
|
||||||
<description>
|
|
||||||
<p>The following bugs have been fixed:</p>
|
|
||||||
<ul>
|
|
||||||
<li>LED page crashing when encountering unsupported LEDs.</li>
|
|
||||||
<li>Scaling issues on Windows.</li>
|
|
||||||
<li>Minimum charge limiter doesn't work.</li>
|
|
||||||
</ul>
|
|
||||||
<p>This release also adds a traceback to the debug info, when there is an error during initialisation.</p>
|
|
||||||
</description>
|
|
||||||
</release>
|
|
||||||
<release version="0.4" date="2025-09-06">
|
|
||||||
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.4</url>
|
|
||||||
<description>
|
|
||||||
<p>This release also adds a new battery statistics page.</p>
|
|
||||||
</description>
|
|
||||||
</release>
|
|
||||||
<release version="0.3" date="2025-04-13">
|
|
||||||
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.3</url>
|
|
||||||
<description>
|
|
||||||
<p>YAFI now shows the battery limiter value.</p>
|
|
||||||
</description>
|
|
||||||
</release>
|
|
||||||
<release version="0.2" date="2025-03-24">
|
|
||||||
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.2</url>
|
|
||||||
<description>
|
|
||||||
<p>This fixes an LED list bug.</p>
|
|
||||||
</description>
|
|
||||||
</release>
|
|
||||||
<release version="0.1" date="2025-03-20">
|
|
||||||
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.1</url>
|
|
||||||
<description>
|
|
||||||
<p>This is the first release of YAFI.</p>
|
|
||||||
</description>
|
|
||||||
</release>
|
|
||||||
</releases>
|
|
||||||
|
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
@@ -1,92 +1,92 @@
|
|||||||
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<rect x="12" y="92" width="104" height="24" rx="8" fill="url(#paint0_linear_293_18)"/>
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
<rect x="12" y="88" width="104" height="24" rx="8" fill="#328361"/>
|
|
||||||
<rect x="12" y="88" width="104" height="24" rx="8" fill="url(#paint1_linear_293_18)" fill-opacity="0.5" style="mix-blend-mode:multiply"/>
|
<svg
|
||||||
<path d="M108 12H20C15.5817 12 12 15.5817 12 20V24V33V102C12 106.418 15.5817 110 20 110H108C112.418 110 116 106.418 116 102V20C116 15.5817 112.418 12 108 12Z" fill="#3FB182"/>
|
width="128"
|
||||||
<path d="M34 25H38V18C38 17.4477 37.5523 17 37 17H35C34.4477 17 34 17.4477 34 18V25Z" fill="#FFE11D"/>
|
height="128"
|
||||||
<path d="M42 25H46V18C46 17.4477 45.5523 17 45 17H43C42.4477 17 42 17.4477 42 18V25Z" fill="#FFE11D"/>
|
viewBox="0 0 128 128"
|
||||||
<path d="M50 25H54V18C54 17.4477 53.5523 17 53 17H51C50.4477 17 50 17.4477 50 18V25Z" fill="#FFE11D"/>
|
version="1.1"
|
||||||
<path d="M58 25H62V18C62 17.4477 61.5523 17 61 17H59C58.4477 17 58 17.4477 58 18V25Z" fill="#FFE11D"/>
|
id="svg1"
|
||||||
<path d="M66 25H70V18C70 17.4477 69.5523 17 69 17H67C66.4477 17 66 17.4477 66 18V25Z" fill="#FFE11D"/>
|
xml:space="preserve"
|
||||||
<path d="M74 25H78V18C78 17.4477 77.5523 17 77 17H75C74.4477 17 74 17.4477 74 18V25Z" fill="#FFE11D"/>
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
<path d="M82 25H86V18C86 17.4477 85.5523 17 85 17H83C82.4477 17 82 17.4477 82 18V25Z" fill="#FFE11D"/>
|
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||||
<path d="M90 25H94V18C94 17.4477 93.5523 17 93 17H91C90.4477 17 90 17.4477 90 18V25Z" fill="#FFE11D"/>
|
id="defs1" /><g
|
||||||
<rect x="24" y="27" width="80" height="74" rx="8" fill="url(#paint2_linear_293_18)"/>
|
id="layer1"><g
|
||||||
<rect x="24" y="27" width="80" height="74" rx="8" fill="black" fill-opacity="0.1"/>
|
id="icon"><g
|
||||||
<rect x="24" y="21" width="80" height="72" rx="8" fill="#EAEAEA"/>
|
id="chip"
|
||||||
<path d="M34 98C34 96.8954 34.8954 96 36 96C37.1046 96 38 96.8954 38 98V105C38 105.552 37.5523 106 37 106H35C34.4477 106 34 105.552 34 105V98Z" fill="#939A00"/>
|
style="stroke-width:0;stroke-dasharray:none"><path
|
||||||
<path d="M42 98C42 96.8954 42.8954 96 44 96C45.1046 96 46 96.8954 46 98V105C46 105.552 45.5523 106 45 106H43C42.4477 106 42 105.552 42 105V98Z" fill="#939A00"/>
|
style="fill:none;stroke:#ffcc00;stroke-width:8;stroke-linecap:round;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
<path d="M50 98C50 96.8954 50.8954 96 52 96C53.1046 96 54 96.8954 54 98V105C54 105.552 53.5523 106 53 106H51C50.4477 106 50 105.552 50 105V98Z" fill="#939A00"/>
|
d="m 34,8 v 8"
|
||||||
<path d="M58 98C58 96.8954 58.8954 96 60 96C61.1046 96 62 96.8954 62 98V105C62 105.552 61.5523 106 61 106H59C58.4477 106 58 105.552 58 105V98Z" fill="#939A00"/>
|
id="pin1" /><path
|
||||||
<path d="M66 98C66 96.8954 66.8954 96 68 96C69.1046 96 70 96.8954 70 98V105C70 105.552 69.5523 106 69 106H67C66.4477 106 66 105.552 66 105V98Z" fill="#939A00"/>
|
style="fill:none;stroke:#ffcc00;stroke-width:8;stroke-linecap:round;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
<path d="M74 98C74 96.8954 74.8954 96 76 96C77.1046 96 78 96.8954 78 98V105C78 105.552 77.5523 106 77 106H75C74.4477 106 74 105.552 74 105V98Z" fill="#939A00"/>
|
d="M 54,8.0000019 V 16.000002"
|
||||||
<path d="M82 98C82 96.8954 82.8954 96 84 96C85.1046 96 86 96.8954 86 98V105C86 105.552 85.5523 106 85 106H83C82.4477 106 82 105.552 82 105V98Z" fill="#939A00"/>
|
id="pin2" /><path
|
||||||
<path d="M90 98C90 96.8954 90.8954 96 92 96C93.1046 96 94 96.8954 94 98V105C94 105.552 93.5523 106 93 106H91C90.4477 106 90 105.552 90 105V98Z" fill="#939A00"/>
|
style="fill:none;stroke:#ffcc00;stroke-width:8;stroke-linecap:round;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
<path d="M34 98C34 96.8954 34.8954 96 36 96C37.1046 96 38 96.8954 38 98V104H34V98Z" fill="#FFE11D"/>
|
d="M 74.000009,8.0000019 V 16.000002"
|
||||||
<path d="M42 98C42 96.8954 42.8954 96 44 96C45.1046 96 46 96.8954 46 98V104H42V98Z" fill="#FFE11D"/>
|
id="pin3" /><path
|
||||||
<path d="M50 98C50 96.8954 50.8954 96 52 96C53.1046 96 54 96.8954 54 98V104H50V98Z" fill="#FFE11D"/>
|
style="fill:none;stroke:#ffcc00;stroke-width:8;stroke-linecap:round;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
<path d="M58 98C58 96.8954 58.8954 96 60 96C61.1046 96 62 96.8954 62 98V104H58V98Z" fill="#FFE11D"/>
|
d="m 93.999992,8 v 8"
|
||||||
<path d="M66 98C66 96.8954 66.8954 96 68 96C69.1046 96 70 96.8954 70 98V104H66V98Z" fill="#FFE11D"/>
|
id="pin4" /><path
|
||||||
<path d="M74 98C74 96.8954 74.8954 96 76 96C77.1046 96 78 96.8954 78 98V104H74V98Z" fill="#FFE11D"/>
|
style="fill:none;stroke:#ffcc00;stroke-width:8;stroke-linecap:round;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
<path d="M82 98C82 96.8954 82.8954 96 84 96C85.1046 96 86 96.8954 86 98V104H82V98Z" fill="#FFE11D"/>
|
d="m 120,34.000001 h -8"
|
||||||
<path d="M90 98C90 96.8954 90.8954 96 92 96C93.1046 96 94 96.8954 94 98V104H90V98Z" fill="#FFE11D"/>
|
id="pin5" /><path
|
||||||
<path d="M34 98C34 96.8954 34.8954 96 36 96C37.1046 96 38 96.8954 38 98H34Z" fill="#808080"/>
|
style="fill:none;stroke:#ffcc00;stroke-width:8;stroke-linecap:round;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
<path d="M42 98C42 96.8954 42.8954 96 44 96C45.1046 96 46 96.8954 46 98H42Z" fill="#808080"/>
|
d="m 120,54.000001 h -8"
|
||||||
<path d="M50 98C50 96.8954 50.8954 96 52 96C53.1046 96 54 96.8954 54 98H50Z" fill="#808080"/>
|
id="pin6" /><path
|
||||||
<path d="M58 98C58 96.8954 58.8954 96 60 96C61.1046 96 62 96.8954 62 98H58Z" fill="#808080"/>
|
style="fill:none;stroke:#ffcc00;stroke-width:8;stroke-linecap:round;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
<path d="M66 98C66 96.8954 66.8954 96 68 96C69.1046 96 70 96.8954 70 98H66Z" fill="#808080"/>
|
d="m 120,74.000009 h -8"
|
||||||
<path d="M74 98C74 96.8954 74.8954 96 76 96C77.1046 96 78 96.8954 78 98H74Z" fill="#808080"/>
|
id="pin7" /><path
|
||||||
<path d="M82 98C82 96.8954 82.8954 96 84 96C85.1046 96 86 96.8954 86 98H82Z" fill="#808080"/>
|
style="fill:none;stroke:#ffcc00;stroke-width:8;stroke-linecap:round;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
<path d="M90 98C90 96.8954 90.8954 96 92 96C93.1046 96 94 96.8954 94 98H90Z" fill="#808080"/>
|
d="m 120,93.999992 h -8"
|
||||||
<g filter="url(#filter0_i_293_18)">
|
id="pin8" /><path
|
||||||
<path d="M48.8658 38.6343C49.4695 35.7019 52.4974 33.9536 55.3388 34.8971L57.6974 35.6803C61.7893 37.039 66.2107 37.039 70.3026 35.6803L72.6612 34.8971C75.5026 33.9536 78.5305 35.7018 79.1342 38.6343L79.6352 41.0684C80.5045 45.2915 82.7152 49.1206 85.9378 51.9849L87.7953 53.6359C90.0331 55.6249 90.0331 59.1213 87.7953 61.1103L85.9378 62.7612C82.7152 65.6256 80.5045 69.4546 79.6352 73.6777L79.1342 76.1118C78.5305 79.0443 75.5026 80.7925 72.6612 79.849L70.3026 79.0659C66.2107 77.7071 61.7893 77.7071 57.6974 79.0659L55.3388 79.849C52.4974 80.7925 49.4695 79.0443 48.8658 76.1118L48.3648 73.6777C47.4955 69.4547 45.2848 65.6256 42.0622 62.7612L40.2047 61.1103C37.9669 59.1213 37.9669 55.6249 40.2047 53.6359L42.0622 51.9849C45.2848 49.1206 47.4955 45.2915 48.3648 41.0684L48.8658 38.6343Z" fill="#D9D9D9"/>
|
style="fill:none;stroke:#ffcc00;stroke-width:8;stroke-linecap:round;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
<path d="M48.8658 38.6343C49.4695 35.7019 52.4974 33.9536 55.3388 34.8971L57.6974 35.6803C61.7893 37.039 66.2107 37.039 70.3026 35.6803L72.6612 34.8971C75.5026 33.9536 78.5305 35.7018 79.1342 38.6343L79.6352 41.0684C80.5045 45.2915 82.7152 49.1206 85.9378 51.9849L87.7953 53.6359C90.0331 55.6249 90.0331 59.1213 87.7953 61.1103L85.9378 62.7612C82.7152 65.6256 80.5045 69.4546 79.6352 73.6777L79.1342 76.1118C78.5305 79.0443 75.5026 80.7925 72.6612 79.849L70.3026 79.0659C66.2107 77.7071 61.7893 77.7071 57.6974 79.0659L55.3388 79.849C52.4974 80.7925 49.4695 79.0443 48.8658 76.1118L48.3648 73.6777C47.4955 69.4547 45.2848 65.6256 42.0622 62.7612L40.2047 61.1103C37.9669 59.1213 37.9669 55.6249 40.2047 53.6359L42.0622 51.9849C45.2848 49.1206 47.4955 45.2915 48.3648 41.0684L48.8658 38.6343Z" fill="#202020"/>
|
d="m 94.000009,112 v 8"
|
||||||
</g>
|
id="pin9" /><path
|
||||||
<g filter="url(#filter1_d_293_18)">
|
style="fill:none;stroke:#ffcc00;stroke-width:8;stroke-linecap:round;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
<path d="M64 70C56.8216 70 51 64.1761 51 57C51 49.8194 56.8216 44 64 44C71.1784 44 77 49.8239 77 57C77 64.1761 71.1784 70 64 70Z" fill="#EAEAEA"/>
|
d="m 74.000026,112 v 8"
|
||||||
</g>
|
id="pin10" /><path
|
||||||
<defs>
|
style="fill:none;stroke:#ffcc00;stroke-width:8;stroke-linecap:round;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
<filter id="filter0_i_293_18" x="38.5264" y="34.6403" width="50.9473" height="45.4655" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
d="m 54.000017,112 v 8"
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
id="pin11" /><path
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
style="fill:none;stroke:#ffcc00;stroke-width:8;stroke-linecap:round;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
d="m 34.000017,112 v 8"
|
||||||
<feOffset dy="2"/>
|
id="pin12" /><path
|
||||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
style="fill:none;stroke:#ffcc00;stroke-width:8;stroke-linecap:round;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
<feColorMatrix type="matrix" values="0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 1 0"/>
|
d="M 16.000002,93.999992 H 8.0000019"
|
||||||
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_293_18"/>
|
id="pin13" /><path
|
||||||
</filter>
|
style="fill:none;stroke:#ffcc00;stroke-width:8;stroke-linecap:round;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
<filter id="filter1_d_293_18" x="51" y="44" width="26" height="28" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
d="M 16.000002,74.000009 H 8.0000019"
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
id="pin14" /><path
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
style="fill:none;stroke:#ffcc00;stroke-width:8;stroke-linecap:round;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
<feOffset dy="2"/>
|
d="M 16.000002,54.000001 H 8.0000019"
|
||||||
<feComposite in2="hardAlpha" operator="out"/>
|
id="pin15" /><path
|
||||||
<feColorMatrix type="matrix" values="0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 1 0"/>
|
style="fill:none;stroke:#ffcc00;stroke-width:8;stroke-linecap:round;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_293_18"/>
|
d="M 16.000002,34.000001 H 8.0000019"
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_293_18" result="shape"/>
|
id="pin16" /><rect
|
||||||
</filter>
|
style="fill:#000000;fill-opacity:0.5;stroke-width:0;stroke-dasharray:none"
|
||||||
<linearGradient id="paint0_linear_293_18" x1="116" y1="116" x2="12" y2="116" gradientUnits="userSpaceOnUse">
|
id="shadow"
|
||||||
<stop stop-color="#404040"/>
|
width="104"
|
||||||
<stop offset="0.03" stop-color="#D0D0D0"/>
|
height="104"
|
||||||
<stop offset="0.06" stop-color="#606060"/>
|
x="16"
|
||||||
<stop offset="0.94" stop-color="#606060"/>
|
y="16"
|
||||||
<stop offset="0.97" stop-color="#D0D0D0"/>
|
rx="16.000002"
|
||||||
<stop offset="1" stop-color="#404040"/>
|
ry="16.000002" /><rect
|
||||||
</linearGradient>
|
style="fill:#808080;stroke-width:0;stroke-dasharray:none"
|
||||||
<linearGradient id="paint1_linear_293_18" x1="116" y1="112" x2="12" y2="112" gradientUnits="userSpaceOnUse">
|
id="package"
|
||||||
<stop stop-color="#404040"/>
|
width="104"
|
||||||
<stop offset="0.03" stop-color="#D0D0D0"/>
|
height="104"
|
||||||
<stop offset="0.06" stop-color="#606060"/>
|
x="12.000001"
|
||||||
<stop offset="0.94" stop-color="#606060"/>
|
y="12.000001"
|
||||||
<stop offset="0.97" stop-color="#D0D0D0"/>
|
rx="16.000002"
|
||||||
<stop offset="1" stop-color="#404040"/>
|
ry="16.000002" /><circle
|
||||||
</linearGradient>
|
style="fill:#b3b3b3;fill-opacity:1;stroke:none;stroke-width:8;stroke-linecap:round;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
<linearGradient id="paint2_linear_293_18" x1="24" y1="85.8476" x2="103.999" y2="85.6325" gradientUnits="userSpaceOnUse">
|
id="dot"
|
||||||
<stop stop-color="#AFAFAF"/>
|
cx="22"
|
||||||
<stop offset="0.04" stop-color="#F6F5F4"/>
|
cy="22"
|
||||||
<stop offset="0.08" stop-color="#D0D0D0"/>
|
r="2" /></g><path
|
||||||
<stop offset="0.92" stop-color="#D0D0D0"/>
|
id="cog"
|
||||||
<stop offset="0.96" stop-color="#F6F5F4"/>
|
style="display:inline;fill:#282000;fill-opacity:1;stroke:none;stroke-width:8.00001;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
<stop offset="1" stop-color="#AFAFAF"/>
|
d="m 47.818363,18 -15.564456,8.986326 4.037106,14.113285 c -2.535988,3.065348 -4.574404,6.558856 -5.988276,10.355467 l -14.230472,3.558595 v 17.972654 l 14.230472,3.558592 c 1.413872,3.79649 3.452288,7.288524 5.988276,10.353516 L 32.253907,101.01367 47.818363,110 58.019531,99.451172 c 1.945156,0.325909 3.942754,0.494135 5.980471,0.494135 2.037713,0 4.035311,-0.168226 5.980467,-0.494135 L 80.181641,110 95.746094,101.01367 91.708984,86.898435 c 2.536165,-3.064992 4.57429,-6.557026 5.988283,-10.353516 L 111.92774,72.986327 V 55.013673 L 97.697267,51.455078 C 96.283274,47.658406 94.245149,44.164959 91.708984,41.099611 L 95.746094,26.986326 80.181641,18 69.980469,28.548828 c -1.945156,-0.325795 -3.942754,-0.494143 -5.980467,-0.494143 -2.037717,0 -4.035315,0.16834 -5.980471,0.494143 z M 64.000002,36 A 27.999999,27.999997 0 0 1 92,63.999998 27.999999,27.999997 0 0 1 64.000002,91.999996 27.999999,27.999997 0 0 1 36,63.999998 27.999999,27.999997 0 0 1 64.000002,36 Z" /><path
|
||||||
</linearGradient>
|
id="Y"
|
||||||
</defs>
|
style="fill:none;stroke:#282000;stroke-width:8;stroke-linecap:round;stroke-dasharray:none"
|
||||||
</svg>
|
d="M 64.000002,62.00022 50.000001,48.000008 m 13.999997,38.000215 4e-6,-24.000003 m -4e-6,0 14.000001,-14.000212 m -13.999997,38.000215 -4e-6,-24.000003" /></g></g></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 5.8 KiB |
@@ -1,4 +1,21 @@
|
|||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<path d="M8 10C6.89563 10 6 9.10402 6 8C6 6.8953 6.89563 6 8 6C9.10437 6 10 6.89598 10 8C10 9.10402 9.10437 10 8 10Z" fill="black"/>
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 2C0 0.895431 0.895431 0 2 0H3V1C3 1.55228 3.44772 2 4 2C4.55228 2 5 1.55228 5 1V0H7V1C7 1.55228 7.44772 2 8 2C8.55228 2 9 1.55228 9 1V0H11V1C11 1.55228 11.4477 2 12 2C12.5523 2 13 1.55228 13 1V0H14C15.1046 0 16 0.895431 16 2V14C16 15.1046 15.1046 16 14 16H13V15C13 14.4477 12.5523 14 12 14C11.4477 14 11 14.4477 11 15V16H9V15C9 14.4477 8.55228 14 8 14C7.44772 14 7 14.4477 7 15V16H5V15C5 14.4477 4.55228 14 4 14C3.44772 14 3 14.4477 3 15V16H2C0.895431 16 0 15.1046 0 14V2ZM5.23026 4.85673C5.04181 5.76259 4.56253 6.58395 3.86386 7.19836C3.37871 7.625 3.37871 8.375 3.86386 8.80164C4.56253 9.41605 5.04181 10.2374 5.23026 11.1433C5.36113 11.7723 6.01759 12.1473 6.6336 11.9449C7.52072 11.6535 8.47928 11.6535 9.3664 11.9449C9.98241 12.1473 10.6389 11.7723 10.7697 11.1433C10.9582 10.2374 11.4375 9.41605 12.1361 8.80164C12.6213 8.375 12.6213 7.625 12.1361 7.19836C11.4375 6.58395 10.9582 5.76259 10.7697 4.85673C10.6389 4.2277 9.98241 3.85271 9.3664 4.05509C8.47928 4.34654 7.52072 4.34654 6.6336 4.05509C6.01759 3.85271 5.36113 4.2277 5.23026 4.85673ZM8 10C6.89563 10 6 9.10402 6 8C6 6.8953 6.89563 6 8 6C9.10437 6 10 6.89598 10 8C10 9.10402 9.10437 10 8 10Z" fill="black"/>
|
|
||||||
</svg>
|
<svg
|
||||||
|
width="128"
|
||||||
|
height="128"
|
||||||
|
viewBox="0 0 128 128"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
xml:space="preserve"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||||
|
id="defs1" /><g
|
||||||
|
id="layer1"><g
|
||||||
|
id="icon"><path
|
||||||
|
id="cog"
|
||||||
|
style="display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:8.00001;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
|
d="m 47.818363,18 -15.564456,8.986326 4.037106,14.113285 c -2.535988,3.065348 -4.574404,6.558856 -5.988276,10.355467 l -14.230472,3.558595 v 17.972654 l 14.230472,3.558592 c 1.413872,3.79649 3.452288,7.288524 5.988276,10.353516 L 32.253907,101.01367 47.818363,110 58.019531,99.451172 c 1.945156,0.325909 3.942754,0.494135 5.980471,0.494135 2.037713,0 4.035311,-0.168226 5.980467,-0.494135 L 80.181641,110 95.746094,101.01367 91.708984,86.898435 c 2.536165,-3.064992 4.57429,-6.557026 5.988283,-10.353516 L 111.92774,72.986327 V 55.013673 L 97.697267,51.455078 C 96.283274,47.658406 94.245149,44.164959 91.708984,41.099611 L 95.746094,26.986326 80.181641,18 69.980469,28.548828 c -1.945156,-0.325795 -3.942754,-0.494143 -5.980467,-0.494143 -2.037717,0 -4.035315,0.16834 -5.980471,0.494143 z M 64.000002,36 A 27.999999,27.999997 0 0 1 92,63.999998 27.999999,27.999997 0 0 1 64.000002,91.999996 27.999999,27.999997 0 0 1 36,63.999998 27.999999,27.999997 0 0 1 64.000002,36 Z" /><path
|
||||||
|
id="Y"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:8;stroke-linecap:round;stroke-dasharray:none"
|
||||||
|
d="M 64.000002,62.00022 50.000001,48.000008 m 13.999997,38.000215 4e-6,-24.000003 m -4e-6,0 14.000001,-14.000212 m -13.999997,38.000215 -4e-6,-24.000003" /></g></g></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 94 KiB |
BIN
docs/2-leds.png
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 150 KiB |
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 157 KiB |
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 93 KiB |
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"only-arches": ["x86_64"]
|
|
||||||
}
|
|
||||||
251
logo.svg
@@ -1,92 +1,159 @@
|
|||||||
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<rect x="12" y="92" width="104" height="24" rx="8" fill="url(#paint0_linear_293_18)"/>
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
<rect x="12" y="88" width="104" height="24" rx="8" fill="#328361"/>
|
|
||||||
<rect x="12" y="88" width="104" height="24" rx="8" fill="url(#paint1_linear_293_18)" fill-opacity="0.5" style="mix-blend-mode:multiply"/>
|
<svg
|
||||||
<path d="M108 12H20C15.5817 12 12 15.5817 12 20V24V33V102C12 106.418 15.5817 110 20 110H108C112.418 110 116 106.418 116 102V20C116 15.5817 112.418 12 108 12Z" fill="#3FB182"/>
|
width="128"
|
||||||
<path d="M34 25H38V18C38 17.4477 37.5523 17 37 17H35C34.4477 17 34 17.4477 34 18V25Z" fill="#FFE11D"/>
|
height="128"
|
||||||
<path d="M42 25H46V18C46 17.4477 45.5523 17 45 17H43C42.4477 17 42 17.4477 42 18V25Z" fill="#FFE11D"/>
|
viewBox="0 0 128 128"
|
||||||
<path d="M50 25H54V18C54 17.4477 53.5523 17 53 17H51C50.4477 17 50 17.4477 50 18V25Z" fill="#FFE11D"/>
|
version="1.1"
|
||||||
<path d="M58 25H62V18C62 17.4477 61.5523 17 61 17H59C58.4477 17 58 17.4477 58 18V25Z" fill="#FFE11D"/>
|
id="svg1"
|
||||||
<path d="M66 25H70V18C70 17.4477 69.5523 17 69 17H67C66.4477 17 66 17.4477 66 18V25Z" fill="#FFE11D"/>
|
xml:space="preserve"
|
||||||
<path d="M74 25H78V18C78 17.4477 77.5523 17 77 17H75C74.4477 17 74 17.4477 74 18V25Z" fill="#FFE11D"/>
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
<path d="M82 25H86V18C86 17.4477 85.5523 17 85 17H83C82.4477 17 82 17.4477 82 18V25Z" fill="#FFE11D"/>
|
sodipodi:docname="logo.svg"
|
||||||
<path d="M90 25H94V18C94 17.4477 93.5523 17 93 17H91C90.4477 17 90 17.4477 90 18V25Z" fill="#FFE11D"/>
|
inkscape:export-filename="logo-plain.svg"
|
||||||
<rect x="24" y="27" width="80" height="74" rx="8" fill="url(#paint2_linear_293_18)"/>
|
inkscape:export-xdpi="96"
|
||||||
<rect x="24" y="27" width="80" height="74" rx="8" fill="black" fill-opacity="0.1"/>
|
inkscape:export-ydpi="96"
|
||||||
<rect x="24" y="21" width="80" height="72" rx="8" fill="#EAEAEA"/>
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
<path d="M34 98C34 96.8954 34.8954 96 36 96C37.1046 96 38 96.8954 38 98V105C38 105.552 37.5523 106 37 106H35C34.4477 106 34 105.552 34 105V98Z" fill="#939A00"/>
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
<path d="M42 98C42 96.8954 42.8954 96 44 96C45.1046 96 46 96.8954 46 98V105C46 105.552 45.5523 106 45 106H43C42.4477 106 42 105.552 42 105V98Z" fill="#939A00"/>
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
<path d="M50 98C50 96.8954 50.8954 96 52 96C53.1046 96 54 96.8954 54 98V105C54 105.552 53.5523 106 53 106H51C50.4477 106 50 105.552 50 105V98Z" fill="#939A00"/>
|
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||||
<path d="M58 98C58 96.8954 58.8954 96 60 96C61.1046 96 62 96.8954 62 98V105C62 105.552 61.5523 106 61 106H59C58.4477 106 58 105.552 58 105V98Z" fill="#939A00"/>
|
id="namedview1"
|
||||||
<path d="M66 98C66 96.8954 66.8954 96 68 96C69.1046 96 70 96.8954 70 98V105C70 105.552 69.5523 106 69 106H67C66.4477 106 66 105.552 66 105V98Z" fill="#939A00"/>
|
pagecolor="#505050"
|
||||||
<path d="M74 98C74 96.8954 74.8954 96 76 96C77.1046 96 78 96.8954 78 98V105C78 105.552 77.5523 106 77 106H75C74.4477 106 74 105.552 74 105V98Z" fill="#939A00"/>
|
bordercolor="#eeeeee"
|
||||||
<path d="M82 98C82 96.8954 82.8954 96 84 96C85.1046 96 86 96.8954 86 98V105C86 105.552 85.5523 106 85 106H83C82.4477 106 82 105.552 82 105V98Z" fill="#939A00"/>
|
borderopacity="1"
|
||||||
<path d="M90 98C90 96.8954 90.8954 96 92 96C93.1046 96 94 96.8954 94 98V105C94 105.552 93.5523 106 93 106H91C90.4477 106 90 105.552 90 105V98Z" fill="#939A00"/>
|
inkscape:showpageshadow="0"
|
||||||
<path d="M34 98C34 96.8954 34.8954 96 36 96C37.1046 96 38 96.8954 38 98V104H34V98Z" fill="#FFE11D"/>
|
inkscape:pageopacity="0"
|
||||||
<path d="M42 98C42 96.8954 42.8954 96 44 96C45.1046 96 46 96.8954 46 98V104H42V98Z" fill="#FFE11D"/>
|
inkscape:pagecheckerboard="0"
|
||||||
<path d="M50 98C50 96.8954 50.8954 96 52 96C53.1046 96 54 96.8954 54 98V104H50V98Z" fill="#FFE11D"/>
|
inkscape:deskcolor="#d1d1d1"
|
||||||
<path d="M58 98C58 96.8954 58.8954 96 60 96C61.1046 96 62 96.8954 62 98V104H58V98Z" fill="#FFE11D"/>
|
inkscape:document-units="px"
|
||||||
<path d="M66 98C66 96.8954 66.8954 96 68 96C69.1046 96 70 96.8954 70 98V104H66V98Z" fill="#FFE11D"/>
|
inkscape:zoom="2"
|
||||||
<path d="M74 98C74 96.8954 74.8954 96 76 96C77.1046 96 78 96.8954 78 98V104H74V98Z" fill="#FFE11D"/>
|
inkscape:cx="37.25"
|
||||||
<path d="M82 98C82 96.8954 82.8954 96 84 96C85.1046 96 86 96.8954 86 98V104H82V98Z" fill="#FFE11D"/>
|
inkscape:cy="109"
|
||||||
<path d="M90 98C90 96.8954 90.8954 96 92 96C93.1046 96 94 96.8954 94 98V104H90V98Z" fill="#FFE11D"/>
|
inkscape:window-width="1876"
|
||||||
<path d="M34 98C34 96.8954 34.8954 96 36 96C37.1046 96 38 96.8954 38 98H34Z" fill="#808080"/>
|
inkscape:window-height="1025"
|
||||||
<path d="M42 98C42 96.8954 42.8954 96 44 96C45.1046 96 46 96.8954 46 98H42Z" fill="#808080"/>
|
inkscape:window-x="0"
|
||||||
<path d="M50 98C50 96.8954 50.8954 96 52 96C53.1046 96 54 96.8954 54 98H50Z" fill="#808080"/>
|
inkscape:window-y="0"
|
||||||
<path d="M58 98C58 96.8954 58.8954 96 60 96C61.1046 96 62 96.8954 62 98H58Z" fill="#808080"/>
|
inkscape:window-maximized="1"
|
||||||
<path d="M66 98C66 96.8954 66.8954 96 68 96C69.1046 96 70 96.8954 70 98H66Z" fill="#808080"/>
|
inkscape:current-layer="layer1" /><defs
|
||||||
<path d="M74 98C74 96.8954 74.8954 96 76 96C77.1046 96 78 96.8954 78 98H74Z" fill="#808080"/>
|
id="defs1" /><g
|
||||||
<path d="M82 98C82 96.8954 82.8954 96 84 96C85.1046 96 86 96.8954 86 98H82Z" fill="#808080"/>
|
inkscape:label="Layer 1"
|
||||||
<path d="M90 98C90 96.8954 90.8954 96 92 96C93.1046 96 94 96.8954 94 98H90Z" fill="#808080"/>
|
inkscape:groupmode="layer"
|
||||||
<g filter="url(#filter0_i_293_18)">
|
id="layer1"><g
|
||||||
<path d="M48.8658 38.6343C49.4695 35.7019 52.4974 33.9536 55.3388 34.8971L57.6974 35.6803C61.7893 37.039 66.2107 37.039 70.3026 35.6803L72.6612 34.8971C75.5026 33.9536 78.5305 35.7018 79.1342 38.6343L79.6352 41.0684C80.5045 45.2915 82.7152 49.1206 85.9378 51.9849L87.7953 53.6359C90.0331 55.6249 90.0331 59.1213 87.7953 61.1103L85.9378 62.7612C82.7152 65.6256 80.5045 69.4546 79.6352 73.6777L79.1342 76.1118C78.5305 79.0443 75.5026 80.7925 72.6612 79.849L70.3026 79.0659C66.2107 77.7071 61.7893 77.7071 57.6974 79.0659L55.3388 79.849C52.4974 80.7925 49.4695 79.0443 48.8658 76.1118L48.3648 73.6777C47.4955 69.4547 45.2848 65.6256 42.0622 62.7612L40.2047 61.1103C37.9669 59.1213 37.9669 55.6249 40.2047 53.6359L42.0622 51.9849C45.2848 49.1206 47.4955 45.2915 48.3648 41.0684L48.8658 38.6343Z" fill="#D9D9D9"/>
|
id="icon"
|
||||||
<path d="M48.8658 38.6343C49.4695 35.7019 52.4974 33.9536 55.3388 34.8971L57.6974 35.6803C61.7893 37.039 66.2107 37.039 70.3026 35.6803L72.6612 34.8971C75.5026 33.9536 78.5305 35.7018 79.1342 38.6343L79.6352 41.0684C80.5045 45.2915 82.7152 49.1206 85.9378 51.9849L87.7953 53.6359C90.0331 55.6249 90.0331 59.1213 87.7953 61.1103L85.9378 62.7612C82.7152 65.6256 80.5045 69.4546 79.6352 73.6777L79.1342 76.1118C78.5305 79.0443 75.5026 80.7925 72.6612 79.849L70.3026 79.0659C66.2107 77.7071 61.7893 77.7071 57.6974 79.0659L55.3388 79.849C52.4974 80.7925 49.4695 79.0443 48.8658 76.1118L48.3648 73.6777C47.4955 69.4547 45.2848 65.6256 42.0622 62.7612L40.2047 61.1103C37.9669 59.1213 37.9669 55.6249 40.2047 53.6359L42.0622 51.9849C45.2848 49.1206 47.4955 45.2915 48.3648 41.0684L48.8658 38.6343Z" fill="#202020"/>
|
inkscape:label="icon"><g
|
||||||
</g>
|
id="chip"
|
||||||
<g filter="url(#filter1_d_293_18)">
|
inkscape:label="chip"
|
||||||
<path d="M64 70C56.8216 70 51 64.1761 51 57C51 49.8194 56.8216 44 64 44C71.1784 44 77 49.8239 77 57C77 64.1761 71.1784 70 64 70Z" fill="#EAEAEA"/>
|
style="stroke-width:0;stroke-dasharray:none"><path
|
||||||
</g>
|
style="stroke-width:8;stroke-dasharray:none;fill:none;stroke:#ffcc00;stroke-linecap:round;paint-order:stroke fill markers"
|
||||||
<defs>
|
d="m 34,8 v 8"
|
||||||
<filter id="filter0_i_293_18" x="38.5264" y="34.6403" width="50.9473" height="45.4655" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
id="pin1"
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
sodipodi:nodetypes="cc"
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
inkscape:label="pin1" /><path
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
style="stroke-width:8;stroke-dasharray:none;fill:none;stroke:#ffcc00;stroke-linecap:round;paint-order:stroke fill markers"
|
||||||
<feOffset dy="2"/>
|
d="M 54,8.0000019 V 16.000002"
|
||||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
id="pin2"
|
||||||
<feColorMatrix type="matrix" values="0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 1 0"/>
|
sodipodi:nodetypes="cc"
|
||||||
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_293_18"/>
|
inkscape:label="pin2" /><path
|
||||||
</filter>
|
style="stroke-width:8;stroke-dasharray:none;fill:none;stroke:#ffcc00;stroke-linecap:round;paint-order:stroke fill markers"
|
||||||
<filter id="filter1_d_293_18" x="51" y="44" width="26" height="28" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
d="M 74.000009,8.0000019 V 16.000002"
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
id="pin3"
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
sodipodi:nodetypes="cc"
|
||||||
<feOffset dy="2"/>
|
inkscape:label="pin3" /><path
|
||||||
<feComposite in2="hardAlpha" operator="out"/>
|
style="stroke-width:8;stroke-dasharray:none;fill:none;stroke:#ffcc00;stroke-linecap:round;paint-order:stroke fill markers"
|
||||||
<feColorMatrix type="matrix" values="0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 1 0"/>
|
d="m 93.999992,8 v 8"
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_293_18"/>
|
id="pin4"
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_293_18" result="shape"/>
|
sodipodi:nodetypes="cc"
|
||||||
</filter>
|
inkscape:label="pin4" /><path
|
||||||
<linearGradient id="paint0_linear_293_18" x1="116" y1="116" x2="12" y2="116" gradientUnits="userSpaceOnUse">
|
style="stroke-width:8;stroke-dasharray:none;fill:none;stroke:#ffcc00;stroke-linecap:round;paint-order:stroke fill markers"
|
||||||
<stop stop-color="#404040"/>
|
d="m 120,34.000001 h -8"
|
||||||
<stop offset="0.03" stop-color="#D0D0D0"/>
|
id="pin5"
|
||||||
<stop offset="0.06" stop-color="#606060"/>
|
sodipodi:nodetypes="cc"
|
||||||
<stop offset="0.94" stop-color="#606060"/>
|
inkscape:label="pin5" /><path
|
||||||
<stop offset="0.97" stop-color="#D0D0D0"/>
|
style="stroke-width:8;stroke-dasharray:none;fill:none;stroke:#ffcc00;stroke-linecap:round;paint-order:stroke fill markers"
|
||||||
<stop offset="1" stop-color="#404040"/>
|
d="m 120,54.000001 h -8"
|
||||||
</linearGradient>
|
id="pin6"
|
||||||
<linearGradient id="paint1_linear_293_18" x1="116" y1="112" x2="12" y2="112" gradientUnits="userSpaceOnUse">
|
sodipodi:nodetypes="cc"
|
||||||
<stop stop-color="#404040"/>
|
inkscape:label="pin6" /><path
|
||||||
<stop offset="0.03" stop-color="#D0D0D0"/>
|
style="stroke-width:8;stroke-dasharray:none;fill:none;stroke:#ffcc00;stroke-linecap:round;paint-order:stroke fill markers"
|
||||||
<stop offset="0.06" stop-color="#606060"/>
|
d="m 120,74.000009 h -8"
|
||||||
<stop offset="0.94" stop-color="#606060"/>
|
id="pin7"
|
||||||
<stop offset="0.97" stop-color="#D0D0D0"/>
|
sodipodi:nodetypes="cc"
|
||||||
<stop offset="1" stop-color="#404040"/>
|
inkscape:label="pin7" /><path
|
||||||
</linearGradient>
|
style="stroke-width:8;stroke-dasharray:none;fill:none;stroke:#ffcc00;stroke-linecap:round;paint-order:stroke fill markers"
|
||||||
<linearGradient id="paint2_linear_293_18" x1="24" y1="85.8476" x2="103.999" y2="85.6325" gradientUnits="userSpaceOnUse">
|
d="m 120,93.999992 h -8"
|
||||||
<stop stop-color="#AFAFAF"/>
|
id="pin8"
|
||||||
<stop offset="0.04" stop-color="#F6F5F4"/>
|
sodipodi:nodetypes="cc"
|
||||||
<stop offset="0.08" stop-color="#D0D0D0"/>
|
inkscape:label="pin8" /><path
|
||||||
<stop offset="0.92" stop-color="#D0D0D0"/>
|
style="stroke-width:8;stroke-dasharray:none;fill:none;stroke:#ffcc00;stroke-linecap:round;paint-order:stroke fill markers"
|
||||||
<stop offset="0.96" stop-color="#F6F5F4"/>
|
d="m 94.000009,112 v 8"
|
||||||
<stop offset="1" stop-color="#AFAFAF"/>
|
id="pin9"
|
||||||
</linearGradient>
|
sodipodi:nodetypes="cc"
|
||||||
</defs>
|
inkscape:label="pin9" /><path
|
||||||
</svg>
|
style="stroke-width:8;stroke-dasharray:none;fill:none;stroke:#ffcc00;stroke-linecap:round;paint-order:stroke fill markers"
|
||||||
|
d="m 74.000026,112 v 8"
|
||||||
|
id="pin10"
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
inkscape:label="pin10" /><path
|
||||||
|
style="stroke-width:8;stroke-dasharray:none;fill:none;stroke:#ffcc00;stroke-linecap:round;paint-order:stroke fill markers"
|
||||||
|
d="m 54.000017,112 v 8"
|
||||||
|
id="pin11"
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
inkscape:label="pin11" /><path
|
||||||
|
style="stroke-width:8;stroke-dasharray:none;fill:none;stroke:#ffcc00;stroke-linecap:round;paint-order:stroke fill markers"
|
||||||
|
d="m 34.000017,112 v 8"
|
||||||
|
id="pin12"
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
inkscape:label="pin12" /><path
|
||||||
|
style="stroke-width:8;stroke-dasharray:none;fill:none;stroke:#ffcc00;stroke-linecap:round;paint-order:stroke fill markers"
|
||||||
|
d="M 16.000002,93.999992 H 8.0000019"
|
||||||
|
id="pin13"
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
inkscape:label="pin13" /><path
|
||||||
|
style="stroke-width:8;stroke-dasharray:none;fill:none;stroke:#ffcc00;stroke-linecap:round;paint-order:stroke fill markers"
|
||||||
|
d="M 16.000002,74.000009 H 8.0000019"
|
||||||
|
id="pin14"
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
inkscape:label="pin14" /><path
|
||||||
|
style="stroke-width:8;stroke-dasharray:none;fill:none;stroke:#ffcc00;stroke-linecap:round;paint-order:stroke fill markers"
|
||||||
|
d="M 16.000002,54.000001 H 8.0000019"
|
||||||
|
id="pin15"
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
inkscape:label="pin15" /><path
|
||||||
|
style="stroke-width:8;stroke-dasharray:none;fill:none;stroke:#ffcc00;stroke-linecap:round;paint-order:stroke fill markers"
|
||||||
|
d="M 16.000002,34.000001 H 8.0000019"
|
||||||
|
id="pin16"
|
||||||
|
sodipodi:nodetypes="cc"
|
||||||
|
inkscape:label="pin16" /><rect
|
||||||
|
style="fill:#000000;stroke-width:0;stroke-dasharray:none;fill-opacity:0.5"
|
||||||
|
id="shadow"
|
||||||
|
width="104"
|
||||||
|
height="104"
|
||||||
|
x="16"
|
||||||
|
y="16"
|
||||||
|
rx="16.000002"
|
||||||
|
ry="16.000002"
|
||||||
|
inkscape:label="shadow" /><rect
|
||||||
|
style="fill:#808080;stroke-width:0;stroke-dasharray:none"
|
||||||
|
id="package"
|
||||||
|
width="104"
|
||||||
|
height="104"
|
||||||
|
x="12.000001"
|
||||||
|
y="12.000001"
|
||||||
|
rx="16.000002"
|
||||||
|
ry="16.000002"
|
||||||
|
inkscape:label="package" /><circle
|
||||||
|
style="fill:#b3b3b3;fill-opacity:1;stroke:none;stroke-width:8;stroke-linecap:round;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
|
id="dot"
|
||||||
|
cx="22"
|
||||||
|
cy="22"
|
||||||
|
r="2"
|
||||||
|
inkscape:label="dot" /></g><path
|
||||||
|
id="cog"
|
||||||
|
style="display:inline;fill:#282000;fill-opacity:1;stroke:none;stroke-width:8.00001;stroke-dasharray:none;paint-order:stroke fill markers"
|
||||||
|
d="m 47.818363,18 -15.564456,8.986326 4.037106,14.113285 c -2.535988,3.065348 -4.574404,6.558856 -5.988276,10.355467 l -14.230472,3.558595 v 17.972654 l 14.230472,3.558592 c 1.413872,3.79649 3.452288,7.288524 5.988276,10.353516 L 32.253907,101.01367 47.818363,110 58.019531,99.451172 c 1.945156,0.325909 3.942754,0.494135 5.980471,0.494135 2.037713,0 4.035311,-0.168226 5.980467,-0.494135 L 80.181641,110 95.746094,101.01367 91.708984,86.898435 c 2.536165,-3.064992 4.57429,-6.557026 5.988283,-10.353516 L 111.92774,72.986327 V 55.013673 L 97.697267,51.455078 C 96.283274,47.658406 94.245149,44.164959 91.708984,41.099611 L 95.746094,26.986326 80.181641,18 69.980469,28.548828 c -1.945156,-0.325795 -3.942754,-0.494143 -5.980467,-0.494143 -2.037717,0 -4.035315,0.16834 -5.980471,0.494143 z M 64.000002,36 A 27.999999,27.999997 0 0 1 92,63.999998 27.999999,27.999997 0 0 1 64.000002,91.999996 27.999999,27.999997 0 0 1 36,63.999998 27.999999,27.999997 0 0 1 64.000002,36 Z"
|
||||||
|
inkscape:label="cog" /><path
|
||||||
|
id="Y"
|
||||||
|
style="fill:none;stroke:#282000;stroke-width:8;stroke-linecap:round;stroke-dasharray:none"
|
||||||
|
d="M 64.000002,62.00022 50.000001,48.000008 m 13.999997,38.000215 4e-6,-24.000003 m -4e-6,0 14.000001,-14.000212 m -13.999997,38.000215 -4e-6,-24.000003"
|
||||||
|
inkscape:label="Y"
|
||||||
|
sodipodi:nodetypes="cccccccc" /></g></g></svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.0 KiB |
@@ -1,5 +1,5 @@
|
|||||||
project('yafi',
|
project('yafi',
|
||||||
version: '0.7',
|
version: '0.5',
|
||||||
meson_version: '>= 1.0.0',
|
meson_version: '>= 1.0.0',
|
||||||
default_options: [ 'warning_level=2', 'werror=false', ],
|
default_options: [ 'warning_level=2', 'werror=false', ],
|
||||||
)
|
)
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 16 KiB |
BIN
pyinstaller/yafi.ico
Normal file → Executable file
|
Before Width: | Height: | Size: 398 KiB After Width: | Height: | Size: 148 KiB |
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "yafi"
|
name = "yafi"
|
||||||
version = "0.7"
|
version = "0.5"
|
||||||
authors = [
|
authors = [
|
||||||
{ name="Steve-Tech" }
|
{ name="Steve-Tech" }
|
||||||
]
|
]
|
||||||
@@ -8,7 +8,7 @@ description = "Yet Another Framework Interface"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cros_ec_python >= 0.3.0",
|
"cros_ec_python >= 0.2.0",
|
||||||
"PyGObject"
|
"PyGObject"
|
||||||
]
|
]
|
||||||
classifiers = [
|
classifiers = [
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "python3-cros_ec_python",
|
|
||||||
"buildsystem": "simple",
|
|
||||||
"build-commands": [
|
|
||||||
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"cros_ec_python\" --no-build-isolation"
|
|
||||||
],
|
|
||||||
"sources": [
|
|
||||||
{
|
|
||||||
"type": "file",
|
|
||||||
"url": "https://files.pythonhosted.org/packages/6c/7a/10d978a02bbe37530490cfd14e0994c433dc29c81b3afcdbde453d512528/cros_ec_python-0.3.0-py3-none-any.whl",
|
|
||||||
"sha256": "aeb14ebdbd60ec6d6a4b11df1482a295466da4a908a468d168efd4cc141e7e3d"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -50,9 +50,6 @@ class BatteryPage(Gtk.Box):
|
|||||||
|
|
||||||
def setup(self, app):
|
def setup(self, app):
|
||||||
battery = ec_commands.memmap.get_battery_values(app.cros_ec)
|
battery = ec_commands.memmap.get_battery_values(app.cros_ec)
|
||||||
if not battery:
|
|
||||||
self.batt_status.set_subtitle("No data")
|
|
||||||
return
|
|
||||||
self.batt_manu.set_subtitle(battery["manufacturer"])
|
self.batt_manu.set_subtitle(battery["manufacturer"])
|
||||||
self.batt_model.set_subtitle(battery["model"])
|
self.batt_model.set_subtitle(battery["model"])
|
||||||
self.batt_serial.set_subtitle(battery["serial"])
|
self.batt_serial.set_subtitle(battery["serial"])
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ class BatteryLimiterPage(Gtk.Box):
|
|||||||
bat_limit = Gtk.Template.Child()
|
bat_limit = Gtk.Template.Child()
|
||||||
bat_limit_label = Gtk.Template.Child()
|
bat_limit_label = Gtk.Template.Child()
|
||||||
bat_limit_scale = Gtk.Template.Child()
|
bat_limit_scale = Gtk.Template.Child()
|
||||||
|
chg_limit_override = Gtk.Template.Child()
|
||||||
|
chg_limit_override_btn = Gtk.Template.Child()
|
||||||
|
|
||||||
bat_ext_group = Gtk.Template.Child()
|
bat_ext_group = Gtk.Template.Child()
|
||||||
bat_ext_enable = Gtk.Template.Child()
|
bat_ext_enable = Gtk.Template.Child()
|
||||||
@@ -59,6 +61,7 @@ class BatteryLimiterPage(Gtk.Box):
|
|||||||
self.bat_limit_label.set_label(f"{ec_limit[1]}%")
|
self.bat_limit_label.set_label(f"{ec_limit[1]}%")
|
||||||
self.chg_limit.set_sensitive(True)
|
self.chg_limit.set_sensitive(True)
|
||||||
self.bat_limit.set_sensitive(True)
|
self.bat_limit.set_sensitive(True)
|
||||||
|
self.chg_limit_override.set_sensitive(True)
|
||||||
|
|
||||||
def handle_chg_limit_change(min, max):
|
def handle_chg_limit_change(min, max):
|
||||||
ec_commands.framework_laptop.set_charge_limit(
|
ec_commands.framework_laptop.set_charge_limit(
|
||||||
@@ -76,6 +79,7 @@ class BatteryLimiterPage(Gtk.Box):
|
|||||||
|
|
||||||
self.chg_limit.set_sensitive(active)
|
self.chg_limit.set_sensitive(active)
|
||||||
self.bat_limit.set_sensitive(active)
|
self.bat_limit.set_sensitive(active)
|
||||||
|
self.chg_limit_override.set_sensitive(active)
|
||||||
|
|
||||||
self.chg_limit_enable.connect(
|
self.chg_limit_enable.connect(
|
||||||
"notify::active", lambda switch, _: handle_chg_limit_enable(switch)
|
"notify::active", lambda switch, _: handle_chg_limit_enable(switch)
|
||||||
@@ -93,6 +97,12 @@ class BatteryLimiterPage(Gtk.Box):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.chg_limit_override_btn.connect(
|
||||||
|
"clicked",
|
||||||
|
lambda _: ec_commands.framework_laptop.override_charge_limit(
|
||||||
|
app.cros_ec
|
||||||
|
),
|
||||||
|
)
|
||||||
except ec_exceptions.ECError as e:
|
except ec_exceptions.ECError as e:
|
||||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
||||||
app.no_support.append(ec_commands.framework_laptop.EC_CMD_CHARGE_LIMIT_CONTROL)
|
app.no_support.append(ec_commands.framework_laptop.EC_CMD_CHARGE_LIMIT_CONTROL)
|
||||||
|
|||||||
@@ -27,24 +27,17 @@ import cros_ec_python.exceptions as ec_exceptions
|
|||||||
class HardwarePage(Gtk.Box):
|
class HardwarePage(Gtk.Box):
|
||||||
__gtype_name__ = 'HardwarePage'
|
__gtype_name__ = 'HardwarePage'
|
||||||
|
|
||||||
hw_als = Gtk.Template.Child()
|
|
||||||
hw_als_label = Gtk.Template.Child()
|
|
||||||
|
|
||||||
hw_chassis = Gtk.Template.Child()
|
hw_chassis = Gtk.Template.Child()
|
||||||
hw_chassis_label = Gtk.Template.Child()
|
hw_chassis_label = Gtk.Template.Child()
|
||||||
|
|
||||||
hw_fp_pwr = Gtk.Template.Child()
|
|
||||||
hw_fp_pwr_en = Gtk.Template.Child()
|
|
||||||
hw_fp_pwr_dis = Gtk.Template.Child()
|
|
||||||
|
|
||||||
hw_priv_cam = Gtk.Template.Child()
|
hw_priv_cam = Gtk.Template.Child()
|
||||||
hw_priv_cam_sw = Gtk.Template.Child()
|
hw_priv_cam_sw = Gtk.Template.Child()
|
||||||
hw_priv_mic = Gtk.Template.Child()
|
hw_priv_mic = Gtk.Template.Child()
|
||||||
hw_priv_mic_sw = Gtk.Template.Child()
|
hw_priv_mic_sw = Gtk.Template.Child()
|
||||||
hw_lid_open = Gtk.Template.Child()
|
|
||||||
hw_lid_open_sw = Gtk.Template.Child()
|
hw_fp_pwr = Gtk.Template.Child()
|
||||||
hw_pwr_btn = Gtk.Template.Child()
|
hw_fp_pwr_en = Gtk.Template.Child()
|
||||||
hw_pwr_btn_sw = Gtk.Template.Child()
|
hw_fp_pwr_dis = Gtk.Template.Child()
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
@@ -73,13 +66,7 @@ class HardwarePage(Gtk.Box):
|
|||||||
GLib.timeout_add_seconds(1, self._update_hardware, app)
|
GLib.timeout_add_seconds(1, self._update_hardware, app)
|
||||||
|
|
||||||
def _update_hardware(self, app):
|
def _update_hardware(self, app):
|
||||||
# Memmap (ALS and Lid Open)
|
success = False
|
||||||
als = ec_commands.memmap.get_als(app.cros_ec)
|
|
||||||
self.hw_als_label.set_label(f"{als[0]} lux" if als[0] != 65535 else "MAX")
|
|
||||||
switches = ec_commands.memmap.get_switches(app.cros_ec)
|
|
||||||
self.hw_lid_open_sw.set_active(switches["lid_open"])
|
|
||||||
self.hw_pwr_btn_sw.set_active(switches["power_button_pressed"])
|
|
||||||
|
|
||||||
# Chassis
|
# Chassis
|
||||||
if not ec_commands.framework_laptop.EC_CMD_CHASSIS_INTRUSION in app.no_support:
|
if not ec_commands.framework_laptop.EC_CMD_CHASSIS_INTRUSION in app.no_support:
|
||||||
try:
|
try:
|
||||||
@@ -95,6 +82,8 @@ class HardwarePage(Gtk.Box):
|
|||||||
self.hw_chassis.set_subtitle(
|
self.hw_chassis.set_subtitle(
|
||||||
"Currently " + ("Open" if ec_chassis_open else "Closed")
|
"Currently " + ("Open" if ec_chassis_open else "Closed")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
success = True
|
||||||
except ec_exceptions.ECError as e:
|
except ec_exceptions.ECError as e:
|
||||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
||||||
app.no_support.append(
|
app.no_support.append(
|
||||||
@@ -115,6 +104,8 @@ class HardwarePage(Gtk.Box):
|
|||||||
)
|
)
|
||||||
self.hw_priv_cam_sw.set_active(ec_privacy["camera"])
|
self.hw_priv_cam_sw.set_active(ec_privacy["camera"])
|
||||||
self.hw_priv_mic_sw.set_active(ec_privacy["microphone"])
|
self.hw_priv_mic_sw.set_active(ec_privacy["microphone"])
|
||||||
|
|
||||||
|
success = True
|
||||||
except ec_exceptions.ECError as e:
|
except ec_exceptions.ECError as e:
|
||||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
||||||
app.no_support.append(
|
app.no_support.append(
|
||||||
@@ -125,4 +116,4 @@ class HardwarePage(Gtk.Box):
|
|||||||
else:
|
else:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
return app.current_page == 4
|
return app.current_page == 4 and success
|
||||||
|
|||||||
94
yafi/leds.py
@@ -27,8 +27,6 @@ import cros_ec_python.exceptions as ec_exceptions
|
|||||||
class LedsPage(Gtk.Box):
|
class LedsPage(Gtk.Box):
|
||||||
__gtype_name__ = 'LedsPage'
|
__gtype_name__ = 'LedsPage'
|
||||||
|
|
||||||
first_run = True
|
|
||||||
|
|
||||||
led_pwr = Gtk.Template.Child()
|
led_pwr = Gtk.Template.Child()
|
||||||
led_pwr_scale = Gtk.Template.Child()
|
led_pwr_scale = Gtk.Template.Child()
|
||||||
|
|
||||||
@@ -37,30 +35,27 @@ class LedsPage(Gtk.Box):
|
|||||||
|
|
||||||
led_advanced = Gtk.Template.Child()
|
led_advanced = Gtk.Template.Child()
|
||||||
|
|
||||||
|
led_pwr_colour = Gtk.Template.Child()
|
||||||
|
|
||||||
|
led_chg_colour = Gtk.Template.Child()
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
def setup(self, app):
|
def setup(self, app):
|
||||||
# Power LED
|
# Power LED
|
||||||
try:
|
try:
|
||||||
|
|
||||||
def handle_led_pwr(scale):
|
def handle_led_pwr(scale):
|
||||||
value = int(abs(scale.get_value() - 2))
|
value = int(abs(scale.get_value() - 2))
|
||||||
ec_commands.framework_laptop.set_fp_led_level(app.cros_ec, value)
|
ec_commands.framework_laptop.set_fp_led_level(app.cros_ec, value)
|
||||||
self.led_pwr.set_subtitle(["High", "Medium", "Low"][value])
|
self.led_pwr.set_subtitle(["High", "Medium", "Low"][value])
|
||||||
|
|
||||||
try:
|
|
||||||
current_fp_level = ec_commands.framework_laptop.get_fp_led_level(
|
current_fp_level = ec_commands.framework_laptop.get_fp_led_level(
|
||||||
app.cros_ec
|
app.cros_ec
|
||||||
).value
|
).value
|
||||||
self.led_pwr_scale.set_value(abs(current_fp_level - 2))
|
self.led_pwr_scale.set_value(abs(current_fp_level - 2))
|
||||||
self.led_pwr.set_subtitle(["High", "Medium", "Low"][current_fp_level])
|
self.led_pwr.set_subtitle(["High", "Medium", "Low"][current_fp_level])
|
||||||
except ValueError:
|
|
||||||
# LED isn't a normal value
|
|
||||||
current_fp_level = ec_commands.framework_laptop.get_fp_led_level_int(
|
|
||||||
app.cros_ec
|
|
||||||
)
|
|
||||||
self.led_pwr.set_subtitle(f"Custom ({current_fp_level}%)")
|
|
||||||
|
|
||||||
self.led_pwr_scale.connect("value-changed", handle_led_pwr)
|
self.led_pwr_scale.connect("value-changed", handle_led_pwr)
|
||||||
except ec_exceptions.ECError as e:
|
except ec_exceptions.ECError as e:
|
||||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
||||||
@@ -89,38 +84,31 @@ class LedsPage(Gtk.Box):
|
|||||||
self.led_kbd.set_visible(False)
|
self.led_kbd.set_visible(False)
|
||||||
|
|
||||||
# Advanced options
|
# Advanced options
|
||||||
if (
|
if ec_commands.general.get_cmd_versions(
|
||||||
ec_commands.general.get_cmd_versions(
|
|
||||||
app.cros_ec, ec_commands.leds.EC_CMD_LED_CONTROL
|
app.cros_ec, ec_commands.leds.EC_CMD_LED_CONTROL
|
||||||
)
|
|
||||||
and self.first_run
|
|
||||||
):
|
):
|
||||||
|
|
||||||
|
# Advanced: Power LED
|
||||||
|
led_pwr_colour_strings = self.led_pwr_colour.get_model()
|
||||||
|
|
||||||
all_colours = ["Red", "Green", "Blue", "Yellow", "White", "Amber"]
|
all_colours = ["Red", "Green", "Blue", "Yellow", "White", "Amber"]
|
||||||
led_names = {
|
|
||||||
ec_commands.leds.EcLedId.EC_LED_ID_BATTERY_LED: "Battery LED",
|
def add_colours(strings, led_id):
|
||||||
ec_commands.leds.EcLedId.EC_LED_ID_POWER_LED: "Power LED",
|
# Auto and Off should already be present
|
||||||
ec_commands.leds.EcLedId.EC_LED_ID_ADAPTER_LED: "Adapter LED",
|
if strings.get_n_items() <= 2:
|
||||||
ec_commands.leds.EcLedId.EC_LED_ID_LEFT_LED: "Left LED",
|
supported_colours = ec_commands.leds.led_control_get_max_values(
|
||||||
ec_commands.leds.EcLedId.EC_LED_ID_RIGHT_LED: "Right LED",
|
|
||||||
ec_commands.leds.EcLedId.EC_LED_ID_RECOVERY_HW_REINIT_LED: "Recovery LED",
|
|
||||||
ec_commands.leds.EcLedId.EC_LED_ID_SYSRQ_DEBUG_LED: "SysRq LED",
|
|
||||||
}
|
|
||||||
leds = {}
|
|
||||||
for i in range(ec_commands.leds.EcLedId.EC_LED_ID_COUNT.value):
|
|
||||||
try:
|
|
||||||
led_id = ec_commands.leds.EcLedId(i)
|
|
||||||
leds[led_id] = ec_commands.leds.led_control_get_max_values(
|
|
||||||
app.cros_ec, led_id
|
app.cros_ec, led_id
|
||||||
)
|
)
|
||||||
except ec_exceptions.ECError as e:
|
for i, colour in enumerate(all_colours):
|
||||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_PARAM:
|
if supported_colours[i]:
|
||||||
continue
|
strings.append(colour)
|
||||||
else:
|
|
||||||
raise e
|
|
||||||
|
|
||||||
# Power LED does not support Blue, even though Intel models think they do
|
try:
|
||||||
leds[ec_commands.leds.EcLedId.EC_LED_ID_POWER_LED][2] = 0
|
add_colours(
|
||||||
|
led_pwr_colour_strings, ec_commands.leds.EcLedId.EC_LED_ID_POWER_LED
|
||||||
|
)
|
||||||
|
except ec_exceptions.ECError as e:
|
||||||
|
self.led_pwr_colour.set_sensitive(False)
|
||||||
|
|
||||||
def handle_led_colour(combobox, led_id):
|
def handle_led_colour(combobox, led_id):
|
||||||
colour = combobox.get_selected() - 2
|
colour = combobox.get_selected() - 2
|
||||||
@@ -144,20 +132,30 @@ class LedsPage(Gtk.Box):
|
|||||||
100,
|
100,
|
||||||
ec_commands.leds.EcLedColors(colour_idx),
|
ec_commands.leds.EcLedColors(colour_idx),
|
||||||
)
|
)
|
||||||
for led_id, supported_colours in leds.items():
|
|
||||||
if any(supported_colours):
|
self.led_pwr_colour.connect(
|
||||||
combo = Adw.ComboRow(title=led_names[led_id])
|
|
||||||
model = Gtk.StringList.new(["Auto", "Off"])
|
|
||||||
for i, colour in enumerate(all_colours):
|
|
||||||
if supported_colours[i]:
|
|
||||||
model.append(colour)
|
|
||||||
combo.set_model(model)
|
|
||||||
combo.connect(
|
|
||||||
"notify::selected",
|
"notify::selected",
|
||||||
lambda combobox, _, led_id=led_id: handle_led_colour(
|
lambda combo, _: handle_led_colour(
|
||||||
combobox, led_id
|
combo, ec_commands.leds.EcLedId.EC_LED_ID_POWER_LED
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
self.led_advanced.add_row(combo)
|
|
||||||
|
|
||||||
self.first_run = False
|
# Advanced: Charging LED
|
||||||
|
led_chg_colour_strings = self.led_chg_colour.get_model()
|
||||||
|
|
||||||
|
try:
|
||||||
|
add_colours(
|
||||||
|
led_chg_colour_strings,
|
||||||
|
ec_commands.leds.EcLedId.EC_LED_ID_BATTERY_LED,
|
||||||
|
)
|
||||||
|
except ec_exceptions.ECError as e:
|
||||||
|
self.led_chg_colour.set_sensitive(False)
|
||||||
|
|
||||||
|
self.led_chg_colour.connect(
|
||||||
|
"notify::selected",
|
||||||
|
lambda combo, _: handle_led_colour(
|
||||||
|
combo, ec_commands.leds.EcLedId.EC_LED_ID_BATTERY_LED
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.led_advanced.set_visible(False)
|
||||||
|
|||||||
11
yafi/main.py
@@ -105,7 +105,7 @@ class YafiApplication(Adw.Application):
|
|||||||
("LEDs", LedsPage()),
|
("LEDs", LedsPage()),
|
||||||
("Battery", BatteryPage()),
|
("Battery", BatteryPage()),
|
||||||
("Battery Limiter", BatteryLimiterPage()),
|
("Battery Limiter", BatteryLimiterPage()),
|
||||||
("Sensors", HardwarePage()),
|
("Hardware", HardwarePage()),
|
||||||
("About", None),
|
("About", None),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -121,7 +121,6 @@ class YafiApplication(Adw.Application):
|
|||||||
self.current_page = page
|
self.current_page = page
|
||||||
self.change_page(self.win.content, pages[page][1])
|
self.change_page(self.win.content, pages[page][1])
|
||||||
else:
|
else:
|
||||||
self.win.navbar.select_row(self.win.navbar.get_row_at_index(self.current_page))
|
|
||||||
self.on_about_action()
|
self.on_about_action()
|
||||||
|
|
||||||
self.win.navbar.connect("row-activated", lambda box, row: switch_page(row.get_index()))
|
self.win.navbar.connect("row-activated", lambda box, row: switch_page(row.get_index()))
|
||||||
@@ -136,16 +135,14 @@ class YafiApplication(Adw.Application):
|
|||||||
about = Adw.AboutDialog(
|
about = Adw.AboutDialog(
|
||||||
application_icon="au.stevetech.yafi",
|
application_icon="au.stevetech.yafi",
|
||||||
application_name="Yet Another Framework Interface",
|
application_name="Yet Another Framework Interface",
|
||||||
comments="YAFI is another GUI for the Framework Laptop Embedded Controller.\n\n"
|
comments="YAFI is another GUI for the Framework Laptop Embedded Controller.\n"
|
||||||
+ "It is written in Python with a GTK4 Adwaita theme, and uses the CrOS_EC_Python library to communicate with the EC.\n\n"
|
+ "It is written in Python with a GTK3 theme, and uses the `CrOS_EC_Python` library to communicate with the EC.",
|
||||||
+ "YAFI is not affiliated with Framework Computer Inc. in any way.",
|
|
||||||
copyright="© 2025 Stephen Horvath",
|
copyright="© 2025 Stephen Horvath",
|
||||||
developer_name="Stephen Horvath",
|
developer_name="Stephen Horvath",
|
||||||
developers=["Stephen Horvath https://github.com/Steve-Tech"],
|
developers=["Stephen Horvath https://github.com/Steve-Tech"],
|
||||||
artists=["Mirabelle SALLES https://github.com/oiimrosabel"],
|
|
||||||
issue_url="https://github.com/Steve-Tech/YAFI/issues",
|
issue_url="https://github.com/Steve-Tech/YAFI/issues",
|
||||||
license_type=Gtk.License.GPL_2_0,
|
license_type=Gtk.License.GPL_2_0,
|
||||||
version="0.7",
|
version="0.5",
|
||||||
website="https://github.com/Steve-Tech/YAFI",
|
website="https://github.com/Steve-Tech/YAFI",
|
||||||
)
|
)
|
||||||
about.add_acknowledgement_section(None, ["Framework Computer Inc. https://frame.work/"])
|
about.add_acknowledgement_section(None, ["Framework Computer Inc. https://frame.work/"])
|
||||||
|
|||||||
127
yafi/thermals.py
@@ -27,17 +27,11 @@ import cros_ec_python.exceptions as ec_exceptions
|
|||||||
class ThermalsPage(Gtk.Box):
|
class ThermalsPage(Gtk.Box):
|
||||||
__gtype_name__ = 'ThermalsPage'
|
__gtype_name__ = 'ThermalsPage'
|
||||||
|
|
||||||
first_run = True
|
|
||||||
|
|
||||||
fan_rpm = Gtk.Template.Child()
|
fan_rpm = Gtk.Template.Child()
|
||||||
fan_mode = Gtk.Template.Child()
|
fan_mode = Gtk.Template.Child()
|
||||||
fan_set_rpm = Gtk.Template.Child()
|
fan_set_rpm = Gtk.Template.Child()
|
||||||
fan_set_percent = Gtk.Template.Child()
|
fan_set_percent = Gtk.Template.Child()
|
||||||
fan_percent_scale = Gtk.Template.Child()
|
fan_percent_scale = Gtk.Template.Child()
|
||||||
fan_set_points = Gtk.Template.Child()
|
|
||||||
set_points = []
|
|
||||||
ec_set_points_supported = False
|
|
||||||
ec_set_points = []
|
|
||||||
|
|
||||||
temperatures = Gtk.Template.Child()
|
temperatures = Gtk.Template.Child()
|
||||||
temp_items = []
|
temp_items = []
|
||||||
@@ -46,40 +40,10 @@ class ThermalsPage(Gtk.Box):
|
|||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
def setup(self, app):
|
def setup(self, app):
|
||||||
# Temperature sensors
|
|
||||||
while temp_child := self.temperatures.get_last_child():
|
|
||||||
self.temperatures.remove(temp_child)
|
|
||||||
self.temp_items.clear()
|
|
||||||
|
|
||||||
try:
|
|
||||||
ec_temp_sensors = ec_commands.thermal.get_temp_sensors(app.cros_ec)
|
|
||||||
except ec_exceptions.ECError as e:
|
|
||||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
|
||||||
# Generate some labels if the command is not supported
|
|
||||||
ec_temp_sensors = {}
|
|
||||||
temps = ec_commands.memmap.get_temps(app.cros_ec)
|
|
||||||
for i, temp in enumerate(temps):
|
|
||||||
ec_temp_sensors[f"Sensor {i}"] = (temp, None)
|
|
||||||
else:
|
|
||||||
raise e
|
|
||||||
|
|
||||||
for key, value in ec_temp_sensors.items():
|
|
||||||
off_row = Adw.ActionRow(title=key, subtitle=f"{value[0]}°C" if value[0] is not None else "Error")
|
|
||||||
off_row.add_css_class("property")
|
|
||||||
self.temperatures.append(off_row)
|
|
||||||
self.temp_items.append(off_row)
|
|
||||||
|
|
||||||
self._update_thermals(app)
|
|
||||||
|
|
||||||
# Don't let the user change the fans if they can't get back to auto
|
# Don't let the user change the fans if they can't get back to auto
|
||||||
if ec_commands.general.get_cmd_versions(
|
if ec_commands.general.get_cmd_versions(
|
||||||
app.cros_ec, ec_commands.thermal.EC_CMD_THERMAL_AUTO_FAN_CTRL
|
app.cros_ec, ec_commands.thermal.EC_CMD_THERMAL_AUTO_FAN_CTRL
|
||||||
):
|
):
|
||||||
self.ec_set_points_supported = ec_commands.general.check_cmd_version(
|
|
||||||
app.cros_ec, ec_commands.thermal.EC_CMD_THERMAL_GET_THRESHOLD, 1
|
|
||||||
) and ec_commands.general.check_cmd_version(
|
|
||||||
app.cros_ec, ec_commands.thermal.EC_CMD_THERMAL_SET_THRESHOLD, 1
|
|
||||||
)
|
|
||||||
|
|
||||||
def handle_fan_mode(mode):
|
def handle_fan_mode(mode):
|
||||||
match mode:
|
match mode:
|
||||||
@@ -87,18 +51,13 @@ class ThermalsPage(Gtk.Box):
|
|||||||
self.fan_set_rpm.set_visible(False)
|
self.fan_set_rpm.set_visible(False)
|
||||||
self.fan_set_percent.set_visible(False)
|
self.fan_set_percent.set_visible(False)
|
||||||
ec_commands.thermal.thermal_auto_fan_ctrl(app.cros_ec)
|
ec_commands.thermal.thermal_auto_fan_ctrl(app.cros_ec)
|
||||||
self.fan_set_points.set_visible(self.ec_set_points_supported)
|
|
||||||
case 1: # Percent
|
case 1: # Percent
|
||||||
self.fan_set_points.set_visible(False)
|
|
||||||
self.fan_set_rpm.set_visible(False)
|
self.fan_set_rpm.set_visible(False)
|
||||||
self.fan_set_percent.set_visible(True)
|
self.fan_set_percent.set_visible(True)
|
||||||
case 2: # RPM
|
case 2: # RPM
|
||||||
self.fan_set_points.set_visible(False)
|
|
||||||
self.fan_set_rpm.set_visible(True)
|
self.fan_set_rpm.set_visible(True)
|
||||||
self.fan_set_percent.set_visible(False)
|
self.fan_set_percent.set_visible(False)
|
||||||
|
|
||||||
handle_fan_mode(self.fan_mode.get_selected())
|
|
||||||
|
|
||||||
self.fan_mode.connect(
|
self.fan_mode.connect(
|
||||||
"notify::selected",
|
"notify::selected",
|
||||||
lambda combo, _: handle_fan_mode(combo.get_selected()),
|
lambda combo, _: handle_fan_mode(combo.get_selected()),
|
||||||
@@ -122,77 +81,41 @@ class ThermalsPage(Gtk.Box):
|
|||||||
):
|
):
|
||||||
|
|
||||||
def handle_fan_rpm(entry):
|
def handle_fan_rpm(entry):
|
||||||
rpm = int(entry.get_value())
|
rpm = int(entry.get_text())
|
||||||
ec_commands.pwm.pwm_set_fan_rpm(app.cros_ec, rpm)
|
ec_commands.pwm.pwm_set_fan_rpm(app.cros_ec, rpm)
|
||||||
|
|
||||||
self.fan_set_rpm.connect(
|
self.fan_set_rpm.connect(
|
||||||
"notify::value", lambda entry, _: handle_fan_rpm(entry)
|
"notify::text", lambda entry, _: handle_fan_rpm(entry)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.fan_set_rpm.set_sensitive(False)
|
self.fan_set_rpm.set_sensitive(False)
|
||||||
else:
|
else:
|
||||||
self.fan_mode.set_sensitive(False)
|
self.fan_mode.set_sensitive(False)
|
||||||
|
|
||||||
# Set points
|
# Temperature sensors
|
||||||
if self.ec_set_points_supported and self.first_run:
|
while temp_child := self.temperatures.get_last_child():
|
||||||
def handle_set_point(entry, key):
|
self.temperatures.remove(temp_child)
|
||||||
index = entry.ec_index
|
self.temp_items.clear()
|
||||||
temp = int(entry.get_value())
|
|
||||||
# Don't allow an off temp higher than max temp and vice versa
|
|
||||||
match key:
|
|
||||||
case "temp_fan_off":
|
|
||||||
if temp > self.ec_set_points[index]["temp_fan_max"]:
|
|
||||||
entry.set_value(self.ec_set_points[index]["temp_fan_off"])
|
|
||||||
return
|
|
||||||
case "temp_fan_max":
|
|
||||||
if temp < self.ec_set_points[index]["temp_fan_off"]:
|
|
||||||
entry.set_value(self.ec_set_points[index]["temp_fan_max"])
|
|
||||||
return
|
|
||||||
self.ec_set_points[entry.ec_index][key] = temp
|
|
||||||
ec_commands.thermal.thermal_set_thresholds(
|
|
||||||
app.cros_ec, index,
|
|
||||||
self.ec_set_points[index]
|
|
||||||
)
|
|
||||||
|
|
||||||
for i, sensor in enumerate(ec_temp_sensors):
|
try:
|
||||||
ec_set_point = ec_commands.thermal.thermal_get_thresholds(app.cros_ec, i)
|
ec_temp_sensors = ec_commands.thermal.get_temp_sensors(app.cros_ec)
|
||||||
self.ec_set_points.append(ec_set_point)
|
except ec_exceptions.ECError as e:
|
||||||
off_row = Adw.SpinRow(
|
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
||||||
title=f"Fan On - {sensor}",
|
# Generate some labels if the command is not supported
|
||||||
subtitle=f"Turn fan on when above temp (°C)",
|
ec_temp_sensors = {}
|
||||||
)
|
temps = ec_commands.memmap.get_temps(app.cros_ec)
|
||||||
off_row.ec_index = i
|
for i, temp in enumerate(temps):
|
||||||
# 0K to 65535K for 16bit unsigned range
|
ec_temp_sensors[f"Sensor {i}"] = (temp, None)
|
||||||
# Actually the EC takes 32bits, but let's keep it like this for sanity
|
else:
|
||||||
off_row.set_adjustment(Gtk.Adjustment(
|
raise e
|
||||||
lower=-273,
|
|
||||||
upper=65_262,
|
|
||||||
page_increment=10,
|
|
||||||
step_increment=1,
|
|
||||||
value=ec_set_point["temp_fan_off"],
|
|
||||||
))
|
|
||||||
off_row.connect(
|
|
||||||
"notify::value", lambda entry, _: handle_set_point(entry, "temp_fan_off")
|
|
||||||
)
|
|
||||||
max_row = Adw.SpinRow(
|
|
||||||
title=f"Fan Max - {sensor}",
|
|
||||||
subtitle=f"Max fan speed when above temp (°C)",
|
|
||||||
)
|
|
||||||
max_row.ec_index = i
|
|
||||||
max_row.set_adjustment(Gtk.Adjustment(
|
|
||||||
lower=-273,
|
|
||||||
upper=65_262,
|
|
||||||
page_increment=10,
|
|
||||||
step_increment=1,
|
|
||||||
value=ec_set_point["temp_fan_max"],
|
|
||||||
))
|
|
||||||
max_row.connect(
|
|
||||||
"notify::value", lambda entry, _: handle_set_point(entry, "temp_fan_max")
|
|
||||||
)
|
|
||||||
self.fan_set_points.add_row(off_row)
|
|
||||||
self.fan_set_points.add_row(max_row)
|
|
||||||
|
|
||||||
self.first_run = False
|
for key, value in ec_temp_sensors.items():
|
||||||
|
new_row = Adw.ActionRow(title=key, subtitle=f"{value[0]}°C")
|
||||||
|
new_row.add_css_class("property")
|
||||||
|
self.temperatures.append(new_row)
|
||||||
|
self.temp_items.append(new_row)
|
||||||
|
|
||||||
|
self._update_thermals(app)
|
||||||
|
|
||||||
# Schedule _update_thermals to run every second
|
# Schedule _update_thermals to run every second
|
||||||
GLib.timeout_add_seconds(1, self._update_thermals, app)
|
GLib.timeout_add_seconds(1, self._update_thermals, app)
|
||||||
@@ -205,7 +128,7 @@ class ThermalsPage(Gtk.Box):
|
|||||||
ec_temp_sensors = ec_commands.memmap.get_temps(app.cros_ec)
|
ec_temp_sensors = ec_commands.memmap.get_temps(app.cros_ec)
|
||||||
# The temp sensors disappear sometimes, so we need to handle that
|
# The temp sensors disappear sometimes, so we need to handle that
|
||||||
for i in range(min(len(self.temp_items), len(ec_temp_sensors))):
|
for i in range(min(len(self.temp_items), len(ec_temp_sensors))):
|
||||||
self.temp_items[i].set_subtitle(f"{ec_temp_sensors[i]}°C" if ec_temp_sensors[i] is not None else "Error")
|
self.temp_items[i].set_subtitle(f"{ec_temp_sensors[i]}°C")
|
||||||
|
|
||||||
# Check if this has already failed and skip if it has
|
# Check if this has already failed and skip if it has
|
||||||
if not ec_commands.pwm.EC_CMD_PWM_GET_FAN_TARGET_RPM in app.no_support:
|
if not ec_commands.pwm.EC_CMD_PWM_GET_FAN_TARGET_RPM in app.no_support:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<!-- Created with Cambalache 0.96.3 -->
|
<!-- Created with Cambalache 0.96.1 -->
|
||||||
<interface>
|
<interface>
|
||||||
<!-- interface-name battery-limiter.ui -->
|
<!-- interface-name battery-limiter.ui -->
|
||||||
<!-- interface-description The Battery page for YAFI -->
|
<!-- interface-description The Battery page for YAFI -->
|
||||||
@@ -79,6 +79,25 @@
|
|||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="AdwActionRow" id="chg_limit_override">
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
<property name="subtitle">Disables the limiter for one charge</property>
|
||||||
|
<property name="title">Override Charge Limiter</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="halign">end</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="chg_limit_override_btn">
|
||||||
|
<property name="label">Override</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="AdwPreferencesGroup" id="bat_ext_group">
|
<object class="AdwPreferencesGroup" id="bat_ext_group">
|
||||||
<property name="description">Preserve the battery lifespan by gradually lowering battery charge voltage automatically if the system is connected to AC for more than the set day limit.</property>
|
<property name="description">Preserve the battery lifespan by gradually lowering battery charge voltage automatically if the system is connected to AC for more than the set day limit.</property>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<!-- Created with Cambalache 0.96.1 -->
|
<!-- Created with Cambalache 0.96.1 -->
|
||||||
<interface>
|
<interface>
|
||||||
<!-- interface-name hardware.ui -->
|
<!-- interface-name hardware.ui -->
|
||||||
<!-- interface-description The Sensors page for YAFI -->
|
<!-- interface-description The Hardware page for YAFI -->
|
||||||
<!-- interface-copyright Steve-Tech -->
|
<!-- interface-copyright Steve-Tech -->
|
||||||
<requires lib="gtk" version="4.0"/>
|
<requires lib="gtk" version="4.0"/>
|
||||||
<requires lib="libadwaita" version="1.0"/>
|
<requires lib="libadwaita" version="1.0"/>
|
||||||
@@ -15,15 +15,7 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="AdwActionRow">
|
<object class="AdwActionRow">
|
||||||
<property name="selectable">False</property>
|
<property name="selectable">False</property>
|
||||||
<property name="title">Sensors</property>
|
<property name="title">Hardware Status</property>
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="AdwActionRow" id="hw_als">
|
|
||||||
<property name="title">Ambient Light Sensor</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="hw_als_label"/>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
@@ -34,30 +26,6 @@
|
|||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
|
||||||
<object class="AdwActionRow" id="hw_fp_pwr">
|
|
||||||
<property name="title">Fingerprint</property>
|
|
||||||
<property name="visible">False</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkBox">
|
|
||||||
<property name="halign">end</property>
|
|
||||||
<property name="homogeneous">True</property>
|
|
||||||
<property name="spacing">5</property>
|
|
||||||
<property name="valign">center</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkButton" id="hw_fp_pwr_en">
|
|
||||||
<property name="label">Enable</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkButton" id="hw_fp_pwr_dis">
|
|
||||||
<property name="label">Disable</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="AdwActionRow" id="hw_priv_cam">
|
<object class="AdwActionRow" id="hw_priv_cam">
|
||||||
<property name="subtitle">Use Privacy Switch</property>
|
<property name="subtitle">Use Privacy Switch</property>
|
||||||
@@ -97,35 +65,23 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="AdwActionRow" id="hw_lid_open">
|
<object class="AdwActionRow" id="hw_fp_pwr">
|
||||||
<property name="title">Lid Open</property>
|
<property name="title">Fingerprint</property>
|
||||||
|
<property name="visible">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="halign">end</property>
|
<property name="halign">end</property>
|
||||||
<property name="homogeneous">True</property>
|
<property name="homogeneous">True</property>
|
||||||
|
<property name="spacing">5</property>
|
||||||
<property name="valign">center</property>
|
<property name="valign">center</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkSwitch" id="hw_lid_open_sw">
|
<object class="GtkButton" id="hw_fp_pwr_en">
|
||||||
<property name="active">True</property>
|
<property name="label">Enable</property>
|
||||||
<property name="sensitive">False</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="AdwActionRow" id="hw_pwr_btn">
|
<object class="GtkButton" id="hw_fp_pwr_dis">
|
||||||
<property name="title">Power Button Pressed</property>
|
<property name="label">Disable</property>
|
||||||
<child>
|
|
||||||
<object class="GtkBox">
|
|
||||||
<property name="halign">end</property>
|
|
||||||
<property name="homogeneous">True</property>
|
|
||||||
<property name="valign">center</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkSwitch" id="hw_pwr_btn_sw">
|
|
||||||
<property name="active">True</property>
|
|
||||||
<property name="sensitive">False</property>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
|||||||
@@ -69,6 +69,52 @@
|
|||||||
<property name="selectable">False</property>
|
<property name="selectable">False</property>
|
||||||
<property name="subtitle">These options break normal functionality</property>
|
<property name="subtitle">These options break normal functionality</property>
|
||||||
<property name="title">Advanced Options</property>
|
<property name="title">Advanced Options</property>
|
||||||
|
<child>
|
||||||
|
<object class="AdwPreferencesGroup">
|
||||||
|
<property name="description">When using these options, the power LED may not turn off with the computer.</property>
|
||||||
|
<property name="margin-bottom">5</property>
|
||||||
|
<property name="margin-end">5</property>
|
||||||
|
<property name="margin-start">5</property>
|
||||||
|
<property name="margin-top">5</property>
|
||||||
|
<property name="title">Power Button LED</property>
|
||||||
|
<child>
|
||||||
|
<object class="AdwComboRow" id="led_pwr_colour">
|
||||||
|
<property name="model">
|
||||||
|
<object class="GtkStringList">
|
||||||
|
<items>
|
||||||
|
<item>Auto</item>
|
||||||
|
<item>Off</item>
|
||||||
|
</items>
|
||||||
|
</object>
|
||||||
|
</property>
|
||||||
|
<property name="title">Colour</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="AdwPreferencesGroup">
|
||||||
|
<property name="description">When using these options, the charging indicator will no longer indicate charging.</property>
|
||||||
|
<property name="margin-bottom">5</property>
|
||||||
|
<property name="margin-end">5</property>
|
||||||
|
<property name="margin-start">5</property>
|
||||||
|
<property name="margin-top">5</property>
|
||||||
|
<property name="title">Charging Indicators</property>
|
||||||
|
<child>
|
||||||
|
<object class="AdwComboRow" id="led_chg_colour">
|
||||||
|
<property name="model">
|
||||||
|
<object class="GtkStringList">
|
||||||
|
<items>
|
||||||
|
<item>Auto</item>
|
||||||
|
<item>Off</item>
|
||||||
|
</items>
|
||||||
|
</object>
|
||||||
|
</property>
|
||||||
|
<property name="title">Colour</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<!-- Created with Cambalache 0.96.3 -->
|
<!-- Created with Cambalache 0.96.1 -->
|
||||||
<interface>
|
<interface>
|
||||||
<!-- interface-name thermals.ui -->
|
<!-- interface-name thermals.ui -->
|
||||||
<!-- interface-description The Thermals page for YAFI -->
|
<!-- interface-description The Thermals page for YAFI -->
|
||||||
@@ -92,12 +92,6 @@
|
|||||||
<property name="visible">False</property>
|
<property name="visible">False</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
|
||||||
<object class="AdwExpanderRow" id="fan_set_points">
|
|
||||||
<property name="selectable">False</property>
|
|
||||||
<property name="title">Fan Set Points</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<style>
|
<style>
|
||||||
<class name="boxed-list"/>
|
<class name="boxed-list"/>
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||||
<!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
|
<!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
|
||||||
<!-- Created with Cambalache 0.96.3 -->
|
<!-- Created with Cambalache 0.96.1 -->
|
||||||
<cambalache-project version="0.96.0" target_tk="gtk-4.0">
|
<cambalache-project version="0.96.0" target_tk="gtk-4.0">
|
||||||
<ui template-class="YafiWindow" filename="yafi.ui" sha256="9d1b2f030e4a816eb0b1aa53ae1d80c5b50a2f4646e32c7a64803eb6f6ed3947"/>
|
<ui template-class="YafiWindow" filename="yafi.ui" sha256="9d1b2f030e4a816eb0b1aa53ae1d80c5b50a2f4646e32c7a64803eb6f6ed3947"/>
|
||||||
<ui template-class="ThermalsPage" filename="thermals.ui" sha256="89f5b68da04abad587d8b949d18357cd956313680e663b10e5d42697f9bfbf6e"/>
|
<ui template-class="ThermalsPage" filename="thermals.ui" sha256="e301e65649005315ff60d250b60a47f6250ad6feb27db104051fcf0143cde173"/>
|
||||||
<ui template-class="LedsPage" filename="leds.ui" sha256="abc3ee759974a5c92feb48cc258dbe7271d0402facf71fd5e779f2bb1a277e16"/>
|
<ui template-class="LedsPage" filename="leds.ui" sha256="0350d22d570de039d63602ba40925f17fff6680fd5909d2ebf19600f351eb0f2"/>
|
||||||
<ui template-class="BatteryLimiterPage" filename="battery-limiter.ui" sha256="3a50b0dea08b9acbaa389d7d7a38bd94970fdc79207ef10638f722f52d9425cd"/>
|
<ui template-class="BatteryLimiterPage" filename="battery-limiter.ui" sha256="b5d41b19cb1fb7ca5b4bcfae43244e54111f5e8d8c51d95448d6a92b5185d2c4"/>
|
||||||
<ui template-class="HardwarePage" filename="hardware.ui" sha256="37ea282198d9f60435f80e4adf8256cd2249e590dcad4b63af634d828673f1bf"/>
|
<ui template-class="HardwarePage" filename="hardware.ui" sha256="f4deec4e38e683fde97656802dbfb2a638ab46a0e36af5c9a37f277f49e2aabb"/>
|
||||||
<ui template-class="BatteryPage" filename="battery.ui" sha256="d495280cb543a26cdee1c2939e5af980d8d3878c326e360eeab4f05195cdbdc9"/>
|
<ui template-class="BatteryPage" filename="battery.ui" sha256="d495280cb543a26cdee1c2939e5af980d8d3878c326e360eeab4f05195cdbdc9"/>
|
||||||
</cambalache-project>
|
</cambalache-project>
|
||||||
|
|||||||