chore: ags configs removed
|
@ -1,130 +0,0 @@
|
|||
env:
|
||||
es2022: true
|
||||
extends:
|
||||
- "eslint:recommended"
|
||||
- "plugin:@typescript-eslint/recommended"
|
||||
parser: "@typescript-eslint/parser"
|
||||
parserOptions:
|
||||
ecmaVersion: 2022
|
||||
sourceType: "module"
|
||||
project: "./tsconfig.json"
|
||||
warnOnUnsupportedTypeScriptVersion: false
|
||||
root: true
|
||||
ignorePatterns:
|
||||
- types/
|
||||
plugins:
|
||||
- "@typescript-eslint"
|
||||
rules:
|
||||
"@typescript-eslint/ban-ts-comment":
|
||||
- "off"
|
||||
"@typescript-eslint/no-non-null-assertion":
|
||||
- "off"
|
||||
# "@typescript-eslint/no-explicit-any":
|
||||
# - "off"
|
||||
"@typescript-eslint/no-unused-vars":
|
||||
- error
|
||||
- varsIgnorePattern: (^unused|_$)
|
||||
argsIgnorePattern: ^(unused|_)
|
||||
"@typescript-eslint/no-empty-interface":
|
||||
- "off"
|
||||
|
||||
arrow-parens:
|
||||
- error
|
||||
- as-needed
|
||||
comma-dangle:
|
||||
- error
|
||||
- always-multiline
|
||||
comma-spacing:
|
||||
- error
|
||||
- before: false
|
||||
after: true
|
||||
comma-style:
|
||||
- error
|
||||
- last
|
||||
curly:
|
||||
- error
|
||||
- multi-or-nest
|
||||
- consistent
|
||||
dot-location:
|
||||
- error
|
||||
- property
|
||||
eol-last:
|
||||
- error
|
||||
eqeqeq:
|
||||
- error
|
||||
- always
|
||||
indent:
|
||||
- error
|
||||
- 4
|
||||
- SwitchCase: 1
|
||||
keyword-spacing:
|
||||
- error
|
||||
- before: true
|
||||
lines-between-class-members:
|
||||
- error
|
||||
- always
|
||||
- exceptAfterSingleLine: true
|
||||
padded-blocks:
|
||||
- error
|
||||
- never
|
||||
- allowSingleLineBlocks: false
|
||||
prefer-const:
|
||||
- error
|
||||
quotes:
|
||||
- error
|
||||
- double
|
||||
- avoidEscape: true
|
||||
semi:
|
||||
- error
|
||||
- never
|
||||
nonblock-statement-body-position:
|
||||
- error
|
||||
- below
|
||||
no-trailing-spaces:
|
||||
- error
|
||||
no-useless-escape:
|
||||
- off
|
||||
max-len:
|
||||
- error
|
||||
- code: 100
|
||||
func-call-spacing:
|
||||
- error
|
||||
array-bracket-spacing:
|
||||
- error
|
||||
space-before-function-paren:
|
||||
- error
|
||||
- anonymous: never
|
||||
named: never
|
||||
asyncArrow: ignore
|
||||
space-before-blocks:
|
||||
- error
|
||||
key-spacing:
|
||||
- error
|
||||
object-curly-spacing:
|
||||
- error
|
||||
- always
|
||||
globals:
|
||||
Widget: readonly
|
||||
Utils: readonly
|
||||
App: readonly
|
||||
Variable: readonly
|
||||
Service: readonly
|
||||
pkg: readonly
|
||||
ARGV: readonly
|
||||
Debugger: readonly
|
||||
GIRepositoryGType: readonly
|
||||
globalThis: readonly
|
||||
imports: readonly
|
||||
Intl: readonly
|
||||
log: readonly
|
||||
logError: readonly
|
||||
print: readonly
|
||||
printerr: readonly
|
||||
window: readonly
|
||||
TextEncoder: readonly
|
||||
TextDecoder: readonly
|
||||
console: readonly
|
||||
setTimeout: readonly
|
||||
setInterval: readonly
|
||||
clearTimeout: readonly
|
||||
clearInterval: readonly
|
6
hypr-configs/dotfiles/ags/.gitignore
vendored
|
@ -1,6 +0,0 @@
|
|||
node_modules
|
||||
types
|
||||
package-lock.json
|
||||
bun.lockb
|
||||
flake.lock
|
||||
.weather
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 8.96875 0 c -0.332031 0.0117188 -0.640625 0.1875 -0.816406 0.46875 l -5 8 c -0.105469 0.171875 -0.152344 0.355469 -0.152344 0.53125 v 1 h 3 v 5 c 0 1.003906 1.316406 1.378906 1.847656 0.53125 l 5 -8 c 0.105469 -0.171875 0.152344 -0.355469 0.152344 -0.53125 v -1 h -3 v -5 c 0 -0.5625 -0.464844 -1.015625 -1.03125 -1 z m 0 0"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 476 B |
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 14 3.175781 v 3.824219 c 0 2.179688 -1.820312 4 -4 4 h -3.585938 l -2 2 h 5.585938 l 3 3 v -3 c 1.644531 0 3 -1.355469 3 -3 v -4 c 0 -1.292969 -0.839844 -2.40625 -2 -2.824219 z m 0 0" fill-opacity="0.34902"/>
|
||||
<path d="m 3 0 c -1.644531 0 -3 1.355469 -3 3 v 4 c 0 1.644531 1.355469 3 3 3 v 3 l 3 -3 h 4 c 1.644531 0 3 -1.355469 3 -3 v -4 c 0 -1.644531 -1.355469 -3 -3 -3 z m 0 0"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 534 B |
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 3.785156 2.03125 c -0.242187 0 -0.523437 0.066406 -0.804687 0.21875 c -1.039063 0.546875 -1.992188 2.335938 -2.511719 4.65625 c -0.4414062 1.972656 -0.605469 4.664062 -0.339844 5.75 c 0.226563 0.933594 0.625 1.34375 1.332032 1.34375 c 1.042968 -0.019531 2.359374 -1.183594 3.191406 -2.75 c 0.601562 -0.867188 2 -1.261719 3.347656 -1.21875 c 1.347656 -0.046875 2.746094 0.351562 3.347656 1.21875 c 0.832032 1.566406 2.148438 2.730469 3.191406 2.75 c 0.707032 0 1.105469 -0.410156 1.332032 -1.34375 c 0.265625 -1.085938 0.101562 -3.777344 -0.339844 -5.75 c -0.519531 -2.320312 -1.472656 -4.109375 -2.511719 -4.65625 c -0.566406 -0.304688 -1.039062 -0.296875 -1.453125 0 c -0.527344 0.375 -1.628906 0.78125 -3.566406 0.78125 c -1.9375 0.003906 -3.039062 -0.40625 -3.566406 -0.78125 c -0.207032 -0.148438 -0.40625 -0.21875 -0.648438 -0.21875 z m 0.246094 3 h 0.992188 v 1 h 0.992187 v 1 h -0.992187 v 1 h -0.992188 v -1 h -0.992188 v -1 h 0.992188 z m 7.441406 0 c 0.273438 0 0.496094 0.222656 0.496094 0.5 s -0.222656 0.5 -0.496094 0.5 c -0.273437 0 -0.496094 -0.222656 -0.496094 -0.5 s 0.222657 -0.5 0.496094 -0.5 z m -0.992187 1 c 0.273437 0 0.496093 0.222656 0.496093 0.5 s -0.222656 0.5 -0.496093 0.5 c -0.273438 0 -0.496094 -0.222656 -0.496094 -0.5 s 0.222656 -0.5 0.496094 -0.5 z m 1.984375 0 c 0.273437 0 0.496094 0.222656 0.496094 0.5 s -0.222657 0.5 -0.496094 0.5 c -0.273438 0 -0.496094 -0.222656 -0.496094 -0.5 s 0.222656 -0.5 0.496094 -0.5 z m -0.992188 1 c 0.273438 0 0.496094 0.222656 0.496094 0.5 s -0.222656 0.5 -0.496094 0.5 c -0.273437 0 -0.496094 -0.222656 -0.496094 -0.5 s 0.222657 -0.5 0.496094 -0.5 z m 0 0"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.7 KiB |
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 4.550781 1 c -1.9375 0 -3.5 1.5625 -3.5 3.5 s 1.5625 3.5 3.5 3.5 h 7 c 1.941407 0 3.5 -1.5625 3.5 -3.5 s -1.558593 -3.5 -3.5 -3.5 z m 7 1 c 1.386719 0 2.5 1.113281 2.5 2.5 c 0 1.382812 -1.113281 2.5 -2.5 2.5 c -1.382812 0 -2.5 -1.117188 -2.5 -2.5 c 0 -1.386719 1.117188 -2.5 2.5 -2.5 z m 0 0"/>
|
||||
<path d="m 4.550781 9 c -1.9375 0 -3.5 1.5625 -3.5 3.5 s 1.5625 3.5 3.5 3.5 h 7 c 1.941407 0 3.5 -1.5625 3.5 -3.5 s -1.558593 -3.5 -3.5 -3.5 z m 0 1 c 1.386719 0 2.5 1.113281 2.5 2.5 c 0 1.382812 -1.113281 2.5 -2.5 2.5 c -1.382812 0 -2.5 -1.117188 -2.5 -2.5 c 0 -1.386719 1.117188 -2.5 2.5 -2.5 z m 0 0" fill-opacity="0.34902"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 777 B |
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 0.917969 8.003906 c 0 3.914063 3.164062 7.078125 7.078125 7.078125 c 3.605468 -0.007812 6.617187 -2.703125 7.023437 -6.285156 c 0.042969 -0.378906 -0.136719 -0.75 -0.457031 -0.957031 c -0.324219 -0.203125 -0.738281 -0.207032 -1.0625 -0.003906 c -0.609375 0.375 -1.316406 0.578124 -2.03125 0.578124 c -2.140625 0 -3.882812 -1.742187 -3.882812 -3.882812 c 0 -0.714844 0.203124 -1.421875 0.578124 -2.03125 c 0.203126 -0.324219 0.199219 -0.738281 -0.003906 -1.0625 c -0.207031 -0.320312 -0.578125 -0.5 -0.957031 -0.457031 c -3.582031 0.40625 -6.277344 3.417969 -6.285156 7.023437 z m 4.667969 -3.472656 c 0 3.253906 2.628906 5.882812 5.886718 5.882812 c 1.085938 0 2.152344 -0.304687 3.078125 -0.878906 l -1.519531 -0.960937 c -0.289062 2.554687 -2.464844 4.503906 -5.035156 4.507812 c -2.796875 0 -5.078125 -2.28125 -5.078125 -5.078125 c 0.003906 -2.570312 1.953125 -4.746094 4.507812 -5.035156 l -0.960937 -1.519531 c -0.574219 0.925781 -0.875 1.992187 -0.878906 3.082031 z m 0 0"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.1 KiB |
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 5 0 c -0.96875 0 -2 1.050781 -2 2 v 2.988281 c 0 0.429688 0.222656 0.675781 0.554688 1.007813 l 2.023437 2.003906 l -2.007813 1.992188 c -0.367187 0.363281 -0.570312 0.6875 -0.570312 1 v 3.007812 c 0 1.011719 0.988281 2 2 2 h 6 c 1.007812 0 2 -1.011719 2 -2.003906 v -3.003906 c 0 -0.3125 -0.222656 -0.628907 -0.570312 -0.976563 l -2.015626 -2.015625 l 1.988282 -1.988281 c 0.261718 -0.261719 0.585937 -0.6875 0.597656 -1.015625 v -2.996094 c 0 -1.003906 -1.007812 -2 -2 -2 z m 6 4 h -6 v -2 h 6 m -3.589844 7 h 1.175782 l 2.414062 2.414062 v 1.585938 h -6 v -1.613281 z m 0 0"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 729 B |
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 8 0 c -0.554688 0 -1 0.445312 -1 1 v 1 c 0 0.554688 0.445312 1 1 1 s 1 -0.445312 1 -1 v -1 c 0 -0.554688 -0.445312 -1 -1 -1 z m -4.996094 2.003906 c -0.253906 0 -0.507812 0.097656 -0.707031 0.296875 c -0.390625 0.390625 -0.390625 1.019531 0 1.414063 l 0.707031 0.707031 c 0.394532 0.390625 1.023438 0.390625 1.414063 0 c 0.394531 -0.394531 0.394531 -1.023437 0 -1.414063 l -0.707031 -0.707031 c -0.195313 -0.199219 -0.449219 -0.296875 -0.707032 -0.296875 z m 9.988282 0 c -0.253907 0 -0.507813 0.097656 -0.707032 0.296875 l -0.707031 0.707031 c -0.390625 0.390626 -0.390625 1.019532 0 1.414063 c 0.394531 0.390625 1.023437 0.390625 1.414063 0 l 0.707031 -0.707031 c 0.394531 -0.394532 0.394531 -1.023438 0 -1.414063 c -0.195313 -0.199219 -0.449219 -0.296875 -0.707031 -0.296875 z m -4.992188 1.996094 c -2.210938 0 -4 1.789062 -4 4 s 1.789062 4 4 4 s 4 -1.789062 4 -4 s -1.789062 -4 -4 -4 z m 0 2 c 1.105469 0 2 0.894531 2 2 s -0.894531 2 -2 2 s -2 -0.894531 -2 -2 s 0.894531 -2 2 -2 z m -7 1 c -0.554688 0 -1 0.445312 -1 1 s 0.445312 1 1 1 h 1 c 0.554688 0 1 -0.445312 1 -1 s -0.445312 -1 -1 -1 z m 13 0 c -0.554688 0 -1 0.445312 -1 1 s 0.445312 1 1 1 h 1 c 0.554688 0 1 -0.445312 1 -1 s -0.445312 -1 -1 -1 z m -10.335938 4.289062 c -0.238281 0.007813 -0.472656 0.105469 -0.660156 0.292969 l -0.707031 0.707031 c -0.390625 0.390626 -0.390625 1.019532 0 1.414063 c 0.394531 0.390625 1.023437 0.390625 1.414063 0 l 0.707031 -0.707031 c 0.394531 -0.394532 0.394531 -1.023438 0 -1.414063 c -0.207031 -0.210937 -0.484375 -0.308593 -0.753907 -0.292969 z m 8.574219 0 c -0.238281 0.007813 -0.472656 0.105469 -0.660156 0.292969 c -0.390625 0.390625 -0.390625 1.019531 0 1.414063 l 0.707031 0.707031 c 0.394532 0.390625 1.023438 0.390625 1.414063 0 c 0.394531 -0.394531 0.394531 -1.023437 0 -1.414063 l -0.707031 -0.707031 c -0.207032 -0.210937 -0.484376 -0.308593 -0.753907 -0.292969 z m -4.292969 1.710938 c -0.527343 0.027344 -0.945312 0.464844 -0.945312 1 v 1 c 0 0.554688 0.445312 1 1 1 s 1 -0.445312 1 -1 v -1 c 0 -0.554688 -0.445312 -1 -1 -1 c -0.015625 0 -0.035156 0 -0.050781 0 z m 0 0"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.2 KiB |
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 11.5 1 c -1.921875 0 -3.5 1.578125 -3.5 3.5 s 1.578125 3.5 3.5 3.5 s 3.5 -1.578125 3.5 -3.5 s -1.578125 -3.5 -3.5 -3.5 z m 0 2 c 0.839844 0 1.5 0.660156 1.5 1.5 s -0.660156 1.5 -1.5 1.5 s -1.5 -0.660156 -1.5 -1.5 s 0.660156 -1.5 1.5 -1.5 z m 0 0"/>
|
||||
<path d="m 4.5 8 c -1.921875 0 -3.5 1.578125 -3.5 3.5 s 1.578125 3.5 3.5 3.5 c 1.386719 0 2.59375 -0.820312 3.15625 -2 h 5.84375 c 0.832031 0 1.5 -0.667969 1.5 -1.5 s -0.667969 -1.5 -1.5 -1.5 h -5.84375 c -0.5625 -1.179688 -1.769531 -2 -3.15625 -2 z m 0 2 c 0.839844 0 1.5 0.660156 1.5 1.5 s -0.660156 1.5 -1.5 1.5 s -1.5 -0.660156 -1.5 -1.5 s 0.660156 -1.5 1.5 -1.5 z m 0 0"/>
|
||||
<path d="m 2.5 3 c -0.832031 0 -1.5 0.667969 -1.5 1.5 s 0.667969 1.5 1.5 1.5 h 4.769531 c -0.175781 -0.480469 -0.265625 -0.988281 -0.269531 -1.5 c 0 -0.511719 0.09375 -1.019531 0.269531 -1.5 z m 0 0" fill-opacity="0.34902"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1,009 B |
|
@ -1,155 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="496"
|
||||
height="496"
|
||||
version="1"
|
||||
id="svg6"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs10" />
|
||||
<g
|
||||
id="g946"
|
||||
transform="matrix(0.97173996,0,0,0.97173996,4.043873,36.112138)">
|
||||
<g
|
||||
id="layer7"
|
||||
style="display:none"
|
||||
transform="translate(-23.75651,-24.84972)">
|
||||
<rect
|
||||
transform="translate(-132.5822,958.04022)"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="rect5389"
|
||||
width="1543.4283"
|
||||
height="483.7439"
|
||||
x="132.5822"
|
||||
y="-957.77832" />
|
||||
</g>
|
||||
<g
|
||||
id="layer6"
|
||||
style="display:none"
|
||||
transform="translate(-156.33871,933.1905)">
|
||||
<rect
|
||||
y="-958.02759"
|
||||
x="132.65129"
|
||||
height="484.30399"
|
||||
width="550.41602"
|
||||
id="rect5379"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#5c201e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<rect
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c24a46;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="rect5372"
|
||||
width="501.94415"
|
||||
height="434.30405"
|
||||
x="156.12303"
|
||||
y="-933.02759" />
|
||||
<rect
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d98d8a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
id="rect5381"
|
||||
width="24.939611"
|
||||
height="24.939611"
|
||||
x="658.02826"
|
||||
y="-958.04022" />
|
||||
</g>
|
||||
<g
|
||||
id="layer3"
|
||||
style="display:inline;opacity:1"
|
||||
transform="translate(37.235605,912.8581)">
|
||||
<g
|
||||
id="g2072"
|
||||
transform="matrix(0.99894325,0,0,0.99894325,-36.551621,-913.90743)"
|
||||
style="fill:#cccccc;fill-opacity:1">
|
||||
<g
|
||||
style="display:none;fill:#cccccc;fill-opacity:1"
|
||||
transform="matrix(0.09048806,0,0,0.09048806,-14.15991,84.454917)"
|
||||
id="layer1-3">
|
||||
<rect
|
||||
y="-2102.4253"
|
||||
x="-1045.6049"
|
||||
height="7145.4614"
|
||||
width="7947.0356"
|
||||
id="rect995"
|
||||
style="opacity:1;fill:#cccccc;fill-opacity:1;stroke-width:10.3605" />
|
||||
</g>
|
||||
<g
|
||||
transform="translate(-156.48372,537.56136)"
|
||||
style="display:inline;opacity:1;fill:#cccccc;fill-opacity:1"
|
||||
id="layer3-6">
|
||||
<g
|
||||
style="fill:#cccccc;stroke-width:11.0512;fill-opacity:1"
|
||||
transform="matrix(0.09048806,0,0,0.09048806,142.32381,-453.10644)"
|
||||
id="g955">
|
||||
<g
|
||||
transform="matrix(11.047619,0,0,11.047619,-1572.2888,9377.7107)"
|
||||
id="g869"
|
||||
style="fill:#cccccc;fill-opacity:1">
|
||||
<g
|
||||
transform="rotate(-60,226.35754,-449.37199)"
|
||||
id="g932"
|
||||
style="fill:#cccccc;stroke-width:11.0512;fill-opacity:1">
|
||||
<path
|
||||
id="path3336-6-7"
|
||||
d="m 449.71876,-420.51322 c 40.73228,70.55837 81.46455,141.11675 122.19683,211.67512 -18.71902,0.1756 -37.43804,0.3512 -56.15706,0.5268 -10.87453,-18.9564 -21.74907,-37.9128 -32.6236,-56.8692 -10.95215,18.8551 -21.9043,37.7102 -32.85645,56.5653 -9.30079,-0.004 -18.60158,-0.007 -27.90237,-0.011 -4.76362,-8.22987 -9.52724,-16.45973 -14.29086,-24.6896 15.60349,-26.83003 31.20698,-53.66007 46.81047,-80.4901 -11.07649,-19.27523 -22.15297,-38.55047 -33.22946,-57.8257 9.35083,-16.29387 18.70167,-32.58775 28.0525,-48.88162 z"
|
||||
style="opacity:1;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:33.1535;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
<path
|
||||
id="path4260-0-5"
|
||||
d="m 309.54892,-710.38827 c 40.73228,70.55837 81.46455,141.11675 122.19683,211.67512 -18.71902,0.1756 -37.43804,0.3512 -56.15706,0.5268 -10.87453,-18.9564 -21.74907,-37.9128 -32.6236,-56.8692 -10.95215,18.8551 -21.9043,37.7102 -32.85645,56.5653 -9.30079,-0.004 -18.60158,-0.007 -27.90237,-0.011 -4.76362,-8.22987 -9.52724,-16.45973 -14.29086,-24.6896 15.60349,-26.83003 31.20698,-53.66007 46.81047,-80.4901 -11.07649,-19.2752 -22.15297,-38.5504 -33.22946,-57.8256 9.35083,-16.29391 18.70167,-32.58781 28.0525,-48.88172 z"
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:33.1535;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#path3336-6-7"
|
||||
id="use3439-6-3"
|
||||
transform="rotate(60,728.23563,-692.24036)"
|
||||
width="100%"
|
||||
height="100%"
|
||||
style="fill:#cccccc;fill-opacity:1;stroke-width:11.0512" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#path3336-6-7"
|
||||
id="use3449-5-5"
|
||||
transform="rotate(180,477.5036,-570.81898)"
|
||||
width="100%"
|
||||
height="100%"
|
||||
style="fill:#cccccc;fill-opacity:1;stroke-width:11.0512" />
|
||||
<use
|
||||
style="display:inline;fill:#cccccc;fill-opacity:1;stroke-width:11.0512"
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#path4260-0-5"
|
||||
id="use4354-5-6"
|
||||
transform="rotate(120,407.33916,-716.08356)"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
<use
|
||||
style="display:inline;fill:#cccccc;fill-opacity:1;stroke-width:11.0512"
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#path4260-0-5"
|
||||
id="use4362-2-2"
|
||||
transform="rotate(-120,407.28823,-715.86995)"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 8.6 KiB |
|
@ -1,321 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
height="16px"
|
||||
viewBox="0 0 16 16"
|
||||
width="16px"
|
||||
version="1.1"
|
||||
id="svg3533"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs3537" />
|
||||
<filter
|
||||
id="a"
|
||||
height="1"
|
||||
width="1"
|
||||
x="0"
|
||||
y="0">
|
||||
<feColorMatrix
|
||||
in="SourceGraphic"
|
||||
type="matrix"
|
||||
values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"
|
||||
id="feColorMatrix3414" />
|
||||
</filter>
|
||||
<mask
|
||||
id="b">
|
||||
<g
|
||||
filter="url(#a)"
|
||||
id="g3419">
|
||||
<image
|
||||
height="800"
|
||||
width="1024"
|
||||
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABAAAAAMgCAYAAAC9FhA7AAAABmJLR0QA/wD/AP+gvaeTAAAMr0lEQVR4nO3YsQ2AMAwAwcB8GZcBWQFEIoq/qy3b9Y8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQdi/bMl/PXorsAAADAA+ffDwAAAAD7CQAAAAAQIAAAAABAgAAAAAAAAQIAAAAABAgAAAAAECAAAAAAQIAAAAAAAAECAAAAAAQIAAAAABAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8dQMXagEYjYWofQAAAABJRU5ErkJggg=="
|
||||
id="image3417" />
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath
|
||||
id="c">
|
||||
<path
|
||||
d="m 0 0 h 1024 v 800 h -1024 z"
|
||||
id="path3422" />
|
||||
</clipPath>
|
||||
<mask
|
||||
id="d">
|
||||
<g
|
||||
filter="url(#a)"
|
||||
id="g3427">
|
||||
<image
|
||||
height="800"
|
||||
width="1024"
|
||||
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABAAAAAMgCAYAAAC9FhA7AAAABmJLR0QA/wD/AP+gvaeTAAAMr0lEQVR4nO3YsQ2AMAwAwUCd/SdlAFYAkYji72rLdv1jAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBx6I98+X8teguAAAA8MD59wMAAADAfgIAAAAABAgAAAAAECAAAAAAQIAAAAAAAAECAAAAAAQIAAAAABAgAAAAAECAAAAAAAABAgAAAAAECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX90LagEYFVKkEwAAAABJRU5ErkJggg=="
|
||||
id="image3425" />
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath
|
||||
id="e">
|
||||
<path
|
||||
d="m 0 0 h 1024 v 800 h -1024 z"
|
||||
id="path3430" />
|
||||
</clipPath>
|
||||
<mask
|
||||
id="f">
|
||||
<g
|
||||
filter="url(#a)"
|
||||
id="g3435">
|
||||
<image
|
||||
height="800"
|
||||
width="1024"
|
||||
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABAAAAAMgCAYAAAC9FhA7AAAABmJLR0QA/wD/AP+gvaeTAAAMr0lEQVR4nO3YsQ2AMAwAwUCd/SdlAFYAkYji72rLdv1jAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBx6I98+X8teguAAAA8MD59wMAAADAfgIAAAAABAgAAAAAECAAAAAAQIAAAAAAAAECAAAAAAQIAAAAABAgAAAAAECAAAAAAAABAgAAAAAECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX90LagEYFVKkEwAAAABJRU5ErkJggg=="
|
||||
id="image3433" />
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath
|
||||
id="g">
|
||||
<path
|
||||
d="m 0 0 h 1024 v 800 h -1024 z"
|
||||
id="path3438" />
|
||||
</clipPath>
|
||||
<mask
|
||||
id="h">
|
||||
<g
|
||||
filter="url(#a)"
|
||||
id="g3443">
|
||||
<image
|
||||
height="800"
|
||||
width="1024"
|
||||
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABAAAAAMgCAYAAAC9FhA7AAAABmJLR0QA/wD/AP+gvaeTAAAMr0lEQVR4nO3YsQ2AMAwAwUCd/SdlAFYAkYji72rLdv1jAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBx6I98+X8teguAAAA8MD59wMAAADAfgIAAAAABAgAAAAAECAAAAAAQIAAAAAAAAECAAAAAAQIAAAAABAgAAAAAECAAAAAAAABAgAAAAAECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX90LagEYFVKkEwAAAABJRU5ErkJggg=="
|
||||
id="image3441" />
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath
|
||||
id="i">
|
||||
<path
|
||||
d="m 0 0 h 1024 v 800 h -1024 z"
|
||||
id="path3446" />
|
||||
</clipPath>
|
||||
<mask
|
||||
id="j">
|
||||
<g
|
||||
filter="url(#a)"
|
||||
id="g3451">
|
||||
<image
|
||||
height="800"
|
||||
width="1024"
|
||||
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABAAAAAMgCAYAAAC9FhA7AAAABmJLR0QA/wD/AP+gvaeTAAAMr0lEQVR4nO3YsQ2AMAwAwUCd/SdlAFYAkYji72rLdv1jAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBx6I98+X8teguAAAA8MD59wMAAADAfgIAAAAABAgAAAAAECAAAAAAQIAAAAAAAAECAAAAAAQIAAAAABAgAAAAAECAAAAAAAABAgAAAAAECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX90LagEYFVKkEwAAAABJRU5ErkJggg=="
|
||||
id="image3449" />
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath
|
||||
id="k">
|
||||
<path
|
||||
d="m 0 0 h 1024 v 800 h -1024 z"
|
||||
id="path3454" />
|
||||
</clipPath>
|
||||
<mask
|
||||
id="l">
|
||||
<g
|
||||
filter="url(#a)"
|
||||
id="g3459">
|
||||
<image
|
||||
height="800"
|
||||
width="1024"
|
||||
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABAAAAAMgCAYAAAC9FhA7AAAABmJLR0QA/wD/AP+gvaeTAAAMr0lEQVR4nO3YsQ2AMAwAwUCd/SdlAFYAkYji72rLdv1jAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBx6I98+X8teguAAAA8MD59wMAAADAfgIAAAAABAgAAAAAECAAAAAAQIAAAAAAAAECAAAAAAQIAAAAABAgAAAAAECAAAAAAAABAgAAAAAECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX90LagEYFVKkEwAAAABJRU5ErkJggg=="
|
||||
id="image3457" />
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath
|
||||
id="m">
|
||||
<path
|
||||
d="m 0 0 h 1024 v 800 h -1024 z"
|
||||
id="path3462" />
|
||||
</clipPath>
|
||||
<mask
|
||||
id="n">
|
||||
<g
|
||||
filter="url(#a)"
|
||||
id="g3467">
|
||||
<image
|
||||
height="800"
|
||||
width="1024"
|
||||
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABAAAAAMgCAYAAAC9FhA7AAAABmJLR0QA/wD/AP+gvaeTAAAMr0lEQVR4nO3YsQ2AMAwAwUCd/SdlAFYAkYji72rLdv1jAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBx6I98+X8teguAAAA8MD59wMAAADAfgIAAAAABAgAAAAAECAAAAAAQIAAAAAAAAECAAAAAAQIAAAAABAgAAAAAECAAAAAAAABAgAAAAAECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX90LagEYFVKkEwAAAABJRU5ErkJggg=="
|
||||
id="image3465" />
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath
|
||||
id="o">
|
||||
<path
|
||||
d="m 0 0 h 1024 v 800 h -1024 z"
|
||||
id="path3470" />
|
||||
</clipPath>
|
||||
<mask
|
||||
id="p">
|
||||
<g
|
||||
filter="url(#a)"
|
||||
id="g3475">
|
||||
<image
|
||||
height="800"
|
||||
width="1024"
|
||||
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABAAAAAMgCAYAAAC9FhA7AAAABmJLR0QA/wD/AP+gvaeTAAAMr0lEQVR4nO3YsQ2AMAwAwcB8GZcBWQFEIoq/qy3b9Y8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQdi/bMl/PXorsAAADAA+ffDwAAAAD7CQAAAAAQIAAAAABAgAAAAAAAAQIAAAAABAgAAAAAECAAAAAAQIAAAAAAAAECAAAAAAQIAAAAABAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8dQMXagEYjYWofQAAAABJRU5ErkJggg=="
|
||||
id="image3473" />
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath
|
||||
id="q">
|
||||
<path
|
||||
d="m 0 0 h 1024 v 800 h -1024 z"
|
||||
id="path3478" />
|
||||
</clipPath>
|
||||
<mask
|
||||
id="r">
|
||||
<g
|
||||
filter="url(#a)"
|
||||
id="g3483">
|
||||
<image
|
||||
height="800"
|
||||
width="1024"
|
||||
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABAAAAAMgCAYAAAC9FhA7AAAABmJLR0QA/wD/AP+gvaeTAAAMqUlEQVR4nO3YsQ3AMAwEMSeTe/QM4QgujqwF4etbCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIen76s4fvAQAAgAPv7QEAAADAPAEAAAAAAgQAAAAACBAAAAAAIEAAAAAAgAABAAAAAAIEAAAAAAgQAAAAACBAAAAAAIAAAQAAAAACBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAUx8hKgEYqUBSPgAAAABJRU5ErkJggg=="
|
||||
id="image3481" />
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath
|
||||
id="s">
|
||||
<path
|
||||
d="m 0 0 h 1024 v 800 h -1024 z"
|
||||
id="path3486" />
|
||||
</clipPath>
|
||||
<path
|
||||
d="m 3 1 c -1.644531 0 -3 1.355469 -3 3 v 6 c 0 1.644531 1.355469 3 3 3 h 10 c 1.644531 0 3 -1.355469 3 -3 v -6 c 0 -0.570312 -0.167969 -1.101562 -0.449219 -1.558594 l -1.550781 1.554688 v 6.003906 c 0 0.570312 -0.429688 1 -1 1 h -10 c -0.570312 0 -1 -0.429688 -1 -1 v -6 c 0 -0.570312 0.429688 -1 1 -1 h 5.96875 l 2.007812 -2 z m 0 0"
|
||||
fill="#2e3436"
|
||||
id="path3489"
|
||||
style="fill:#000000" />
|
||||
<g
|
||||
clip-path="url(#c)"
|
||||
mask="url(#b)"
|
||||
transform="matrix(1 0 0 1 -40 -620)"
|
||||
id="g3493"
|
||||
style="fill:#000000">
|
||||
<path
|
||||
d="m 439.105469 225.78125 h 7.839843 c -0.890624 0.371094 -0.972656 1.847656 0 2.25 h -7.839843 z m 0 0"
|
||||
fill="#2e3436"
|
||||
id="path3491"
|
||||
style="fill:#000000" />
|
||||
</g>
|
||||
<g
|
||||
clip-path="url(#e)"
|
||||
mask="url(#d)"
|
||||
transform="matrix(1 0 0 1 -40 -620)"
|
||||
id="g3497"
|
||||
style="fill:#000000">
|
||||
<path
|
||||
d="m 29.25 627.75 h 0.75 v 0.75 h -0.75 z m 0 0"
|
||||
fill="#2e3436"
|
||||
fill-rule="evenodd"
|
||||
id="path3495"
|
||||
style="fill:#000000" />
|
||||
</g>
|
||||
<g
|
||||
clip-path="url(#g)"
|
||||
mask="url(#f)"
|
||||
transform="matrix(1 0 0 1 -40 -620)"
|
||||
id="g3501"
|
||||
style="fill:#000000">
|
||||
<path
|
||||
d="m 30 627 h 0.75 v 0.75 h -0.75 z m 0 0"
|
||||
fill="#2e3436"
|
||||
fill-rule="evenodd"
|
||||
id="path3499"
|
||||
style="fill:#000000" />
|
||||
</g>
|
||||
<g
|
||||
clip-path="url(#i)"
|
||||
mask="url(#h)"
|
||||
transform="matrix(1 0 0 1 -40 -620)"
|
||||
id="g3505"
|
||||
style="fill:#000000">
|
||||
<path
|
||||
d="m 30.75 629.25 h 0.75 v 0.75 h -0.75 z m 0 0"
|
||||
fill="#2e3436"
|
||||
fill-rule="evenodd"
|
||||
id="path3503"
|
||||
style="fill:#000000" />
|
||||
</g>
|
||||
<g
|
||||
clip-path="url(#k)"
|
||||
mask="url(#j)"
|
||||
transform="matrix(1 0 0 1 -40 -620)"
|
||||
id="g3509"
|
||||
style="fill:#000000">
|
||||
<path
|
||||
d="m 29.25 629.25 h 0.75 v 0.75 h -0.75 z m 0 0"
|
||||
fill="#2e3436"
|
||||
fill-rule="evenodd"
|
||||
id="path3507"
|
||||
style="fill:#000000" />
|
||||
</g>
|
||||
<g
|
||||
clip-path="url(#m)"
|
||||
mask="url(#l)"
|
||||
transform="matrix(1 0 0 1 -40 -620)"
|
||||
id="g3513"
|
||||
style="fill:#000000">
|
||||
<path
|
||||
d="m 30 630 h 0.75 v 0.75 h -0.75 z m 0 0"
|
||||
fill="#2e3436"
|
||||
fill-rule="evenodd"
|
||||
id="path3511"
|
||||
style="fill:#000000" />
|
||||
</g>
|
||||
<g
|
||||
clip-path="url(#o)"
|
||||
mask="url(#n)"
|
||||
transform="matrix(1 0 0 1 -40 -620)"
|
||||
id="g3517"
|
||||
style="fill:#000000">
|
||||
<path
|
||||
d="m 31.5 630 h 0.75 v 0.75 h -0.75 z m 0 0"
|
||||
fill="#2e3436"
|
||||
fill-rule="evenodd"
|
||||
id="path3515"
|
||||
style="fill:#000000" />
|
||||
</g>
|
||||
<g
|
||||
clip-path="url(#q)"
|
||||
mask="url(#p)"
|
||||
transform="matrix(1 0 0 1 -40 -620)"
|
||||
id="g3521"
|
||||
style="fill:#000000">
|
||||
<path
|
||||
d="m 119.253906 648.75 v 5.25 h 5.25 v -5.25 z m 0 0"
|
||||
fill="#2e3436"
|
||||
id="path3519"
|
||||
style="fill:#000000" />
|
||||
</g>
|
||||
<path
|
||||
d="m 11 7 c 0 1.65625 -1.339844 3.007812 -3 3 h -3 v -3 c 0 -1.660156 1.34375 -3 3 -3 c 1.660156 0 3 1.339844 3 3 z m 0 0"
|
||||
fill="#2e3436"
|
||||
id="path3523"
|
||||
style="fill:#000000" />
|
||||
<path
|
||||
d="m 13.398438 0 l -3.46875 3.457031 c 0.683593 0.355469 1.234374 0.910157 1.589843 1.589844 l 0.171875 -0.171875 l 0.007813 0.007812 l 4.300781 -4.300781 v -0.582031 z m 0 0"
|
||||
fill="#2e3436"
|
||||
id="path3525"
|
||||
style="fill:#000000" />
|
||||
<g
|
||||
clip-path="url(#s)"
|
||||
mask="url(#r)"
|
||||
transform="matrix(1 0 0 1 -40 -620)"
|
||||
id="g3529"
|
||||
style="fill:#000000">
|
||||
<path
|
||||
d="m 181.503906 635.25 h 2.25 v 9 h -2.25 z m 0 0"
|
||||
fill="#2e3436"
|
||||
id="path3527"
|
||||
style="fill:#000000" />
|
||||
</g>
|
||||
<path
|
||||
d="m 5 14 c -1.105469 0 -2 0.894531 -2 2 h 10 c 0 -1.105469 -0.894531 -2 -2 -2 z m 0 0"
|
||||
fill="#2e3436"
|
||||
id="path3531"
|
||||
style="fill:#000000" />
|
||||
</svg>
|
Before Width: | Height: | Size: 46 KiB |
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 5 5 h 6 v 6 h -6 z m 0 0"/>
|
||||
<path d="m 13 5 h 3 v 1 h -3 z m 0 0"/>
|
||||
<path d="m 13 7 h 3 v 1 h -3 z m 0 0"/>
|
||||
<path d="m 13 9 h 3 v 1 h -3 z m 0 0"/>
|
||||
<path d="m 0 6 h 3 v 1 h -3 z m 0 0"/>
|
||||
<path d="m 0 8 h 3 v 1 h -3 z m 0 0"/>
|
||||
<path d="m 0 10 h 3 v 1 h -3 z m 0 0"/>
|
||||
<path d="m 5 0 h 1 v 3 h -1 z m 0 0"/>
|
||||
<path d="m 7 0 h 1 v 3 h -1 z m 0 0"/>
|
||||
<path d="m 9 0 h 1 v 3 h -1 z m 0 0"/>
|
||||
<path d="m 10 13 h 1 v 3 h -1 z m 0 0"/>
|
||||
<path d="m 8 13 h 1 v 3 h -1 z m 0 0"/>
|
||||
<path d="m 6 13 h 1 v 3 h -1 z m 0 0"/>
|
||||
<path d="m 5 2 c -1.644531 0 -3 1.355469 -3 3 v 6 c 0 1.644531 1.355469 3 3 3 h 6 c 1.644531 0 3 -1.355469 3 -3 v -6 c 0 -1.644531 -1.355469 -3 -3 -3 z m 0 2 h 6 c 0.570312 0 1 0.429688 1 1 v 6 c 0 0.570312 -0.429688 1 -1 1 h -6 c -0.570312 0 -1 -0.429688 -1 -1 v -6 c 0 -0.570312 0.429688 -1 1 -1 z m 0 0"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1,014 B |
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 2.199219 0 c -1.207031 0 -2.199219 1.007812 -2.199219 2.207031 v 10.585938 c 0 1.199219 0.992188 2.207031 2.199219 2.207031 h 11.601562 c 1.207031 0 2.199219 -1.007812 2.199219 -2.207031 v -10.585938 c 0 -1.199219 -0.992188 -2.207031 -2.199219 -2.207031 z m 0 2 h 11.601562 c 0.121094 0 0.199219 0.070312 0.199219 0.207031 v 10.585938 c 0 0.136719 -0.078125 0.207031 -0.199219 0.207031 h -11.601562 c -0.121094 0 -0.199219 -0.070312 -0.199219 -0.207031 v -10.585938 c 0 -0.136719 0.078125 -0.207031 0.199219 -0.207031 z m 0 0"/>
|
||||
<path d="m 4.515625 5.898438 c -0.164063 -0.003907 -0.324219 0.0625 -0.441406 0.175781 c -0.230469 0.234375 -0.230469 0.617187 0 0.851562 l 1.578125 1.574219 l -1.578125 1.574219 c -0.230469 0.234375 -0.230469 0.617187 0 0.851562 c 0.234375 0.230469 0.617187 0.230469 0.851562 0 l 2 -2 c 0.230469 -0.234375 0.230469 -0.617187 0 -0.851562 l -2 -2 c -0.109375 -0.105469 -0.257812 -0.167969 -0.410156 -0.175781 z m 3.484375 4.101562 v 1 h 3 v -1 z m 0 0"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.1 KiB |
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 2 0 c -1.214844 0 -2 0.828125 -2 2 v 12 c 0 1 1 2 2 2 h 11.984375 c 1 0 2 -1 2 -2 v -12 c 0 -1.238281 -0.828125 -2 -2 -2 z m 0 2 h 2 v 2 h -2 z m 3 0 h 2 v 2 h -2 z m 3 0 h 2 v 2 h -2 z m -6 4 h 11.984375 v 8 h -11.984375 z m 0 0"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 382 B |
|
@ -1,46 +0,0 @@
|
|||
import GLib from "gi://GLib"
|
||||
|
||||
const main = "/tmp/asztal/main.js"
|
||||
const entry = `${App.configDir}/main.ts`
|
||||
const bundler = GLib.getenv("AGS_BUNDLER") || "bun"
|
||||
|
||||
const v = {
|
||||
ags: pkg.version?.split(".").map(Number) || [],
|
||||
expect: [1, 8, 1],
|
||||
}
|
||||
|
||||
try {
|
||||
switch (bundler) {
|
||||
case "bun": await Utils.execAsync([
|
||||
"bun", "build", entry,
|
||||
"--outfile", main,
|
||||
"--external", "resource://*",
|
||||
"--external", "gi://*",
|
||||
"--external", "file://*",
|
||||
]); break
|
||||
|
||||
case "esbuild": await Utils.execAsync([
|
||||
"esbuild", "--bundle", entry,
|
||||
"--format=esm",
|
||||
`--outfile=${main}`,
|
||||
"--external:resource://*",
|
||||
"--external:gi://*",
|
||||
"--external:file://*",
|
||||
]); break
|
||||
|
||||
default:
|
||||
throw `"${bundler}" is not a valid bundler`
|
||||
}
|
||||
|
||||
if (v.ags[1] < v.expect[1] || v.ags[2] < v.expect[2]) {
|
||||
print(`my config needs at least v${v.expect.join(".")}, yours is v${v.ags.join(".")}`)
|
||||
App.quit()
|
||||
}
|
||||
|
||||
await import(`file://${main}`)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
App.quit()
|
||||
}
|
||||
|
||||
export { }
|
|
@ -1,103 +0,0 @@
|
|||
{
|
||||
inputs,
|
||||
writeShellScript,
|
||||
system,
|
||||
stdenv,
|
||||
cage,
|
||||
swww,
|
||||
esbuild,
|
||||
dart-sass,
|
||||
fd,
|
||||
fzf,
|
||||
brightnessctl,
|
||||
accountsservice,
|
||||
slurp,
|
||||
wf-recorder,
|
||||
wl-clipboard,
|
||||
wayshot,
|
||||
swappy,
|
||||
hyprpicker,
|
||||
pavucontrol,
|
||||
networkmanager,
|
||||
gtk3,
|
||||
which,
|
||||
}: let
|
||||
name = "asztal";
|
||||
|
||||
ags = inputs.ags.packages.${system}.default.override {
|
||||
extraPackages = [accountsservice];
|
||||
};
|
||||
|
||||
dependencies = [
|
||||
which
|
||||
dart-sass
|
||||
fd
|
||||
fzf
|
||||
brightnessctl
|
||||
swww
|
||||
inputs.matugen.packages.${system}.default
|
||||
slurp
|
||||
wf-recorder
|
||||
wl-clipboard
|
||||
wayshot
|
||||
swappy
|
||||
hyprpicker
|
||||
pavucontrol
|
||||
networkmanager
|
||||
gtk3
|
||||
];
|
||||
|
||||
addBins = list: builtins.concatStringsSep ":" (builtins.map (p: "${p}/bin") list);
|
||||
|
||||
greeter = writeShellScript "greeter" ''
|
||||
export PATH=$PATH:${addBins dependencies}
|
||||
${cage}/bin/cage -ds -m last ${ags}/bin/ags -- -c ${config}/greeter.js
|
||||
'';
|
||||
|
||||
desktop = writeShellScript name ''
|
||||
export PATH=$PATH:${addBins dependencies}
|
||||
${ags}/bin/ags -b ${name} -c ${config}/config.js $@
|
||||
'';
|
||||
|
||||
config = stdenv.mkDerivation {
|
||||
inherit name;
|
||||
src = ./.;
|
||||
|
||||
buildPhase = ''
|
||||
${esbuild}/bin/esbuild \
|
||||
--bundle ./main.ts \
|
||||
--outfile=main.js \
|
||||
--format=esm \
|
||||
--external:resource://\* \
|
||||
--external:gi://\* \
|
||||
|
||||
${esbuild}/bin/esbuild \
|
||||
--bundle ./greeter/greeter.ts \
|
||||
--outfile=greeter.js \
|
||||
--format=esm \
|
||||
--external:resource://\* \
|
||||
--external:gi://\* \
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
cp -r assets $out
|
||||
cp -r style $out
|
||||
cp -r greeter $out
|
||||
cp -r widget $out
|
||||
cp -f main.js $out/config.js
|
||||
cp -f greeter.js $out/greeter.js
|
||||
'';
|
||||
};
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
inherit name;
|
||||
src = config;
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
cp -r . $out
|
||||
cp ${desktop} $out/bin/${name}
|
||||
cp ${greeter} $out/bin/greeter
|
||||
'';
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
const main = "/tmp/ags/greeter.js"
|
||||
const entry = `${App.configDir}/greeter/greeter.ts`
|
||||
|
||||
try {
|
||||
await Utils.execAsync([
|
||||
"bun", "build", entry,
|
||||
"--outfile", main,
|
||||
"--external", "resource://*",
|
||||
"--external", "gi://*",
|
||||
"--external", "file://*",
|
||||
])
|
||||
await import(`file://${main}`)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
App.quit()
|
||||
}
|
||||
|
||||
export { }
|
|
@ -1,114 +0,0 @@
|
|||
import GLib from "gi://GLib?version=2.0"
|
||||
import icons from "lib/icons"
|
||||
import { bash } from "lib/utils"
|
||||
|
||||
const userName = await bash("find /home -maxdepth 1 -printf '%f\n' | tail -n 1")
|
||||
const iconFile = `/var/lib/AccountsService/icons/${userName}`
|
||||
|
||||
// FIXME: AccountsService crashes?
|
||||
// import AccountsService from "gi://AccountsService?version=1.0"
|
||||
// const { iconFile, realName, userName } = AccountsService.UserManager
|
||||
// .get_default().list_users()[0]
|
||||
|
||||
const loggingin = Variable(false)
|
||||
|
||||
const CMD = GLib.getenv("ASZTAL_DM_CMD")
|
||||
|| "Hyprland"
|
||||
|
||||
const ENV = GLib.getenv("ASZTAL_DM_ENV")
|
||||
|| "WLR_NO_HARDWARE_CURSORS=1 _JAVA_AWT_WM_NONREPARENTING=1"
|
||||
|
||||
async function login(pw: string) {
|
||||
loggingin.value = true
|
||||
const greetd = await Service.import("greetd")
|
||||
return greetd.login(userName, pw, CMD, ENV.split(/\s+/))
|
||||
.catch(res => {
|
||||
loggingin.value = false
|
||||
response.label = res?.description || JSON.stringify(res)
|
||||
password.text = ""
|
||||
revealer.reveal_child = true
|
||||
})
|
||||
}
|
||||
|
||||
const avatar = Widget.Box({
|
||||
class_name: "avatar",
|
||||
hpack: "center",
|
||||
css: `background-image: url('${iconFile}')`,
|
||||
})
|
||||
|
||||
const password = Widget.Entry({
|
||||
placeholder_text: "Password",
|
||||
hexpand: true,
|
||||
visibility: false,
|
||||
on_accept: ({ text }) => { login(text || "") },
|
||||
})
|
||||
|
||||
const response = Widget.Label({
|
||||
class_name: "response",
|
||||
wrap: true,
|
||||
max_width_chars: 35,
|
||||
hpack: "center",
|
||||
hexpand: true,
|
||||
xalign: .5,
|
||||
})
|
||||
|
||||
const revealer = Widget.Revealer({
|
||||
transition: "slide_down",
|
||||
child: response,
|
||||
})
|
||||
|
||||
export default Widget.Box({
|
||||
class_name: "auth",
|
||||
attribute: { password },
|
||||
vertical: true,
|
||||
children: [
|
||||
Widget.Overlay({
|
||||
child: Widget.Box(
|
||||
{
|
||||
css: "min-width: 200px; min-height: 200px;",
|
||||
vertical: true,
|
||||
},
|
||||
Widget.Box({
|
||||
class_name: "wallpaper",
|
||||
css: `background-image: url('${WALLPAPER}')`,
|
||||
}),
|
||||
Widget.Box({
|
||||
class_name: "wallpaper-contrast",
|
||||
vexpand: true,
|
||||
}),
|
||||
),
|
||||
overlay: Widget.Box(
|
||||
{
|
||||
vpack: "end",
|
||||
vertical: true,
|
||||
},
|
||||
avatar,
|
||||
Widget.Box({
|
||||
hpack: "center",
|
||||
children: [
|
||||
Widget.Icon(icons.ui.avatar),
|
||||
Widget.Label(userName),
|
||||
],
|
||||
}),
|
||||
Widget.Box(
|
||||
{
|
||||
class_name: "password",
|
||||
},
|
||||
Widget.Spinner({
|
||||
visible: loggingin.bind(),
|
||||
active: true,
|
||||
}),
|
||||
Widget.Icon({
|
||||
visible: loggingin.bind().as(b => !b),
|
||||
icon: icons.ui.lock,
|
||||
}),
|
||||
password,
|
||||
),
|
||||
),
|
||||
}),
|
||||
Widget.Box(
|
||||
{ class_name: "response-box" },
|
||||
revealer,
|
||||
),
|
||||
],
|
||||
})
|
|
@ -1,37 +0,0 @@
|
|||
import "./session"
|
||||
import "style/style"
|
||||
import GLib from "gi://GLib?version=2.0"
|
||||
import RegularWindow from "widget/RegularWindow"
|
||||
import statusbar from "./statusbar"
|
||||
import auth from "./auth"
|
||||
|
||||
const win = RegularWindow({
|
||||
name: "greeter",
|
||||
setup: self => {
|
||||
self.set_default_size(500, 500)
|
||||
self.show_all()
|
||||
auth.attribute.password.grab_focus()
|
||||
},
|
||||
child: Widget.Overlay({
|
||||
child: Widget.Box({ expand: true }),
|
||||
overlays: [
|
||||
Widget.Box({
|
||||
vpack: "start",
|
||||
hpack: "fill",
|
||||
hexpand: true,
|
||||
child: statusbar,
|
||||
}),
|
||||
Widget.Box({
|
||||
vpack: "center",
|
||||
hpack: "center",
|
||||
child: auth,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
})
|
||||
|
||||
App.config({
|
||||
icons: "./assets",
|
||||
windows: [win],
|
||||
cursorTheme: GLib.getenv("XCURSOR_THEME")!,
|
||||
})
|
|
@ -1,23 +0,0 @@
|
|||
import GLib from "gi://GLib?version=2.0"
|
||||
import { bash } from "lib/utils"
|
||||
|
||||
// import AccountsService from "gi://AccountsService?version=1.0"
|
||||
// const { userName } = AccountsService.UserManager.get_default().list_users()[0]
|
||||
|
||||
const userName = await bash("find /home -maxdepth 1 -printf '%f\n' | tail -n 1")
|
||||
|
||||
declare global {
|
||||
const WALLPAPER: string
|
||||
}
|
||||
|
||||
Object.assign(globalThis, {
|
||||
TMP: `${GLib.get_tmp_dir()}/greeter`,
|
||||
OPTIONS: "/var/cache/greeter/options.json",
|
||||
WALLPAPER: "/var/cache/greeter/background",
|
||||
// TMP: "/tmp/ags",
|
||||
// OPTIONS: Utils.CACHE_DIR + "/options.json",
|
||||
// WALLPAPER: Utils.HOME + "/.config/background",
|
||||
USER: userName,
|
||||
})
|
||||
|
||||
Utils.ensureDirectory(TMP)
|
|
@ -1,46 +0,0 @@
|
|||
import { clock } from "lib/variables"
|
||||
import options from "options"
|
||||
import icons from "lib/icons"
|
||||
import BatteryBar from "widget/bar/buttons/BatteryBar"
|
||||
import PanelButton from "widget/bar/PanelButton"
|
||||
|
||||
const { scheme } = options.theme
|
||||
const { monochrome } = options.bar.powermenu
|
||||
const { format } = options.bar.date
|
||||
|
||||
const poweroff = PanelButton({
|
||||
class_name: "powermenu",
|
||||
child: Widget.Icon(icons.powermenu.shutdown),
|
||||
on_clicked: () => Utils.exec("shutdown now"),
|
||||
setup: self => self.hook(monochrome, () => {
|
||||
self.toggleClassName("colored", !monochrome.value)
|
||||
self.toggleClassName("box")
|
||||
}),
|
||||
})
|
||||
|
||||
const date = PanelButton({
|
||||
class_name: "date",
|
||||
child: Widget.Label({
|
||||
label: clock.bind().as(c => c.format(`${format}`)!),
|
||||
}),
|
||||
})
|
||||
|
||||
const darkmode = PanelButton({
|
||||
class_name: "darkmode",
|
||||
child: Widget.Icon({ icon: scheme.bind().as(s => icons.color[s]) }),
|
||||
on_clicked: () => scheme.value = scheme.value === "dark" ? "light" : "dark",
|
||||
})
|
||||
|
||||
export default Widget.CenterBox({
|
||||
class_name: "bar",
|
||||
hexpand: true,
|
||||
center_widget: date,
|
||||
end_widget: Widget.Box({
|
||||
hpack: "end",
|
||||
children: [
|
||||
darkmode,
|
||||
BatteryBar(),
|
||||
poweroff,
|
||||
],
|
||||
}),
|
||||
})
|
|
@ -1,16 +0,0 @@
|
|||
import icons from "./icons"
|
||||
|
||||
export default async function init() {
|
||||
const bat = await Service.import("battery")
|
||||
bat.connect("notify::percent", ({ percent, charging }) => {
|
||||
const low = 30
|
||||
if (percent !== low || percent !== low / 2 || !charging)
|
||||
return
|
||||
|
||||
Utils.notify({
|
||||
summary: `${percent}% Battery Percentage`,
|
||||
iconName: icons.battery.warning,
|
||||
urgency: "critical",
|
||||
})
|
||||
})
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
import Gio from "gi://Gio"
|
||||
import options from "options"
|
||||
|
||||
const settings = new Gio.Settings({
|
||||
schema: "org.gnome.desktop.interface",
|
||||
})
|
||||
|
||||
function gtk() {
|
||||
const scheme = options.theme.scheme.value
|
||||
settings.set_string("color-scheme", `prefer-${scheme}`)
|
||||
}
|
||||
|
||||
export default function init() {
|
||||
options.theme.scheme.connect("changed", gtk)
|
||||
gtk()
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
import options from "options"
|
||||
const { messageAsync } = await Service.import("hyprland")
|
||||
|
||||
const {
|
||||
hyprland,
|
||||
theme: {
|
||||
spacing,
|
||||
radius,
|
||||
border: { width },
|
||||
blur,
|
||||
shadows,
|
||||
dark: {
|
||||
primary: { bg: darkActive },
|
||||
},
|
||||
light: {
|
||||
primary: { bg: lightActive },
|
||||
},
|
||||
scheme,
|
||||
},
|
||||
} = options
|
||||
|
||||
const deps = [
|
||||
"hyprland",
|
||||
spacing.id,
|
||||
radius.id,
|
||||
blur.id,
|
||||
width.id,
|
||||
shadows.id,
|
||||
darkActive.id,
|
||||
lightActive.id,
|
||||
scheme.id,
|
||||
]
|
||||
|
||||
function primary() {
|
||||
return scheme.value === "dark"
|
||||
? darkActive.value
|
||||
: lightActive.value
|
||||
}
|
||||
|
||||
function rgba(color: string) {
|
||||
return `rgba(${color}ff)`.replace("#", "")
|
||||
}
|
||||
|
||||
function sendBatch(batch: string[]) {
|
||||
const cmd = batch
|
||||
.filter(x => !!x)
|
||||
.map(x => `keyword ${x}`)
|
||||
.join("; ")
|
||||
|
||||
return messageAsync(`[[BATCH]]/${cmd}`)
|
||||
}
|
||||
|
||||
async function setupHyprland() {
|
||||
const wm_gaps = Math.floor(hyprland.gaps.value * spacing.value)
|
||||
|
||||
sendBatch([
|
||||
`general:border_size ${width}`,
|
||||
`general:gaps_out ${wm_gaps}`,
|
||||
`general:gaps_in ${Math.floor(wm_gaps / 2)}`,
|
||||
`general:col.active_border ${rgba(primary())}`,
|
||||
`general:col.inactive_border ${rgba(hyprland.inactiveBorder.value)}`,
|
||||
`decoration:rounding ${radius}`,
|
||||
`decoration:drop_shadow ${shadows.value ? "yes" : "no"}`,
|
||||
`dwindle:no_gaps_when_only ${hyprland.gapsWhenOnly.value ? 0 : 1}`,
|
||||
`master:no_gaps_when_only ${hyprland.gapsWhenOnly.value ? 0 : 1}`,
|
||||
])
|
||||
|
||||
await sendBatch(App.windows.map(({ name }) => `layerrule unset, ${name}`))
|
||||
|
||||
if (blur.value > 0) {
|
||||
sendBatch(App.windows.flatMap(({ name }) => [
|
||||
`layerrule unset, ${name}`,
|
||||
`layerrule blur, ${name}`,
|
||||
`layerrule ignorealpha ${/* based on shadow color */.29}, ${name}`,
|
||||
]))
|
||||
}
|
||||
}
|
||||
|
||||
export default function init() {
|
||||
options.handler(deps, setupHyprland)
|
||||
setupHyprland()
|
||||
}
|
|
@ -1,145 +0,0 @@
|
|||
export const substitutes = {
|
||||
"transmission-gtk": "transmission",
|
||||
"blueberry.py": "blueberry",
|
||||
"Caprine": "facebook-messenger",
|
||||
"com.raggesilver.BlackBox-symbolic": "terminal-symbolic",
|
||||
"org.wezfurlong.wezterm-symbolic": "terminal-symbolic",
|
||||
"audio-headset-bluetooth": "audio-headphones-symbolic",
|
||||
"audio-card-analog-usb": "audio-speakers-symbolic",
|
||||
"audio-card-analog-pci": "audio-card-symbolic",
|
||||
"preferences-system": "emblem-system-symbolic",
|
||||
"com.github.Aylur.ags-symbolic": "controls-symbolic",
|
||||
"com.github.Aylur.ags": "controls-symbolic",
|
||||
}
|
||||
|
||||
export default {
|
||||
missing: "image-missing-symbolic",
|
||||
nix: {
|
||||
nix: "nix-snowflake-symbolic",
|
||||
},
|
||||
app: {
|
||||
terminal: "terminal-symbolic",
|
||||
},
|
||||
fallback: {
|
||||
executable: "application-x-executable",
|
||||
notification: "dialog-information-symbolic",
|
||||
video: "video-x-generic-symbolic",
|
||||
audio: "audio-x-generic-symbolic",
|
||||
},
|
||||
ui: {
|
||||
close: "window-close-symbolic",
|
||||
colorpicker: "color-select-symbolic",
|
||||
info: "info-symbolic",
|
||||
link: "external-link-symbolic",
|
||||
lock: "system-lock-screen-symbolic",
|
||||
menu: "open-menu-symbolic",
|
||||
refresh: "view-refresh-symbolic",
|
||||
search: "system-search-symbolic",
|
||||
settings: "emblem-system-symbolic",
|
||||
themes: "preferences-desktop-theme-symbolic",
|
||||
tick: "object-select-symbolic",
|
||||
time: "hourglass-symbolic",
|
||||
toolbars: "toolbars-symbolic",
|
||||
warning: "dialog-warning-symbolic",
|
||||
avatar: "avatar-default-symbolic",
|
||||
arrow: {
|
||||
right: "pan-end-symbolic",
|
||||
left: "pan-start-symbolic",
|
||||
down: "pan-down-symbolic",
|
||||
up: "pan-up-symbolic",
|
||||
},
|
||||
},
|
||||
audio: {
|
||||
mic: {
|
||||
muted: "microphone-disabled-symbolic",
|
||||
low: "microphone-sensitivity-low-symbolic",
|
||||
medium: "microphone-sensitivity-medium-symbolic",
|
||||
high: "microphone-sensitivity-high-symbolic",
|
||||
},
|
||||
volume: {
|
||||
muted: "audio-volume-muted-symbolic",
|
||||
low: "audio-volume-low-symbolic",
|
||||
medium: "audio-volume-medium-symbolic",
|
||||
high: "audio-volume-high-symbolic",
|
||||
overamplified: "audio-volume-overamplified-symbolic",
|
||||
},
|
||||
type: {
|
||||
headset: "audio-headphones-symbolic",
|
||||
speaker: "audio-speakers-symbolic",
|
||||
card: "audio-card-symbolic",
|
||||
},
|
||||
mixer: "mixer-symbolic",
|
||||
},
|
||||
powerprofile: {
|
||||
balanced: "power-profile-balanced-symbolic",
|
||||
"power-saver": "power-profile-power-saver-symbolic",
|
||||
performance: "power-profile-performance-symbolic",
|
||||
},
|
||||
asusctl: {
|
||||
profile: {
|
||||
Balanced: "power-profile-balanced-symbolic",
|
||||
Quiet: "power-profile-power-saver-symbolic",
|
||||
Performance: "power-profile-performance-symbolic",
|
||||
},
|
||||
mode: {
|
||||
Integrated: "processor-symbolic",
|
||||
Hybrid: "controller-symbolic",
|
||||
},
|
||||
},
|
||||
battery: {
|
||||
charging: "battery-flash-symbolic",
|
||||
warning: "battery-empty-symbolic",
|
||||
},
|
||||
bluetooth: {
|
||||
enabled: "bluetooth-active-symbolic",
|
||||
disabled: "bluetooth-disabled-symbolic",
|
||||
},
|
||||
brightness: {
|
||||
indicator: "display-brightness-symbolic",
|
||||
keyboard: "keyboard-brightness-symbolic",
|
||||
screen: "display-brightness-symbolic",
|
||||
},
|
||||
powermenu: {
|
||||
sleep: "weather-clear-night-symbolic",
|
||||
reboot: "system-reboot-symbolic",
|
||||
logout: "system-log-out-symbolic",
|
||||
shutdown: "system-shutdown-symbolic",
|
||||
},
|
||||
recorder: {
|
||||
recording: "media-record-symbolic",
|
||||
},
|
||||
notifications: {
|
||||
noisy: "org.gnome.Settings-notifications-symbolic",
|
||||
silent: "notifications-disabled-symbolic",
|
||||
message: "chat-bubbles-symbolic",
|
||||
},
|
||||
trash: {
|
||||
full: "user-trash-full-symbolic",
|
||||
empty: "user-trash-symbolic",
|
||||
},
|
||||
mpris: {
|
||||
shuffle: {
|
||||
enabled: "media-playlist-shuffle-symbolic",
|
||||
disabled: "media-playlist-consecutive-symbolic",
|
||||
},
|
||||
loop: {
|
||||
none: "media-playlist-repeat-symbolic",
|
||||
track: "media-playlist-repeat-song-symbolic",
|
||||
playlist: "media-playlist-repeat-symbolic",
|
||||
},
|
||||
playing: "media-playback-pause-symbolic",
|
||||
paused: "media-playback-start-symbolic",
|
||||
stopped: "media-playback-start-symbolic",
|
||||
prev: "media-skip-backward-symbolic",
|
||||
next: "media-skip-forward-symbolic",
|
||||
},
|
||||
system: {
|
||||
cpu: "org.gnome.SystemMonitor-symbolic",
|
||||
ram: "drive-harddisk-solidstate-symbolic",
|
||||
temp: "temperature-symbolic",
|
||||
},
|
||||
color: {
|
||||
dark: "dark-mode-symbolic",
|
||||
light: "light-mode-symbolic",
|
||||
},
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
import matugen from "./matugen"
|
||||
import hyprland from "./hyprland"
|
||||
import tmux from "./tmux"
|
||||
import gtk from "./gtk"
|
||||
import lowBattery from "./battery"
|
||||
import notifications from "./notifications"
|
||||
|
||||
export default function init() {
|
||||
try {
|
||||
gtk()
|
||||
tmux()
|
||||
matugen()
|
||||
lowBattery()
|
||||
notifications()
|
||||
hyprland()
|
||||
} catch (error) {
|
||||
logError(error)
|
||||
}
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
import wallpaper from "service/wallpaper"
|
||||
import options from "options"
|
||||
import { sh, dependencies } from "./utils"
|
||||
|
||||
export default function init() {
|
||||
wallpaper.connect("changed", () => matugen())
|
||||
options.autotheme.connect("changed", () => matugen())
|
||||
}
|
||||
|
||||
function animate(...setters: Array<() => void>) {
|
||||
const delay = options.transition.value / 2
|
||||
setters.forEach((fn, i) => Utils.timeout(delay * i, fn))
|
||||
}
|
||||
|
||||
export async function matugen(
|
||||
type: "image" | "color" = "image",
|
||||
arg = wallpaper.wallpaper,
|
||||
) {
|
||||
if (!options.autotheme.value || !dependencies("matugen"))
|
||||
return
|
||||
|
||||
const colors = await sh(`matugen --dry-run -j hex ${type} ${arg}`)
|
||||
const c = JSON.parse(colors).colors as { light: Colors, dark: Colors }
|
||||
const { dark, light } = options.theme
|
||||
|
||||
animate(
|
||||
() => {
|
||||
dark.widget.value = c.dark.on_surface
|
||||
light.widget.value = c.light.on_surface
|
||||
},
|
||||
() => {
|
||||
dark.border.value = c.dark.outline
|
||||
light.border.value = c.light.outline
|
||||
},
|
||||
() => {
|
||||
dark.bg.value = c.dark.surface
|
||||
light.bg.value = c.light.surface
|
||||
},
|
||||
() => {
|
||||
dark.fg.value = c.dark.on_surface
|
||||
light.fg.value = c.light.on_surface
|
||||
},
|
||||
() => {
|
||||
dark.primary.bg.value = c.dark.primary
|
||||
light.primary.bg.value = c.light.primary
|
||||
options.bar.battery.charging.value = options.theme.scheme.value === "dark"
|
||||
? c.dark.primary : c.light.primary
|
||||
},
|
||||
() => {
|
||||
dark.primary.fg.value = c.dark.on_primary
|
||||
light.primary.fg.value = c.light.on_primary
|
||||
},
|
||||
() => {
|
||||
dark.error.bg.value = c.dark.error
|
||||
light.error.bg.value = c.light.error
|
||||
},
|
||||
() => {
|
||||
dark.error.fg.value = c.dark.on_error
|
||||
light.error.fg.value = c.light.on_error
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
type Colors = {
|
||||
background: string
|
||||
error: string
|
||||
error_container: string
|
||||
inverse_on_surface: string
|
||||
inverse_primary: string
|
||||
inverse_surface: string
|
||||
on_background: string
|
||||
on_error: string
|
||||
on_error_container: string
|
||||
on_primary: string
|
||||
on_primary_container: string
|
||||
on_primary_fixed: string
|
||||
on_primary_fixed_variant: string
|
||||
on_secondary: string
|
||||
on_secondary_container: string
|
||||
on_secondary_fixed: string
|
||||
on_secondary_fixed_variant: string
|
||||
on_surface: string
|
||||
on_surface_variant: string
|
||||
on_tertiary: string
|
||||
on_tertiary_container: string
|
||||
on_tertiary_fixed: string
|
||||
on_tertiary_fixed_variant: string
|
||||
outline: string
|
||||
outline_variant: string
|
||||
primary: string
|
||||
primary_container: string
|
||||
primary_fixed: string
|
||||
primary_fixed_dim: string
|
||||
scrim: string
|
||||
secondary: string
|
||||
secondary_container: string
|
||||
secondary_fixed: string
|
||||
secondary_fixed_dim: string
|
||||
shadow: string
|
||||
surface: string
|
||||
surface_bright: string
|
||||
surface_container: string
|
||||
surface_container_high: string
|
||||
surface_container_highest: string
|
||||
surface_container_low: string
|
||||
surface_container_lowest: string
|
||||
surface_dim: string
|
||||
surface_variant: string
|
||||
tertiary: string
|
||||
tertiary_container: string
|
||||
tertiary_fixed: string
|
||||
tertiary_fixed_dim: string
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
import options from "options"
|
||||
const notifs = await Service.import("notifications")
|
||||
|
||||
// TODO: consider adding this to upstream
|
||||
|
||||
const { blacklist } = options.notifications
|
||||
|
||||
export default function init() {
|
||||
const notify = notifs.constructor.prototype.Notify.bind(notifs)
|
||||
notifs.constructor.prototype.Notify = function(appName: string, ...rest: unknown[]) {
|
||||
if (blacklist.value.includes(appName))
|
||||
return Number.MAX_SAFE_INTEGER
|
||||
|
||||
return notify(appName, ...rest)
|
||||
}
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
import { Variable } from "resource:///com/github/Aylur/ags/variable.js"
|
||||
|
||||
type OptProps = {
|
||||
persistent?: boolean
|
||||
}
|
||||
|
||||
export class Opt<T = unknown> extends Variable<T> {
|
||||
static { Service.register(this) }
|
||||
|
||||
constructor(initial: T, { persistent = false }: OptProps = {}) {
|
||||
super(initial)
|
||||
this.initial = initial
|
||||
this.persistent = persistent
|
||||
}
|
||||
|
||||
initial: T
|
||||
id = ""
|
||||
persistent: boolean
|
||||
toString() { return `${this.value}` }
|
||||
toJSON() { return `opt:${this.value}` }
|
||||
|
||||
getValue = (): T => {
|
||||
return super.getValue()
|
||||
}
|
||||
|
||||
init(cacheFile: string) {
|
||||
const cacheV = JSON.parse(Utils.readFile(cacheFile) || "{}")[this.id]
|
||||
if (cacheV !== undefined)
|
||||
this.value = cacheV
|
||||
|
||||
this.connect("changed", () => {
|
||||
const cache = JSON.parse(Utils.readFile(cacheFile) || "{}")
|
||||
cache[this.id] = this.value
|
||||
Utils.writeFileSync(JSON.stringify(cache, null, 2), cacheFile)
|
||||
})
|
||||
}
|
||||
|
||||
reset() {
|
||||
if (this.persistent)
|
||||
return
|
||||
|
||||
if (JSON.stringify(this.value) !== JSON.stringify(this.initial)) {
|
||||
this.value = this.initial
|
||||
return this.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const opt = <T>(initial: T, opts?: OptProps) => new Opt(initial, opts)
|
||||
|
||||
function getOptions(object: object, path = ""): Opt[] {
|
||||
return Object.keys(object).flatMap(key => {
|
||||
const obj: Opt = object[key]
|
||||
const id = path ? path + "." + key : key
|
||||
|
||||
if (obj instanceof Variable) {
|
||||
obj.id = id
|
||||
return obj
|
||||
}
|
||||
|
||||
if (typeof obj === "object")
|
||||
return getOptions(obj, id)
|
||||
|
||||
return []
|
||||
})
|
||||
}
|
||||
|
||||
export function mkOptions<T extends object>(cacheFile: string, object: T) {
|
||||
for (const opt of getOptions(object))
|
||||
opt.init(cacheFile)
|
||||
|
||||
Utils.ensureDirectory(cacheFile.split("/").slice(0, -1).join("/"))
|
||||
|
||||
const configFile = `${TMP}/config.json`
|
||||
const values = getOptions(object).reduce((obj, { id, value }) => ({ [id]: value, ...obj }), {})
|
||||
Utils.writeFileSync(JSON.stringify(values, null, 2), configFile)
|
||||
Utils.monitorFile(configFile, () => {
|
||||
const cache = JSON.parse(Utils.readFile(configFile) || "{}")
|
||||
for (const opt of getOptions(object)) {
|
||||
if (JSON.stringify(cache[opt.id]) !== JSON.stringify(opt.value))
|
||||
opt.value = cache[opt.id]
|
||||
}
|
||||
})
|
||||
|
||||
function sleep(ms = 0) {
|
||||
return new Promise(r => setTimeout(r, ms))
|
||||
}
|
||||
|
||||
async function reset(
|
||||
[opt, ...list] = getOptions(object),
|
||||
id = opt?.reset(),
|
||||
): Promise<Array<string>> {
|
||||
if (!opt)
|
||||
return sleep().then(() => [])
|
||||
|
||||
return id
|
||||
? [id, ...(await sleep(50).then(() => reset(list)))]
|
||||
: await sleep().then(() => reset(list))
|
||||
}
|
||||
|
||||
return Object.assign(object, {
|
||||
configFile,
|
||||
array: () => getOptions(object),
|
||||
async reset() {
|
||||
return (await reset()).join("\n")
|
||||
},
|
||||
handler(deps: string[], callback: () => void) {
|
||||
for (const opt of getOptions(object)) {
|
||||
if (deps.some(i => opt.id.startsWith(i)))
|
||||
opt.connect("changed", callback)
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
import GLib from "gi://GLib?version=2.0"
|
||||
|
||||
declare global {
|
||||
const OPTIONS: string
|
||||
const TMP: string
|
||||
const USER: string
|
||||
}
|
||||
|
||||
Object.assign(globalThis, {
|
||||
OPTIONS: `${GLib.get_user_cache_dir()}/ags/options.json`,
|
||||
TMP: `${GLib.get_tmp_dir()}/asztal`,
|
||||
USER: GLib.get_user_name(),
|
||||
})
|
||||
|
||||
Utils.ensureDirectory(TMP)
|
||||
App.addIcons(`${App.configDir}/assets`)
|
|
@ -1,14 +0,0 @@
|
|||
import options from "options"
|
||||
import { sh } from "./utils"
|
||||
|
||||
export async function tmux() {
|
||||
const { scheme, dark, light } = options.theme
|
||||
const hex = scheme.value === "dark" ? dark.primary.bg.value : light.primary.bg.value
|
||||
if (await sh("which tmux").catch(() => false))
|
||||
sh(`tmux set @main_accent "${hex}"`)
|
||||
}
|
||||
|
||||
export default function init() {
|
||||
options.theme.dark.primary.bg.connect("changed", tmux)
|
||||
options.theme.light.primary.bg.connect("changed", tmux)
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { type Application } from "types/service/applications"
|
||||
import icons, { substitutes } from "./icons"
|
||||
import Gtk from "gi://Gtk?version=3.0"
|
||||
import Gdk from "gi://Gdk"
|
||||
import GLib from "gi://GLib?version=2.0"
|
||||
|
||||
export type Binding<T> = import("types/service").Binding<any, any, T>
|
||||
|
||||
/**
|
||||
* @returns substitute icon || name || fallback icon
|
||||
*/
|
||||
export function icon(name: string | null, fallback = icons.missing) {
|
||||
if (!name)
|
||||
return fallback || ""
|
||||
|
||||
if (GLib.file_test(name, GLib.FileTest.EXISTS))
|
||||
return name
|
||||
|
||||
const icon = (substitutes[name] || name)
|
||||
if (Utils.lookUpIcon(icon))
|
||||
return icon
|
||||
|
||||
print(`no icon substitute "${icon}" for "${name}", fallback: "${fallback}"`)
|
||||
return fallback
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns execAsync(["bash", "-c", cmd])
|
||||
*/
|
||||
export async function bash(strings: TemplateStringsArray | string, ...values: unknown[]) {
|
||||
const cmd = typeof strings === "string" ? strings : strings
|
||||
.flatMap((str, i) => str + `${values[i] ?? ""}`)
|
||||
.join("")
|
||||
|
||||
return Utils.execAsync(["bash", "-c", cmd]).catch(err => {
|
||||
console.error(cmd, err)
|
||||
return ""
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns execAsync(cmd)
|
||||
*/
|
||||
export async function sh(cmd: string | string[]) {
|
||||
return Utils.execAsync(cmd).catch(err => {
|
||||
console.error(typeof cmd === "string" ? cmd : cmd.join(" "), err)
|
||||
return ""
|
||||
})
|
||||
}
|
||||
|
||||
export function forMonitors(widget: (monitor: number) => Gtk.Window) {
|
||||
const n = Gdk.Display.get_default()?.get_n_monitors() || 1
|
||||
return range(n, 0).flatMap(widget)
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns [start...length]
|
||||
*/
|
||||
export function range(length: number, start = 1) {
|
||||
return Array.from({ length }, (_, i) => i + start)
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns true if all of the `bins` are found
|
||||
*/
|
||||
export function dependencies(...bins: string[]) {
|
||||
const missing = bins.filter(bin => Utils.exec({
|
||||
cmd: `which ${bin}`,
|
||||
out: () => false,
|
||||
err: () => true,
|
||||
}))
|
||||
|
||||
if (missing.length > 0) {
|
||||
console.warn(Error(`missing dependencies: ${missing.join(", ")}`))
|
||||
Utils.notify(`missing dependencies: ${missing.join(", ")}`)
|
||||
}
|
||||
|
||||
return missing.length === 0
|
||||
}
|
||||
|
||||
/**
|
||||
* run app detached
|
||||
*/
|
||||
export function launchApp(app: Application) {
|
||||
const exe = app.executable
|
||||
.split(/\s+/)
|
||||
.filter(str => !str.startsWith("%") && !str.startsWith("@"))
|
||||
.join(" ")
|
||||
|
||||
bash(`${exe} &`)
|
||||
app.frequency += 1
|
||||
}
|
||||
|
||||
/**
|
||||
* to use with drag and drop
|
||||
*/
|
||||
export function createSurfaceFromWidget(widget: Gtk.Widget) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const cairo = imports.gi.cairo as any
|
||||
const alloc = widget.get_allocation()
|
||||
const surface = new cairo.ImageSurface(
|
||||
cairo.Format.ARGB32,
|
||||
alloc.width,
|
||||
alloc.height,
|
||||
)
|
||||
const cr = new cairo.Context(surface)
|
||||
cr.setSourceRGBA(255, 255, 255, 0)
|
||||
cr.rectangle(0, 0, alloc.width, alloc.height)
|
||||
cr.fill()
|
||||
widget.draw(cr)
|
||||
return surface
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
import GLib from "gi://GLib"
|
||||
// import options from "options"
|
||||
//
|
||||
// const intval = options.system.fetchInterval.value
|
||||
// const tempPath = options.system.temperature.value
|
||||
|
||||
export const clock = Variable(GLib.DateTime.new_now_local(), {
|
||||
poll: [1000, () => GLib.DateTime.new_now_local()],
|
||||
})
|
||||
|
||||
export const uptime = Variable(0, {
|
||||
poll: [60_000, "cat /proc/uptime", line =>
|
||||
Number.parseInt(line.split(".")[0]) / 60,
|
||||
],
|
||||
})
|
||||
|
||||
export const distro = {
|
||||
id: GLib.get_os_info("ID"),
|
||||
logo: GLib.get_os_info("LOGO"),
|
||||
}
|
||||
|
||||
// const divide = ([total, free]: string[]) => Number.parseInt(free) / Number.parseInt(total)
|
||||
//
|
||||
// export const cpu = Variable(0, {
|
||||
// poll: [intval, "top -b -n 1", out => divide(["100", out.split("\n")
|
||||
// .find(line => line.includes("Cpu(s)"))
|
||||
// ?.split(/\s+/)[1]
|
||||
// .replace(",", ".") || "0"])],
|
||||
// })
|
||||
//
|
||||
// export const ram = Variable(0, {
|
||||
// poll: [intval, "free", out => divide(out.split("\n")
|
||||
// .find(line => line.includes("Mem:"))
|
||||
// ?.split(/\s+/)
|
||||
// .splice(1, 2) || ["1", "1"])],
|
||||
// })
|
||||
//
|
||||
// export const temperature = Variable(0, {
|
||||
// poll: [intval, `cat ${tempPath}`, n => {
|
||||
// return Number.parseInt(n) / 100_000
|
||||
// }],
|
||||
// })
|
|
@ -1,41 +0,0 @@
|
|||
import "lib/session"
|
||||
import "style/style"
|
||||
import init from "lib/init"
|
||||
import options from "options"
|
||||
import Bar from "widget/bar/Bar"
|
||||
import Launcher from "widget/launcher/Launcher"
|
||||
import NotificationPopups from "widget/notifications/NotificationPopups"
|
||||
import OSD from "widget/osd/OSD"
|
||||
import Overview from "widget/overview/Overview"
|
||||
import PowerMenu from "widget/powermenu/PowerMenu"
|
||||
import ScreenCorners from "widget/bar/ScreenCorners"
|
||||
import SettingsDialog from "widget/settings/SettingsDialog"
|
||||
import Verification from "widget/powermenu/Verification"
|
||||
import { forMonitors } from "lib/utils"
|
||||
import { setupQuickSettings } from "widget/quicksettings/QuickSettings"
|
||||
import { setupDateMenu } from "widget/datemenu/DateMenu"
|
||||
|
||||
App.config({
|
||||
onConfigParsed: () => {
|
||||
setupQuickSettings()
|
||||
setupDateMenu()
|
||||
init()
|
||||
},
|
||||
closeWindowDelay: {
|
||||
"launcher": options.transition.value,
|
||||
"overview": options.transition.value,
|
||||
"quicksettings": options.transition.value,
|
||||
"datemenu": options.transition.value,
|
||||
},
|
||||
windows: () => [
|
||||
...forMonitors(Bar),
|
||||
...forMonitors(NotificationPopups),
|
||||
...forMonitors(ScreenCorners),
|
||||
...forMonitors(OSD),
|
||||
Launcher(),
|
||||
Overview(),
|
||||
PowerMenu(),
|
||||
SettingsDialog(),
|
||||
Verification(),
|
||||
],
|
||||
})
|
|
@ -1,243 +0,0 @@
|
|||
import { opt, mkOptions } from "lib/option"
|
||||
import { distro } from "lib/variables"
|
||||
import { icon } from "lib/utils"
|
||||
import icons from "lib/icons"
|
||||
|
||||
const options = mkOptions(OPTIONS, {
|
||||
autotheme: opt(false),
|
||||
|
||||
wallpaper: {
|
||||
resolution: opt<import("service/wallpaper").Resolution>(1920),
|
||||
market: opt<import("service/wallpaper").Market>("random"),
|
||||
},
|
||||
|
||||
theme: {
|
||||
dark: {
|
||||
primary: {
|
||||
bg: opt("#51a4e7"),
|
||||
fg: opt("#141414"),
|
||||
},
|
||||
error: {
|
||||
bg: opt("#e55f86"),
|
||||
fg: opt("#141414"),
|
||||
},
|
||||
bg: opt("#171717"),
|
||||
fg: opt("#eeeeee"),
|
||||
widget: opt("#eeeeee"),
|
||||
border: opt("#eeeeee"),
|
||||
},
|
||||
light: {
|
||||
primary: {
|
||||
bg: opt("#426ede"),
|
||||
fg: opt("#eeeeee"),
|
||||
},
|
||||
error: {
|
||||
bg: opt("#b13558"),
|
||||
fg: opt("#eeeeee"),
|
||||
},
|
||||
bg: opt("#fffffa"),
|
||||
fg: opt("#080808"),
|
||||
widget: opt("#080808"),
|
||||
border: opt("#080808"),
|
||||
},
|
||||
|
||||
blur: opt(0),
|
||||
scheme: opt<"dark" | "light">("dark"),
|
||||
widget: { opacity: opt(94) },
|
||||
border: {
|
||||
width: opt(1),
|
||||
opacity: opt(96),
|
||||
},
|
||||
|
||||
shadows: opt(true),
|
||||
padding: opt(7),
|
||||
spacing: opt(12),
|
||||
radius: opt(11),
|
||||
},
|
||||
|
||||
transition: opt(200),
|
||||
|
||||
font: {
|
||||
size: opt(13),
|
||||
name: opt("Ubuntu Nerd Font"),
|
||||
},
|
||||
|
||||
bar: {
|
||||
flatButtons: opt(true),
|
||||
position: opt<"top" | "bottom">("top"),
|
||||
corners: opt(50),
|
||||
transparent: opt(false),
|
||||
layout: {
|
||||
start: opt<Array<import("widget/bar/Bar").BarWidget>>([
|
||||
"launcher",
|
||||
"workspaces",
|
||||
"taskbar",
|
||||
"expander",
|
||||
"messages",
|
||||
]),
|
||||
center: opt<Array<import("widget/bar/Bar").BarWidget>>([
|
||||
"date",
|
||||
]),
|
||||
end: opt<Array<import("widget/bar/Bar").BarWidget>>([
|
||||
"media",
|
||||
"expander",
|
||||
"systray",
|
||||
"colorpicker",
|
||||
"screenrecord",
|
||||
"system",
|
||||
"battery",
|
||||
"powermenu",
|
||||
]),
|
||||
},
|
||||
launcher: {
|
||||
icon: {
|
||||
colored: opt(true),
|
||||
icon: opt(icon(distro.logo, icons.ui.search)),
|
||||
},
|
||||
label: {
|
||||
colored: opt(false),
|
||||
label: opt(" Applications"),
|
||||
},
|
||||
action: opt(() => App.toggleWindow("launcher")),
|
||||
},
|
||||
date: {
|
||||
format: opt("%H:%M - %A %e."),
|
||||
action: opt(() => App.toggleWindow("datemenu")),
|
||||
},
|
||||
battery: {
|
||||
bar: opt<"hidden" | "regular" | "whole">("regular"),
|
||||
charging: opt("#00D787"),
|
||||
percentage: opt(true),
|
||||
blocks: opt(7),
|
||||
width: opt(50),
|
||||
low: opt(30),
|
||||
},
|
||||
workspaces: {
|
||||
workspaces: opt(7),
|
||||
},
|
||||
taskbar: {
|
||||
iconSize: opt(0),
|
||||
monochrome: opt(true),
|
||||
exclusive: opt(false),
|
||||
},
|
||||
messages: {
|
||||
action: opt(() => App.toggleWindow("datemenu")),
|
||||
},
|
||||
systray: {
|
||||
ignore: opt([
|
||||
"KDE Connect Indicator",
|
||||
"spotify-client",
|
||||
]),
|
||||
},
|
||||
media: {
|
||||
monochrome: opt(true),
|
||||
preferred: opt("spotify"),
|
||||
direction: opt<"left" | "right">("right"),
|
||||
format: opt("{artists} - {title}"),
|
||||
length: opt(40),
|
||||
},
|
||||
powermenu: {
|
||||
monochrome: opt(false),
|
||||
action: opt(() => App.toggleWindow("powermenu")),
|
||||
},
|
||||
},
|
||||
|
||||
launcher: {
|
||||
width: opt(0),
|
||||
margin: opt(80),
|
||||
nix: {
|
||||
pkgs: opt("nixpkgs/nixos-unstable"),
|
||||
max: opt(8),
|
||||
},
|
||||
sh: {
|
||||
max: opt(16),
|
||||
},
|
||||
apps: {
|
||||
iconSize: opt(62),
|
||||
max: opt(6),
|
||||
favorites: opt([
|
||||
[
|
||||
"firefox",
|
||||
"wezterm",
|
||||
"org.gnome.Nautilus",
|
||||
"org.gnome.Calendar",
|
||||
"spotify",
|
||||
],
|
||||
]),
|
||||
},
|
||||
},
|
||||
|
||||
overview: {
|
||||
scale: opt(9),
|
||||
workspaces: opt(7),
|
||||
monochromeIcon: opt(true),
|
||||
},
|
||||
|
||||
powermenu: {
|
||||
sleep: opt("systemctl suspend"),
|
||||
reboot: opt("systemctl reboot"),
|
||||
logout: opt("pkill Hyprland"),
|
||||
shutdown: opt("shutdown now"),
|
||||
layout: opt<"line" | "box">("line"),
|
||||
labels: opt(true),
|
||||
},
|
||||
|
||||
quicksettings: {
|
||||
avatar: {
|
||||
image: opt(`/var/lib/AccountsService/icons/${Utils.USER}`),
|
||||
size: opt(70),
|
||||
},
|
||||
width: opt(380),
|
||||
position: opt<"left" | "center" | "right">("right"),
|
||||
networkSettings: opt("gtk-launch gnome-control-center"),
|
||||
media: {
|
||||
monochromeIcon: opt(true),
|
||||
coverSize: opt(100),
|
||||
},
|
||||
},
|
||||
|
||||
datemenu: {
|
||||
position: opt<"left" | "center" | "right">("center"),
|
||||
weather: {
|
||||
interval: opt(60_000),
|
||||
unit: opt<"metric" | "imperial" | "standard">("metric"),
|
||||
key: opt<string>(
|
||||
JSON.parse(Utils.readFile(`${App.configDir}/.weather`) || "{}")?.key || "",
|
||||
),
|
||||
cities: opt<Array<number>>(
|
||||
JSON.parse(Utils.readFile(`${App.configDir}/.weather`) || "{}")?.cities || [],
|
||||
),
|
||||
},
|
||||
},
|
||||
|
||||
osd: {
|
||||
progress: {
|
||||
vertical: opt(true),
|
||||
pack: {
|
||||
h: opt<"start" | "center" | "end">("end"),
|
||||
v: opt<"start" | "center" | "end">("center"),
|
||||
},
|
||||
},
|
||||
microphone: {
|
||||
pack: {
|
||||
h: opt<"start" | "center" | "end">("center"),
|
||||
v: opt<"start" | "center" | "end">("end"),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
notifications: {
|
||||
position: opt<Array<"top" | "bottom" | "left" | "right">>(["top", "right"]),
|
||||
blacklist: opt(["Spotify"]),
|
||||
width: opt(440),
|
||||
},
|
||||
|
||||
hyprland: {
|
||||
gaps: opt(2.4),
|
||||
inactiveBorder: opt("#282828"),
|
||||
gapsWhenOnly: opt(false),
|
||||
},
|
||||
})
|
||||
|
||||
globalThis["options"] = options
|
||||
export default options
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"name": "ags-dotfiles",
|
||||
"author": "Aylur",
|
||||
"kofi": "https://ko-fi.com/aylur",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/Aylur/dotfiles.git"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@girs/accountsservice-1.0": "^1.0.0-3.2.7",
|
||||
"@typescript-eslint/eslint-plugin": "^6.20.0",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-standard-with-typescript": "^43.0.1",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-n": "^16.6.2",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
import { sh } from "lib/utils"
|
||||
|
||||
type Profile = "Performance" | "Balanced" | "Quiet"
|
||||
type Mode = "Hybrid" | "Integrated"
|
||||
|
||||
class Asusctl extends Service {
|
||||
static {
|
||||
Service.register(this, {}, {
|
||||
"profile": ["string", "r"],
|
||||
"mode": ["string", "r"],
|
||||
})
|
||||
}
|
||||
|
||||
get available() {
|
||||
return Utils.exec("which asusctl", () => true, () => false)
|
||||
}
|
||||
|
||||
#profile: Profile = "Balanced"
|
||||
#mode: Mode = "Hybrid"
|
||||
|
||||
async nextProfile() {
|
||||
await sh("asusctl profile -n")
|
||||
const profile = await sh("asusctl profile -p")
|
||||
const p = profile.split(" ")[3] as Profile
|
||||
this.#profile = p
|
||||
this.changed("profile")
|
||||
}
|
||||
|
||||
async setProfile(prof: Profile) {
|
||||
await sh(`asusctl profile --profile-set ${prof}`)
|
||||
this.#profile = prof
|
||||
this.changed("profile")
|
||||
}
|
||||
|
||||
async nextMode() {
|
||||
await sh(`supergfxctl -m ${this.#mode === "Hybrid" ? "Integrated" : "Hybrid"}`)
|
||||
this.#mode = await sh("supergfxctl -g") as Mode
|
||||
this.changed("profile")
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
|
||||
if (this.available) {
|
||||
sh("asusctl profile -p").then(p => this.#profile = p.split(" ")[3] as Profile)
|
||||
sh("supergfxctl -g").then(m => this.#mode = m as Mode)
|
||||
}
|
||||
}
|
||||
|
||||
get profiles(): Profile[] { return ["Performance", "Balanced", "Quiet"] }
|
||||
get profile() { return this.#profile }
|
||||
get mode() { return this.#mode }
|
||||
}
|
||||
|
||||
export default new Asusctl
|
|
@ -1,69 +0,0 @@
|
|||
import { bash, dependencies, sh } from "lib/utils"
|
||||
|
||||
if (!dependencies("brightnessctl"))
|
||||
App.quit()
|
||||
|
||||
const get = (args: string) => Number(Utils.exec(`brightnessctl ${args}`))
|
||||
const screen = await bash`ls -w1 /sys/class/backlight | head -1`
|
||||
const kbd = await bash`ls -w1 /sys/class/leds | head -1`
|
||||
|
||||
class Brightness extends Service {
|
||||
static {
|
||||
Service.register(this, {}, {
|
||||
"screen": ["float", "rw"],
|
||||
"kbd": ["int", "rw"],
|
||||
})
|
||||
}
|
||||
|
||||
#kbdMax = get(`--device ${kbd} max`)
|
||||
#kbd = get(`--device ${kbd} get`)
|
||||
#screenMax = get("max")
|
||||
#screen = get("get") / (get("max") || 1)
|
||||
|
||||
get kbd() { return this.#kbd }
|
||||
get screen() { return this.#screen }
|
||||
|
||||
set kbd(value) {
|
||||
if (value < 0 || value > this.#kbdMax)
|
||||
return
|
||||
|
||||
sh(`brightnessctl -d ${kbd} s ${value} -q`).then(() => {
|
||||
this.#kbd = value
|
||||
this.changed("kbd")
|
||||
})
|
||||
}
|
||||
|
||||
set screen(percent) {
|
||||
if (percent < 0)
|
||||
percent = 0
|
||||
|
||||
if (percent > 1)
|
||||
percent = 1
|
||||
|
||||
sh(`brightnessctl set ${Math.floor(percent * 100)}% -q`).then(() => {
|
||||
this.#screen = percent
|
||||
this.changed("screen")
|
||||
})
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
|
||||
const screenPath = `/sys/class/backlight/${screen}/brightness`
|
||||
const kbdPath = `/sys/class/leds/${kbd}/brightness`
|
||||
|
||||
Utils.monitorFile(screenPath, async f => {
|
||||
const v = await Utils.readFileAsync(f)
|
||||
this.#screen = Number(v) / this.#screenMax
|
||||
this.changed("screen")
|
||||
})
|
||||
|
||||
Utils.monitorFile(kbdPath, async f => {
|
||||
const v = await Utils.readFileAsync(f)
|
||||
this.#kbd = Number(v) / this.#kbdMax
|
||||
this.changed("kbd")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default new Brightness
|
|
@ -1,56 +0,0 @@
|
|||
import icons from "lib/icons"
|
||||
import { bash, dependencies } from "lib/utils"
|
||||
|
||||
const COLORS_CACHE = Utils.CACHE_DIR + "/colorpicker.json"
|
||||
const MAX_NUM_COLORS = 10
|
||||
|
||||
class ColorPicker extends Service {
|
||||
static {
|
||||
Service.register(this, {}, {
|
||||
"colors": ["jsobject"],
|
||||
})
|
||||
}
|
||||
|
||||
#notifID = 0
|
||||
#colors = JSON.parse(Utils.readFile(COLORS_CACHE) || "[]") as string[]
|
||||
|
||||
get colors() { return [...this.#colors] }
|
||||
set colors(colors) {
|
||||
this.#colors = colors
|
||||
this.changed("colors")
|
||||
}
|
||||
|
||||
// TODO: doesn't work?
|
||||
async wlCopy(color: string) {
|
||||
if (dependencies("wl-copy"))
|
||||
bash(`wl-copy ${color}`)
|
||||
}
|
||||
|
||||
readonly pick = async () => {
|
||||
if (!dependencies("hyprpicker"))
|
||||
return
|
||||
|
||||
const color = await bash("hyprpicker -a -r")
|
||||
if (!color)
|
||||
return
|
||||
|
||||
this.wlCopy(color)
|
||||
const list = this.colors
|
||||
if (!list.includes(color)) {
|
||||
list.push(color)
|
||||
if (list.length > MAX_NUM_COLORS)
|
||||
list.shift()
|
||||
|
||||
this.colors = list
|
||||
Utils.writeFile(JSON.stringify(list, null, 2), COLORS_CACHE)
|
||||
}
|
||||
|
||||
this.#notifID = await Utils.notify({
|
||||
id: this.#notifID,
|
||||
iconName: icons.ui.colorpicker,
|
||||
summary: color,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default new ColorPicker
|
|
@ -1,110 +0,0 @@
|
|||
import icons from "lib/icons"
|
||||
import { bash, dependencies } from "lib/utils"
|
||||
import options from "options"
|
||||
|
||||
const CACHE = `${Utils.CACHE_DIR}/nixpkgs`
|
||||
const PREFIX = "legacyPackages.x86_64-linux."
|
||||
const MAX = options.launcher.nix.max
|
||||
const nixpkgs = options.launcher.nix.pkgs
|
||||
|
||||
export type Nixpkg = {
|
||||
name: string
|
||||
description: string
|
||||
pname: string
|
||||
version: string
|
||||
}
|
||||
|
||||
class Nix extends Service {
|
||||
static {
|
||||
Service.register(this, {}, {
|
||||
"available": ["boolean", "r"],
|
||||
"ready": ["boolean", "rw"],
|
||||
})
|
||||
}
|
||||
|
||||
#db: { [name: string]: Nixpkg } = {}
|
||||
#ready = true
|
||||
|
||||
private set ready(r: boolean) {
|
||||
this.#ready = r
|
||||
this.changed("ready")
|
||||
}
|
||||
|
||||
get db() { return this.#db }
|
||||
get ready() { return this.#ready }
|
||||
get available() {
|
||||
return Utils.exec("which nix", () => true, () => false)
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
if (!this.available)
|
||||
return this
|
||||
|
||||
this.#updateList()
|
||||
nixpkgs.connect("changed", this.#updateList)
|
||||
}
|
||||
|
||||
query = async (filter: string) => {
|
||||
if (!dependencies("fzf", "nix") || !this.#ready)
|
||||
return [] as string[]
|
||||
|
||||
return bash(`cat ${CACHE} | fzf -f ${filter} -e | head -n ${MAX} `)
|
||||
.then(str => str.split("\n").filter(i => i))
|
||||
}
|
||||
|
||||
nix(cmd: string, bin: string, args: string) {
|
||||
return Utils.execAsync(`nix ${cmd} ${nixpkgs}#${bin} --impure ${args}`)
|
||||
}
|
||||
|
||||
run = async (input: string) => {
|
||||
if (!dependencies("nix"))
|
||||
return
|
||||
|
||||
try {
|
||||
const [bin, ...args] = input.trim().split(/\s+/)
|
||||
|
||||
this.ready = false
|
||||
await this.nix("shell", bin, "--command sh -c 'exit'")
|
||||
this.ready = true
|
||||
|
||||
this.nix("run", bin, ["--", ...args].join(" "))
|
||||
} catch (err) {
|
||||
if (typeof err === "string")
|
||||
Utils.notify("NixRun Error", err, icons.nix.nix)
|
||||
else
|
||||
logError(err)
|
||||
} finally {
|
||||
this.ready = true
|
||||
}
|
||||
}
|
||||
|
||||
#updateList = async () => {
|
||||
if (!dependencies("nix"))
|
||||
return
|
||||
|
||||
this.ready = false
|
||||
this.#db = {}
|
||||
|
||||
const search = await bash(`nix search ${nixpkgs} --json`)
|
||||
if (!search) {
|
||||
this.ready = true
|
||||
return
|
||||
}
|
||||
|
||||
const json = Object.entries(JSON.parse(search) as {
|
||||
[name: string]: Nixpkg
|
||||
})
|
||||
|
||||
for (const [pkg, info] of json) {
|
||||
const name = pkg.replace(PREFIX, "")
|
||||
this.#db[name] = { ...info, name }
|
||||
}
|
||||
|
||||
const list = Object.keys(this.#db).join("\n")
|
||||
await Utils.writeFile(list, CACHE)
|
||||
this.ready = true
|
||||
}
|
||||
}
|
||||
|
||||
export default new Nix
|
|
@ -1,47 +0,0 @@
|
|||
import options from "options"
|
||||
|
||||
const { sleep, reboot, logout, shutdown } = options.powermenu
|
||||
|
||||
export type Action = "sleep" | "reboot" | "logout" | "shutdown"
|
||||
|
||||
class PowerMenu extends Service {
|
||||
static {
|
||||
Service.register(this, {}, {
|
||||
"title": ["string"],
|
||||
"cmd": ["string"],
|
||||
})
|
||||
}
|
||||
|
||||
#title = ""
|
||||
#cmd = ""
|
||||
|
||||
get title() { return this.#title }
|
||||
|
||||
action(action: Action) {
|
||||
[this.#cmd, this.#title] = {
|
||||
sleep: [sleep.value, "Sleep"],
|
||||
reboot: [reboot.value, "Reboot"],
|
||||
logout: [logout.value, "Log Out"],
|
||||
shutdown: [shutdown.value, "Shutdown"],
|
||||
}[action]
|
||||
|
||||
this.notify("cmd")
|
||||
this.notify("title")
|
||||
this.emit("changed")
|
||||
App.closeWindow("powermenu")
|
||||
App.openWindow("verification")
|
||||
}
|
||||
|
||||
readonly shutdown = () => {
|
||||
this.action("shutdown")
|
||||
}
|
||||
|
||||
readonly exec = () => {
|
||||
App.closeWindow("verification")
|
||||
Utils.exec(this.#cmd)
|
||||
}
|
||||
}
|
||||
|
||||
const powermenu = new PowerMenu
|
||||
Object.assign(globalThis, { powermenu })
|
||||
export default powermenu
|
|
@ -1,102 +0,0 @@
|
|||
import GLib from "gi://GLib"
|
||||
import icons from "lib/icons"
|
||||
import { dependencies, sh, bash } from "lib/utils"
|
||||
|
||||
const now = () => GLib.DateTime.new_now_local().format("%Y-%m-%d_%H-%M-%S")
|
||||
|
||||
class Recorder extends Service {
|
||||
static {
|
||||
Service.register(this, {}, {
|
||||
"timer": ["int"],
|
||||
"recording": ["boolean"],
|
||||
})
|
||||
}
|
||||
|
||||
#recordings = Utils.HOME + "/Videos/Screencasting"
|
||||
#screenshots = Utils.HOME + "/Pictures/Screenshots"
|
||||
#file = ""
|
||||
#interval = 0
|
||||
|
||||
recording = false
|
||||
timer = 0
|
||||
|
||||
async start() {
|
||||
if (!dependencies("slurp", "wf-recorder"))
|
||||
return
|
||||
|
||||
if (this.recording)
|
||||
return
|
||||
|
||||
Utils.ensureDirectory(this.#recordings)
|
||||
this.#file = `${this.#recordings}/${now()}.mp4`
|
||||
sh(`wf-recorder -g "${await sh("slurp")}" -f ${this.#file} --pixel-format yuv420p`)
|
||||
|
||||
this.recording = true
|
||||
this.changed("recording")
|
||||
|
||||
this.timer = 0
|
||||
this.#interval = Utils.interval(1000, () => {
|
||||
this.changed("timer")
|
||||
this.timer++
|
||||
})
|
||||
}
|
||||
|
||||
async stop() {
|
||||
if (!this.recording)
|
||||
return
|
||||
|
||||
await bash("killall -INT wf-recorder")
|
||||
this.recording = false
|
||||
this.changed("recording")
|
||||
GLib.source_remove(this.#interval)
|
||||
|
||||
Utils.notify({
|
||||
iconName: icons.fallback.video,
|
||||
summary: "Screenrecord",
|
||||
body: this.#file,
|
||||
actions: {
|
||||
"Show in Files": () => sh(`xdg-open ${this.#recordings}`),
|
||||
"View": () => sh(`xdg-open ${this.#file}`),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async screenshot(full = false) {
|
||||
if (!dependencies("slurp", "wayshot"))
|
||||
return
|
||||
|
||||
const file = `${this.#screenshots}/${now()}.png`
|
||||
Utils.ensureDirectory(this.#screenshots)
|
||||
|
||||
if (full) {
|
||||
await sh(`wayshot -f ${file}`)
|
||||
}
|
||||
else {
|
||||
const size = await sh("slurp")
|
||||
if (!size)
|
||||
return
|
||||
|
||||
await sh(`wayshot -f ${file} -s "${size}"`)
|
||||
}
|
||||
|
||||
bash(`wl-copy < ${file}`)
|
||||
|
||||
Utils.notify({
|
||||
image: file,
|
||||
summary: "Screenshot",
|
||||
body: file,
|
||||
actions: {
|
||||
"Show in Files": () => sh(`xdg-open ${this.#screenshots}`),
|
||||
"View": () => sh(`xdg-open ${file}`),
|
||||
"Edit": () => {
|
||||
if (dependencies("swappy"))
|
||||
sh(`swappy -f ${file}`)
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const recorder = new Recorder
|
||||
Object.assign(globalThis, { recorder })
|
||||
export default recorder
|
|
@ -1,48 +0,0 @@
|
|||
import GLib from "gi://GLib?version=2.0"
|
||||
import { bash, dependencies } from "lib/utils"
|
||||
import icons from "lib/icons"
|
||||
import options from "options"
|
||||
|
||||
const MAX = options.launcher.sh.max
|
||||
const BINS = `${Utils.CACHE_DIR}/binaries`
|
||||
|
||||
async function ls(path: string) {
|
||||
return Utils.execAsync(`ls ${path}`).catch(() => "")
|
||||
}
|
||||
|
||||
async function reload() {
|
||||
const bins = await Promise.all(GLib.getenv("PATH")!
|
||||
.split(":")
|
||||
.map(ls))
|
||||
|
||||
Utils.writeFile(bins.join("\n"), BINS)
|
||||
}
|
||||
|
||||
async function query(filter: string) {
|
||||
if (!dependencies("fzf"))
|
||||
return [] as string[]
|
||||
|
||||
return bash(`cat ${BINS} | fzf -f ${filter} | head -n ${MAX}`)
|
||||
.then(str => Array.from(new Set(str.split("\n").filter(i => i)).values()))
|
||||
.catch(err => { print(err); return [] })
|
||||
}
|
||||
|
||||
function run(args: string) {
|
||||
Utils.execAsync(args)
|
||||
.then(out => {
|
||||
print(`:sh ${args.trim()}:`)
|
||||
print(out)
|
||||
})
|
||||
.catch(err => {
|
||||
Utils.notify("ShRun Error", err, icons.app.terminal)
|
||||
})
|
||||
}
|
||||
|
||||
class Sh extends Service {
|
||||
static { Service.register(this) }
|
||||
constructor() { super(); reload() }
|
||||
query = query
|
||||
run = run
|
||||
}
|
||||
|
||||
export default new Sh
|
|
@ -1,99 +0,0 @@
|
|||
import options from "options"
|
||||
import { dependencies, sh } from "lib/utils"
|
||||
|
||||
export type Resolution = 1920 | 1366 | 3840
|
||||
export type Market =
|
||||
| "random"
|
||||
| "en-US"
|
||||
| "ja-JP"
|
||||
| "en-AU"
|
||||
| "en-GB"
|
||||
| "de-DE"
|
||||
| "en-NZ"
|
||||
| "en-CA"
|
||||
|
||||
const WP = `${Utils.HOME}/.config/background`
|
||||
const Cache = `${Utils.HOME}/Pictures/Wallpapers/Bing`
|
||||
|
||||
class Wallpaper extends Service {
|
||||
static {
|
||||
Service.register(this, {}, {
|
||||
"wallpaper": ["string"],
|
||||
})
|
||||
}
|
||||
|
||||
#blockMonitor = false
|
||||
|
||||
#wallpaper() {
|
||||
if (!dependencies("swww"))
|
||||
return
|
||||
|
||||
sh("hyprctl cursorpos").then(pos => {
|
||||
sh([
|
||||
"swww", "img",
|
||||
"--invert-y",
|
||||
"--transition-type", "grow",
|
||||
"--transition-pos", pos.replace(" ", ""),
|
||||
WP,
|
||||
]).then(() => {
|
||||
this.changed("wallpaper")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async #setWallpaper(path: string) {
|
||||
this.#blockMonitor = true
|
||||
|
||||
await sh(`cp ${path} ${WP}`)
|
||||
this.#wallpaper()
|
||||
|
||||
this.#blockMonitor = false
|
||||
}
|
||||
|
||||
async #fetchBing() {
|
||||
const res = await Utils.fetch("https://bing.biturl.top/", {
|
||||
params: {
|
||||
resolution: options.wallpaper.resolution.value,
|
||||
format: "json",
|
||||
image_format: "jpg",
|
||||
index: "random",
|
||||
mkt: options.wallpaper.market.value,
|
||||
},
|
||||
}).then(res => res.text())
|
||||
|
||||
if (!res.startsWith("{"))
|
||||
return console.warn("bing api", res)
|
||||
|
||||
const { url } = JSON.parse(res)
|
||||
const file = `${Cache}/${url.replace("https://www.bing.com/th?id=", "")}`
|
||||
|
||||
if (dependencies("curl")) {
|
||||
Utils.ensureDirectory(Cache)
|
||||
await sh(`curl "${url}" --output ${file}`)
|
||||
this.#setWallpaper(file)
|
||||
}
|
||||
}
|
||||
|
||||
readonly random = () => { this.#fetchBing() }
|
||||
readonly set = (path: string) => { this.#setWallpaper(path) }
|
||||
get wallpaper() { return WP }
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
|
||||
if (!dependencies("swww"))
|
||||
return this
|
||||
|
||||
// gtk portal
|
||||
Utils.monitorFile(WP, () => {
|
||||
if (!this.#blockMonitor)
|
||||
this.#wallpaper()
|
||||
})
|
||||
|
||||
Utils.execAsync("swww-daemon")
|
||||
.then(this.#wallpaper)
|
||||
.catch(() => null)
|
||||
}
|
||||
}
|
||||
|
||||
export default new Wallpaper
|
|
@ -1,59 +0,0 @@
|
|||
import options from "options"
|
||||
|
||||
const { interval, key, cities, unit } = options.datemenu.weather
|
||||
|
||||
class Weather extends Service {
|
||||
static {
|
||||
Service.register(this, {}, {
|
||||
"forecasts": ["jsobject"],
|
||||
})
|
||||
}
|
||||
|
||||
#forecasts: Forecast[] = []
|
||||
get forecasts() { return this.#forecasts }
|
||||
|
||||
async #fetch(placeid: number) {
|
||||
const url = "https://api.openweathermap.org/data/2.5/forecast"
|
||||
const res = await Utils.fetch(url, {
|
||||
params: {
|
||||
id: placeid,
|
||||
appid: key.value,
|
||||
untis: unit.value,
|
||||
},
|
||||
})
|
||||
return await res.json()
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
if (!key.value)
|
||||
return this
|
||||
|
||||
Utils.interval(interval.value, () => {
|
||||
Promise.all(cities.value.map(this.#fetch)).then(forecasts => {
|
||||
this.#forecasts = forecasts as Forecast[]
|
||||
this.changed("forecasts")
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default new Weather
|
||||
|
||||
type Forecast = {
|
||||
city: {
|
||||
name: string,
|
||||
}
|
||||
list: Array<{
|
||||
dt: number
|
||||
main: {
|
||||
temp: number
|
||||
feels_like: number
|
||||
},
|
||||
weather: Array<{
|
||||
main: string,
|
||||
description: string,
|
||||
icon: string,
|
||||
}>
|
||||
}>
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
@import './mixins/button.scss';
|
||||
|
||||
* {
|
||||
font-size: $font-size;
|
||||
font-family: $font-name;
|
||||
}
|
||||
|
||||
separator {
|
||||
&.horizontal {
|
||||
min-height: $border-width;
|
||||
}
|
||||
|
||||
&.vertical {
|
||||
min-width: $border-width;
|
||||
}
|
||||
}
|
||||
|
||||
window.popup {
|
||||
>* {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
menu {
|
||||
border-radius: $popover-radius;
|
||||
background-color: $bg;
|
||||
padding: $popover-padding;
|
||||
border: $border-width solid $popover-border-color;
|
||||
|
||||
separator {
|
||||
background-color: $border-color;
|
||||
}
|
||||
|
||||
menuitem {
|
||||
@include button;
|
||||
padding: $spacing * .5;
|
||||
margin: ($spacing * .5) 0;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tooltip {
|
||||
* {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
|
||||
>*>* {
|
||||
background-color: $bg;
|
||||
border-radius: $radius;
|
||||
border: $border-width solid $popover-border-color;
|
||||
color: $fg;
|
||||
padding: 8px;
|
||||
margin: 4px;
|
||||
box-shadow: 0 0 3px 0 $shadow-color;
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
@import './button';
|
||||
|
||||
@mixin accs-button($flat: false, $reactive: true) {
|
||||
@include unset;
|
||||
color: $fg;
|
||||
|
||||
>* {
|
||||
border-radius: $radius;
|
||||
transition: $transition;
|
||||
|
||||
@if $flat {
|
||||
background-color: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
@else {
|
||||
background-color: $widget-bg;
|
||||
box-shadow: inset 0 0 0 $border-width $border-color;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@if $reactive {
|
||||
|
||||
&:focus>*,
|
||||
&.focused>* {
|
||||
@include button-focus;
|
||||
}
|
||||
|
||||
&:hover>* {
|
||||
@include button-hover;
|
||||
}
|
||||
|
||||
&:active,
|
||||
&.active,
|
||||
&.on,
|
||||
&:checked {
|
||||
>* {
|
||||
@include button-active;
|
||||
}
|
||||
|
||||
&:hover>* {
|
||||
box-shadow: inset 0 0 0 $border-width $border-color,
|
||||
inset 0 0 0 99px $hover-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
@mixin button-focus() {
|
||||
box-shadow: inset 0 0 0 $border-width $primary-bg;
|
||||
background-color: $hover-bg;
|
||||
color: $hover-fg;
|
||||
}
|
||||
|
||||
@mixin button-hover() {
|
||||
box-shadow: inset 0 0 0 $border-width $border-color;
|
||||
background-color: $hover-bg;
|
||||
color: $hover-fg;
|
||||
}
|
||||
|
||||
@mixin button-active() {
|
||||
box-shadow: inset 0 0 0 $border-width $border-color;
|
||||
background-image: $active-gradient;
|
||||
background-color: $primary-bg;
|
||||
color: $primary-fg;
|
||||
}
|
||||
|
||||
@mixin button-disabled() {
|
||||
box-shadow: none;
|
||||
background-color: transparent;
|
||||
color: transparentize($fg, 0.7);
|
||||
}
|
||||
|
||||
@mixin button($flat: false, $reactive: true, $radius: $radius, $focusable: true) {
|
||||
all: unset;
|
||||
transition: $transition;
|
||||
border-radius: $radius;
|
||||
color: $fg;
|
||||
|
||||
@if $flat {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
@else {
|
||||
background-color: $widget-bg;
|
||||
box-shadow: inset 0 0 0 $border-width $border-color;
|
||||
}
|
||||
|
||||
@if $reactive {
|
||||
@if $focusable {
|
||||
&:focus {
|
||||
@include button-focus;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@include button-hover;
|
||||
}
|
||||
|
||||
&:active,
|
||||
&.on,
|
||||
&.active,
|
||||
&:checked {
|
||||
@include button-active;
|
||||
|
||||
&:hover {
|
||||
box-shadow: inset 0 0 0 $border-width $border-color,
|
||||
inset 0 0 0 99px $hover-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
@include button-disabled;
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
@mixin floating-widget {
|
||||
@if $shadows {
|
||||
box-shadow: 0 0 5px 0 $shadow-color;
|
||||
}
|
||||
|
||||
margin: max($spacing, 8px);
|
||||
border: $border-width solid $popover-border-color;
|
||||
background-color: $bg;
|
||||
color: $fg;
|
||||
border-radius: $popover-radius;
|
||||
padding: $popover-padding;
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
@mixin hidden {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
border-color: transparent;
|
||||
box-shadow: none;
|
||||
-gtk-icon-transform: scale(0);
|
||||
|
||||
* {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
border-color: transparent;
|
||||
box-shadow: none;
|
||||
-gtk-icon-transform: scale(0);
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
@mixin media() {
|
||||
@include widget;
|
||||
padding: $padding;
|
||||
|
||||
.cover {
|
||||
@if $shadows {
|
||||
box-shadow: 2px 2px 2px 0 $shadow-color;
|
||||
}
|
||||
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
border-radius: $radius*0.8;
|
||||
margin-right: $spacing;
|
||||
}
|
||||
|
||||
button {
|
||||
@include button($flat: true);
|
||||
padding: $padding * .5;
|
||||
|
||||
&.play-pause {
|
||||
margin: 0 ($spacing * .5);
|
||||
}
|
||||
|
||||
image {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
}
|
||||
|
||||
.artist {
|
||||
color: transparentize($fg, .2);
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
scale {
|
||||
@include slider($width: .5em, $slider: false, $gradient: linear-gradient($fg, $fg));
|
||||
margin-bottom: $padding * .5;
|
||||
|
||||
trough {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
@mixin scrollable($top: false, $bottom: false) {
|
||||
|
||||
@if $top and $shadows {
|
||||
undershoot.top {
|
||||
background: linear-gradient(to bottom, $shadow-color, transparent, transparent, transparent, transparent, transparent);
|
||||
}
|
||||
}
|
||||
|
||||
@if $bottom and $shadows {
|
||||
undershoot.bottom {
|
||||
background: linear-gradient(to top, $shadow-color, transparent, transparent, transparent, transparent, transparent);
|
||||
}
|
||||
}
|
||||
|
||||
scrollbar,
|
||||
scrollbar * {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
scrollbar.vertical {
|
||||
transition: $transition;
|
||||
background-color: transparentize($bg, 0.7);
|
||||
|
||||
&:hover {
|
||||
background-color: transparentize($bg, 0.3);
|
||||
|
||||
slider {
|
||||
background-color: transparentize($fg, 0.3);
|
||||
min-width: .6em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
scrollbar.vertical slider {
|
||||
background-color: transparentize($fg, 0.5);
|
||||
border-radius: $radius;
|
||||
min-width: .4em;
|
||||
min-height: 2em;
|
||||
transition: $transition;
|
||||
}
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
@import './unset';
|
||||
|
||||
@mixin slider($width: 0.7em, $slider-width: .5em, $gradient: $active-gradient, $slider: true, $focusable: true, $radius: $radius) {
|
||||
@include unset($rec: true);
|
||||
|
||||
trough {
|
||||
transition: $transition;
|
||||
border-radius: $radius;
|
||||
border: $border;
|
||||
background-color: $widget-bg;
|
||||
min-height: $width;
|
||||
min-width: $width;
|
||||
|
||||
highlight,
|
||||
progress {
|
||||
border-radius: max($radius - $border-width, 0);
|
||||
background-image: $gradient;
|
||||
min-height: $width;
|
||||
min-width: $width;
|
||||
}
|
||||
}
|
||||
|
||||
slider {
|
||||
box-shadow: none;
|
||||
background-color: transparent;
|
||||
border: $border-width solid transparent;
|
||||
transition: $transition;
|
||||
border-radius: $radius;
|
||||
min-height: $width;
|
||||
min-width: $width;
|
||||
margin: -$slider-width;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
trough {
|
||||
background-color: $hover-bg;
|
||||
}
|
||||
|
||||
slider {
|
||||
@if $slider {
|
||||
background-color: $fg;
|
||||
border-color: $border-color;
|
||||
|
||||
@if $shadows {
|
||||
box-shadow: 0 0 3px 0 $shadow-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
|
||||
highlight,
|
||||
progress {
|
||||
background-color: transparentize($fg, 0.4);
|
||||
background-image: none;
|
||||
}
|
||||
}
|
||||
|
||||
@if $focusable {
|
||||
trough:focus {
|
||||
background-color: $hover-bg;
|
||||
box-shadow: inset 0 0 0 $border-width $primary-bg;
|
||||
|
||||
slider {
|
||||
@if $slider {
|
||||
background-color: $fg;
|
||||
box-shadow: inset 0 0 0 $border-width $primary-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
@mixin spacing($multiplier: 1, $spacing: $spacing, $rec: false) {
|
||||
&.horizontal>* {
|
||||
margin: 0 calc($spacing * $multiplier / 2);
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.vertical>* {
|
||||
margin: calc($spacing * $multiplier / 2) 0;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@if $rec {
|
||||
box {
|
||||
&.horizontal>* {
|
||||
margin: 0 $spacing * $multiplier / 2;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.vertical>* {
|
||||
margin: $spacing * $multiplier / 2 0;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
@import './button';
|
||||
|
||||
@mixin switch {
|
||||
@include button;
|
||||
|
||||
slider {
|
||||
background-color: $primary-fg;
|
||||
border-radius: $radius;
|
||||
min-width: 24px;
|
||||
min-height: 24px;
|
||||
}
|
||||
|
||||
image {
|
||||
color: transparent;
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
@mixin unset($rec: false) {
|
||||
all: unset;
|
||||
|
||||
@if $rec {
|
||||
* {
|
||||
all: unset
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
@mixin widget {
|
||||
transition: $transition;
|
||||
border-radius: $radius;
|
||||
color: $fg;
|
||||
background-color: $widget-bg;
|
||||
border: $border;
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
/* eslint-disable max-len */
|
||||
import { type Opt } from "lib/option"
|
||||
import { bash, dependencies } from "lib/utils"
|
||||
import options from "options"
|
||||
|
||||
const deps = [
|
||||
"font",
|
||||
"theme",
|
||||
"bar.corners",
|
||||
"bar.flatButtons",
|
||||
"bar.position",
|
||||
"bar.battery.charging",
|
||||
"bar.battery.blocks",
|
||||
]
|
||||
|
||||
const {
|
||||
dark,
|
||||
light,
|
||||
blur,
|
||||
scheme,
|
||||
padding,
|
||||
spacing,
|
||||
radius,
|
||||
shadows,
|
||||
widget,
|
||||
border,
|
||||
} = options.theme
|
||||
|
||||
const popoverPaddingMultiplier = 1.6
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const t = (dark: Opt<any> | string, light: Opt<any> | string) => scheme.value === "dark"
|
||||
? `${dark}` : `${light}`
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const $ = (name: string, value: string | Opt<any>) => `$${name}: ${value};`
|
||||
|
||||
const variables = () => [
|
||||
$("bg", blur.value ? `transparentize(${t(dark.bg, light.bg)}, ${blur.value / 100})` : t(dark.bg, light.bg)),
|
||||
$("fg", t(dark.fg, light.fg)),
|
||||
|
||||
$("primary-bg", t(dark.primary.bg, light.primary.bg)),
|
||||
$("primary-fg", t(dark.primary.fg, light.primary.fg)),
|
||||
|
||||
$("error-bg", t(dark.error.bg, light.error.bg)),
|
||||
$("error-fg", t(dark.error.fg, light.error.fg)),
|
||||
|
||||
$("scheme", scheme),
|
||||
$("padding", `${padding}pt`),
|
||||
$("spacing", `${spacing}pt`),
|
||||
$("radius", `${radius}px`),
|
||||
$("transition", `${options.transition}ms`),
|
||||
|
||||
$("shadows", `${shadows}`),
|
||||
|
||||
$("widget-bg", `transparentize(${t(dark.widget, light.widget)}, ${widget.opacity.value / 100})`),
|
||||
|
||||
$("hover-bg", `transparentize(${t(dark.widget, light.widget)}, ${(widget.opacity.value * .9) / 100})`),
|
||||
$("hover-fg", `lighten(${t(dark.fg, light.fg)}, 8%)`),
|
||||
|
||||
$("border-width", `${border.width}px`),
|
||||
$("border-color", `transparentize(${t(dark.border, light.border)}, ${border.opacity.value / 100})`),
|
||||
$("border", "$border-width solid $border-color"),
|
||||
|
||||
$("active-gradient", `linear-gradient(to right, ${t(dark.primary.bg, light.primary.bg)}, darken(${t(dark.primary.bg, light.primary.bg)}, 4%))`),
|
||||
$("shadow-color", t("rgba(0,0,0,.6)", "rgba(0,0,0,.4)")),
|
||||
$("text-shadow", t("2pt 2pt 2pt $shadow-color", "none")),
|
||||
$("box-shadow", t("2pt 2pt 2pt 0 $shadow-color, inset 0 0 0 $border-width $border-color", "none")),
|
||||
|
||||
$("popover-border-color", `transparentize(${t(dark.border, light.border)}, ${Math.max(((border.opacity.value - 1) / 100), 0)})`),
|
||||
$("popover-padding", `$padding * ${popoverPaddingMultiplier}`),
|
||||
$("popover-radius", radius.value === 0 ? "0" : "$radius + $popover-padding"),
|
||||
|
||||
$("font-size", `${options.font.size}pt`),
|
||||
$("font-name", options.font.name),
|
||||
|
||||
// etc
|
||||
$("charging-bg", options.bar.battery.charging),
|
||||
$("bar-battery-blocks", options.bar.battery.blocks),
|
||||
$("bar-position", options.bar.position),
|
||||
$("hyprland-gaps-multiplier", options.hyprland.gaps),
|
||||
$("screen-corner-multiplier", `${options.bar.corners.value * 0.01}`),
|
||||
]
|
||||
|
||||
async function resetCss() {
|
||||
if (!dependencies("sass", "fd"))
|
||||
return
|
||||
|
||||
try {
|
||||
const vars = `${TMP}/variables.scss`
|
||||
const scss = `${TMP}/main.scss`
|
||||
const css = `${TMP}/main.css`
|
||||
|
||||
const fd = await bash(`fd ".scss" ${App.configDir}`)
|
||||
const files = fd.split(/\s+/)
|
||||
const imports = [vars, ...files].map(f => `@import '${f}';`)
|
||||
|
||||
await Utils.writeFile(variables().join("\n"), vars)
|
||||
await Utils.writeFile(imports.join("\n"), scss)
|
||||
|
||||
await bash`sass ${scss} ${css}`
|
||||
|
||||
App.applyCss(css, true)
|
||||
} catch (error) {
|
||||
error instanceof Error
|
||||
? logError(error)
|
||||
: console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
Utils.monitorFile(`${App.configDir}/style`, resetCss)
|
||||
|
||||
options.handler(deps, resetCss)
|
||||
|
||||
await resetCss()
|
|
@ -1,265 +0,0 @@
|
|||
@use 'sass:color';
|
||||
|
||||
$bar-spacing: $spacing * .3;
|
||||
$button-radius: $radius;
|
||||
|
||||
@mixin panel-button($flat: true, $reactive: true) {
|
||||
@include accs-button($flat, $reactive);
|
||||
|
||||
>* {
|
||||
border-radius: $button-radius;
|
||||
margin: $bar-spacing;
|
||||
}
|
||||
|
||||
label,
|
||||
image {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
>* {
|
||||
padding: $padding * 0.4 $padding * 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.bar {
|
||||
transition: $transition;
|
||||
background-color: $bg;
|
||||
|
||||
.panel-button {
|
||||
@include panel-button;
|
||||
|
||||
&:not(.flat) {
|
||||
|
||||
@include accs-button($flat: false);
|
||||
}
|
||||
}
|
||||
|
||||
.launcher {
|
||||
.colored {
|
||||
color: transparentize($primary-bg, 0.2);
|
||||
}
|
||||
|
||||
&:hover .colored {
|
||||
color: $primary-bg;
|
||||
}
|
||||
|
||||
&:active .colored,
|
||||
&.active .colored {
|
||||
color: $primary-fg;
|
||||
}
|
||||
}
|
||||
|
||||
.workspaces {
|
||||
label {
|
||||
font-size: 0;
|
||||
min-width: 5pt;
|
||||
min-height: 5pt;
|
||||
border-radius: $radius*.6;
|
||||
box-shadow: inset 0 0 0 $border-width $border-color;
|
||||
margin: 0 $padding * .5;
|
||||
transition: $transition* .5;
|
||||
background-color: transparentize($fg, .8);
|
||||
|
||||
&.occupied {
|
||||
background-color: transparentize($fg, .2);
|
||||
min-width: 7pt;
|
||||
min-height: 7pt;
|
||||
}
|
||||
|
||||
&.active {
|
||||
// background-color: $primary-bg;
|
||||
background-image: $active-gradient;
|
||||
min-width: 20pt;
|
||||
min-height: 12pt;
|
||||
}
|
||||
}
|
||||
|
||||
&.active,
|
||||
&:active {
|
||||
label {
|
||||
background-color: transparentize($primary-fg, .3);
|
||||
|
||||
&.occupied {
|
||||
background-color: transparentize($primary-fg, .15);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: $primary-fg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.media label {
|
||||
margin: 0 ($spacing * .5)
|
||||
}
|
||||
|
||||
.taskbar .indicator.active {
|
||||
background-color: $primary-bg;
|
||||
border-radius: $radius;
|
||||
min-height: 4pt;
|
||||
min-width: 6pt;
|
||||
margin: 2pt;
|
||||
}
|
||||
|
||||
.powermenu.colored,
|
||||
.recorder {
|
||||
image {
|
||||
color: transparentize($error-bg, 0.3);
|
||||
}
|
||||
|
||||
&:hover image {
|
||||
color: transparentize($error-bg, 0.15);
|
||||
}
|
||||
|
||||
&:active image {
|
||||
color: $primary-fg;
|
||||
}
|
||||
}
|
||||
|
||||
.quicksettings>box>box {
|
||||
@include spacing($spacing: if($bar-spacing==0, $padding / 2, $bar-spacing));
|
||||
}
|
||||
|
||||
.quicksettings:not(.active):not(:active) {
|
||||
.bluetooth {
|
||||
color: $primary-bg;
|
||||
|
||||
label {
|
||||
font-size: $font-size * .7;
|
||||
color: $fg;
|
||||
text-shadow: $text-shadow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.battery-bar {
|
||||
>* {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&.bar-hidden>box {
|
||||
padding: 0 $spacing * .5;
|
||||
|
||||
image {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
levelbar * {
|
||||
all: unset;
|
||||
transition: $transition;
|
||||
}
|
||||
|
||||
.whole {
|
||||
@if $shadows {
|
||||
image {
|
||||
-gtk-icon-shadow: $text-shadow;
|
||||
}
|
||||
|
||||
label {
|
||||
text-shadow: $text-shadow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.regular image {
|
||||
margin-left: $spacing * .5;
|
||||
}
|
||||
|
||||
trough {
|
||||
@include widget;
|
||||
min-height: 12pt;
|
||||
min-width: 12pt;
|
||||
}
|
||||
|
||||
.regular trough {
|
||||
margin-right: $spacing * .5;
|
||||
}
|
||||
|
||||
block {
|
||||
margin: 0;
|
||||
|
||||
&:last-child {
|
||||
border-radius: 0 $button-radius $button-radius 0;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-radius: $button-radius 0 0 $button-radius;
|
||||
}
|
||||
}
|
||||
|
||||
.vertical {
|
||||
block {
|
||||
&:last-child {
|
||||
border-radius: 0 0 $button-radius $button-radius;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-radius: $button-radius $button-radius 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@for $i from 1 through $bar-battery-blocks {
|
||||
block:nth-child(#{$i}).filled {
|
||||
background-color: color.mix($bg, $primary-bg, $i*3)
|
||||
}
|
||||
|
||||
&.low block:nth-child(#{$i}).filled {
|
||||
background-color: color.mix($bg, $error-bg, $i*3)
|
||||
}
|
||||
|
||||
&.charging block:nth-child(#{$i}).filled {
|
||||
background-color: color.mix($bg, $charging-bg, $i*3)
|
||||
}
|
||||
|
||||
&:active .regular block:nth-child(#{$i}).filled {
|
||||
background-color: color.mix($bg, $primary-fg, $i*3)
|
||||
}
|
||||
}
|
||||
|
||||
&.low image {
|
||||
color: $error-bg
|
||||
}
|
||||
|
||||
&.charging image {
|
||||
color: $charging-bg
|
||||
}
|
||||
|
||||
&:active image {
|
||||
color: $primary-fg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bar.transparent {
|
||||
background-color: transparent;
|
||||
|
||||
.panel-button {
|
||||
&:hover>* {
|
||||
box-shadow: 1px 1px 3px 0 $shadow-color, inset 0 0 0 $border-width $border-color;
|
||||
background-color: $bg;
|
||||
}
|
||||
|
||||
&:not(:hover):not(.active) {
|
||||
|
||||
label,
|
||||
image {
|
||||
text-shadow: $text-shadow;
|
||||
-gtk-icon-shadow: $text-shadow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.workspaces label {
|
||||
box-shadow: inset 0 0 0 $border-width $border-color,
|
||||
1px 1px 3px 0 $shadow-color;
|
||||
}
|
||||
|
||||
.battery-bar trough {
|
||||
box-shadow: 1px 1px 3px 0 $shadow-color;
|
||||
|
||||
}
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
@import "./notifications.scss";
|
||||
|
||||
@mixin calendar {
|
||||
@include widget;
|
||||
padding: $padding*2 $padding*2 0;
|
||||
|
||||
calendar {
|
||||
all: unset;
|
||||
|
||||
&.button {
|
||||
@include button($flat: true);
|
||||
}
|
||||
|
||||
&:selected {
|
||||
box-shadow: inset 0 -8px 0 0 transparentize($primary-bg, 0.5),
|
||||
inset 0 0 0 1px $primary-bg;
|
||||
border-radius: $radius*0.6;
|
||||
}
|
||||
|
||||
&.header {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
color: transparentize($fg, 0.5);
|
||||
}
|
||||
|
||||
&.highlight {
|
||||
background-color: transparent;
|
||||
color: transparentize($primary-bg, 0.5);
|
||||
}
|
||||
|
||||
&:indeterminate {
|
||||
color: transparentize($fg, 0.9);
|
||||
}
|
||||
|
||||
font-size: 1.1em;
|
||||
padding: .2em;
|
||||
}
|
||||
}
|
||||
|
||||
window#datemenu .datemenu {
|
||||
@include floating-widget;
|
||||
|
||||
.notifications {
|
||||
.header {
|
||||
margin-bottom: $spacing;
|
||||
margin-right: $spacing;
|
||||
|
||||
>label {
|
||||
margin-left: $radius * .5;
|
||||
}
|
||||
|
||||
button {
|
||||
@include button;
|
||||
padding: $padding*.7 $padding;
|
||||
}
|
||||
}
|
||||
|
||||
.notification-scrollable {
|
||||
@include scrollable($top: true, $bottom: true);
|
||||
}
|
||||
|
||||
.notification-list {
|
||||
margin-right: $spacing;
|
||||
}
|
||||
|
||||
.notification {
|
||||
@include notification;
|
||||
@include widget;
|
||||
padding: $padding;
|
||||
margin-bottom: $spacing;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
image {
|
||||
font-size: 7em;
|
||||
}
|
||||
|
||||
label {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
separator {
|
||||
background-color: $popover-border-color;
|
||||
border-radius: $radius;
|
||||
margin-right: $spacing;
|
||||
}
|
||||
|
||||
.datemenu {
|
||||
@include spacing;
|
||||
}
|
||||
|
||||
.clock-box {
|
||||
padding: $padding;
|
||||
|
||||
.clock {
|
||||
font-size: 5em;
|
||||
}
|
||||
|
||||
.uptime {
|
||||
color: transparentize($fg, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.calendar {
|
||||
@include calendar;
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
@import "../mixins/floating-widget.scss";
|
||||
@import "../mixins/widget.scss";
|
||||
@import "../mixins/spacing.scss";
|
||||
@import "../mixins/unset.scss";
|
||||
@import "../mixins/a11y-button.scss";
|
||||
@import "./bar.scss";
|
||||
|
||||
window#greeter {
|
||||
background-color: lighten($bg, 6%);
|
||||
color: $fg;
|
||||
|
||||
.bar {
|
||||
background-color: transparent;
|
||||
|
||||
.date {
|
||||
@include unset($rec: true);
|
||||
@include panel-button($flat: true, $reactive: false);
|
||||
}
|
||||
}
|
||||
|
||||
.auth {
|
||||
@include floating_widget;
|
||||
border-radius: $radius;
|
||||
min-width: 400px;
|
||||
padding: 0;
|
||||
|
||||
.wallpaper {
|
||||
min-height: 220px;
|
||||
background-size: cover;
|
||||
border-top-left-radius: $radius;
|
||||
border-top-right-radius: $radius;
|
||||
}
|
||||
|
||||
.wallpaper-contrast {
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
border-radius: 99px;
|
||||
min-width: 140px;
|
||||
min-height: 140px;
|
||||
background-size: cover;
|
||||
box-shadow: 3px 3px 6px 0 $shadow-color;
|
||||
margin-bottom: $spacing;
|
||||
}
|
||||
|
||||
|
||||
.password {
|
||||
entry {
|
||||
@include button;
|
||||
padding: $padding*.7 $padding;
|
||||
margin-left: $spacing*.5;
|
||||
}
|
||||
|
||||
margin: 0 $padding*4;
|
||||
margin-top: $spacing;
|
||||
}
|
||||
|
||||
.response-box {
|
||||
color: $error-bg;
|
||||
margin: $spacing 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,143 +0,0 @@
|
|||
@use "sass:math";
|
||||
@use "sass:color";
|
||||
|
||||
window#launcher .launcher {
|
||||
@include floating_widget;
|
||||
|
||||
.quicklaunch {
|
||||
@include spacing;
|
||||
|
||||
button {
|
||||
@include button($flat: true);
|
||||
padding: $padding;
|
||||
}
|
||||
}
|
||||
|
||||
entry {
|
||||
@include button;
|
||||
padding: $padding;
|
||||
margin: $spacing;
|
||||
|
||||
selection {
|
||||
color: color.mix($fg, $bg, 50%);
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
label,
|
||||
image {
|
||||
color: $fg;
|
||||
}
|
||||
}
|
||||
|
||||
image.spinner {
|
||||
color: $primary-bg;
|
||||
margin-right: $spacing;
|
||||
}
|
||||
|
||||
separator {
|
||||
margin: 4pt 0;
|
||||
background-color: $popover-border-color;
|
||||
}
|
||||
|
||||
button.app-item {
|
||||
@include button($flat: true, $reactive: false);
|
||||
|
||||
>box {
|
||||
@include spacing(0.5);
|
||||
}
|
||||
|
||||
transition: $transition;
|
||||
padding: $padding;
|
||||
|
||||
label {
|
||||
transition: $transition;
|
||||
|
||||
&.title {
|
||||
color: $fg;
|
||||
}
|
||||
|
||||
&.description {
|
||||
color: transparentize($fg, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
image {
|
||||
transition: $transition;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
.title {
|
||||
color: $primary-bg;
|
||||
}
|
||||
|
||||
.description {
|
||||
color: transparentize($primary-bg, .4);
|
||||
}
|
||||
|
||||
image {
|
||||
-gtk-icon-shadow: 2px 2px $primary-bg;
|
||||
}
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: transparentize($primary-bg, 0.5);
|
||||
border-radius: $radius;
|
||||
box-shadow: inset 0 0 0 $border-width $border-color;
|
||||
|
||||
.title {
|
||||
color: $fg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button.help,
|
||||
button.nix-item {
|
||||
@include button($flat: true, $reactive: false);
|
||||
padding: 0 ($padding * .5);
|
||||
|
||||
label {
|
||||
transition: $transition;
|
||||
color: $fg;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.description {
|
||||
color: transparentize($fg, .3)
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
label {
|
||||
text-shadow: $text-shadow;
|
||||
}
|
||||
|
||||
.name,
|
||||
.version {
|
||||
color: $primary-bg;
|
||||
}
|
||||
|
||||
.description {
|
||||
color: transparentize($primary-bg, .3)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button.sh-item {
|
||||
@include button($flat: true, $reactive: false);
|
||||
padding: 0 ($padding * .5);
|
||||
|
||||
transition: $transition;
|
||||
color: $fg;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: $primary-bg;
|
||||
text-shadow: $text-shadow;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
@mixin notification() {
|
||||
&.critical {
|
||||
box-shadow: inset 0 0 .5em 0 $error-bg;
|
||||
}
|
||||
|
||||
&:hover button.close-button {
|
||||
@include button-hover;
|
||||
background-color: transparentize($error-bg, .5);
|
||||
}
|
||||
|
||||
.content {
|
||||
.title {
|
||||
margin-right: $spacing;
|
||||
color: $fg;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.time {
|
||||
color: transparentize($fg, .2);
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: .9em;
|
||||
color: transparentize($fg, .2);
|
||||
}
|
||||
|
||||
.icon {
|
||||
border-radius: $radius*0.8;
|
||||
margin-right: $spacing;
|
||||
|
||||
&.img {
|
||||
border: $border;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
box.actions {
|
||||
@include spacing(0.5);
|
||||
margin-top: $spacing;
|
||||
|
||||
button {
|
||||
@include button;
|
||||
border-radius: $radius*0.8;
|
||||
font-size: 1.2em;
|
||||
padding: $padding * 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
button.close-button {
|
||||
@include button($flat: true);
|
||||
margin-left: $spacing / 2;
|
||||
border-radius: $radius*0.8;
|
||||
min-width: 1.2em;
|
||||
min-height: 1.2em;
|
||||
|
||||
&:hover {
|
||||
background-color: transparentize($error-bg, .2);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-image: none;
|
||||
background-color: $error-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.notifications {
|
||||
@include unset;
|
||||
|
||||
.notification {
|
||||
@include notification;
|
||||
@include floating-widget;
|
||||
border-radius: $radius;
|
||||
|
||||
.description {
|
||||
min-width: 350px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
window.indicator {
|
||||
.progress {
|
||||
@include floating-widget;
|
||||
padding: $padding * .5;
|
||||
border-radius: if($radius >0, calc($radius + $padding*.5), 0);
|
||||
@debug $radius;
|
||||
|
||||
.fill {
|
||||
border-radius: $radius;
|
||||
background-color: $primary-bg;
|
||||
color: $primary-fg;
|
||||
|
||||
image {
|
||||
-gtk-icon-transform: scale(0.7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.microphone {
|
||||
@include floating-widget;
|
||||
margin: $spacing * 2;
|
||||
padding: $popover-padding * 2;
|
||||
font-size: 58px;
|
||||
color: transparentize($fg, .1)
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
window#overview .overview {
|
||||
@include floating-widget;
|
||||
@include spacing;
|
||||
|
||||
.workspace {
|
||||
&.active>widget {
|
||||
border-color: $primary-bg
|
||||
}
|
||||
|
||||
>widget {
|
||||
@include widget;
|
||||
border-radius: if($radius ==0, 0, $radius + $padding);
|
||||
|
||||
&:hover {
|
||||
background-color: $hover-bg;
|
||||
}
|
||||
|
||||
&:drop(active) {
|
||||
border-color: $primary-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.client {
|
||||
@include button;
|
||||
border-radius: $radius;
|
||||
margin: $padding;
|
||||
|
||||
&.hidden {
|
||||
@include hidden;
|
||||
transition: 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
window#powermenu,
|
||||
window#verification {
|
||||
// the fraction has to be more than hyprland ignorealpha
|
||||
background-color: rgba(0, 0, 0, .4);
|
||||
}
|
||||
|
||||
window#verification .verification {
|
||||
@include floating-widget;
|
||||
padding: $popover-padding * 1.5;
|
||||
min-width: 300px;
|
||||
min-height: 100px;
|
||||
|
||||
.text-box {
|
||||
margin-bottom: $spacing;
|
||||
|
||||
.title {
|
||||
font-size: 1.6em;
|
||||
}
|
||||
|
||||
.desc {
|
||||
color: transparentize($fg, 0.1);
|
||||
font-size: 1.1em;
|
||||
}
|
||||
}
|
||||
|
||||
.buttons {
|
||||
@include spacing;
|
||||
margin-top: $padding;
|
||||
|
||||
button {
|
||||
@include button;
|
||||
font-size: 1.5em;
|
||||
padding: $padding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window#powermenu .powermenu {
|
||||
@include floating-widget;
|
||||
|
||||
&.line {
|
||||
padding: $popover-padding * 1.5;
|
||||
|
||||
button {
|
||||
padding: $popover-padding;
|
||||
}
|
||||
|
||||
label {
|
||||
margin-bottom: $spacing * -.5;
|
||||
}
|
||||
}
|
||||
|
||||
&.box {
|
||||
padding: $popover-padding * 2;
|
||||
|
||||
button {
|
||||
padding: $popover-padding * 1.5;
|
||||
}
|
||||
|
||||
label {
|
||||
margin-bottom: $spacing * -1;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
@include unset;
|
||||
|
||||
image {
|
||||
@include button;
|
||||
border-radius: $radius + ($popover-padding * 1.4);
|
||||
min-width: 1.7em;
|
||||
min-height: 1.7em;
|
||||
font-size: 4em;
|
||||
}
|
||||
|
||||
label,
|
||||
image {
|
||||
color: transparentize($fg, 0.1);
|
||||
}
|
||||
|
||||
label {
|
||||
margin-top: $spacing * .3;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
image {
|
||||
@include button-hover;
|
||||
}
|
||||
|
||||
label {
|
||||
color: $fg;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus image {
|
||||
@include button-focus;
|
||||
}
|
||||
|
||||
&:active image {
|
||||
@include button-active;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&:active {
|
||||
label {
|
||||
color: $primary-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,177 +0,0 @@
|
|||
window#quicksettings .quicksettings {
|
||||
@include floating-widget;
|
||||
@include spacing;
|
||||
|
||||
padding: $popover-padding * 1.4;
|
||||
|
||||
.avatar {
|
||||
@include widget;
|
||||
border-radius: $radius * 3;
|
||||
}
|
||||
|
||||
.header {
|
||||
@include spacing(.5);
|
||||
color: transparentize($fg, .15);
|
||||
|
||||
button {
|
||||
@include button;
|
||||
padding: $padding;
|
||||
|
||||
image {
|
||||
font-size: 1.4em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sliders-box {
|
||||
@include widget;
|
||||
padding: $padding;
|
||||
|
||||
button {
|
||||
@include button($flat: true);
|
||||
padding: $padding * .5;
|
||||
}
|
||||
|
||||
.volume button.arrow:last-child {
|
||||
margin-left: $spacing * .4;
|
||||
}
|
||||
|
||||
.volume,
|
||||
.brightness {
|
||||
padding: $padding * .5;
|
||||
}
|
||||
|
||||
scale {
|
||||
@include slider;
|
||||
margin: 0 ($spacing * .5);
|
||||
|
||||
&.muted highlight {
|
||||
background-image: none;
|
||||
background-color: transparentize($fg, $amount: .2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.row {
|
||||
@include spacing;
|
||||
}
|
||||
|
||||
.menu {
|
||||
@include unset;
|
||||
@include widget;
|
||||
padding: $padding;
|
||||
margin-top: $spacing;
|
||||
|
||||
.icon {
|
||||
margin: 0 ($spacing * .5);
|
||||
margin-left: $spacing * .2;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
separator {
|
||||
margin: ($radius * .5);
|
||||
background-color: $border-color;
|
||||
}
|
||||
|
||||
button {
|
||||
@include button($flat: true);
|
||||
padding: ($padding * .5);
|
||||
|
||||
image:first-child {
|
||||
margin-right: $spacing * .5;
|
||||
}
|
||||
}
|
||||
|
||||
.bluetooth-devices {
|
||||
@include spacing(.5);
|
||||
}
|
||||
|
||||
switch {
|
||||
@include switch;
|
||||
}
|
||||
}
|
||||
|
||||
.sliders-box .menu {
|
||||
margin: ($spacing * .5) 0;
|
||||
|
||||
&.app-mixer {
|
||||
.mixer-item {
|
||||
padding: $padding * .5;
|
||||
padding-left: 0;
|
||||
padding-right: $padding * 2;
|
||||
|
||||
scale {
|
||||
@include slider($width: .5em);
|
||||
}
|
||||
|
||||
image {
|
||||
font-size: 1.2em;
|
||||
margin: 0 $padding;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.toggle-button {
|
||||
@include button;
|
||||
font-weight: bold;
|
||||
|
||||
image {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
label {
|
||||
margin-left: $spacing * .3;
|
||||
}
|
||||
|
||||
button {
|
||||
@include button($flat: true);
|
||||
|
||||
&:first-child {
|
||||
padding: $padding * 1.2;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding: $padding * .5;
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: $primary-bg;
|
||||
|
||||
label,
|
||||
image {
|
||||
color: $primary-fg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.simple-toggle {
|
||||
@include button;
|
||||
font-weight: bold;
|
||||
padding: $padding * 1.2;
|
||||
|
||||
label {
|
||||
margin-left: $spacing * .3;
|
||||
}
|
||||
|
||||
image {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
}
|
||||
|
||||
.media {
|
||||
@include spacing;
|
||||
|
||||
.player {
|
||||
@include media;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
$_shadow-size: $padding;
|
||||
$_radius: $radius * $hyprland-gaps-multiplier * $screen-corner-multiplier;
|
||||
$_margin: 99px;
|
||||
|
||||
window.screen-corner:not(.hidden) {
|
||||
transition: $transition;
|
||||
|
||||
box.shadow {
|
||||
margin-right: $_margin * -1;
|
||||
margin-left: $_margin * -1;
|
||||
|
||||
@if $shadows {
|
||||
box-shadow: inset 0 0 $_shadow-size 0 $shadow-color;
|
||||
}
|
||||
|
||||
@if $bar-position =="top" {
|
||||
margin-bottom: $_margin * -1;
|
||||
}
|
||||
|
||||
@if $bar-position =="bottom" {
|
||||
margin-top: $_margin * -1;
|
||||
}
|
||||
}
|
||||
|
||||
box.border {
|
||||
@if $bar-position =="top" {
|
||||
border-top: $border-width solid $bg;
|
||||
}
|
||||
|
||||
@if $bar-position =="bottom" {
|
||||
border-bottom: $border-width solid $bg;
|
||||
}
|
||||
|
||||
margin-right: $_margin;
|
||||
margin-left: $_margin;
|
||||
}
|
||||
|
||||
box.corner {
|
||||
box-shadow: 0 0 0 $border-width $border-color;
|
||||
}
|
||||
|
||||
&.corners {
|
||||
box.border {
|
||||
border-radius: if($radius>0, $_radius, 0);
|
||||
box-shadow: 0 0 0 $_radius $bg;
|
||||
}
|
||||
|
||||
box.corner {
|
||||
border-radius: if($radius>0, $_radius, 0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,144 +0,0 @@
|
|||
window.settings-dialog {
|
||||
background-color: $bg;
|
||||
color: $fg;
|
||||
|
||||
.header {
|
||||
.pager {
|
||||
@include spacing(.5);
|
||||
}
|
||||
|
||||
padding: $padding;
|
||||
|
||||
button {
|
||||
@include button;
|
||||
font-weight: bold;
|
||||
padding: $padding*.5 $padding;
|
||||
|
||||
box {
|
||||
@include spacing($spacing: .3em);
|
||||
}
|
||||
}
|
||||
|
||||
button.close {
|
||||
padding: $padding * .5;
|
||||
}
|
||||
|
||||
button.reset {
|
||||
@include button($flat: true);
|
||||
padding: $padding*.5;
|
||||
}
|
||||
}
|
||||
|
||||
.page {
|
||||
@include scrollable($top: true);
|
||||
|
||||
.page-content {
|
||||
padding: $padding*2;
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.group {
|
||||
.group-title {
|
||||
color: $primary-bg;
|
||||
margin-bottom: $spacing*.5;
|
||||
}
|
||||
|
||||
.group-reset {
|
||||
@include button($flat: true);
|
||||
margin: $spacing * .5;
|
||||
padding: $padding * .5;
|
||||
|
||||
&:disabled {
|
||||
color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: $spacing;
|
||||
}
|
||||
}
|
||||
|
||||
.row {
|
||||
background-color: $widget-bg;
|
||||
padding: $padding;
|
||||
border: $border;
|
||||
border-top: none;
|
||||
|
||||
&:first-child {
|
||||
border-radius: $radius $radius 0 0;
|
||||
border: $border;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-radius: 0 0 $radius $radius;
|
||||
}
|
||||
|
||||
&:first-child:last-child {
|
||||
border-radius: $radius;
|
||||
border: $border;
|
||||
}
|
||||
|
||||
button.reset {
|
||||
margin-left: $spacing;
|
||||
}
|
||||
|
||||
label.id,
|
||||
label.note {
|
||||
color: transparentize($fg, .4)
|
||||
}
|
||||
|
||||
entry,
|
||||
button {
|
||||
@include button;
|
||||
padding: $padding;
|
||||
}
|
||||
|
||||
switch {
|
||||
@include switch;
|
||||
}
|
||||
|
||||
spinbutton {
|
||||
@include unset;
|
||||
|
||||
entry {
|
||||
border-radius: $radius 0 0 $radius;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button:last-child {
|
||||
border-radius: 0 $radius $radius 0;
|
||||
}
|
||||
}
|
||||
|
||||
.enum-setter {
|
||||
label {
|
||||
background-color: $widget-bg;
|
||||
border: $border;
|
||||
padding: 0 $padding;
|
||||
border-radius: $radius 0 0 $radius;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button:last-child {
|
||||
border-radius: 0 $radius $radius 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.wallpaper {
|
||||
button {
|
||||
margin-top: $spacing * .5;
|
||||
}
|
||||
|
||||
.preview {
|
||||
border-radius: $radius;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"lib": [
|
||||
"ES2022"
|
||||
],
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"strict": true,
|
||||
"noImplicitAny": false,
|
||||
"baseUrl": ".",
|
||||
"typeRoots": [
|
||||
"./types",
|
||||
"./node_modules/@girs"
|
||||
],
|
||||
"skipLibCheck": true
|
||||
}
|
||||
}
|
|
@ -1,156 +0,0 @@
|
|||
import { type WindowProps } from "types/widgets/window"
|
||||
import { type RevealerProps } from "types/widgets/revealer"
|
||||
import { type EventBoxProps } from "types/widgets/eventbox"
|
||||
import type Gtk from "gi://Gtk?version=3.0"
|
||||
import options from "options"
|
||||
|
||||
type Transition = RevealerProps["transition"]
|
||||
type Child = WindowProps["child"]
|
||||
|
||||
type PopupWindowProps = Omit<WindowProps, "name"> & {
|
||||
name: string
|
||||
layout?: keyof ReturnType<typeof Layout>
|
||||
transition?: Transition,
|
||||
}
|
||||
|
||||
export const Padding = (name: string, {
|
||||
css = "",
|
||||
hexpand = true,
|
||||
vexpand = true,
|
||||
}: EventBoxProps = {}) => Widget.EventBox({
|
||||
hexpand,
|
||||
vexpand,
|
||||
can_focus: false,
|
||||
child: Widget.Box({ css }),
|
||||
setup: w => w.on("button-press-event", () => App.toggleWindow(name)),
|
||||
})
|
||||
|
||||
const PopupRevealer = (
|
||||
name: string,
|
||||
child: Child,
|
||||
transition: Transition = "slide_down",
|
||||
) => Widget.Box(
|
||||
{ css: "padding: 1px;" },
|
||||
Widget.Revealer({
|
||||
transition,
|
||||
child: Widget.Box({
|
||||
class_name: "window-content",
|
||||
child,
|
||||
}),
|
||||
transitionDuration: options.transition.bind(),
|
||||
setup: self => self.hook(App, (_, wname, visible) => {
|
||||
if (wname === name)
|
||||
self.reveal_child = visible
|
||||
}),
|
||||
}),
|
||||
)
|
||||
|
||||
const Layout = (name: string, child: Child, transition?: Transition) => ({
|
||||
"center": () => Widget.CenterBox({},
|
||||
Padding(name),
|
||||
Widget.CenterBox(
|
||||
{ vertical: true },
|
||||
Padding(name),
|
||||
PopupRevealer(name, child, transition),
|
||||
Padding(name),
|
||||
),
|
||||
Padding(name),
|
||||
),
|
||||
"top": () => Widget.CenterBox({},
|
||||
Padding(name),
|
||||
Widget.Box(
|
||||
{ vertical: true },
|
||||
PopupRevealer(name, child, transition),
|
||||
Padding(name),
|
||||
),
|
||||
Padding(name),
|
||||
),
|
||||
"top-right": () => Widget.Box({},
|
||||
Padding(name),
|
||||
Widget.Box(
|
||||
{
|
||||
hexpand: false,
|
||||
vertical: true,
|
||||
},
|
||||
PopupRevealer(name, child, transition),
|
||||
Padding(name),
|
||||
),
|
||||
),
|
||||
"top-center": () => Widget.Box({},
|
||||
Padding(name),
|
||||
Widget.Box(
|
||||
{
|
||||
hexpand: false,
|
||||
vertical: true,
|
||||
},
|
||||
PopupRevealer(name, child, transition),
|
||||
Padding(name),
|
||||
),
|
||||
Padding(name),
|
||||
),
|
||||
"top-left": () => Widget.Box({},
|
||||
Widget.Box(
|
||||
{
|
||||
hexpand: false,
|
||||
vertical: true,
|
||||
},
|
||||
PopupRevealer(name, child, transition),
|
||||
Padding(name),
|
||||
),
|
||||
Padding(name),
|
||||
),
|
||||
"bottom-left": () => Widget.Box({},
|
||||
Widget.Box(
|
||||
{
|
||||
hexpand: false,
|
||||
vertical: true,
|
||||
},
|
||||
Padding(name),
|
||||
PopupRevealer(name, child, transition),
|
||||
),
|
||||
Padding(name),
|
||||
),
|
||||
"bottom-center": () => Widget.Box({},
|
||||
Padding(name),
|
||||
Widget.Box(
|
||||
{
|
||||
hexpand: false,
|
||||
vertical: true,
|
||||
},
|
||||
Padding(name),
|
||||
PopupRevealer(name, child, transition),
|
||||
),
|
||||
Padding(name),
|
||||
),
|
||||
"bottom-right": () => Widget.Box({},
|
||||
Padding(name),
|
||||
Widget.Box(
|
||||
{
|
||||
hexpand: false,
|
||||
vertical: true,
|
||||
},
|
||||
Padding(name),
|
||||
PopupRevealer(name, child, transition),
|
||||
),
|
||||
),
|
||||
})
|
||||
|
||||
export default ({
|
||||
name,
|
||||
child,
|
||||
layout = "center",
|
||||
transition,
|
||||
exclusivity = "ignore",
|
||||
...props
|
||||
}: PopupWindowProps) => Widget.Window<Gtk.Widget>({
|
||||
name,
|
||||
class_names: [name, "popup-window"],
|
||||
setup: w => w.keybind("Escape", () => App.closeWindow(name)),
|
||||
visible: false,
|
||||
keymode: "on-demand",
|
||||
exclusivity,
|
||||
layer: "top",
|
||||
anchor: ["top", "bottom", "right", "left"],
|
||||
child: Layout(name, child, transition)[layout](),
|
||||
...props,
|
||||
})
|
|
@ -1,3 +0,0 @@
|
|||
import Gtk from "gi://Gtk?version=3.0"
|
||||
|
||||
export default Widget.subclass<typeof Gtk.Window, Gtk.Window.ConstructorProperties>(Gtk.Window)
|
|
@ -1,60 +0,0 @@
|
|||
import BatteryBar from "./buttons/BatteryBar"
|
||||
import ColorPicker from "./buttons/ColorPicker"
|
||||
import Date from "./buttons/Date"
|
||||
import Launcher from "./buttons/Launcher"
|
||||
import Media from "./buttons/Media"
|
||||
import PowerMenu from "./buttons/PowerMenu"
|
||||
import SysTray from "./buttons/SysTray"
|
||||
import SystemIndicators from "./buttons/SystemIndicators"
|
||||
import Taskbar from "./buttons/Taskbar"
|
||||
import Workspaces from "./buttons/Workspaces"
|
||||
import ScreenRecord from "./buttons/ScreenRecord"
|
||||
import Messages from "./buttons/Messages"
|
||||
import options from "options"
|
||||
|
||||
const { start, center, end } = options.bar.layout
|
||||
const { transparent, position } = options.bar
|
||||
|
||||
export type BarWidget = keyof typeof widget
|
||||
|
||||
const widget = {
|
||||
battery: BatteryBar,
|
||||
colorpicker: ColorPicker,
|
||||
date: Date,
|
||||
launcher: Launcher,
|
||||
media: Media,
|
||||
powermenu: PowerMenu,
|
||||
systray: SysTray,
|
||||
system: SystemIndicators,
|
||||
taskbar: Taskbar,
|
||||
workspaces: Workspaces,
|
||||
screenrecord: ScreenRecord,
|
||||
messages: Messages,
|
||||
expander: () => Widget.Box({ expand: true }),
|
||||
}
|
||||
|
||||
export default (monitor: number) => Widget.Window({
|
||||
monitor,
|
||||
class_name: "bar",
|
||||
name: `bar${monitor}`,
|
||||
exclusivity: "exclusive",
|
||||
anchor: position.bind().as(pos => [pos, "right", "left"]),
|
||||
child: Widget.CenterBox({
|
||||
css: "min-width: 2px; min-height: 2px;",
|
||||
startWidget: Widget.Box({
|
||||
hexpand: true,
|
||||
children: start.bind().as(s => s.map(w => widget[w]())),
|
||||
}),
|
||||
centerWidget: Widget.Box({
|
||||
hpack: "center",
|
||||
children: center.bind().as(c => c.map(w => widget[w]())),
|
||||
}),
|
||||
endWidget: Widget.Box({
|
||||
hexpand: true,
|
||||
children: end.bind().as(e => e.map(w => widget[w]())),
|
||||
}),
|
||||
}),
|
||||
setup: self => self.hook(transparent, () => {
|
||||
self.toggleClassName("transparent", transparent.value)
|
||||
}),
|
||||
})
|
|
@ -1,46 +0,0 @@
|
|||
import options from "options"
|
||||
import { ButtonProps } from "types/widgets/button"
|
||||
|
||||
type PanelButtonProps = ButtonProps & {
|
||||
window?: string,
|
||||
flat?: boolean
|
||||
}
|
||||
|
||||
export default ({
|
||||
window = "",
|
||||
flat,
|
||||
child,
|
||||
setup,
|
||||
...rest
|
||||
}: PanelButtonProps) => Widget.Button({
|
||||
child: Widget.Box({ child }),
|
||||
setup: self => {
|
||||
let open = false
|
||||
|
||||
self.toggleClassName("panel-button")
|
||||
self.toggleClassName(window)
|
||||
|
||||
self.hook(options.bar.flatButtons, () => {
|
||||
self.toggleClassName("flat", flat ?? options.bar.flatButtons.value)
|
||||
})
|
||||
|
||||
self.hook(App, (_, win, visible) => {
|
||||
if (win !== window)
|
||||
return
|
||||
|
||||
if (open && !visible) {
|
||||
open = false
|
||||
self.toggleClassName("active", false)
|
||||
}
|
||||
|
||||
if (visible) {
|
||||
open = true
|
||||
self.toggleClassName("active")
|
||||
}
|
||||
})
|
||||
|
||||
if (setup)
|
||||
setup(self)
|
||||
},
|
||||
...rest,
|
||||
})
|
|
@ -1,29 +0,0 @@
|
|||
import options from "options"
|
||||
|
||||
const { corners, transparent } = options.bar
|
||||
|
||||
export default (monitor: number) => Widget.Window({
|
||||
monitor,
|
||||
name: `corner${monitor}`,
|
||||
class_name: "screen-corner",
|
||||
anchor: ["top", "bottom", "right", "left"],
|
||||
click_through: true,
|
||||
child: Widget.Box({
|
||||
class_name: "shadow",
|
||||
child: Widget.Box({
|
||||
class_name: "border",
|
||||
expand: true,
|
||||
child: Widget.Box({
|
||||
class_name: "corner",
|
||||
expand: true,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
setup: self => self
|
||||
.hook(corners, () => {
|
||||
self.toggleClassName("corners", corners.value > 0)
|
||||
})
|
||||
.hook(transparent, () => {
|
||||
self.toggleClassName("hidden", transparent.value)
|
||||
}),
|
||||
})
|
|
@ -1,94 +0,0 @@
|
|||
import icons from "lib/icons"
|
||||
import options from "options"
|
||||
import PanelButton from "../PanelButton"
|
||||
|
||||
const battery = await Service.import("battery")
|
||||
const { bar, percentage, blocks, width, low } = options.bar.battery
|
||||
|
||||
const Indicator = () => Widget.Icon({
|
||||
setup: self => self.hook(battery, () => {
|
||||
self.icon = battery.charging || battery.charged
|
||||
? icons.battery.charging
|
||||
: battery.icon_name
|
||||
}),
|
||||
})
|
||||
|
||||
const PercentLabel = () => Widget.Revealer({
|
||||
transition: "slide_right",
|
||||
click_through: true,
|
||||
reveal_child: percentage.bind(),
|
||||
child: Widget.Label({
|
||||
label: battery.bind("percent").as(p => `${p}%`),
|
||||
}),
|
||||
})
|
||||
|
||||
const LevelBar = () => {
|
||||
const level = Widget.LevelBar({
|
||||
bar_mode: "discrete",
|
||||
max_value: blocks.bind(),
|
||||
visible: bar.bind().as(b => b !== "hidden"),
|
||||
value: battery.bind("percent").as(p => (p / 100) * blocks.value),
|
||||
})
|
||||
const update = () => {
|
||||
level.value = (battery.percent / 100) * blocks.value
|
||||
level.css = `block { min-width: ${width.value / blocks.value}pt; }`
|
||||
}
|
||||
return level
|
||||
.hook(width, update)
|
||||
.hook(blocks, update)
|
||||
.hook(bar, () => {
|
||||
level.vpack = bar.value === "whole" ? "fill" : "center"
|
||||
level.hpack = bar.value === "whole" ? "fill" : "center"
|
||||
})
|
||||
}
|
||||
|
||||
const WholeButton = () => Widget.Overlay({
|
||||
vexpand: true,
|
||||
child: LevelBar(),
|
||||
class_name: "whole",
|
||||
pass_through: true,
|
||||
overlay: Widget.Box({
|
||||
hpack: "center",
|
||||
children: [
|
||||
Widget.Icon({
|
||||
icon: icons.battery.charging,
|
||||
visible: Utils.merge([
|
||||
battery.bind("charging"),
|
||||
battery.bind("charged"),
|
||||
], (ing, ed) => ing || ed),
|
||||
}),
|
||||
Widget.Box({
|
||||
hpack: "center",
|
||||
vpack: "center",
|
||||
child: PercentLabel(),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
})
|
||||
|
||||
const Regular = () => Widget.Box({
|
||||
class_name: "regular",
|
||||
children: [
|
||||
Indicator(),
|
||||
PercentLabel(),
|
||||
LevelBar(),
|
||||
],
|
||||
})
|
||||
|
||||
export default () => PanelButton({
|
||||
class_name: "battery-bar",
|
||||
hexpand: false,
|
||||
on_clicked: () => { percentage.value = !percentage.value },
|
||||
visible: battery.bind("available"),
|
||||
child: Widget.Box({
|
||||
expand: true,
|
||||
visible: battery.bind("available"),
|
||||
child: bar.bind().as(b => b === "whole" ? WholeButton() : Regular()),
|
||||
}),
|
||||
setup: self => self
|
||||
.hook(bar, w => w.toggleClassName("bar-hidden", bar.value === "hidden"))
|
||||
.hook(battery, w => {
|
||||
w.toggleClassName("charging", battery.charging || battery.charged)
|
||||
w.toggleClassName("low", battery.percent < low.value)
|
||||
}),
|
||||
})
|
|
@ -1,37 +0,0 @@
|
|||
import PanelButton from "../PanelButton"
|
||||
import colorpicker from "service/colorpicker"
|
||||
import Gdk from "gi://Gdk"
|
||||
|
||||
const css = (color: string) => `
|
||||
* {
|
||||
background-color: ${color};
|
||||
color: transparent;
|
||||
}
|
||||
*:hover {
|
||||
color: white;
|
||||
text-shadow: 2px 2px 3px rgba(0,0,0,.8);
|
||||
}`
|
||||
|
||||
export default () => {
|
||||
const menu = Widget.Menu({
|
||||
class_name: "colorpicker",
|
||||
children: colorpicker.bind("colors").as(c => c.map(color => Widget.MenuItem({
|
||||
child: Widget.Label(color),
|
||||
css: css(color),
|
||||
on_activate: () => colorpicker.wlCopy(color),
|
||||
}))),
|
||||
})
|
||||
|
||||
return PanelButton({
|
||||
class_name: "color-picker",
|
||||
child: Widget.Icon("color-select-symbolic"),
|
||||
tooltip_text: colorpicker.bind("colors").as(v => `${v.length} colors`),
|
||||
on_clicked: colorpicker.pick,
|
||||
on_secondary_click: self => {
|
||||
if (colorpicker.colors.length === 0)
|
||||
return
|
||||
|
||||
menu.popup_at_widget(self, Gdk.Gravity.SOUTH, Gdk.Gravity.NORTH, null)
|
||||
},
|
||||
})
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
import { clock } from "lib/variables"
|
||||
import PanelButton from "../PanelButton"
|
||||
import options from "options"
|
||||
|
||||
const { format, action } = options.bar.date
|
||||
const time = Utils.derive([clock, format], (c, f) => c.format(f) || "")
|
||||
|
||||
export default () => PanelButton({
|
||||
window: "datemenu",
|
||||
on_clicked: action.bind(),
|
||||
child: Widget.Label({
|
||||
justification: "center",
|
||||
label: time.bind(),
|
||||
}),
|
||||
})
|
|
@ -1,49 +0,0 @@
|
|||
import PanelButton from "../PanelButton"
|
||||
import options from "options"
|
||||
import nix from "service/nix"
|
||||
|
||||
const { icon, label, action } = options.bar.launcher
|
||||
|
||||
function Spinner() {
|
||||
const child = Widget.Icon({
|
||||
icon: icon.icon.bind(),
|
||||
class_name: Utils.merge([
|
||||
icon.colored.bind(),
|
||||
nix.bind("ready"),
|
||||
], (c, r) => `${c ? "colored" : ""} ${r ? "" : "spinning"}`),
|
||||
css: `
|
||||
@keyframes spin {
|
||||
to { -gtk-icon-transform: rotate(1turn); }
|
||||
}
|
||||
|
||||
image.spinning {
|
||||
animation-name: spin;
|
||||
animation-duration: 1s;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
`,
|
||||
})
|
||||
|
||||
return Widget.Revealer({
|
||||
transition: "slide_left",
|
||||
child,
|
||||
reveal_child: Utils.merge([
|
||||
icon.icon.bind(),
|
||||
nix.bind("ready"),
|
||||
], (i, r) => Boolean(i || r)),
|
||||
})
|
||||
}
|
||||
|
||||
export default () => PanelButton({
|
||||
window: "launcher",
|
||||
on_clicked: action.bind(),
|
||||
child: Widget.Box([
|
||||
Spinner(),
|
||||
Widget.Label({
|
||||
class_name: label.colored.bind().as(c => c ? "colored" : ""),
|
||||
visible: label.label.bind().as(v => !!v),
|
||||
label: label.label.bind(),
|
||||
}),
|
||||
]),
|
||||
})
|
|
@ -1,92 +0,0 @@
|
|||
import { type MprisPlayer } from "types/service/mpris"
|
||||
import PanelButton from "../PanelButton"
|
||||
import options from "options"
|
||||
import icons from "lib/icons"
|
||||
import { icon } from "lib/utils"
|
||||
|
||||
const mpris = await Service.import("mpris")
|
||||
const { length, direction, preferred, monochrome, format } = options.bar.media
|
||||
|
||||
const getPlayer = (name = preferred.value) =>
|
||||
mpris.getPlayer(name) || mpris.players[0] || null
|
||||
|
||||
const Content = (player: MprisPlayer) => {
|
||||
const revealer = Widget.Revealer({
|
||||
click_through: true,
|
||||
visible: length.bind().as(l => l > 0),
|
||||
transition: direction.bind().as(d => `slide_${d}` as const),
|
||||
setup: self => {
|
||||
let current = ""
|
||||
self.hook(player, () => {
|
||||
if (current === player.track_title)
|
||||
return
|
||||
|
||||
current = player.track_title
|
||||
self.reveal_child = true
|
||||
Utils.timeout(3000, () => {
|
||||
!self.is_destroyed && (self.reveal_child = false)
|
||||
})
|
||||
})
|
||||
},
|
||||
child: Widget.Label({
|
||||
truncate: "end",
|
||||
max_width_chars: length.bind().as(n => n > 0 ? n : -1),
|
||||
label: Utils.merge([
|
||||
player.bind("track_title"),
|
||||
player.bind("track_artists"),
|
||||
format.bind(),
|
||||
], () => `${format}`
|
||||
.replace("{title}", player.track_title)
|
||||
.replace("{artists}", player.track_artists.join(", "))
|
||||
.replace("{artist}", player.track_artists[0] || "")
|
||||
.replace("{album}", player.track_album)
|
||||
.replace("{name}", player.name)
|
||||
.replace("{identity}", player.identity),
|
||||
),
|
||||
}),
|
||||
})
|
||||
|
||||
const playericon = Widget.Icon({
|
||||
icon: Utils.merge([player.bind("entry"), monochrome.bind()], (entry => {
|
||||
const name = `${entry}${monochrome.value ? "-symbolic" : ""}`
|
||||
return icon(name, icons.fallback.audio)
|
||||
})),
|
||||
})
|
||||
|
||||
return Widget.Box({
|
||||
attribute: { revealer },
|
||||
children: direction.bind().as(d => d === "right"
|
||||
? [playericon, revealer] : [revealer, playericon]),
|
||||
})
|
||||
}
|
||||
|
||||
export default () => {
|
||||
let player = getPlayer()
|
||||
|
||||
const btn = PanelButton({
|
||||
class_name: "media",
|
||||
child: Widget.Icon(icons.fallback.audio),
|
||||
})
|
||||
|
||||
const update = () => {
|
||||
player = getPlayer()
|
||||
btn.visible = !!player
|
||||
|
||||
if (!player)
|
||||
return
|
||||
|
||||
const content = Content(player)
|
||||
const { revealer } = content.attribute
|
||||
btn.child = content
|
||||
btn.on_primary_click = () => { player.playPause() }
|
||||
btn.on_secondary_click = () => { player.playPause() }
|
||||
btn.on_scroll_up = () => { player.next() }
|
||||
btn.on_scroll_down = () => { player.previous() }
|
||||
btn.on_hover = () => { revealer.reveal_child = true }
|
||||
btn.on_hover_lost = () => { revealer.reveal_child = false }
|
||||
}
|
||||
|
||||
return btn
|
||||
.hook(preferred, update)
|
||||
.hook(mpris, update, "notify::players")
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
import icons from "lib/icons"
|
||||
import PanelButton from "../PanelButton"
|
||||
import options from "options"
|
||||
|
||||
const n = await Service.import("notifications")
|
||||
const notifs = n.bind("notifications")
|
||||
const action = options.bar.messages.action.bind()
|
||||
|
||||
export default () => PanelButton({
|
||||
class_name: "messages",
|
||||
on_clicked: action,
|
||||
visible: notifs.as(n => n.length > 0),
|
||||
child: Widget.Box([
|
||||
Widget.Icon(icons.notifications.message),
|
||||
]),
|
||||
})
|
|
@ -1,15 +0,0 @@
|
|||
import icons from "lib/icons"
|
||||
import PanelButton from "../PanelButton"
|
||||
import options from "options"
|
||||
|
||||
const { monochrome, action } = options.bar.powermenu
|
||||
|
||||
export default () => PanelButton({
|
||||
window: "powermenu",
|
||||
on_clicked: action.bind(),
|
||||
child: Widget.Icon(icons.powermenu.shutdown),
|
||||
setup: self => self.hook(monochrome, () => {
|
||||
self.toggleClassName("colored", !monochrome.value)
|
||||
self.toggleClassName("box")
|
||||
}),
|
||||
})
|
|
@ -1,21 +0,0 @@
|
|||
import PanelButton from "../PanelButton"
|
||||
import screenrecord from "service/screenrecord"
|
||||
import icons from "lib/icons"
|
||||
|
||||
export default () => PanelButton({
|
||||
class_name: "recorder",
|
||||
on_clicked: () => screenrecord.stop(),
|
||||
visible: screenrecord.bind("recording"),
|
||||
child: Widget.Box({
|
||||
children: [
|
||||
Widget.Icon(icons.recorder.recording),
|
||||
Widget.Label({
|
||||
label: screenrecord.bind("timer").as(time => {
|
||||
const sec = time % 60
|
||||
const min = Math.floor(time / 60)
|
||||
return `${min}:${sec < 10 ? "0" + sec : sec}`
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
})
|
|
@ -1,39 +0,0 @@
|
|||
import { type TrayItem } from "types/service/systemtray"
|
||||
import PanelButton from "../PanelButton"
|
||||
import Gdk from "gi://Gdk"
|
||||
import options from "options"
|
||||
|
||||
const systemtray = await Service.import("systemtray")
|
||||
const { ignore } = options.bar.systray
|
||||
|
||||
const SysTrayItem = (item: TrayItem) => PanelButton({
|
||||
class_name: "tray-item",
|
||||
child: Widget.Icon({ icon: item.bind("icon") }),
|
||||
tooltip_markup: item.bind("tooltip_markup"),
|
||||
setup: self => {
|
||||
const { menu } = item
|
||||
if (!menu)
|
||||
return
|
||||
|
||||
const id = menu.connect("popped-up", () => {
|
||||
self.toggleClassName("active")
|
||||
menu.connect("notify::visible", () => {
|
||||
self.toggleClassName("active", menu.visible)
|
||||
})
|
||||
menu.disconnect(id!)
|
||||
})
|
||||
|
||||
self.connect("destroy", () => menu.disconnect(id))
|
||||
},
|
||||
|
||||
on_primary_click: btn => item.menu?.popup_at_widget(
|
||||
btn, Gdk.Gravity.SOUTH, Gdk.Gravity.NORTH, null),
|
||||
|
||||
on_secondary_click: btn => item.menu?.popup_at_widget(
|
||||
btn, Gdk.Gravity.SOUTH, Gdk.Gravity.NORTH, null),
|
||||
})
|
||||
|
||||
export default () => Widget.Box()
|
||||
.bind("children", systemtray, "items", i => i
|
||||
.filter(({ id }) => !ignore.value.includes(id))
|
||||
.map(SysTrayItem))
|
|
@ -1,98 +0,0 @@
|
|||
import PanelButton from "../PanelButton"
|
||||
import icons from "lib/icons"
|
||||
import asusctl from "service/asusctl"
|
||||
|
||||
const notifications = await Service.import("notifications")
|
||||
const bluetooth = await Service.import("bluetooth")
|
||||
const audio = await Service.import("audio")
|
||||
const network = await Service.import("network")
|
||||
const powerprof = await Service.import("powerprofiles")
|
||||
|
||||
const ProfileIndicator = () => {
|
||||
const visible = asusctl.available
|
||||
? asusctl.bind("profile").as(p => p !== "Balanced")
|
||||
: powerprof.bind("active_profile").as(p => p !== "balanced")
|
||||
|
||||
const icon = asusctl.available
|
||||
? asusctl.bind("profile").as(p => icons.asusctl.profile[p])
|
||||
: powerprof.bind("active_profile").as(p => icons.powerprofile[p])
|
||||
|
||||
return Widget.Icon({ visible, icon })
|
||||
}
|
||||
|
||||
const ModeIndicator = () => {
|
||||
if (!asusctl.available) {
|
||||
return Widget.Icon({
|
||||
setup(self) {
|
||||
Utils.idle(() => self.visible = false)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return Widget.Icon({
|
||||
visible: asusctl.bind("mode").as(m => m !== "Hybrid"),
|
||||
icon: asusctl.bind("mode").as(m => icons.asusctl.mode[m]),
|
||||
})
|
||||
}
|
||||
|
||||
const MicrophoneIndicator = () => Widget.Icon()
|
||||
.hook(audio, self => self.visible =
|
||||
audio.recorders.length > 0
|
||||
|| audio.microphone.is_muted
|
||||
|| false)
|
||||
.hook(audio.microphone, self => {
|
||||
const vol = audio.microphone.is_muted ? 0 : audio.microphone.volume
|
||||
const { muted, low, medium, high } = icons.audio.mic
|
||||
const cons = [[67, high], [34, medium], [1, low], [0, muted]] as const
|
||||
self.icon = cons.find(([n]) => n <= vol * 100)?.[1] || ""
|
||||
})
|
||||
|
||||
const DNDIndicator = () => Widget.Icon({
|
||||
visible: notifications.bind("dnd"),
|
||||
icon: icons.notifications.silent,
|
||||
})
|
||||
|
||||
const BluetoothIndicator = () => Widget.Overlay({
|
||||
class_name: "bluetooth",
|
||||
passThrough: true,
|
||||
visible: bluetooth.bind("enabled"),
|
||||
child: Widget.Icon({
|
||||
icon: icons.bluetooth.enabled,
|
||||
}),
|
||||
overlay: Widget.Label({
|
||||
hpack: "end",
|
||||
vpack: "start",
|
||||
label: bluetooth.bind("connected_devices").as(c => `${c.length}`),
|
||||
visible: bluetooth.bind("connected_devices").as(c => c.length > 0),
|
||||
}),
|
||||
})
|
||||
|
||||
const NetworkIndicator = () => Widget.Icon().hook(network, self => {
|
||||
const icon = network[network.primary || "wifi"]?.icon_name
|
||||
self.icon = icon || ""
|
||||
self.visible = !!icon
|
||||
})
|
||||
|
||||
const AudioIndicator = () => Widget.Icon()
|
||||
.hook(audio.speaker, self => {
|
||||
const vol = audio.speaker.is_muted ? 0 : audio.speaker.volume
|
||||
const { muted, low, medium, high, overamplified } = icons.audio.volume
|
||||
const cons = [[101, overamplified], [67, high], [34, medium], [1, low], [0, muted]] as const
|
||||
self.icon = cons.find(([n]) => n <= vol * 100)?.[1] || ""
|
||||
})
|
||||
|
||||
export default () => PanelButton({
|
||||
window: "quicksettings",
|
||||
on_clicked: () => App.toggleWindow("quicksettings"),
|
||||
on_scroll_up: () => audio.speaker.volume += 0.02,
|
||||
on_scroll_down: () => audio.speaker.volume -= 0.02,
|
||||
child: Widget.Box([
|
||||
ProfileIndicator(),
|
||||
ModeIndicator(),
|
||||
DNDIndicator(),
|
||||
BluetoothIndicator(),
|
||||
NetworkIndicator(),
|
||||
AudioIndicator(),
|
||||
MicrophoneIndicator(),
|
||||
]),
|
||||
})
|
|
@ -1,90 +0,0 @@
|
|||
import { launchApp, icon } from "lib/utils"
|
||||
import icons from "lib/icons"
|
||||
import options from "options"
|
||||
import PanelButton from "../PanelButton"
|
||||
|
||||
const hyprland = await Service.import("hyprland")
|
||||
const apps = await Service.import("applications")
|
||||
const { monochrome, exclusive, iconSize } = options.bar.taskbar
|
||||
const { position } = options.bar
|
||||
|
||||
const focus = (address: string) => hyprland.messageAsync(
|
||||
`dispatch focuswindow address:${address}`)
|
||||
|
||||
const DummyItem = (address: string) => Widget.Box({
|
||||
attribute: { address },
|
||||
visible: false,
|
||||
})
|
||||
|
||||
const AppItem = (address: string) => {
|
||||
const client = hyprland.getClient(address)
|
||||
if (!client || client.class === "")
|
||||
return DummyItem(address)
|
||||
|
||||
const app = apps.list.find(app => app.match(client.class))
|
||||
|
||||
const btn = PanelButton({
|
||||
class_name: "panel-button",
|
||||
tooltip_text: Utils.watch(client.title, hyprland, () =>
|
||||
hyprland.getClient(address)?.title || "",
|
||||
),
|
||||
on_primary_click: () => focus(address),
|
||||
on_middle_click: () => app && launchApp(app),
|
||||
child: Widget.Icon({
|
||||
size: iconSize.bind(),
|
||||
icon: monochrome.bind().as(m => icon(
|
||||
(app?.icon_name || client.class) + (m ? "-symbolic" : ""),
|
||||
icons.fallback.executable + (m ? "-symbolic" : ""),
|
||||
)),
|
||||
}),
|
||||
})
|
||||
|
||||
return Widget.Box(
|
||||
{
|
||||
attribute: { address },
|
||||
visible: Utils.watch(true, [exclusive, hyprland], () => {
|
||||
return exclusive.value
|
||||
? hyprland.active.workspace.id === client.workspace.id
|
||||
: true
|
||||
}),
|
||||
},
|
||||
Widget.Overlay({
|
||||
child: btn,
|
||||
pass_through: true,
|
||||
overlay: Widget.Box({
|
||||
className: "indicator",
|
||||
hpack: "center",
|
||||
vpack: position.bind().as(p => p === "top" ? "start" : "end"),
|
||||
setup: w => w.hook(hyprland, () => {
|
||||
w.toggleClassName("active", hyprland.active.client.address === address)
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
function sortItems<T extends { attribute: { address: string } }>(arr: T[]) {
|
||||
return arr.sort(({ attribute: a }, { attribute: b }) => {
|
||||
const aclient = hyprland.getClient(a.address)!
|
||||
const bclient = hyprland.getClient(b.address)!
|
||||
return aclient.workspace.id - bclient.workspace.id
|
||||
})
|
||||
}
|
||||
|
||||
export default () => Widget.Box({
|
||||
class_name: "taskbar",
|
||||
children: sortItems(hyprland.clients.map(c => AppItem(c.address))),
|
||||
setup: w => w
|
||||
.hook(hyprland, (w, address?: string) => {
|
||||
if (typeof address === "string")
|
||||
w.children = w.children.filter(ch => ch.attribute.address !== address)
|
||||
}, "client-removed")
|
||||
.hook(hyprland, (w, address?: string) => {
|
||||
if (typeof address === "string")
|
||||
w.children = sortItems([...w.children, AppItem(address)])
|
||||
}, "client-added")
|
||||
.hook(hyprland, (w, event?: string) => {
|
||||
if (event === "movewindow")
|
||||
w.children = sortItems(w.children)
|
||||
}, "event"),
|
||||
})
|
|
@ -1,38 +0,0 @@
|
|||
import PanelButton from "../PanelButton"
|
||||
import options from "options"
|
||||
import { sh, range } from "lib/utils"
|
||||
|
||||
const hyprland = await Service.import("hyprland")
|
||||
const { workspaces } = options.bar.workspaces
|
||||
|
||||
const dispatch = (arg: string | number) => {
|
||||
sh(`hyprctl dispatch workspace ${arg}`)
|
||||
}
|
||||
|
||||
const Workspaces = (ws: number) => Widget.Box({
|
||||
children: range(ws || 20).map(i => Widget.Label({
|
||||
attribute: i,
|
||||
vpack: "center",
|
||||
label: `${i}`,
|
||||
setup: self => self.hook(hyprland, () => {
|
||||
self.toggleClassName("active", hyprland.active.workspace.id === i)
|
||||
self.toggleClassName("occupied", (hyprland.getWorkspace(i)?.windows || 0) > 0)
|
||||
}),
|
||||
})),
|
||||
setup: box => {
|
||||
if (ws === 0) {
|
||||
box.hook(hyprland.active.workspace, () => box.children.map(btn => {
|
||||
btn.visible = hyprland.workspaces.some(ws => ws.id === btn.attribute)
|
||||
}))
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
export default () => PanelButton({
|
||||
window: "overview",
|
||||
class_name: "workspaces",
|
||||
on_scroll_up: () => dispatch("m+1"),
|
||||
on_scroll_down: () => dispatch("m-1"),
|
||||
on_clicked: () => App.toggleWindow("overview"),
|
||||
child: workspaces.bind().as(Workspaces),
|
||||
})
|
|
@ -1,37 +0,0 @@
|
|||
import { clock, uptime } from "lib/variables"
|
||||
|
||||
function up(up: number) {
|
||||
const h = Math.floor(up / 60)
|
||||
const m = Math.floor(up % 60)
|
||||
return `uptime: ${h}:${m < 10 ? "0" + m : m}`
|
||||
}
|
||||
|
||||
export default () => Widget.Box({
|
||||
vertical: true,
|
||||
class_name: "date-column vertical",
|
||||
children: [
|
||||
Widget.Box({
|
||||
class_name: "clock-box",
|
||||
vertical: true,
|
||||
children: [
|
||||
Widget.Label({
|
||||
class_name: "clock",
|
||||
label: clock.bind().as(t => t.format("%H:%M")!),
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: "uptime",
|
||||
label: uptime.bind().as(up),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
Widget.Box({
|
||||
class_name: "calendar",
|
||||
children: [
|
||||
Widget.Calendar({
|
||||
hexpand: true,
|
||||
hpack: "center",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
})
|
|
@ -1,36 +0,0 @@
|
|||
import PopupWindow from "widget/PopupWindow"
|
||||
import NotificationColumn from "./NotificationColumn"
|
||||
import DateColumn from "./DateColumn"
|
||||
import options from "options"
|
||||
|
||||
const { bar, datemenu } = options
|
||||
const pos = bar.position.bind()
|
||||
const layout = Utils.derive([bar.position, datemenu.position], (bar, qs) =>
|
||||
`${bar}-${qs}` as const,
|
||||
)
|
||||
|
||||
const Settings = () => Widget.Box({
|
||||
class_name: "datemenu horizontal",
|
||||
vexpand: false,
|
||||
children: [
|
||||
NotificationColumn(),
|
||||
Widget.Separator({ orientation: 1 }),
|
||||
DateColumn(),
|
||||
],
|
||||
})
|
||||
|
||||
const DateMenu = () => PopupWindow({
|
||||
name: "datemenu",
|
||||
exclusivity: "exclusive",
|
||||
transition: pos.as(pos => pos === "top" ? "slide_down" : "slide_up"),
|
||||
layout: layout.value,
|
||||
child: Settings(),
|
||||
})
|
||||
|
||||
export function setupDateMenu() {
|
||||
App.addWindow(DateMenu())
|
||||
layout.connect("changed", () => {
|
||||
App.removeWindow("datemenu")
|
||||
App.addWindow(DateMenu())
|
||||
})
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
import { type Notification as Notif } from "types/service/notifications"
|
||||
import Notification from "widget/notifications/Notification"
|
||||
import options from "options"
|
||||
import icons from "lib/icons"
|
||||
|
||||
const notifications = await Service.import("notifications")
|
||||
const notifs = notifications.bind("notifications")
|
||||
|
||||
const Animated = (n: Notif) => Widget.Revealer({
|
||||
transition_duration: options.transition.value,
|
||||
transition: "slide_down",
|
||||
child: Notification(n),
|
||||
setup: self => Utils.timeout(options.transition.value, () => {
|
||||
if (!self.is_destroyed)
|
||||
self.reveal_child = true
|
||||
}),
|
||||
})
|
||||
|
||||
const ClearButton = () => Widget.Button({
|
||||
on_clicked: notifications.clear,
|
||||
sensitive: notifs.as(n => n.length > 0),
|
||||
child: Widget.Box({
|
||||
children: [
|
||||
Widget.Label("Clear "),
|
||||
Widget.Icon({
|
||||
icon: notifs.as(n => icons.trash[n.length > 0 ? "full" : "empty"]),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
})
|
||||
|
||||
const Header = () => Widget.Box({
|
||||
class_name: "header",
|
||||
children: [
|
||||
Widget.Label({ label: "Notifications", hexpand: true, xalign: 0 }),
|
||||
ClearButton(),
|
||||
],
|
||||
})
|
||||
|
||||
const NotificationList = () => {
|
||||
const map: Map<number, ReturnType<typeof Animated>> = new Map
|
||||
const box = Widget.Box({
|
||||
vertical: true,
|
||||
children: notifications.notifications.map(n => {
|
||||
const w = Animated(n)
|
||||
map.set(n.id, w)
|
||||
return w
|
||||
}),
|
||||
visible: notifs.as(n => n.length > 0),
|
||||
})
|
||||
|
||||
function remove(_: unknown, id: number) {
|
||||
const n = map.get(id)
|
||||
if (n) {
|
||||
n.reveal_child = false
|
||||
Utils.timeout(options.transition.value, () => {
|
||||
n.destroy()
|
||||
map.delete(id)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return box
|
||||
.hook(notifications, remove, "closed")
|
||||
.hook(notifications, (_, id: number) => {
|
||||
if (id !== undefined) {
|
||||
if (map.has(id))
|
||||
remove(null, id)
|
||||
|
||||
const n = notifications.getNotification(id)!
|
||||
|
||||
const w = Animated(n)
|
||||
map.set(id, w)
|
||||
box.children = [w, ...box.children]
|
||||
}
|
||||
}, "notified")
|
||||
}
|
||||
|
||||
const Placeholder = () => Widget.Box({
|
||||
class_name: "placeholder",
|
||||
vertical: true,
|
||||
vpack: "center",
|
||||
hpack: "center",
|
||||
vexpand: true,
|
||||
hexpand: true,
|
||||
visible: notifs.as(n => n.length === 0),
|
||||
children: [
|
||||
Widget.Icon(icons.notifications.silent),
|
||||
Widget.Label("Your inbox is empty"),
|
||||
],
|
||||
})
|
||||
|
||||
export default () => Widget.Box({
|
||||
class_name: "notifications",
|
||||
css: options.notifications.width.bind().as(w => `min-width: ${w}px`),
|
||||
vertical: true,
|
||||
children: [
|
||||
Header(),
|
||||
Widget.Scrollable({
|
||||
vexpand: true,
|
||||
hscroll: "never",
|
||||
class_name: "notification-scrollable",
|
||||
child: Widget.Box({
|
||||
class_name: "notification-list vertical",
|
||||
vertical: true,
|
||||
children: [
|
||||
NotificationList(),
|
||||
Placeholder(),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
],
|
||||
})
|
|
@ -1,40 +0,0 @@
|
|||
import options from "options"
|
||||
import { matugen } from "lib/matugen"
|
||||
const mpris = await Service.import("mpris")
|
||||
|
||||
const pref = () => options.bar.media.preferred.value
|
||||
|
||||
export default (monitor: number) => Widget.Window({
|
||||
monitor,
|
||||
layer: "bottom",
|
||||
name: `desktop${monitor}`,
|
||||
class_name: "desktop",
|
||||
anchor: ["top", "bottom", "left", "right"],
|
||||
child: Widget.Box({
|
||||
expand: true,
|
||||
css: options.theme.dark.primary.bg.bind().as(c => `
|
||||
transition: 500ms;
|
||||
background-color: ${c}`),
|
||||
child: Widget.Box({
|
||||
class_name: "wallpaper",
|
||||
expand: true,
|
||||
vpack: "center",
|
||||
hpack: "center",
|
||||
setup: self => self
|
||||
.hook(mpris, () => {
|
||||
const img = mpris.getPlayer(pref())!.cover_path
|
||||
matugen("image", img)
|
||||
Utils.timeout(500, () => self.css = `
|
||||
background-image: url('${img}');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
transition: 200ms;
|
||||
min-width: 700px;
|
||||
min-height: 700px;
|
||||
border-radius: 30px;
|
||||
box-shadow: 25px 25px 30px 0 rgba(0,0,0,0.5);`,
|
||||
)
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
})
|
|
@ -1,130 +0,0 @@
|
|||
import { type Application } from "types/service/applications"
|
||||
import { launchApp, icon } from "lib/utils"
|
||||
import options from "options"
|
||||
import icons from "lib/icons"
|
||||
|
||||
const apps = await Service.import("applications")
|
||||
const { query } = apps
|
||||
const { iconSize } = options.launcher.apps
|
||||
|
||||
const QuickAppButton = (app: Application) => Widget.Button({
|
||||
hexpand: true,
|
||||
tooltip_text: app.name,
|
||||
on_clicked: () => {
|
||||
App.closeWindow("launcher")
|
||||
launchApp(app)
|
||||
},
|
||||
child: Widget.Icon({
|
||||
size: iconSize.bind(),
|
||||
icon: icon(app.icon_name, icons.fallback.executable),
|
||||
}),
|
||||
})
|
||||
|
||||
const AppItem = (app: Application) => {
|
||||
const title = Widget.Label({
|
||||
class_name: "title",
|
||||
label: app.name,
|
||||
hexpand: true,
|
||||
xalign: 0,
|
||||
vpack: "center",
|
||||
truncate: "end",
|
||||
})
|
||||
|
||||
const description = Widget.Label({
|
||||
class_name: "description",
|
||||
label: app.description || "",
|
||||
hexpand: true,
|
||||
wrap: true,
|
||||
max_width_chars: 30,
|
||||
xalign: 0,
|
||||
justification: "left",
|
||||
vpack: "center",
|
||||
})
|
||||
|
||||
const appicon = Widget.Icon({
|
||||
icon: icon(app.icon_name, icons.fallback.executable),
|
||||
size: iconSize.bind(),
|
||||
})
|
||||
|
||||
const textBox = Widget.Box({
|
||||
vertical: true,
|
||||
vpack: "center",
|
||||
children: app.description ? [title, description] : [title],
|
||||
})
|
||||
|
||||
return Widget.Button({
|
||||
class_name: "app-item",
|
||||
attribute: { app },
|
||||
child: Widget.Box({
|
||||
children: [appicon, textBox],
|
||||
}),
|
||||
on_clicked: () => {
|
||||
App.closeWindow("launcher")
|
||||
launchApp(app)
|
||||
},
|
||||
})
|
||||
}
|
||||
export function Favorites() {
|
||||
const favs = options.launcher.apps.favorites.bind()
|
||||
return Widget.Revealer({
|
||||
visible: favs.as(f => f.length > 0),
|
||||
child: Widget.Box({
|
||||
vertical: true,
|
||||
children: favs.as(favs => favs.flatMap(fs => [
|
||||
Widget.Separator(),
|
||||
Widget.Box({
|
||||
class_name: "quicklaunch horizontal",
|
||||
children: fs
|
||||
.map(f => query(f)?.[0])
|
||||
.filter(f => f)
|
||||
.map(QuickAppButton),
|
||||
}),
|
||||
])),
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
export function Launcher() {
|
||||
const applist = Variable(query(""))
|
||||
const max = options.launcher.apps.max
|
||||
let first = applist.value[0]
|
||||
|
||||
function SeparatedAppItem(app: Application) {
|
||||
return Widget.Revealer(
|
||||
{ attribute: { app } },
|
||||
Widget.Box(
|
||||
{ vertical: true },
|
||||
Widget.Separator(),
|
||||
AppItem(app),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
const list = Widget.Box({
|
||||
vertical: true,
|
||||
children: applist.bind().as(list => list.map(SeparatedAppItem)),
|
||||
setup: self => self
|
||||
.hook(apps, () => applist.value = query(""), "notify::frequents"),
|
||||
})
|
||||
|
||||
return Object.assign(list, {
|
||||
filter(text: string | null) {
|
||||
first = query(text || "")[0]
|
||||
list.children.reduce((i, item) => {
|
||||
if (!text || i >= max.value) {
|
||||
item.reveal_child = false
|
||||
return i
|
||||
}
|
||||
if (item.attribute.app.match(text)) {
|
||||
item.reveal_child = true
|
||||
return ++i
|
||||
}
|
||||
item.reveal_child = false
|
||||
return i
|
||||
}, 0)
|
||||
},
|
||||
launchFirst() {
|
||||
launchApp(first)
|
||||
},
|
||||
})
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
import { type Binding } from "lib/utils"
|
||||
import PopupWindow, { Padding } from "widget/PopupWindow"
|
||||
import icons from "lib/icons"
|
||||
import options from "options"
|
||||
import nix from "service/nix"
|
||||
import * as AppLauncher from "./AppLauncher"
|
||||
import * as NixRun from "./NixRun"
|
||||
import * as ShRun from "./ShRun"
|
||||
|
||||
const { width, margin } = options.launcher
|
||||
const isnix = nix.available
|
||||
|
||||
function Launcher() {
|
||||
const favs = AppLauncher.Favorites()
|
||||
const applauncher = AppLauncher.Launcher()
|
||||
const sh = ShRun.ShRun()
|
||||
const shicon = ShRun.Icon()
|
||||
const nix = NixRun.NixRun()
|
||||
const nixload = NixRun.Spinner()
|
||||
|
||||
function HelpButton(cmd: string, desc: string | Binding<string>) {
|
||||
return Widget.Box(
|
||||
{ vertical: true },
|
||||
Widget.Separator(),
|
||||
Widget.Button(
|
||||
{
|
||||
class_name: "help",
|
||||
on_clicked: () => {
|
||||
entry.grab_focus()
|
||||
entry.text = `:${cmd} `
|
||||
entry.set_position(-1)
|
||||
},
|
||||
},
|
||||
Widget.Box([
|
||||
Widget.Label({
|
||||
class_name: "name",
|
||||
label: `:${cmd}`,
|
||||
}),
|
||||
Widget.Label({
|
||||
hexpand: true,
|
||||
hpack: "end",
|
||||
class_name: "description",
|
||||
label: desc,
|
||||
}),
|
||||
]),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
const help = Widget.Revealer({
|
||||
child: Widget.Box(
|
||||
{ vertical: true },
|
||||
HelpButton("sh", "run a binary"),
|
||||
isnix ? HelpButton("nx", options.launcher.nix.pkgs.bind().as(pkg =>
|
||||
`run a nix package from ${pkg}`,
|
||||
)) : Widget.Box(),
|
||||
),
|
||||
})
|
||||
|
||||
const entry = Widget.Entry({
|
||||
hexpand: true,
|
||||
primary_icon_name: icons.ui.search,
|
||||
on_accept: ({ text }) => {
|
||||
if (text?.startsWith(":nx"))
|
||||
nix.run(text.substring(3))
|
||||
else if (text?.startsWith(":sh"))
|
||||
sh.run(text.substring(3))
|
||||
else
|
||||
applauncher.launchFirst()
|
||||
|
||||
App.toggleWindow("launcher")
|
||||
entry.text = ""
|
||||
},
|
||||
on_change: ({ text }) => {
|
||||
text ||= ""
|
||||
favs.reveal_child = text === ""
|
||||
help.reveal_child = text.split(" ").length === 1 && text?.startsWith(":")
|
||||
|
||||
if (text?.startsWith(":nx"))
|
||||
nix.filter(text.substring(3))
|
||||
else
|
||||
nix.filter("")
|
||||
|
||||
if (text?.startsWith(":sh"))
|
||||
sh.filter(text.substring(3))
|
||||
else
|
||||
sh.filter("")
|
||||
|
||||
if (!text?.startsWith(":"))
|
||||
applauncher.filter(text)
|
||||
},
|
||||
})
|
||||
|
||||
function focus() {
|
||||
entry.text = "Search"
|
||||
entry.set_position(-1)
|
||||
entry.select_region(0, -1)
|
||||
entry.grab_focus()
|
||||
favs.reveal_child = true
|
||||
}
|
||||
|
||||
const layout = Widget.Box({
|
||||
css: width.bind().as(v => `min-width: ${v}pt;`),
|
||||
class_name: "launcher",
|
||||
vertical: true,
|
||||
vpack: "start",
|
||||
setup: self => self.hook(App, (_, win, visible) => {
|
||||
if (win !== "launcher")
|
||||
return
|
||||
|
||||
entry.text = ""
|
||||
if (visible)
|
||||
focus()
|
||||
}),
|
||||
children: [
|
||||
Widget.Box([entry, nixload, shicon]),
|
||||
favs,
|
||||
help,
|
||||
applauncher,
|
||||
nix,
|
||||
sh,
|
||||
],
|
||||
})
|
||||
|
||||
return Widget.Box(
|
||||
{ vertical: true, css: "padding: 1px" },
|
||||
Padding("launcher", {
|
||||
css: margin.bind().as(v => `min-height: ${v}pt;`),
|
||||
vexpand: false,
|
||||
}),
|
||||
layout,
|
||||
)
|
||||
}
|
||||
|
||||
export default () => PopupWindow({
|
||||
name: "launcher",
|
||||
layout: "top",
|
||||
child: Launcher(),
|
||||
})
|
|
@ -1,118 +0,0 @@
|
|||
import icons from "lib/icons"
|
||||
import nix, { type Nixpkg } from "service/nix"
|
||||
|
||||
const iconVisible = Variable(false)
|
||||
|
||||
function Item(pkg: Nixpkg) {
|
||||
const name = Widget.Label({
|
||||
class_name: "name",
|
||||
label: pkg.name.split(".").at(-1),
|
||||
})
|
||||
|
||||
const subpkg = pkg.name.includes(".") ? Widget.Label({
|
||||
class_name: "description",
|
||||
hpack: "end",
|
||||
hexpand: true,
|
||||
label: ` ${pkg.name.split(".").slice(0, -1).join(".")}`,
|
||||
}) : null
|
||||
|
||||
const version = Widget.Label({
|
||||
class_name: "version",
|
||||
label: pkg.version,
|
||||
hexpand: true,
|
||||
hpack: "end",
|
||||
})
|
||||
|
||||
const description = pkg.description ? Widget.Label({
|
||||
class_name: "description",
|
||||
label: pkg.description,
|
||||
justification: "left",
|
||||
wrap: true,
|
||||
hpack: "start",
|
||||
max_width_chars: 40,
|
||||
}) : null
|
||||
|
||||
return Widget.Box(
|
||||
{
|
||||
attribute: { name: pkg.name },
|
||||
vertical: true,
|
||||
},
|
||||
Widget.Separator(),
|
||||
Widget.Button(
|
||||
{
|
||||
class_name: "nix-item",
|
||||
on_clicked: () => {
|
||||
nix.run(pkg.name)
|
||||
App.closeWindow("launcher")
|
||||
},
|
||||
},
|
||||
Widget.Box(
|
||||
{ vertical: true },
|
||||
Widget.Box([name, version]),
|
||||
Widget.Box([
|
||||
description as ReturnType<typeof Widget.Label>,
|
||||
subpkg as ReturnType<typeof Widget.Label>,
|
||||
]),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
export function Spinner() {
|
||||
const icon = Widget.Icon({
|
||||
icon: icons.nix.nix,
|
||||
class_name: "spinner",
|
||||
css: `
|
||||
@keyframes spin {
|
||||
to { -gtk-icon-transform: rotate(1turn); }
|
||||
}
|
||||
|
||||
image.spinning {
|
||||
animation-name: spin;
|
||||
animation-duration: 1s;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
`,
|
||||
setup: self => self.hook(nix, () => {
|
||||
self.toggleClassName("spinning", !nix.ready)
|
||||
}),
|
||||
})
|
||||
|
||||
return Widget.Revealer({
|
||||
transition: "slide_left",
|
||||
child: icon,
|
||||
reveal_child: Utils.merge([
|
||||
nix.bind("ready"),
|
||||
iconVisible.bind(),
|
||||
], (ready, show) => !ready || show),
|
||||
})
|
||||
}
|
||||
|
||||
export function NixRun() {
|
||||
const list = Widget.Box<ReturnType<typeof Item>>({
|
||||
vertical: true,
|
||||
})
|
||||
|
||||
const revealer = Widget.Revealer({
|
||||
child: list,
|
||||
})
|
||||
|
||||
async function filter(term: string) {
|
||||
iconVisible.value = Boolean(term)
|
||||
|
||||
if (!term)
|
||||
revealer.reveal_child = false
|
||||
|
||||
if (term.trim()) {
|
||||
const found = await nix.query(term)
|
||||
list.children = found.map(k => Item(nix.db[k]))
|
||||
revealer.reveal_child = true
|
||||
}
|
||||
}
|
||||
|
||||
return Object.assign(revealer, {
|
||||
filter,
|
||||
run: nix.run,
|
||||
})
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
import icons from "lib/icons"
|
||||
import sh from "service/sh"
|
||||
|
||||
const iconVisible = Variable(false)
|
||||
|
||||
function Item(bin: string) {
|
||||
return Widget.Box(
|
||||
{
|
||||
attribute: { bin },
|
||||
vertical: true,
|
||||
},
|
||||
Widget.Separator(),
|
||||
Widget.Button({
|
||||
child: Widget.Label({
|
||||
label: bin,
|
||||
hpack: "start",
|
||||
}),
|
||||
class_name: "sh-item",
|
||||
on_clicked: () => {
|
||||
Utils.execAsync(bin)
|
||||
App.closeWindow("launcher")
|
||||
},
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
export function Icon() {
|
||||
const icon = Widget.Icon({
|
||||
icon: icons.app.terminal,
|
||||
class_name: "spinner",
|
||||
})
|
||||
|
||||
return Widget.Revealer({
|
||||
transition: "slide_left",
|
||||
child: icon,
|
||||
reveal_child: iconVisible.bind(),
|
||||
})
|
||||
}
|
||||
|
||||
export function ShRun() {
|
||||
const list = Widget.Box<ReturnType<typeof Item>>({
|
||||
vertical: true,
|
||||
})
|
||||
|
||||
const revealer = Widget.Revealer({
|
||||
child: list,
|
||||
})
|
||||
|
||||
async function filter(term: string) {
|
||||
iconVisible.value = Boolean(term)
|
||||
|
||||
if (!term)
|
||||
revealer.reveal_child = false
|
||||
|
||||
if (term.trim()) {
|
||||
const found = await sh.query(term)
|
||||
list.children = found.map(Item)
|
||||
revealer.reveal_child = true
|
||||
}
|
||||
}
|
||||
|
||||
return Object.assign(revealer, {
|
||||
filter,
|
||||
run: sh.run,
|
||||
})
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
import { type Notification } from "types/service/notifications"
|
||||
import GLib from "gi://GLib"
|
||||
import icons from "lib/icons"
|
||||
|
||||
const time = (time: number, format = "%H:%M") => GLib.DateTime
|
||||
.new_from_unix_local(time)
|
||||
.format(format)
|
||||
|
||||
const NotificationIcon = ({ app_entry, app_icon, image }: Notification) => {
|
||||
if (image) {
|
||||
return Widget.Box({
|
||||
vpack: "start",
|
||||
hexpand: false,
|
||||
class_name: "icon img",
|
||||
css: `
|
||||
background-image: url("${image}");
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
min-width: 78px;
|
||||
min-height: 78px;
|
||||
`,
|
||||
})
|
||||
}
|
||||
|
||||
let icon = icons.fallback.notification
|
||||
if (Utils.lookUpIcon(app_icon))
|
||||
icon = app_icon
|
||||
|
||||
if (Utils.lookUpIcon(app_entry || ""))
|
||||
icon = app_entry || ""
|
||||
|
||||
return Widget.Box({
|
||||
vpack: "start",
|
||||
hexpand: false,
|
||||
class_name: "icon",
|
||||
css: `
|
||||
min-width: 78px;
|
||||
min-height: 78px;
|
||||
`,
|
||||
child: Widget.Icon({
|
||||
icon,
|
||||
size: 58,
|
||||
hpack: "center", hexpand: true,
|
||||
vpack: "center", vexpand: true,
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
export default (notification: Notification) => {
|
||||
const content = Widget.Box({
|
||||
class_name: "content",
|
||||
children: [
|
||||
NotificationIcon(notification),
|
||||
Widget.Box({
|
||||
hexpand: true,
|
||||
vertical: true,
|
||||
children: [
|
||||
Widget.Box({
|
||||
children: [
|
||||
Widget.Label({
|
||||
class_name: "title",
|
||||
xalign: 0,
|
||||
justification: "left",
|
||||
hexpand: true,
|
||||
max_width_chars: 24,
|
||||
truncate: "end",
|
||||
wrap: true,
|
||||
label: notification.summary.trim(),
|
||||
use_markup: true,
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: "time",
|
||||
vpack: "start",
|
||||
label: time(notification.time),
|
||||
}),
|
||||
Widget.Button({
|
||||
class_name: "close-button",
|
||||
vpack: "start",
|
||||
child: Widget.Icon("window-close-symbolic"),
|
||||
on_clicked: notification.close,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: "description",
|
||||
hexpand: true,
|
||||
use_markup: true,
|
||||
xalign: 0,
|
||||
justification: "left",
|
||||
label: notification.body.trim(),
|
||||
max_width_chars: 24,
|
||||
wrap: true,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
||||
const actionsbox = notification.actions.length > 0 ? Widget.Revealer({
|
||||
transition: "slide_down",
|
||||
child: Widget.EventBox({
|
||||
child: Widget.Box({
|
||||
class_name: "actions horizontal",
|
||||
children: notification.actions.map(action => Widget.Button({
|
||||
class_name: "action-button",
|
||||
on_clicked: () => notification.invoke(action.id),
|
||||
hexpand: true,
|
||||
child: Widget.Label(action.label),
|
||||
})),
|
||||
}),
|
||||
}),
|
||||
}) : null
|
||||
|
||||
const eventbox = Widget.EventBox({
|
||||
vexpand: false,
|
||||
on_primary_click: notification.dismiss,
|
||||
on_hover() {
|
||||
if (actionsbox)
|
||||
actionsbox.reveal_child = true
|
||||
},
|
||||
on_hover_lost() {
|
||||
if (actionsbox)
|
||||
actionsbox.reveal_child = true
|
||||
|
||||
notification.dismiss()
|
||||
},
|
||||
child: Widget.Box({
|
||||
vertical: true,
|
||||
children: actionsbox ? [content, actionsbox] : [content],
|
||||
}),
|
||||
})
|
||||
|
||||
return Widget.Box({
|
||||
class_name: `notification ${notification.urgency}`,
|
||||
child: eventbox,
|
||||
})
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
import Notification from "./Notification"
|
||||
import options from "options"
|
||||
|
||||
const notifications = await Service.import("notifications")
|
||||
const { transition } = options
|
||||
const { position } = options.notifications
|
||||
const { timeout, idle } = Utils
|
||||
|
||||
function Animated(id: number) {
|
||||
const n = notifications.getNotification(id)!
|
||||
const widget = Notification(n)
|
||||
|
||||
const inner = Widget.Revealer({
|
||||
transition: "slide_left",
|
||||
transition_duration: transition.value,
|
||||
child: widget,
|
||||
})
|
||||
|
||||
const outer = Widget.Revealer({
|
||||
transition: "slide_down",
|
||||
transition_duration: transition.value,
|
||||
child: inner,
|
||||
})
|
||||
|
||||
const box = Widget.Box({
|
||||
hpack: "end",
|
||||
child: outer,
|
||||
})
|
||||
|
||||
idle(() => {
|
||||
outer.reveal_child = true
|
||||
timeout(transition.value, () => {
|
||||
inner.reveal_child = true
|
||||
})
|
||||
})
|
||||
|
||||
return Object.assign(box, {
|
||||
dismiss() {
|
||||
inner.reveal_child = false
|
||||
timeout(transition.value, () => {
|
||||
outer.reveal_child = false
|
||||
timeout(transition.value, () => {
|
||||
box.destroy()
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
function PopupList() {
|
||||
const map: Map<number, ReturnType<typeof Animated>> = new Map
|
||||
const box = Widget.Box({
|
||||
hpack: "end",
|
||||
vertical: true,
|
||||
css: options.notifications.width.bind().as(w => `min-width: ${w}px;`),
|
||||
})
|
||||
|
||||
function remove(_: unknown, id: number) {
|
||||
map.get(id)?.dismiss()
|
||||
map.delete(id)
|
||||
}
|
||||
|
||||
return box
|
||||
.hook(notifications, (_, id: number) => {
|
||||
if (id !== undefined) {
|
||||
if (map.has(id))
|
||||
remove(null, id)
|
||||
|
||||
if (notifications.dnd)
|
||||
return
|
||||
|
||||
const w = Animated(id)
|
||||
map.set(id, w)
|
||||
box.children = [w, ...box.children]
|
||||
}
|
||||
}, "notified")
|
||||
.hook(notifications, remove, "dismissed")
|
||||
.hook(notifications, remove, "closed")
|
||||
}
|
||||
|
||||
export default (monitor: number) => Widget.Window({
|
||||
monitor,
|
||||
name: `notifications${monitor}`,
|
||||
anchor: position.bind(),
|
||||
class_name: "notifications",
|
||||
child: Widget.Box({
|
||||
css: "padding: 2px;",
|
||||
child: PopupList(),
|
||||
}),
|
||||
})
|
|
@ -1,111 +0,0 @@
|
|||
import { icon } from "lib/utils"
|
||||
import icons from "lib/icons"
|
||||
import Progress from "./Progress"
|
||||
import brightness from "service/brightness"
|
||||
import options from "options"
|
||||
|
||||
const audio = await Service.import("audio")
|
||||
const { progress, microphone } = options.osd
|
||||
|
||||
const DELAY = 2500
|
||||
|
||||
function OnScreenProgress(vertical: boolean) {
|
||||
const indicator = Widget.Icon({
|
||||
size: 42,
|
||||
vpack: "start",
|
||||
})
|
||||
const progress = Progress({
|
||||
vertical,
|
||||
width: vertical ? 42 : 300,
|
||||
height: vertical ? 300 : 42,
|
||||
child: indicator,
|
||||
})
|
||||
|
||||
const revealer = Widget.Revealer({
|
||||
transition: "slide_left",
|
||||
child: progress,
|
||||
})
|
||||
|
||||
let count = 0
|
||||
function show(value: number, icon: string) {
|
||||
revealer.reveal_child = true
|
||||
indicator.icon = icon
|
||||
progress.setValue(value)
|
||||
count++
|
||||
Utils.timeout(DELAY, () => {
|
||||
count--
|
||||
|
||||
if (count === 0)
|
||||
revealer.reveal_child = false
|
||||
})
|
||||
}
|
||||
|
||||
return revealer
|
||||
.hook(brightness, () => show(
|
||||
brightness.screen,
|
||||
icons.brightness.screen,
|
||||
), "notify::screen")
|
||||
.hook(brightness, () => show(
|
||||
brightness.kbd,
|
||||
icons.brightness.keyboard,
|
||||
), "notify::kbd")
|
||||
.hook(audio.speaker, () => show(
|
||||
audio.speaker.volume,
|
||||
icon(audio.speaker.icon_name || "", icons.audio.type.speaker),
|
||||
), "notify::volume")
|
||||
}
|
||||
|
||||
function MicrophoneMute() {
|
||||
const icon = Widget.Icon({
|
||||
class_name: "microphone",
|
||||
})
|
||||
|
||||
const revealer = Widget.Revealer({
|
||||
transition: "slide_up",
|
||||
child: icon,
|
||||
})
|
||||
|
||||
let count = 0
|
||||
let mute = audio.microphone.stream?.is_muted ?? false
|
||||
|
||||
return revealer.hook(audio.microphone, () => Utils.idle(() => {
|
||||
if (mute !== audio.microphone.stream?.is_muted) {
|
||||
mute = audio.microphone.stream!.is_muted
|
||||
icon.icon = icons.audio.mic[mute ? "muted" : "high"]
|
||||
revealer.reveal_child = true
|
||||
count++
|
||||
|
||||
Utils.timeout(DELAY, () => {
|
||||
count--
|
||||
if (count === 0)
|
||||
revealer.reveal_child = false
|
||||
})
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
export default (monitor: number) => Widget.Window({
|
||||
monitor,
|
||||
name: `indicator${monitor}`,
|
||||
class_name: "indicator",
|
||||
layer: "overlay",
|
||||
click_through: true,
|
||||
anchor: ["right", "left", "top", "bottom"],
|
||||
child: Widget.Box({
|
||||
css: "padding: 2px;",
|
||||
expand: true,
|
||||
child: Widget.Overlay(
|
||||
{ child: Widget.Box({ expand: true }) },
|
||||
Widget.Box({
|
||||
hpack: progress.pack.h.bind(),
|
||||
vpack: progress.pack.v.bind(),
|
||||
child: progress.vertical.bind().as(OnScreenProgress),
|
||||
}),
|
||||
Widget.Box({
|
||||
hpack: microphone.pack.h.bind(),
|
||||
vpack: microphone.pack.v.bind(),
|
||||
child: MicrophoneMute(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
})
|
|
@ -1,74 +0,0 @@
|
|||
import type Gtk from "gi://Gtk?version=3.0"
|
||||
import GLib from "gi://GLib?version=2.0"
|
||||
import { range } from "lib/utils"
|
||||
import options from "options"
|
||||
|
||||
type ProgressProps = {
|
||||
height?: number
|
||||
width?: number
|
||||
vertical?: boolean
|
||||
child: Gtk.Widget
|
||||
}
|
||||
|
||||
export default ({
|
||||
height = 18,
|
||||
width = 180,
|
||||
vertical = false,
|
||||
child,
|
||||
}: ProgressProps) => {
|
||||
const fill = Widget.Box({
|
||||
class_name: "fill",
|
||||
hexpand: vertical,
|
||||
vexpand: !vertical,
|
||||
hpack: vertical ? "fill" : "start",
|
||||
vpack: vertical ? "end" : "fill",
|
||||
child,
|
||||
})
|
||||
|
||||
const container = Widget.Box({
|
||||
class_name: "progress",
|
||||
child: fill,
|
||||
css: `
|
||||
min-width: ${width}px;
|
||||
min-height: ${height}px;
|
||||
`,
|
||||
})
|
||||
|
||||
let fill_size = 0
|
||||
let animations: number[] = []
|
||||
|
||||
return Object.assign(container, {
|
||||
setValue(value: number) {
|
||||
if (value < 0)
|
||||
return
|
||||
|
||||
if (animations.length > 0) {
|
||||
for (const id of animations)
|
||||
GLib.source_remove(id)
|
||||
|
||||
animations = []
|
||||
}
|
||||
|
||||
const axis = vertical ? "height" : "width"
|
||||
const axisv = vertical ? height : width
|
||||
const min = vertical ? width : height
|
||||
const preferred = (axisv - min) * value + min
|
||||
|
||||
if (!fill_size) {
|
||||
fill_size = preferred
|
||||
fill.css = `min-${axis}: ${preferred}px;`
|
||||
return
|
||||
}
|
||||
|
||||
const frames = options.transition.value / 10
|
||||
const goal = preferred - fill_size
|
||||
const step = goal / frames
|
||||
|
||||
animations = range(frames, 0).map(i => Utils.timeout(5 * i, () => {
|
||||
fill_size += step
|
||||
fill.css = `min-${axis}: ${fill_size}px`
|
||||
animations.shift()
|
||||
}))
|
||||
},
|
||||
})
|
||||
}
|