diff --git a/.forgejo/workflows/discord.yml b/.forgejo/workflows/discord.yml deleted file mode 100644 index 18d6d0ad..00000000 --- a/.forgejo/workflows/discord.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Discord - -on: - - workflow_dispatch - - push - -jobs: - discord_commits: - runs-on: ubuntu-latest - name: discord commits - if: contains(github.event.head_commit.message, '(servers)') - - steps: - - name: Discommit - uses: https://github.com/matt1432/discommit@v0.0.2 - with: - discord_webhook: ${{ secrets.DISCORD_WEBHOOK }} - api_url: 'https://git.nelim.org/api/v1/repos/$OWNER/$REPO/git/commits/$REF' - title: 'New commit containing changes to server configs:' diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index f779955b..00000000 --- a/.gitattributes +++ /dev/null @@ -1,5 +0,0 @@ -flake.lock -diff -flake.nix -diff -**/non-declarative-conf -diff -**/package-lock.json -diff -**/HomeAssistantGenerated -diff diff --git a/.gitignore b/.gitignore index 61a9e2b7..eeb53b92 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,2 @@ -# Python *.egg-info - -# NPM -*node_modules -*build/ - -# Direnv -*.direnv/ - -# Generated by nix -result* -!results/ -.nixd.json - -## AGS -**/vars.ts -**/config.js -*icons -**/types - -# Other *.temp diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index 6c775dd0..00000000 --- a/LICENSE.md +++ /dev/null @@ -1,16 +0,0 @@ -MIT No Attribution - -Copyright 2024 Mathis H. - -Permission is hereby granted, free of charge, to any person obtaining a copy of this -software and associated documentation files (the "Software"), to deal in the Software -without restriction, including without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 51065103..ff6cbeaf 100644 --- a/README.md +++ b/README.md @@ -1,100 +1,18 @@ # My NixOS configs -## AGS +what is currently not working: -You might find it weird that most of my config is written in TypeScript. -That's because all my desktops run -[AGS](https://github.com/Aylur/ags) -for UI. Click on -[this](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/modules/ags) -to see my configuration. +- plymouth theme has no login prompt +- sddm theme flashes white +- autosign in to keyring -I'm also a victim of Stockholm syndrome at this point and make my scripts -in TypeScript because it's the scripting language I am most comfortable with. +what i want to do: -## About +- learn flakes +- add auto-rotate widget in ags control center +- when multiple widgets open, clicking on a background one puts it forward -### General +## Docs -This repo is the complete configuration of machines I own running NixOS or Nix -and any other related smaller projects exposed by a Nix Flake. - -Its main directory structure is based on a flake's -[outputs](https://wiki.nixos.org/wiki/Flakes#Output_schema). - -I try to follow a few rules to better organise my Nix code: - - - Every main subdirectory only has an optional `default.nix` and subfolders for each - of its attributes. - - Inside a subdirectory, if there is non nix code, it will be in a `config` folder. - - Every module should not do anything if imported. An enable option should be toggled - for it to have any effect. - - Any nix file that represents a module should be named `default.nix` (a nix file - which is imported directly can be called anything else alongside `default.nix`) - -### Flake Location - -This git repo will always be located at `$FLAKE` (`config.environment.variables.FLAKE`) -and symlinked to `/etc/nixos` to have everything where NixOS tools -expect things to be. - -ie. - -```bash -sudo rm -r /etc/nixos - -echo "$FLAKE" # /home/matt/.nix - -sudo ln -sf /home/matt/.nix /etc/nixos -``` - -### Subdirectories - -| Output / Directory | Description | -| -------------------- | ----------- | -| `apps` | [Misc scripts ran from the flake](./apps) | -| `configurations` | [device, ISO and nix-on-droid configurations](./configurations) | -| `devShells` | [Development shells for a bunch of projects and languages](./devShells) | -| `homeManagerModules` | [Modules made for home-manager](./homeManagerModules) | -| `inputs` | [Pre-evaluated flake inputs](./inputs) | -| `lib` | [Custom Nix functions made easily available](./lib) | -| `modules` | [Modules made for NixOS systems](./modules) | -| `nixFastChecks` | [Attribute set of derivations exposed by this flake](./nixFastChecks) | -| `overlays` | [Nixpkgs overlays](./overlays) | -| `packages` | [Some custom packages not available in nixpkgs or modified from it](./packages) | -| `results` | Directory where I neatly keep my result symlinks from `nixFastChecks` | -| `scopedPackages` | [Some custom package scopes not available in nixpkgs or modified from it](./scopedPackages) | - -### Secrets - -All my secrets are in a private git repo that makes use of -[sops-nix](https://github.com/Mic92/sops-nix). -I generate `.sops.yaml` from `.sops.nix`: - -```nix -let - wim = "somekey"; - binto = "somekey2"; -in { - creation_rules = [ - { - path_regex = "secrets/[^/]+\\.(yaml|json|env|ini)$"; - key_groups = [ - { - age = [wim binto]; - } - ]; - } - ]; -} -``` - -which is then converted to `.sops.yaml` using -[remarshal](https://github.com/remarshal-project/remarshal) -and this shell command: - -```bash -nix eval --json --file ./.sops.nix | remarshal --if json --of yaml > .sops.yaml -``` - -TLDR: I **[hate](https://ruudvanasseldonk.com/2023/01/11/the-yaml-document-from-hell)** YAML +Since I use my laptop with one user, I symlinked the configs to my home +directory following the tutorial [here](https://nixos.wiki/wiki/NixOS_configuration_editors) diff --git a/_outputs.nix b/_outputs.nix deleted file mode 100644 index 1a333448..00000000 --- a/_outputs.nix +++ /dev/null @@ -1,110 +0,0 @@ -{ - inputs = import ./inputs; - - outputs = inputs @ { - self, - systems, - nixpkgs, - secrets, - ... - }: let - inherit (self.lib) mkNixOS mkNixOnDroid mkPkgs; - - perSystem = attrs: - nixpkgs.lib.genAttrs (import systems) (system: - attrs (mkPkgs {inherit system nixpkgs;})); - in { - lib = import ./lib {inherit inputs perSystem;}; - - nixOnDroidConfigurations.default = - mkNixOnDroid [./configurations/android]; - - nixosConfigurations = { - # Desktops - wim = mkNixOS { - extraModules = [ - ./configurations/wim - secrets.nixosModules.default - ]; - }; - binto = mkNixOS { - cudaSupport = true; - extraModules = [./configurations/binto]; - }; - - bbsteamie = mkNixOS { - mainUser = "mariah"; - extraModules = [./configurations/bbsteamie]; - }; - - # NAS - nos = mkNixOS { - cudaSupport = true; - extraModules = [ - ./configurations/nos - secrets.nixosModules.nos - ]; - }; - - # Build / test server - servivi = mkNixOS { - extraModules = [ - ./configurations/servivi - secrets.nixosModules.servivi - ]; - }; - - # Home-assistant - homie = mkNixOS { - extraModules = [ - ./configurations/homie - secrets.nixosModules.homie - ]; - }; - - # Cluster - thingone = mkNixOS { - extraModules = [ - (import ./configurations/cluster "thingone") - secrets.nixosModules.thingy - ]; - }; - thingtwo = mkNixOS { - extraModules = [ - (import ./configurations/cluster "thingtwo") - secrets.nixosModules.thingy - ]; - }; - - live-image = mkNixOS { - mainUser = "nixos"; - extraModules = [./configurations/live-image]; - }; - }; - - # For nix-fast-build. I use a custom output to alleviate eval time of this flake. ie. when doing nix flake show - nixFastChecks = import ./nixFastChecks {inherit perSystem self;}; - - homeManagerModules = import ./homeManagerModules {inherit self;}; - - nixosModules = import ./modules {inherit self;}; - - overlays = import ./overlays {inherit self;}; - - apps = - perSystem (pkgs: - import ./apps {inherit pkgs self;}); - - appsPackages = perSystem (pkgs: pkgs.appsPackages); - - devShells = - perSystem (pkgs: - import ./devShells {inherit pkgs self;}); - - packages = perSystem (pkgs: pkgs.selfPackages); - - scopedPackages = perSystem (pkgs: pkgs.scopedPackages); - - formatter = perSystem (pkgs: pkgs.alejandra); - }; -} diff --git a/apps/README.md b/apps/README.md deleted file mode 100644 index b19acde3..00000000 --- a/apps/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Apps - -This directory contains every derivations for apps exposed by this flake. - -## List of my apps found in `self.apps` - -| Name | Description | -| ---- | ----------- | -| `extract-subs` | Extract all `srt` subtitle files from a `mkv` video with the appropriate name. | -| `gen-docs` | Generates the READMEs in this repository from nix attributes. | -| `list2series` | Converts a Komga read list into a comics series for reading with mihon. | -| `mc-mods` | Checks if a list of mods have a version available for a specific Minecraft version and a specific loader. | -| `pin-inputs` | Takes a list of inputs to pin to their current rev in `flake.lock`. | -| `update-sources` | Updates all derivation sources in this repository and generates a commit message for the changes made. | diff --git a/apps/buildApp.nix b/apps/buildApp.nix deleted file mode 100644 index 9495988b..00000000 --- a/apps/buildApp.nix +++ /dev/null @@ -1,61 +0,0 @@ -{ - lib, - src, - npmDepsHash, - runtimeInputs, - buildNpmPackage, - meta, - makeWrapper, - nodejs_latest, - jq, - ... -}: let - inherit (lib) boolToString concatMapStringsSep concatStringsSep mapAttrsToList; - inherit (builtins) fromJSON isBool readFile; - - packageJSON = fromJSON (readFile "${src}/package.json"); - tsconfig = fromJSON (readFile ./config/tsconfig.base.json); - - pname = packageJSON.name; - inherit (packageJSON) version; -in - buildNpmPackage { - inherit pname version src runtimeInputs npmDepsHash; - - prePatch = '' - # Patch tsconfig - mv ./tsconfig.json ./project.json - sed 's/^ *\/\/.*//' ${./config/tsconfig.base.json} > ./base.json - ${jq}/bin/jq -sr '.[0] * .[1] | del(.extends)' ./project.json ./base.json > ./tsconfig.json - rm base.json project.json - ''; - - nativeBuildInputs = [makeWrapper]; - - postInstall = '' - wrapProgram $out/bin/${pname} \ - --prefix PATH : ${concatMapStringsSep ":" (p: p + "/bin") runtimeInputs} - ''; - - doCheck = true; - - checkPhase = '' - runHook preCheck - - npx tsc ${concatStringsSep " " (mapAttrsToList (n: v: - if n == "lib" - then concatMapStringsSep " " (x: "--lib ${x}") v - else "--${n} ${ - if isBool v - then boolToString v - else toString v - }") - tsconfig.compilerOptions)} src/app.ts - - runHook postCheck - ''; - - nodejs = nodejs_latest; - - meta = {mainProgram = pname;} // meta; - } diff --git a/apps/config/.envrc b/apps/config/.envrc deleted file mode 100644 index fd3dddda..00000000 --- a/apps/config/.envrc +++ /dev/null @@ -1,2 +0,0 @@ -use flake $FLAKE#node -npm ci diff --git a/apps/config/eslint.config.ts b/apps/config/eslint.config.ts deleted file mode 100644 index f6bb50a7..00000000 --- a/apps/config/eslint.config.ts +++ /dev/null @@ -1,451 +0,0 @@ -import eslint from '@eslint/js'; -import jsdoc from 'eslint-plugin-jsdoc'; -import stylistic from '@stylistic/eslint-plugin'; -import tseslint from 'typescript-eslint'; - - -export default tseslint.config({ - files: ['**/*.js', '**/*.ts'], - ignores: ['node_modules/**', 'types/**'], - - extends: [ - eslint.configs.recommended, - jsdoc.configs['flat/recommended-typescript'], - stylistic.configs['recommended-flat'], - ...tseslint.configs.recommended, - ...tseslint.configs.stylistic, - ], - - rules: { - // JSDoc settings - 'jsdoc/tag-lines': ['warn', 'any', { startLines: 1 }], - 'jsdoc/check-line-alignment': ['warn', 'always', { - tags: ['param', 'arg', 'argument', 'property', 'prop'], - }], - 'jsdoc/no-types': 'off', - - // Newer settings - '@typescript-eslint/no-extraneous-class': ['off'], - '@typescript-eslint/no-implied-eval': ['off'], - 'class-methods-use-this': 'off', - '@stylistic/no-multiple-empty-lines': 'off', - - // Pre-flat config - '@typescript-eslint/no-unused-vars': [ - 'error', - { - args: 'all', - argsIgnorePattern: '^_', - caughtErrors: 'all', - caughtErrorsIgnorePattern: '^_', - destructuredArrayIgnorePattern: '^_', - varsIgnorePattern: '^_', - ignoreRestSiblings: true, - }, - ], - - 'array-callback-return': [ - 'error', - { - allowImplicit: true, - checkForEach: true, - }, - ], - 'no-constructor-return': [ - 'error', - ], - 'no-unreachable-loop': [ - 'error', - { - ignore: [ - 'ForInStatement', - 'ForOfStatement', - ], - }, - ], - 'no-use-before-define': [ - 'error', - { - functions: false, - }, - ], - 'block-scoped-var': [ - 'error', - ], - 'curly': [ - 'warn', - ], - 'default-case-last': [ - 'warn', - ], - 'default-param-last': [ - 'error', - ], - 'eqeqeq': [ - 'error', - 'smart', - ], - 'func-names': [ - 'warn', - 'never', - ], - 'func-style': [ - 'warn', - 'expression', - ], - 'logical-assignment-operators': [ - 'warn', - 'always', - ], - 'no-array-constructor': [ - 'error', - ], - 'no-empty-function': [ - 'warn', - ], - 'no-empty-static-block': [ - 'warn', - ], - 'no-extend-native': [ - 'error', - ], - 'no-extra-bind': [ - 'warn', - ], - 'no-implicit-coercion': [ - 'warn', - ], - 'no-iterator': [ - 'error', - ], - 'no-labels': [ - 'error', - ], - 'no-lone-blocks': [ - 'error', - ], - 'no-lonely-if': [ - 'error', - ], - 'no-loop-func': [ - 'error', - ], - 'no-magic-numbers': [ - 'error', - { - ignore: [ - -1, - 0.1, - 0, - 1, - 2, - 3, - 4, - 5, - 10, - 12, - 33, - 66, - 100, - 255, - 360, - 450, - 500, - 1000, - ], - ignoreDefaultValues: true, - ignoreClassFieldInitialValues: true, - }, - ], - 'no-multi-assign': [ - 'error', - ], - 'no-new-wrappers': [ - 'error', - ], - 'no-object-constructor': [ - 'error', - ], - 'no-proto': [ - 'error', - ], - 'no-return-assign': [ - 'error', - ], - 'no-sequences': [ - 'error', - ], - 'no-shadow': [ - 'error', - { - builtinGlobals: true, - allow: [ - 'Window', - ], - }, - ], - 'no-undef-init': [ - 'warn', - ], - 'no-undefined': [ - 'error', - ], - 'no-useless-constructor': [ - 'warn', - ], - 'no-useless-escape': [ - 'off', - ], - 'no-useless-return': [ - 'error', - ], - 'no-var': [ - 'error', - ], - 'no-void': [ - 'off', - ], - 'no-with': [ - 'error', - ], - 'object-shorthand': [ - 'error', - 'always', - ], - 'one-var': [ - 'error', - 'never', - ], - 'operator-assignment': [ - 'warn', - 'always', - ], - 'prefer-arrow-callback': [ - 'error', - ], - 'prefer-const': [ - 'error', - ], - 'prefer-object-has-own': [ - 'error', - ], - 'prefer-regex-literals': [ - 'error', - ], - 'prefer-template': [ - 'warn', - ], - 'no-prototype-builtins': 'off', - '@typescript-eslint/no-var-requires': [ - 'off', - ], - '@stylistic/array-bracket-newline': [ - 'warn', - 'consistent', - ], - '@stylistic/array-bracket-spacing': [ - 'warn', - 'never', - ], - '@stylistic/arrow-parens': [ - 'warn', - 'always', - ], - '@stylistic/brace-style': [ - 'warn', - 'stroustrup', - ], - '@stylistic/comma-dangle': [ - 'warn', - 'always-multiline', - ], - '@stylistic/comma-spacing': [ - 'warn', - { - before: false, - after: true, - }, - ], - '@stylistic/comma-style': [ - 'error', - 'last', - ], - '@stylistic/dot-location': [ - 'error', - 'property', - ], - '@stylistic/function-call-argument-newline': [ - 'warn', - 'consistent', - ], - '@stylistic/function-paren-newline': [ - 'warn', - 'consistent', - ], - '@stylistic/indent': [ - 'warn', - 4, - { - SwitchCase: 1, - ignoreComments: true, - ignoredNodes: ['TemplateLiteral > *'], - }, - ], - '@stylistic/key-spacing': [ - 'warn', - { - beforeColon: false, - afterColon: true, - }, - ], - '@stylistic/keyword-spacing': [ - 'warn', - { - before: true, - }, - ], - '@stylistic/linebreak-style': [ - 'error', - 'unix', - ], - '@stylistic/lines-between-class-members': [ - 'warn', - 'always', - { - exceptAfterSingleLine: true, - }, - ], - '@stylistic/max-len': [ - 'warn', - { - code: 105, - ignoreComments: true, - ignoreTrailingComments: true, - ignoreUrls: true, - }, - ], - '@stylistic/multiline-ternary': [ - 'warn', - 'always-multiline', - ], - '@stylistic/new-parens': [ - 'error', - ], - '@stylistic/no-mixed-operators': [ - 'warn', - ], - '@stylistic/no-mixed-spaces-and-tabs': [ - 'error', - ], - '@stylistic/no-multi-spaces': [ - 'error', - ], - '@stylistic/no-tabs': [ - 'error', - ], - '@stylistic/no-trailing-spaces': [ - 'error', - ], - '@stylistic/no-whitespace-before-property': [ - 'warn', - ], - '@stylistic/nonblock-statement-body-position': [ - 'error', - 'below', - ], - '@stylistic/object-curly-newline': [ - 'warn', - { - consistent: true, - }, - ], - '@stylistic/object-curly-spacing': [ - 'warn', - 'always', - ], - '@stylistic/operator-linebreak': [ - 'warn', - 'after', - ], - '@stylistic/padded-blocks': [ - 'error', - 'never', - ], - '@stylistic/padding-line-between-statements': [ - 'warn', - { - blankLine: 'always', - prev: '*', - next: 'return', - }, - { - blankLine: 'always', - prev: [ - 'const', - 'let', - 'var', - ], - next: '*', - }, - { - blankLine: 'any', - prev: [ - 'const', - 'let', - 'var', - ], - next: [ - 'const', - 'let', - 'var', - ], - }, - { - blankLine: 'always', - prev: [ - 'case', - 'default', - ], - next: '*', - }, - ], - '@stylistic/quote-props': [ - 'error', - 'consistent-as-needed', - ], - '@stylistic/quotes': [ - 'error', - 'single', - { - avoidEscape: true, - }, - ], - '@stylistic/semi': [ - 'error', - 'always', - ], - '@stylistic/semi-spacing': [ - 'warn', - ], - '@stylistic/space-before-blocks': [ - 'warn', - ], - '@stylistic/space-before-function-paren': [ - 'warn', - 'never', - ], - '@stylistic/space-infix-ops': [ - 'warn', - ], - '@stylistic/spaced-comment': [ - 'warn', - 'always', - ], - '@stylistic/switch-colon-spacing': [ - 'warn', - ], - '@stylistic/wrap-regex': [ - 'warn', - ], - }, -}); diff --git a/apps/config/index.ts b/apps/config/index.ts deleted file mode 100644 index 1b8d2a33..00000000 --- a/apps/config/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import eslintConf from './eslint.config'; - -export default eslintConf; diff --git a/apps/config/package-lock.json b/apps/config/package-lock.json deleted file mode 100644 index 9ec7382b..00000000 --- a/apps/config/package-lock.json +++ /dev/null @@ -1,1729 +0,0 @@ -{ - "name": "eslint-conf", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "eslint-conf", - "version": "0.0.0", - "dependencies": { - "@eslint/js": "9.25.0", - "@stylistic/eslint-plugin": "4.2.0", - "eslint": "9.25.0", - "eslint-plugin-jsdoc": "50.6.9", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3", - "typescript-eslint": "8.30.1" - } - }, - "node_modules/@es-joy/jsdoccomment": { - "version": "0.49.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.49.0.tgz", - "integrity": "sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==", - "license": "MIT", - "dependencies": { - "comment-parser": "1.4.1", - "esquery": "^1.6.0", - "jsdoc-type-pratt-parser": "~4.1.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", - "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", - "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.6", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz", - "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", - "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/js": { - "version": "9.25.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.25.0.tgz", - "integrity": "sha512-iWhsUS8Wgxz9AXNfvfOPFSW4VfMXdVhp1hjkZVhXCrpgh/aLcc45rX6MPu+tIVUWDw0HfNwth7O28M1xDxNf9w==", - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", - "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.13.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", - "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", - "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pkgr/core": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", - "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/@stylistic/eslint-plugin": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-4.2.0.tgz", - "integrity": "sha512-8hXezgz7jexGHdo5WN6JBEIPHCSFyyU4vgbxevu4YLVS5vl+sxqAAGyXSzfNDyR6xMNSH5H1x67nsXcYMOHtZA==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/utils": "^8.23.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", - "estraverse": "^5.3.0", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "eslint": ">=9.0.0" - } - }, - "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.30.1.tgz", - "integrity": "sha512-v+VWphxMjn+1t48/jO4t950D6KR8JaJuNXzi33Ve6P8sEmPr5k6CEXjdGwT6+LodVnEa91EQCtwjWNUCPweo+Q==", - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.30.1", - "@typescript-eslint/type-utils": "8.30.1", - "@typescript-eslint/utils": "8.30.1", - "@typescript-eslint/visitor-keys": "8.30.1", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.0.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.30.1.tgz", - "integrity": "sha512-H+vqmWwT5xoNrXqWs/fesmssOW70gxFlgcMlYcBaWNPIEWDgLa4W9nkSPmhuOgLnXq9QYgkZ31fhDyLhleCsAg==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "8.30.1", - "@typescript-eslint/types": "8.30.1", - "@typescript-eslint/typescript-estree": "8.30.1", - "@typescript-eslint/visitor-keys": "8.30.1", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.30.1.tgz", - "integrity": "sha512-+C0B6ChFXZkuaNDl73FJxRYT0G7ufVPOSQkqkpM/U198wUwUFOtgo1k/QzFh1KjpBitaK7R1tgjVz6o9HmsRPg==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.30.1", - "@typescript-eslint/visitor-keys": "8.30.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.30.1.tgz", - "integrity": "sha512-64uBF76bfQiJyHgZISC7vcNz3adqQKIccVoKubyQcOnNcdJBvYOILV1v22Qhsw3tw3VQu5ll8ND6hycgAR5fEA==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "8.30.1", - "@typescript-eslint/utils": "8.30.1", - "debug": "^4.3.4", - "ts-api-utils": "^2.0.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.30.1.tgz", - "integrity": "sha512-81KawPfkuulyWo5QdyG/LOKbspyyiW+p4vpn4bYO7DM/hZImlVnFwrpCTnmNMOt8CvLRr5ojI9nU1Ekpw4RcEw==", - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.30.1.tgz", - "integrity": "sha512-kQQnxymiUy9tTb1F2uep9W6aBiYODgq5EMSk6Nxh4Z+BDUoYUSa029ISs5zTzKBFnexQEh71KqwjKnRz58lusQ==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.30.1", - "@typescript-eslint/visitor-keys": "8.30.1", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.0.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.30.1.tgz", - "integrity": "sha512-T/8q4R9En2tcEsWPQgB5BQ0XJVOtfARcUvOa8yJP3fh9M/mXraLxZrkCfGb6ChrO/V3W+Xbd04RacUEqk1CFEQ==", - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.30.1", - "@typescript-eslint/types": "8.30.1", - "@typescript-eslint/typescript-estree": "8.30.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.30.1.tgz", - "integrity": "sha512-aEhgas7aJ6vZnNFC7K4/vMGDGyOiqWcYZPpIWrTKuTAlsvDNKy2GFDqh9smL+iq069ZvR0YzEeq0B8NJlLzjFA==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.30.1", - "eslint-visitor-keys": "^4.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/are-docs-informative": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", - "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/comment-parser": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", - "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", - "license": "MIT", - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/confbox": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.1.tgz", - "integrity": "sha512-hkT3yDPFbs95mNCy1+7qNKC6Pro+/ibzYxtM2iqEigpf0sVw+bg4Zh9/snjsBcf990vfIsg5+1U7VyiyBb3etg==", - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "license": "MIT" - }, - "node_modules/es-module-lexer": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", - "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", - "license": "MIT" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.25.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.25.0.tgz", - "integrity": "sha512-MsBdObhM4cEwkzCiraDv7A6txFXEqtNXOb877TsSp2FCkBNl8JfVQrmiuDqC1IkejT6JLPzYBXx/xAiYhyzgGA==", - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.20.0", - "@eslint/config-helpers": "^0.2.1", - "@eslint/core": "^0.13.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.25.0", - "@eslint/plugin-kit": "^0.2.8", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.3.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-jsdoc": { - "version": "50.6.9", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.6.9.tgz", - "integrity": "sha512-7/nHu3FWD4QRG8tCVqcv+BfFtctUtEDWc29oeDXB4bwmDM2/r1ndl14AG/2DUntdqH7qmpvdemJKwb3R97/QEw==", - "license": "BSD-3-Clause", - "dependencies": { - "@es-joy/jsdoccomment": "~0.49.0", - "are-docs-informative": "^0.0.2", - "comment-parser": "1.4.1", - "debug": "^4.3.6", - "escape-string-regexp": "^4.0.0", - "espree": "^10.1.0", - "esquery": "^1.6.0", - "parse-imports": "^2.1.1", - "semver": "^7.6.3", - "spdx-expression-parse": "^4.0.0", - "synckit": "^0.9.1" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", - "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/espree": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", - "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.14.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/exsolve": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.2.tgz", - "integrity": "sha512-ZEcIMbthn2zeX4/wD/DLxDUjuCltHXT8Htvm/JFlTkdYgWh2+HGppgwwNUnIVxzxP7yJOPtuBAec0dLx6lVY8w==", - "license": "MIT" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "license": "MIT" - }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "license": "ISC" - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "license": "MIT" - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsdoc-type-pratt-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", - "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", - "license": "MIT", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "license": "MIT" - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "license": "MIT" - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-imports": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.2.1.tgz", - "integrity": "sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==", - "license": "Apache-2.0 AND MIT", - "dependencies": { - "es-module-lexer": "^1.5.3", - "slashes": "^3.0.12" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "license": "MIT" - }, - "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-types": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.1.0.tgz", - "integrity": "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==", - "license": "MIT", - "dependencies": { - "confbox": "^0.2.1", - "exsolve": "^1.0.1", - "pathe": "^2.0.3" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/slashes": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz", - "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", - "license": "ISC" - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", - "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.21", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", - "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", - "license": "CC0-1.0" - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/synckit": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", - "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", - "license": "MIT", - "dependencies": { - "@pkgr/core": "^0.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/ts-api-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", - "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", - "license": "MIT", - "engines": { - "node": ">=18.12" - }, - "peerDependencies": { - "typescript": ">=4.8.4" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-eslint": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.30.1.tgz", - "integrity": "sha512-D7lC0kcehVH7Mb26MRQi64LMyRJsj3dToJxM1+JVTl53DQSV5/7oUGWQLcKl1C1KnoVHxMMU2FNQMffr7F3Row==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/eslint-plugin": "8.30.1", - "@typescript-eslint/parser": "8.30.1", - "@typescript-eslint/utils": "8.30.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/apps/config/package.json b/apps/config/package.json deleted file mode 100644 index 81a117a8..00000000 --- a/apps/config/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "eslint-conf", - "version": "0.0.0", - "type": "module", - "exports": "./index.ts", - "dependencies": { - "@eslint/js": "9.25.0", - "@stylistic/eslint-plugin": "4.2.0", - "eslint": "9.25.0", - "eslint-plugin-jsdoc": "50.6.9", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3", - "typescript-eslint": "8.30.1" - } -} diff --git a/apps/config/tsconfig.base.json b/apps/config/tsconfig.base.json deleted file mode 100644 index e7db3c94..00000000 --- a/apps/config/tsconfig.base.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "compilerOptions": { - "target": "ESNext", - "lib": [ - "ESNext" - ], - "module": "preserve", - "moduleResolution": "bundler", - "baseUrl": ".", - "noEmit": true, - "newLine": "LF", - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "isolatedModules": true, - "skipLibCheck": true, - "strict": true, - "noImplicitAny": false - } -} diff --git a/apps/config/tsconfig.json b/apps/config/tsconfig.json deleted file mode 100644 index fbea8199..00000000 --- a/apps/config/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "./tsconfig.base.json", - "includes": [ - "*.ts", - "**/*.ts", - "*.js", - "**/*.js" - ] -} diff --git a/apps/default.nix b/apps/default.nix deleted file mode 100644 index f137bbd7..00000000 --- a/apps/default.nix +++ /dev/null @@ -1,9 +0,0 @@ -{pkgs, ...}: let - inherit (pkgs.lib) getExe mapAttrs; - - mkApp = pkg: { - program = getExe pkg; - type = "app"; - }; -in - mapAttrs (n: v: mkApp v) pkgs.appsPackages diff --git a/apps/extract-subs/.envrc b/apps/extract-subs/.envrc deleted file mode 100644 index 1107eeb4..00000000 --- a/apps/extract-subs/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -use flake $FLAKE#subtitles-dev -(cd ../config; npm ci) -npm ci diff --git a/apps/extract-subs/default.nix b/apps/extract-subs/default.nix deleted file mode 100644 index 36e2db66..00000000 --- a/apps/extract-subs/default.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ - buildApp, - ffmpeg-full, - ... -}: -buildApp { - src = ./.; - npmDepsHash = "sha256-gDGieED+RReHmhnjd0BWREt2OSbPlknw4aCFci5Pj14="; - - runtimeInputs = [ - ffmpeg-full - ]; - - meta.description = '' - Extract all `srt` subtitle files from a `mkv` video with the appropriate name. - ''; -} diff --git a/apps/extract-subs/eslint.config.ts b/apps/extract-subs/eslint.config.ts deleted file mode 100644 index 7d0908f3..00000000 --- a/apps/extract-subs/eslint.config.ts +++ /dev/null @@ -1,3 +0,0 @@ -import eslintConf from 'eslint-conf'; - -export default eslintConf; diff --git a/apps/extract-subs/package-lock.json b/apps/extract-subs/package-lock.json deleted file mode 100644 index ef24528b..00000000 --- a/apps/extract-subs/package-lock.json +++ /dev/null @@ -1,1544 +0,0 @@ -{ - "name": "extract-subs", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "extract-subs", - "version": "0.0.0", - "dependencies": { - "@types/fluent-ffmpeg": "2.1.27", - "@types/node": "22.14.1", - "esbuild": "0.25.2", - "eslint": "9.25.0", - "fluent-ffmpeg": "2.1.3", - "jiti": "2.4.2", - "typescript": "5.8.3" - }, - "bin": { - "extract-subs": "out/bin/app.cjs" - }, - "devDependencies": { - "eslint-conf": "file:../config" - } - }, - "../config": { - "name": "eslint-conf", - "version": "0.0.0", - "dev": true, - "dependencies": { - "@eslint/js": "9.25.0", - "@stylistic/eslint-plugin": "4.2.0", - "eslint": "9.25.0", - "eslint-plugin-jsdoc": "50.6.9", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3", - "typescript-eslint": "8.30.1" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", - "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz", - "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz", - "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz", - "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz", - "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz", - "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz", - "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz", - "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz", - "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz", - "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz", - "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz", - "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz", - "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz", - "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz", - "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz", - "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz", - "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz", - "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz", - "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz", - "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz", - "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz", - "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz", - "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz", - "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz", - "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.1.tgz", - "integrity": "sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==", - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", - "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.6", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz", - "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", - "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "9.25.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.25.0.tgz", - "integrity": "sha512-iWhsUS8Wgxz9AXNfvfOPFSW4VfMXdVhp1hjkZVhXCrpgh/aLcc45rX6MPu+tIVUWDw0HfNwth7O28M1xDxNf9w==", - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", - "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.13.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", - "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", - "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", - "license": "MIT" - }, - "node_modules/@types/fluent-ffmpeg": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/@types/fluent-ffmpeg/-/fluent-ffmpeg-2.1.27.tgz", - "integrity": "sha512-QiDWjihpUhriISNoBi2hJBRUUmoj/BMTYcfz+F+ZM9hHWBYABFAE6hjP/TbCZC0GWwlpa3FzvHH9RzFeRusZ7A==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.14.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz", - "integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "license": "MIT" - }, - "node_modules/esbuild": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", - "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.2", - "@esbuild/android-arm": "0.25.2", - "@esbuild/android-arm64": "0.25.2", - "@esbuild/android-x64": "0.25.2", - "@esbuild/darwin-arm64": "0.25.2", - "@esbuild/darwin-x64": "0.25.2", - "@esbuild/freebsd-arm64": "0.25.2", - "@esbuild/freebsd-x64": "0.25.2", - "@esbuild/linux-arm": "0.25.2", - "@esbuild/linux-arm64": "0.25.2", - "@esbuild/linux-ia32": "0.25.2", - "@esbuild/linux-loong64": "0.25.2", - "@esbuild/linux-mips64el": "0.25.2", - "@esbuild/linux-ppc64": "0.25.2", - "@esbuild/linux-riscv64": "0.25.2", - "@esbuild/linux-s390x": "0.25.2", - "@esbuild/linux-x64": "0.25.2", - "@esbuild/netbsd-arm64": "0.25.2", - "@esbuild/netbsd-x64": "0.25.2", - "@esbuild/openbsd-arm64": "0.25.2", - "@esbuild/openbsd-x64": "0.25.2", - "@esbuild/sunos-x64": "0.25.2", - "@esbuild/win32-arm64": "0.25.2", - "@esbuild/win32-ia32": "0.25.2", - "@esbuild/win32-x64": "0.25.2" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.25.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.25.0.tgz", - "integrity": "sha512-MsBdObhM4cEwkzCiraDv7A6txFXEqtNXOb877TsSp2FCkBNl8JfVQrmiuDqC1IkejT6JLPzYBXx/xAiYhyzgGA==", - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.20.0", - "@eslint/config-helpers": "^0.2.1", - "@eslint/core": "^0.13.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.25.0", - "@eslint/plugin-kit": "^0.2.8", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.3.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-conf": { - "resolved": "../config", - "link": true - }, - "node_modules/eslint-scope": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", - "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", - "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.14.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "license": "MIT" - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "license": "ISC" - }, - "node_modules/fluent-ffmpeg": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.3.tgz", - "integrity": "sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==", - "license": "MIT", - "dependencies": { - "async": "^0.2.9", - "which": "^1.1.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/fluent-ffmpeg/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "license": "MIT" - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "license": "MIT" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "license": "MIT" - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "license": "MIT" - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/apps/extract-subs/package.json b/apps/extract-subs/package.json deleted file mode 100644 index 72f349c3..00000000 --- a/apps/extract-subs/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "extract-subs", - "version": "0.0.0", - "bin": "out/bin/app.cjs", - "type": "module", - "scripts": { - "build": "node_ver=$(node -v); esbuild src/app.ts --bundle --platform=node --target=\"node${node_ver:1:2}\" --outfile=out/bin/app.cjs" - }, - "dependencies": { - "@types/fluent-ffmpeg": "2.1.27", - "fluent-ffmpeg": "2.1.3", - "@types/node": "22.14.1", - "esbuild": "0.25.2", - "eslint": "9.25.0", - "jiti": "2.4.2", - "typescript": "5.8.3" - }, - "devDependencies": { - "eslint-conf": "file:../config" - } -} diff --git a/apps/extract-subs/src/app.ts b/apps/extract-subs/src/app.ts deleted file mode 100644 index 3f21e7b4..00000000 --- a/apps/extract-subs/src/app.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { spawnSync as spawn } from 'child_process'; - -import ffprobe from './ffprobe'; -import { ISO6393To1 } from './lang-codes'; - -/* Types */ -import { FfprobeStream } from 'fluent-ffmpeg'; - - -const SPAWN_OPTS = { - stdio: [process.stdin, process.stdout, process.stderr], -}; - - -/** - * These are the cli arguments - * - * @param videoPath the directory in which we want to sync the subtitles - * @param languages a comma-separated list of languages (3 letters) to sync the subtitles - */ -const video = process.argv[2]; -const languages = process.argv[3]?.split(','); - - -// Global Vars -const subIndexes: number[] = []; -let videoPath: string; -let baseName: string; - - -/** - * Gets the relative path to the subtitle file of a ffmpeg stream. - * - * @param sub the stream of the subtitles to extract - * @returns the path of the subtitle file - */ -const getSubPath = (sub: FfprobeStream): string => { - const language = ISO6393To1.get(sub.tags.language); - - const forced = sub.disposition?.forced === 0 ? - '' : - '.forced'; - - const hearingImpaired = sub.disposition?.hearing_impaired === 0 ? - '' : - '.sdh'; - - return `${baseName}${forced}.${language}${hearingImpaired}.srt`; -}; - -/** - * Removes all subtitles streams from the video file. - */ -const removeContainerSubs = (): void => { - spawn('mv', [ - videoPath, - `${videoPath}.bak`, - ], SPAWN_OPTS); - - spawn('ffmpeg', [ - '-i', `${videoPath}.bak`, - '-map', '0', - ...subIndexes.map((i) => ['-map', `-0:${i}`]).flat(), - '-c', 'copy', videoPath, - ], SPAWN_OPTS); - - spawn('rm', [ - `${videoPath}.bak`, - ], SPAWN_OPTS); -}; - -/** - * Extracts a sub of a video file to a subtitle file. - * - * @param sub the stream of the subtitles to extract - */ -const extractSub = (sub: FfprobeStream): void => { - const subFile = getSubPath(sub); - - spawn('ffmpeg', [ - '-i', videoPath, - '-map', `0:${sub.index}`, subFile, - ], SPAWN_OPTS); - - subIndexes.push(sub.index); -}; - -/** - * Sorts the list of streams to only keep subtitles - * that can be extracted. - * - * @param lang the language of the subtitles - * @param streams the streams - * @returns the streams that represent subtitles - */ -const findSubs = ( - lang: string, - streams: FfprobeStream[], -): FfprobeStream[] => { - const subs = streams.filter((s) => s.tags?.language && - s.tags.language === lang && - s.codec_type === 'subtitle'); - - const pgs = subs.filter((s) => s.codec_name === 'hdmv_pgs_subtitle'); - - // If we only have PGS subs, warn user - if (pgs.length === subs.length) { - console.warn(`No SRT subtitle tracks were found for ${lang}`); - } - - // Remove PGS streams from subs - return subs.filter((s) => s.codec_name !== 'hdmv_pgs_subtitle'); -}; - -/** - * Where the magic happens. - */ -const main = async(): Promise<void> => { - // Get rid of video extension - baseName = videoPath.split('/').at(-1)!.replace(/\.[^.]*$/, ''); - - // ffprobe the video file to see available sub tracks - const data = await ffprobe(videoPath); - - if (!data?.streams) { - return; - } - - // Check for languages wanted - languages.forEach((lang) => { - const subs = findSubs(lang, data.streams); - - if (subs.length === 0) { - console.warn(`No subtitle tracks were found for ${lang}`); - - return; - } - - // Extract all subs - subs.forEach((sub) => { - extractSub(sub); - }); - }); - - removeContainerSubs(); -}; - - -// Check if there are 2 params -if (video && languages) { - videoPath = video; - main(); -} -else { - console.error('Error: no argument passed'); - process.exit(1); -} diff --git a/apps/extract-subs/src/ffprobe.ts b/apps/extract-subs/src/ffprobe.ts deleted file mode 100644 index efdc4df8..00000000 --- a/apps/extract-subs/src/ffprobe.ts +++ /dev/null @@ -1,8 +0,0 @@ -import Ffmpeg from 'fluent-ffmpeg'; - - -export default (videoPath: string) => new Promise<Ffmpeg.FfprobeData>((resolve) => { - Ffmpeg.ffprobe(videoPath, (_e, data) => { - resolve(data); - }); -}); diff --git a/apps/extract-subs/src/lang-codes.ts b/apps/extract-subs/src/lang-codes.ts deleted file mode 100644 index eec5458b..00000000 --- a/apps/extract-subs/src/lang-codes.ts +++ /dev/null @@ -1,373 +0,0 @@ -export const ISO6391To3 = new Map([ - ['aa', 'aar'], - ['ab', 'abk'], - ['af', 'afr'], - ['ak', 'aka'], - ['am', 'amh'], - ['ar', 'ara'], - ['an', 'arg'], - ['as', 'asm'], - ['av', 'ava'], - ['ae', 'ave'], - ['ay', 'aym'], - ['az', 'aze'], - ['ba', 'bak'], - ['bm', 'bam'], - ['be', 'bel'], - ['bn', 'ben'], - ['bi', 'bis'], - ['bo', 'bod'], - ['bs', 'bos'], - ['br', 'bre'], - ['bg', 'bul'], - ['ca', 'cat'], - ['cs', 'ces'], - ['ch', 'cha'], - ['ce', 'che'], - ['cu', 'chu'], - ['cv', 'chv'], - ['kw', 'cor'], - ['co', 'cos'], - ['cr', 'cre'], - ['cy', 'cym'], - ['da', 'dan'], - ['de', 'deu'], - ['dv', 'div'], - ['dz', 'dzo'], - ['el', 'ell'], - ['en', 'eng'], - ['eo', 'epo'], - ['et', 'est'], - ['eu', 'eus'], - ['ee', 'ewe'], - ['fo', 'fao'], - ['fa', 'fas'], - ['fj', 'fij'], - ['fi', 'fin'], - ['fr', 'fre'], - ['fy', 'fry'], - ['ff', 'ful'], - ['gd', 'gla'], - ['ga', 'gle'], - ['gl', 'glg'], - ['gv', 'glv'], - ['gn', 'grn'], - ['gu', 'guj'], - ['ht', 'hat'], - ['ha', 'hau'], - ['sh', 'hbs'], - ['he', 'heb'], - ['hz', 'her'], - ['hi', 'hin'], - ['ho', 'hmo'], - ['hr', 'hrv'], - ['hu', 'hun'], - ['hy', 'hye'], - ['ig', 'ibo'], - ['io', 'ido'], - ['ii', 'iii'], - ['iu', 'iku'], - ['ie', 'ile'], - ['ia', 'ina'], - ['id', 'ind'], - ['ik', 'ipk'], - ['is', 'isl'], - ['it', 'ita'], - ['jv', 'jav'], - ['ja', 'jpn'], - ['kl', 'kal'], - ['kn', 'kan'], - ['ks', 'kas'], - ['ka', 'kat'], - ['kr', 'kau'], - ['kk', 'kaz'], - ['km', 'khm'], - ['ki', 'kik'], - ['rw', 'kin'], - ['ky', 'kir'], - ['kv', 'kom'], - ['kg', 'kon'], - ['ko', 'kor'], - ['kj', 'kua'], - ['ku', 'kur'], - ['lo', 'lao'], - ['la', 'lat'], - ['lv', 'lav'], - ['li', 'lim'], - ['ln', 'lin'], - ['lt', 'lit'], - ['lb', 'ltz'], - ['lu', 'lub'], - ['lg', 'lug'], - ['mh', 'mah'], - ['ml', 'mal'], - ['mr', 'mar'], - ['mk', 'mkd'], - ['mg', 'mlg'], - ['mt', 'mlt'], - ['mn', 'mon'], - ['mi', 'mri'], - ['ms', 'msa'], - ['my', 'mya'], - ['na', 'nau'], - ['nv', 'nav'], - ['nr', 'nbl'], - ['nd', 'nde'], - ['ng', 'ndo'], - ['ne', 'nep'], - ['nl', 'nld'], - ['nn', 'nno'], - ['nb', 'nob'], - ['no', 'nor'], - ['ny', 'nya'], - ['oc', 'oci'], - ['oj', 'oji'], - ['or', 'ori'], - ['om', 'orm'], - ['os', 'oss'], - ['pa', 'pan'], - ['pi', 'pli'], - ['pl', 'pol'], - ['pt', 'por'], - ['ps', 'pus'], - ['qu', 'que'], - ['rm', 'roh'], - ['ro', 'ron'], - ['rn', 'run'], - ['ru', 'rus'], - ['sg', 'sag'], - ['sa', 'san'], - ['si', 'sin'], - ['sk', 'slk'], - ['sl', 'slv'], - ['se', 'sme'], - ['sm', 'smo'], - ['sn', 'sna'], - ['sd', 'snd'], - ['so', 'som'], - ['st', 'sot'], - ['es', 'spa'], - ['sq', 'sqi'], - ['sc', 'srd'], - ['sr', 'srp'], - ['ss', 'ssw'], - ['su', 'sun'], - ['sw', 'swa'], - ['sv', 'swe'], - ['ty', 'tah'], - ['ta', 'tam'], - ['tt', 'tat'], - ['te', 'tel'], - ['tg', 'tgk'], - ['tl', 'tgl'], - ['th', 'tha'], - ['ti', 'tir'], - ['to', 'ton'], - ['tn', 'tsn'], - ['ts', 'tso'], - ['tk', 'tuk'], - ['tr', 'tur'], - ['tw', 'twi'], - ['ug', 'uig'], - ['uk', 'ukr'], - ['ur', 'urd'], - ['uz', 'uzb'], - ['ve', 'ven'], - ['vi', 'vie'], - ['vo', 'vol'], - ['wa', 'wln'], - ['wo', 'wol'], - ['xh', 'xho'], - ['yi', 'yid'], - ['yo', 'yor'], - ['za', 'zha'], - ['zh', 'zho'], - ['zu', 'zul'], -]); - -export const ISO6393To1 = new Map([ - ['aar', 'aa'], - ['abk', 'ab'], - ['afr', 'af'], - ['aka', 'ak'], - ['amh', 'am'], - ['ara', 'ar'], - ['arg', 'an'], - ['asm', 'as'], - ['ava', 'av'], - ['ave', 'ae'], - ['aym', 'ay'], - ['aze', 'az'], - ['bak', 'ba'], - ['bam', 'bm'], - ['bel', 'be'], - ['ben', 'bn'], - ['bis', 'bi'], - ['bod', 'bo'], - ['bos', 'bs'], - ['bre', 'br'], - ['bul', 'bg'], - ['cat', 'ca'], - ['ces', 'cs'], - ['cha', 'ch'], - ['che', 'ce'], - ['chu', 'cu'], - ['chv', 'cv'], - ['cor', 'kw'], - ['cos', 'co'], - ['cre', 'cr'], - ['cym', 'cy'], - ['dan', 'da'], - ['deu', 'de'], - ['div', 'dv'], - ['dzo', 'dz'], - ['ell', 'el'], - ['eng', 'en'], - ['epo', 'eo'], - ['est', 'et'], - ['eus', 'eu'], - ['ewe', 'ee'], - ['fao', 'fo'], - ['fas', 'fa'], - ['fij', 'fj'], - ['fin', 'fi'], - ['fre', 'fr'], - ['fry', 'fy'], - ['ful', 'ff'], - ['gla', 'gd'], - ['gle', 'ga'], - ['glg', 'gl'], - ['glv', 'gv'], - ['grn', 'gn'], - ['guj', 'gu'], - ['hat', 'ht'], - ['hau', 'ha'], - ['hbs', 'sh'], - ['heb', 'he'], - ['her', 'hz'], - ['hin', 'hi'], - ['hmo', 'ho'], - ['hrv', 'hr'], - ['hun', 'hu'], - ['hye', 'hy'], - ['ibo', 'ig'], - ['ido', 'io'], - ['iii', 'ii'], - ['iku', 'iu'], - ['ile', 'ie'], - ['ina', 'ia'], - ['ind', 'id'], - ['ipk', 'ik'], - ['isl', 'is'], - ['ita', 'it'], - ['jav', 'jv'], - ['jpn', 'ja'], - ['kal', 'kl'], - ['kan', 'kn'], - ['kas', 'ks'], - ['kat', 'ka'], - ['kau', 'kr'], - ['kaz', 'kk'], - ['khm', 'km'], - ['kik', 'ki'], - ['kin', 'rw'], - ['kir', 'ky'], - ['kom', 'kv'], - ['kon', 'kg'], - ['kor', 'ko'], - ['kua', 'kj'], - ['kur', 'ku'], - ['lao', 'lo'], - ['lat', 'la'], - ['lav', 'lv'], - ['lim', 'li'], - ['lin', 'ln'], - ['lit', 'lt'], - ['ltz', 'lb'], - ['lub', 'lu'], - ['lug', 'lg'], - ['mah', 'mh'], - ['mal', 'ml'], - ['mar', 'mr'], - ['mkd', 'mk'], - ['mlg', 'mg'], - ['mlt', 'mt'], - ['mon', 'mn'], - ['mri', 'mi'], - ['msa', 'ms'], - ['mya', 'my'], - ['nau', 'na'], - ['nav', 'nv'], - ['nbl', 'nr'], - ['nde', 'nd'], - ['ndo', 'ng'], - ['nep', 'ne'], - ['nld', 'nl'], - ['nno', 'nn'], - ['nob', 'nb'], - ['nor', 'no'], - ['nya', 'ny'], - ['oci', 'oc'], - ['oji', 'oj'], - ['ori', 'or'], - ['orm', 'om'], - ['oss', 'os'], - ['pan', 'pa'], - ['pli', 'pi'], - ['pol', 'pl'], - ['por', 'pt'], - ['pus', 'ps'], - ['que', 'qu'], - ['roh', 'rm'], - ['ron', 'ro'], - ['run', 'rn'], - ['rus', 'ru'], - ['sag', 'sg'], - ['san', 'sa'], - ['sin', 'si'], - ['slk', 'sk'], - ['slv', 'sl'], - ['sme', 'se'], - ['smo', 'sm'], - ['sna', 'sn'], - ['snd', 'sd'], - ['som', 'so'], - ['sot', 'st'], - ['spa', 'es'], - ['sqi', 'sq'], - ['srd', 'sc'], - ['srp', 'sr'], - ['ssw', 'ss'], - ['sun', 'su'], - ['swa', 'sw'], - ['swe', 'sv'], - ['tah', 'ty'], - ['tam', 'ta'], - ['tat', 'tt'], - ['tel', 'te'], - ['tgk', 'tg'], - ['tgl', 'tl'], - ['tha', 'th'], - ['tir', 'ti'], - ['ton', 'to'], - ['tsn', 'tn'], - ['tso', 'ts'], - ['tuk', 'tk'], - ['tur', 'tr'], - ['twi', 'tw'], - ['uig', 'ug'], - ['ukr', 'uk'], - ['urd', 'ur'], - ['uzb', 'uz'], - ['ven', 've'], - ['vie', 'vi'], - ['vol', 'vo'], - ['wln', 'wa'], - ['wol', 'wo'], - ['xho', 'xh'], - ['yid', 'yi'], - ['yor', 'yo'], - ['zha', 'za'], - ['zho', 'zh'], - ['zul', 'zu'], -]); diff --git a/apps/extract-subs/tsconfig.json b/apps/extract-subs/tsconfig.json deleted file mode 100644 index 763e4667..00000000 --- a/apps/extract-subs/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "../config/tsconfig.base.json", - "includes": [ - "*.ts", - "**/*.ts", - "*.js", - "**/*.js" - ] -} diff --git a/apps/gen-docs/default.nix b/apps/gen-docs/default.nix deleted file mode 100644 index f18758e9..00000000 --- a/apps/gen-docs/default.nix +++ /dev/null @@ -1,15 +0,0 @@ -{ - writeShellApplication, - jq, - pandoc, - ... -}: -writeShellApplication { - name = "gen-docs"; - runtimeInputs = [jq pandoc]; - text = builtins.readFile ./script.sh; - - meta.description = '' - Generates the READMEs in this repository from nix attributes. - ''; -} diff --git a/apps/gen-docs/getAttrsMeta.nix b/apps/gen-docs/getAttrsMeta.nix deleted file mode 100644 index 3f50970d..00000000 --- a/apps/gen-docs/getAttrsMeta.nix +++ /dev/null @@ -1,13 +0,0 @@ -attr: selfPath: let - inherit (builtins) mapAttrs replaceStrings; - - modules = import "${selfPath}/${attr}" {description = true;}; - - trimNewlines = s: replaceStrings ["\n"] [" "] s; -in { - attrs = - mapAttrs (_: v: { - desc = trimNewlines v; - }) - modules; -} diff --git a/apps/gen-docs/getConfigMeta.nix b/apps/gen-docs/getConfigMeta.nix deleted file mode 100644 index ed3df8c4..00000000 --- a/apps/gen-docs/getConfigMeta.nix +++ /dev/null @@ -1,12 +0,0 @@ -configs: let - inherit (builtins) mapAttrs replaceStrings; - - trimNewlines = s: replaceStrings ["\n"] [" "] s; -in { - attrs = - mapAttrs (_: v: { - roleDesc = trimNewlines (v.config.meta.roleDescription or ""); - hwDesc = trimNewlines (v.config.meta.hardwareDescription or ""); - }) - configs; -} diff --git a/apps/gen-docs/getPackageMeta.nix b/apps/gen-docs/getPackageMeta.nix deleted file mode 100644 index 7df49ac1..00000000 --- a/apps/gen-docs/getPackageMeta.nix +++ /dev/null @@ -1,13 +0,0 @@ -x: let - inherit (builtins) currentSystem mapAttrs removeAttrs replaceStrings; - - trimNewlines = s: replaceStrings ["\n"] [" "] s; - packages = removeAttrs x.${currentSystem} ["default"]; -in { - attrs = - mapAttrs (_: v: { - desc = trimNewlines (v.meta.description or ""); - homepage = v.meta.homepage or ""; - }) - packages; -} diff --git a/apps/gen-docs/getScopesMeta.nix b/apps/gen-docs/getScopesMeta.nix deleted file mode 100644 index 6d11055a..00000000 --- a/apps/gen-docs/getScopesMeta.nix +++ /dev/null @@ -1,31 +0,0 @@ -attr: selfPath: let - inherit (builtins) currentSystem getFlake mapAttrs removeAttrs replaceStrings; - - self = getFlake selfPath; - scopes = ((import "${selfPath}/${attr}" {description = true;}) {} {}).scopedPackages; - - trimNewlines = s: replaceStrings ["\n"] [" "] s; -in { - attrs = - mapAttrs (n: v: { - desc = trimNewlines v; - packages = let - scopePkgs = removeAttrs self.${attr}.${currentSystem}.${n} [ - "buildFirefoxXpiAddon" - "callPackage" - "newScope" - "override" - "overrideDerivation" - "overrideScope" - "packages" - "recurseForDerivations" - ]; - in - mapAttrs (_: pkg: { - desc = trimNewlines (pkg.meta.description or ""); - homepage = pkg.meta.homepage or ""; - }) - scopePkgs; - }) - scopes; -} diff --git a/apps/gen-docs/script.sh b/apps/gen-docs/script.sh deleted file mode 100755 index 7a1803c9..00000000 --- a/apps/gen-docs/script.sh +++ /dev/null @@ -1,43 +0,0 @@ -substituteDerivs() { - echo '' | pandoc --metadata-file <( - nix eval \ - --impure \ - --json \ - "$FLAKE"#"$1" \ - --apply "import \"$FLAKE/apps/gen-docs/$3.nix\"" | - jq -r - ) -t markdown --template "$FLAKE/apps/gen-docs/templates/$2.md" -o "$FLAKE/$2/README.md" -} - -substituteAttrs() { - echo '' | pandoc --metadata-file <( - nix eval \ - --impure \ - --json \ - --expr "\"$FLAKE\"" \ - --apply "(import \"$FLAKE/apps/gen-docs/getAttrsMeta.nix\") \"$1\"" | - jq -r - ) -t markdown --template "$FLAKE/apps/gen-docs/templates/$1.md" -o "$FLAKE/$1/README.md" -} - -substituteScopes() { - echo '' | pandoc --metadata-file <( - nix eval \ - --impure \ - --json \ - --expr "\"$FLAKE\"" \ - --apply "(import \"$FLAKE/apps/gen-docs/getScopesMeta.nix\") \"$1\"" | - jq -r - ) -t markdown --template "$FLAKE/apps/gen-docs/templates/$1.md" -o "$FLAKE/$1/README.md" -} - -substituteDerivs "appsPackages" "apps" "getPackageMeta" -substituteDerivs "nixosConfigurations" "configurations" "getConfigMeta" -substituteDerivs "devShells" "devShells" "getPackageMeta" -substituteDerivs "packages" "packages" "getPackageMeta" - -substituteAttrs "modules" -substituteAttrs "homeManagerModules" -substituteAttrs "overlays" - -substituteScopes "scopedPackages" diff --git a/apps/gen-docs/templates/apps.md b/apps/gen-docs/templates/apps.md deleted file mode 100644 index 223fa55a..00000000 --- a/apps/gen-docs/templates/apps.md +++ /dev/null @@ -1,11 +0,0 @@ -# Apps - -This directory contains every derivations for apps exposed by this flake. - -## List of my apps found in `self.apps` - -| Name | Description | -| ---- | ----------- | -$for(attrs/pairs)$ -| `$it.key$` | $it.value.desc/nowrap$ | -$endfor$ diff --git a/apps/gen-docs/templates/configurations.md b/apps/gen-docs/templates/configurations.md deleted file mode 100644 index 6fde7f9e..00000000 --- a/apps/gen-docs/templates/configurations.md +++ /dev/null @@ -1,13 +0,0 @@ -# NixosConfigurations - -This directory contains every device's main configuration file, their `hardware-configuration.nix` and some custom modules -unique to them. - -## List of my devices - -| Name | Model / Specs | Description | -| --------- | ------------- | ------------------------------------------------------------------------------------------------ | -| `android` | OnePlus 9 Pro | [Nix-On-Droid](https://github.com/nix-community/nix-on-droid) configuration for my OnePlus 9 Pro | -$for(attrs/pairs)$ -| `$it.key$` | $it.value.hwDesc/nowrap$ | $it.value.roleDesc/nowrap$ | -$endfor$ diff --git a/apps/gen-docs/templates/devShells.md b/apps/gen-docs/templates/devShells.md deleted file mode 100644 index f890ad90..00000000 --- a/apps/gen-docs/templates/devShells.md +++ /dev/null @@ -1,11 +0,0 @@ -# DevShells - -This directory contains every derivations for devShells exposed by this flake. - -## List of my devShells found in `self.devShells` - -| Name | Description | -| ---- | ----------- | -$for(attrs/pairs)$ -| `$it.key$` | $it.value.desc/nowrap$ | -$endfor$ diff --git a/apps/gen-docs/templates/homeManagerModules.md b/apps/gen-docs/templates/homeManagerModules.md deleted file mode 100644 index 3f743315..00000000 --- a/apps/gen-docs/templates/homeManagerModules.md +++ /dev/null @@ -1,11 +0,0 @@ -# HomeManagerModules - -This directory contains every home-manager modules exposed by this flake. - -## List of my home-manager modules found in `self.homeManagerModules` - -| Name | Description | -| ---- | ----------- | -$for(attrs/pairs)$ -| `$it.key$` | $it.value.desc/nowrap$ | -$endfor$ diff --git a/apps/gen-docs/templates/modules.md b/apps/gen-docs/templates/modules.md deleted file mode 100644 index c35da37c..00000000 --- a/apps/gen-docs/templates/modules.md +++ /dev/null @@ -1,11 +0,0 @@ -# NixosModules - -This directory contains every modules for NixOS exposed by this flake. - -## List of my modules found in `self.nixosModules` - -| Name | Description | -| ---- | ----------- | -$for(attrs/pairs)$ -| `$it.key$` | $it.value.desc/nowrap$ | -$endfor$ diff --git a/apps/gen-docs/templates/overlays.md b/apps/gen-docs/templates/overlays.md deleted file mode 100644 index 90c1583f..00000000 --- a/apps/gen-docs/templates/overlays.md +++ /dev/null @@ -1,11 +0,0 @@ -# Overlays - -This directory contains every overlay exposed by this flake. - -## List of my overlays found in `self.overlays` - -| Name | Description | -| ---- | ----------- | -$for(attrs/pairs)$ -| `$it.key$` | $it.value.desc/nowrap$ | -$endfor$ diff --git a/apps/gen-docs/templates/packages.md b/apps/gen-docs/templates/packages.md deleted file mode 100644 index c0935bc9..00000000 --- a/apps/gen-docs/templates/packages.md +++ /dev/null @@ -1,11 +0,0 @@ -# Packages - -This directory contains every derivations for packages exposed by this flake. - -## List of my packages found in `self.packages` - -| Name | Description | Homepage | -| ---- | ----------- | -------- | -$for(attrs/pairs)$ -| `$it.key$` | $it.value.desc/nowrap$ | $it.value.homepage/nowrap$ | -$endfor$ diff --git a/apps/gen-docs/templates/scopedPackages.md b/apps/gen-docs/templates/scopedPackages.md deleted file mode 100644 index 011321d3..00000000 --- a/apps/gen-docs/templates/scopedPackages.md +++ /dev/null @@ -1,18 +0,0 @@ -# ScopedPackages - -This directory contains every package scopes exposed by this flake. - -## List of my package scopes found in `self.scopedPackages` - -$for(attrs/pairs)$ -### $it.key$ - -$it.value.desc/nowrap$ - -| Name | Description | Homepage | -| ---- | ----------- | -------- | -$for(it.value.packages/pairs)$ -| `$it.key$` | $it.value.desc/nowrap$ | $it.value.homepage/nowrap$ | -$endfor$ - -$endfor$ diff --git a/apps/list2series/.envrc b/apps/list2series/.envrc deleted file mode 100644 index a3a97ba6..00000000 --- a/apps/list2series/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -use flake $FLAKE#node -(cd ../config; npm ci) -npm ci diff --git a/apps/list2series/.gitignore b/apps/list2series/.gitignore deleted file mode 100644 index 4c49bd78..00000000 --- a/apps/list2series/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.env diff --git a/apps/list2series/default.nix b/apps/list2series/default.nix deleted file mode 100644 index 3663ec97..00000000 --- a/apps/list2series/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -{buildApp, ...}: -buildApp { - src = ./.; - npmDepsHash = "sha256-lFAf1jUqonnOtKqTi1rOX/2He0fA/uC3i09GS1ajDPE="; - - runtimeInputs = []; - - meta.description = '' - Converts a Komga read list into a comics series for reading with mihon. - ''; -} diff --git a/apps/list2series/eslint.config.ts b/apps/list2series/eslint.config.ts deleted file mode 100644 index 7d0908f3..00000000 --- a/apps/list2series/eslint.config.ts +++ /dev/null @@ -1,3 +0,0 @@ -import eslintConf from 'eslint-conf'; - -export default eslintConf; diff --git a/apps/list2series/package-lock.json b/apps/list2series/package-lock.json deleted file mode 100644 index 29a44b4d..00000000 --- a/apps/list2series/package-lock.json +++ /dev/null @@ -1,1812 +0,0 @@ -{ - "name": "list2series", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "list2series", - "version": "0.0.0", - "dependencies": { - "@types/node": "22.14.1", - "axios": "1.8.4", - "esbuild": "0.25.2", - "eslint": "9.25.0", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3" - }, - "bin": { - "list2series": "out/bin/app.cjs" - }, - "devDependencies": { - "eslint-conf": "file:../config" - } - }, - "../config": { - "name": "eslint-conf", - "version": "0.0.0", - "dev": true, - "dependencies": { - "@eslint/js": "9.25.0", - "@stylistic/eslint-plugin": "4.2.0", - "eslint": "9.25.0", - "eslint-plugin-jsdoc": "50.6.9", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3", - "typescript-eslint": "8.30.1" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", - "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz", - "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz", - "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz", - "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz", - "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz", - "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz", - "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz", - "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz", - "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz", - "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz", - "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz", - "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz", - "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz", - "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz", - "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz", - "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz", - "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz", - "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz", - "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz", - "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz", - "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz", - "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz", - "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz", - "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz", - "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.1.tgz", - "integrity": "sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==", - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", - "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.6", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz", - "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", - "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "9.25.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.25.0.tgz", - "integrity": "sha512-iWhsUS8Wgxz9AXNfvfOPFSW4VfMXdVhp1hjkZVhXCrpgh/aLcc45rX6MPu+tIVUWDw0HfNwth7O28M1xDxNf9w==", - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", - "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.13.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", - "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", - "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.14.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz", - "integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/axios": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", - "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/confbox": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", - "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "license": "MIT" - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/esbuild": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", - "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.2", - "@esbuild/android-arm": "0.25.2", - "@esbuild/android-arm64": "0.25.2", - "@esbuild/android-x64": "0.25.2", - "@esbuild/darwin-arm64": "0.25.2", - "@esbuild/darwin-x64": "0.25.2", - "@esbuild/freebsd-arm64": "0.25.2", - "@esbuild/freebsd-x64": "0.25.2", - "@esbuild/linux-arm": "0.25.2", - "@esbuild/linux-arm64": "0.25.2", - "@esbuild/linux-ia32": "0.25.2", - "@esbuild/linux-loong64": "0.25.2", - "@esbuild/linux-mips64el": "0.25.2", - "@esbuild/linux-ppc64": "0.25.2", - "@esbuild/linux-riscv64": "0.25.2", - "@esbuild/linux-s390x": "0.25.2", - "@esbuild/linux-x64": "0.25.2", - "@esbuild/netbsd-arm64": "0.25.2", - "@esbuild/netbsd-x64": "0.25.2", - "@esbuild/openbsd-arm64": "0.25.2", - "@esbuild/openbsd-x64": "0.25.2", - "@esbuild/sunos-x64": "0.25.2", - "@esbuild/win32-arm64": "0.25.2", - "@esbuild/win32-ia32": "0.25.2", - "@esbuild/win32-x64": "0.25.2" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.25.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.25.0.tgz", - "integrity": "sha512-MsBdObhM4cEwkzCiraDv7A6txFXEqtNXOb877TsSp2FCkBNl8JfVQrmiuDqC1IkejT6JLPzYBXx/xAiYhyzgGA==", - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.20.0", - "@eslint/config-helpers": "^0.2.1", - "@eslint/core": "^0.13.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.25.0", - "@eslint/plugin-kit": "^0.2.8", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.3.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-conf": { - "resolved": "../config", - "link": true - }, - "node_modules/eslint-scope": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", - "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", - "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.14.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/exsolve": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.5.tgz", - "integrity": "sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==", - "license": "MIT" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "license": "MIT" - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "license": "ISC" - }, - "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", - "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "license": "MIT" - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "license": "MIT" - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "license": "MIT" - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "license": "MIT" - }, - "node_modules/pkg-types": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.1.0.tgz", - "integrity": "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==", - "license": "MIT", - "dependencies": { - "confbox": "^0.2.1", - "exsolve": "^1.0.1", - "pathe": "^2.0.3" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "license": "MIT" - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/apps/list2series/package.json b/apps/list2series/package.json deleted file mode 100644 index 296fb2e9..00000000 --- a/apps/list2series/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "list2series", - "version": "0.0.0", - "bin": "out/bin/app.cjs", - "type": "module", - "scripts": { - "build": "node_ver=$(node -v); esbuild src/app.ts --bundle --platform=node --target=\"node${node_ver:1:2}\" --outfile=out/bin/app.cjs" - }, - "dependencies": { - "@types/node": "22.14.1", - "axios": "1.8.4", - "esbuild": "0.25.2", - "eslint": "9.25.0", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3" - }, - "devDependencies": { - "eslint-conf": "file:../config" - } -} diff --git a/apps/list2series/src/app.ts b/apps/list2series/src/app.ts deleted file mode 100644 index e9d456f3..00000000 --- a/apps/list2series/src/app.ts +++ /dev/null @@ -1,214 +0,0 @@ -import axios from 'axios'; -import { linkSync, mkdirSync, readFileSync, rmSync } from 'fs'; -import { basename } from 'path'; - -import { type Book, type ReadList, type Series } from './types'; - - -// Examples of calling this script: -// $ just l2s copy 0K65Q482KK7SD -// $ just l2s meta 0K65Q482KK7SD -const API = JSON.parse( - readFileSync(`${process.env.FLAKE}/apps/list2series/.env`, { encoding: 'utf-8' }), -).API; - -const LIST_ID = process.argv[3]; - -const getListInfo = async(): Promise<ReadList> => { - const res = await axios.request({ - method: 'get', - maxBodyLength: Infinity, - url: `https://komga.nelim.org/api/v1/readlists/${LIST_ID}`, - headers: { - 'Accept': 'application/json', - 'X-API-Key': API, - }, - }); - - return res.data; -}; - -const getSeries = async(seriesTitle: string, operator = true): Promise<Series[]> => { - return (await axios.request({ - method: 'post', - maxBodyLength: Infinity, - url: 'https://komga.nelim.org/api/v1/series/list?unpaged=true', - headers: { - 'Content-Type': 'application/json', - 'Accept': 'application/json', - 'X-API-Key': API, - }, - data: JSON.stringify({ - condition: { - title: { - operator: operator ? 'is' : 'isNot', - value: seriesTitle, - }, - }, - }), - })).data.content; -}; - -const getSeriesBooks = async(listName: string, seriesPath: string): Promise<Book[]> => { - const thisSeries = (await getSeries('', false)).find((s) => s.url === seriesPath); - - if (!thisSeries) { - throw new Error('Series could not be found'); - } - - // Reset Series metadata - axios.request({ - method: 'patch', - maxBodyLength: Infinity, - url: `https://komga.nelim.org/api/v1/series/${thisSeries.id}/metadata`, - headers: { - 'Content-Type': 'application/json', - 'X-API-Key': API, - }, - data: JSON.stringify({ - ageRating: null, - ageRatingLock: true, - alternateTitles: null, - alternateTitlesLock: true, - genres: null, - genresLock: true, - language: null, - languageLock: true, - links: null, - linksLock: true, - publisherLock: true, - readingDirection: 'LEFT_TO_RIGHT', - readingDirectionLock: true, - sharingLabels: null, - sharingLabelsLock: true, - status: null, - statusLock: true, - summary: null, - summaryLock: true, - tags: null, - tagsLock: true, - title: listName, - titleLock: true, - titleSort: listName, - titleSortLock: true, - totalBookCountLock: true, - }), - }); - - const books = await axios.request({ - method: 'post', - maxBodyLength: Infinity, - url: 'https://komga.nelim.org/api/v1/books/list?unpaged=true', - headers: { - 'Content-Type': 'application/json', - 'Accept': 'application/json', - 'X-API-Key': API, - }, - data: JSON.stringify({ - condition: { - seriesId: { - operator: 'is', - value: thisSeries.id, - }, - }, - }), - }); - - return books.data.content; -}; - -const getBookInfo = async(id: string): Promise<Book> => { - const res = await axios.request({ - method: 'get', - maxBodyLength: Infinity, - url: `https://komga.nelim.org/api/v1/books/${id}`, - headers: { - 'Accept': 'application/json', - 'X-API-Key': API, - }, - }); - - return res.data; -}; - -// There doesn't seem to be a way to wait for the scan to be done -const scanLibrary = (): void => { - axios.request({ - method: 'post', - maxBodyLength: Infinity, - url: 'https://komga.nelim.org/api/v1/libraries/0K4QG58XA29DZ/scan', - headers: { - 'X-API-Key': API, - }, - }); -}; - -const setBookMetadata = async(i: number, source: Book, target: Book): Promise<void> => { - const thisSeries = (await getSeries(source.seriesTitle))[0]; - - source.metadata.title = thisSeries.booksCount !== 1 ? - `${source.seriesTitle} Issue #${source.metadata.number}` : - source.metadata.title = source.seriesTitle; - - source.metadata.number = i.toString(); - source.metadata.numberSort = i; - - const metadata = JSON.stringify(source.metadata); - - axios.request({ - method: 'patch', - maxBodyLength: Infinity, - url: `https://komga.nelim.org/api/v1/books/${target.id}/metadata`, - headers: { - 'Content-Type': 'application/json', - 'X-API-Key': API, - }, - data: metadata, - }); -}; - -const main = async(): Promise<void> => { - const list = await getListInfo(); - const ids = list.bookIds; - const seriesPath = `/data/comics/[List] ${list.name}`; - - const listBooks = [] as Book[]; - - for (let i = 0; i < ids.length; i++) { - const book = await getBookInfo(ids[i]); - - listBooks[i] = book; - }; - - if (process.argv[2] === 'copy') { - rmSync(seriesPath, { recursive: true, force: true }); - mkdirSync(seriesPath, { recursive: true }); - - for (const book of listBooks) { - const bookPath = book.url; - const inListPath = `${seriesPath}/${basename(bookPath)}`; - - console.log(`hardlinking ${basename(bookPath)}`); - linkSync(bookPath, inListPath); - } - - scanLibrary(); - } - - else if (process.argv[2] === 'meta') { - const seriesBooks = await getSeriesBooks(`[List] ${list.name}`, seriesPath); - - for (const target of seriesBooks) { - const source = listBooks.find((b) => basename(b.url) === basename(target.url)); - - if (source) { - const i = listBooks.indexOf(source) + 1; - - console.log(`Setting metadata for ${source.name}`); - setBookMetadata(i, source, target); - } - } - } -}; - -main(); diff --git a/apps/list2series/src/types.ts b/apps/list2series/src/types.ts deleted file mode 100644 index da05a10a..00000000 --- a/apps/list2series/src/types.ts +++ /dev/null @@ -1,135 +0,0 @@ -export interface Media { - status: string - mediaType: string - pagesCount: number - comment: string - epubDivinaCompatible: boolean - epubIsKepub: boolean - mediaProfile: string -} - -export interface Author { - name: string - role: string -} - -export interface Link { - label: string - url: string -} - -export interface ShortBookMetadata { - authors: Author[] - tags: unknown[] - releaseDate: string - summary: string - summaryNumber: string - created: string - lastModified: string -} - -export interface BookMetadata { - title: string - titleLock: boolean - summary: string - summaryLock: boolean - number: string - numberLock: boolean - numberSort: number - numberSortLock: boolean - releaseDate: string - releaseDateLock: boolean - authors: Author[] - authorsLock: boolean - tags: unknown[] - tagsLock: boolean - isbn: string - isbnLock: boolean - links: Link[] - linksLock: boolean - created: string - lastModified: string -} - -export interface Book { - id: string - seriesId: string - seriesTitle: string - libraryId: string - name: string - url: string - number: number - created: string - lastModified: string - fileLastModified: string - sizeBytes: number - size: string - media: Media - metadata: BookMetadata - readProgress: null | unknown - deleted: boolean - fileHash: string - oneshot: boolean -} - -export interface SeriesMetadata { - status: string - statusLock: boolean - title: string - titleLock: boolean - titleSort: string - titleSortLock: boolean - summary: string - summaryLock: boolean - readingDirection: string - readingDirectionLock: boolean - publisher: string - publisherLock: boolean - ageRating: null | string - ageRatingLock: boolean - language: string - languageLock: boolean - genres: string[] - genresLock: boolean - tags: unknown[] - tagsLock: boolean - totalBookCount: null | number - totalBookCountLock: boolean - sharingLabels: unknown[] - sharingLabelsLock: boolean - links: Link[] - linksLock: boolean - alternateTitles: string[] - alternateTitlesLock: boolean - created: string - lastModified: string -} - -export interface Series { - id: string - libraryId: string - name: string - url: string - created: string - lastModified: string - fileLastModified: string - booksCount: number - booksReadCount: number - booksUnreadCount: number - booksInProgressCount: number - metadata: SeriesMetadata - booksMetadata: ShortBookMetadata - deleted: boolean - oneshot: boolean -} - -export interface ReadList { - id: string - name: string - summary: string - ordered: boolean - bookIds: string[] - createdDate: string - lastModifiedDate: string - filtered: boolean -} diff --git a/apps/list2series/tsconfig.json b/apps/list2series/tsconfig.json deleted file mode 100644 index 763e4667..00000000 --- a/apps/list2series/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "../config/tsconfig.base.json", - "includes": [ - "*.ts", - "**/*.ts", - "*.js", - "**/*.js" - ] -} diff --git a/apps/mc-mods/.envrc b/apps/mc-mods/.envrc deleted file mode 100644 index a3a97ba6..00000000 --- a/apps/mc-mods/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -use flake $FLAKE#node -(cd ../config; npm ci) -npm ci diff --git a/apps/mc-mods/default.nix b/apps/mc-mods/default.nix deleted file mode 100644 index 3ace1134..00000000 --- a/apps/mc-mods/default.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ - buildApp, - nodejs_latest, - ... -}: -buildApp { - src = ./.; - npmDepsHash = "sha256-s5c8hgdGPrYAIw0ov0Gn36vO1leLy4VfuWH9GmyqipE="; - - runtimeInputs = [ - nodejs_latest - ]; - - meta.description = '' - Checks if a list of mods have a version available for a specific Minecraft - version and a specific loader. - ''; -} diff --git a/apps/mc-mods/eslint.config.ts b/apps/mc-mods/eslint.config.ts deleted file mode 100644 index 7d0908f3..00000000 --- a/apps/mc-mods/eslint.config.ts +++ /dev/null @@ -1,3 +0,0 @@ -import eslintConf from 'eslint-conf'; - -export default eslintConf; diff --git a/apps/mc-mods/package-lock.json b/apps/mc-mods/package-lock.json deleted file mode 100644 index f617849b..00000000 --- a/apps/mc-mods/package-lock.json +++ /dev/null @@ -1,1533 +0,0 @@ -{ - "name": "mc-mods", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "mc-mods", - "version": "0.0.0", - "dependencies": { - "@types/node": "22.14.1", - "esbuild": "0.25.2", - "eslint": "9.25.0", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3" - }, - "bin": { - "mc-mods": "out/bin/app.cjs" - }, - "devDependencies": { - "eslint-conf": "file:../config" - } - }, - "../config": { - "name": "eslint-conf", - "version": "0.0.0", - "dev": true, - "dependencies": { - "@eslint/js": "9.25.0", - "@stylistic/eslint-plugin": "4.2.0", - "eslint": "9.25.0", - "eslint-plugin-jsdoc": "50.6.9", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3", - "typescript-eslint": "8.30.1" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", - "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz", - "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz", - "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz", - "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz", - "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz", - "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz", - "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz", - "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz", - "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz", - "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz", - "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz", - "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz", - "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz", - "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz", - "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz", - "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz", - "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz", - "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz", - "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz", - "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz", - "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz", - "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz", - "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz", - "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz", - "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.1.tgz", - "integrity": "sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==", - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", - "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.6", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz", - "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", - "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "9.25.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.25.0.tgz", - "integrity": "sha512-iWhsUS8Wgxz9AXNfvfOPFSW4VfMXdVhp1hjkZVhXCrpgh/aLcc45rX6MPu+tIVUWDw0HfNwth7O28M1xDxNf9w==", - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", - "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.13.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", - "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", - "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.14.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz", - "integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/confbox": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", - "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "license": "MIT" - }, - "node_modules/esbuild": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", - "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.2", - "@esbuild/android-arm": "0.25.2", - "@esbuild/android-arm64": "0.25.2", - "@esbuild/android-x64": "0.25.2", - "@esbuild/darwin-arm64": "0.25.2", - "@esbuild/darwin-x64": "0.25.2", - "@esbuild/freebsd-arm64": "0.25.2", - "@esbuild/freebsd-x64": "0.25.2", - "@esbuild/linux-arm": "0.25.2", - "@esbuild/linux-arm64": "0.25.2", - "@esbuild/linux-ia32": "0.25.2", - "@esbuild/linux-loong64": "0.25.2", - "@esbuild/linux-mips64el": "0.25.2", - "@esbuild/linux-ppc64": "0.25.2", - "@esbuild/linux-riscv64": "0.25.2", - "@esbuild/linux-s390x": "0.25.2", - "@esbuild/linux-x64": "0.25.2", - "@esbuild/netbsd-arm64": "0.25.2", - "@esbuild/netbsd-x64": "0.25.2", - "@esbuild/openbsd-arm64": "0.25.2", - "@esbuild/openbsd-x64": "0.25.2", - "@esbuild/sunos-x64": "0.25.2", - "@esbuild/win32-arm64": "0.25.2", - "@esbuild/win32-ia32": "0.25.2", - "@esbuild/win32-x64": "0.25.2" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.25.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.25.0.tgz", - "integrity": "sha512-MsBdObhM4cEwkzCiraDv7A6txFXEqtNXOb877TsSp2FCkBNl8JfVQrmiuDqC1IkejT6JLPzYBXx/xAiYhyzgGA==", - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.20.0", - "@eslint/config-helpers": "^0.2.1", - "@eslint/core": "^0.13.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.25.0", - "@eslint/plugin-kit": "^0.2.8", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.3.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-conf": { - "resolved": "../config", - "link": true - }, - "node_modules/eslint-scope": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", - "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", - "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.14.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/exsolve": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.5.tgz", - "integrity": "sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==", - "license": "MIT" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "license": "MIT" - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "license": "ISC" - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "license": "MIT" - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "license": "MIT" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "license": "MIT" - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "license": "MIT" - }, - "node_modules/pkg-types": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.1.0.tgz", - "integrity": "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==", - "license": "MIT", - "dependencies": { - "confbox": "^0.2.1", - "exsolve": "^1.0.1", - "pathe": "^2.0.3" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "license": "MIT" - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/apps/mc-mods/package.json b/apps/mc-mods/package.json deleted file mode 100644 index a8f1d294..00000000 --- a/apps/mc-mods/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "mc-mods", - "version": "0.0.0", - "bin": "out/bin/app.cjs", - "type": "module", - "scripts": { - "build": "node_ver=$(node -v); esbuild src/app.ts --bundle --platform=node --target=\"node${node_ver:1:2}\" --outfile=out/bin/app.cjs" - }, - "dependencies": { - "@types/node": "22.14.1", - "esbuild": "0.25.2", - "eslint": "9.25.0", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3" - }, - "devDependencies": { - "eslint-conf": "file:../config" - } -} diff --git a/apps/mc-mods/src/app.ts b/apps/mc-mods/src/app.ts deleted file mode 100644 index 032baebc..00000000 --- a/apps/mc-mods/src/app.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { createWriteStream, mkdirSync, rmSync } from 'fs'; -import { Readable } from 'stream'; - -interface Hashes { - sha1: string - sha512: string -} -interface File { - hashes: Hashes - url: string - filename: string - primary: boolean - size: number - file_type: string -} -interface Dependency { - version_id: string - project_id: string - file_name: string - dependency_type: string -} -interface ModVersion { - game_versions: string[] - loaders: string[] - id: string - project_id: string - author_id: string - featured: boolean - name: string - version_number: string - changelog: string - changelog_url: string - date_published: string - downloads: number - version_type: string - status: string - files: File[] - dependencies: Dependency[] -} - -const LOADER = 'fabric'; - -const game_version = process.argv[2] ?? ''; -const action = process.argv[3] ?? 'check'; - -const getVersions = async(slug: string): Promise<ModVersion[]> => { - const res = await fetch(`https://api.modrinth.com/v2/project/${slug}/version`); - - return res.ok ? - await res.json() as ModVersion[] : - []; -}; - -const checkModCompat = async(slug: string): Promise<ModVersion | null> => { - const versions = await getVersions(slug); - - const matching = versions.filter((ver) => - ver.game_versions.includes(game_version) && - ver.loaders.includes(LOADER)); - - if (matching.length === 0) { - return null; - } - - const timeSorted = matching.sort((a, b) => { - const dateA = new Date(a.date_published); - const dateB = new Date(b.date_published); - - return dateB.getTime() - dateA.getTime(); - }); - - return timeSorted.some((v) => v.version_type === 'release') ? - timeSorted.filter((v) => v.version_type === 'release')[0] : - timeSorted[0]; -}; - -const getDownloadUrls = (version: ModVersion): string[] => version.files.map((file) => file.url); - -const showModDownloadUrls = async(modName: string): Promise<boolean> => { - const ver = await checkModCompat(modName); - - if (ver) { - const urls = getDownloadUrls(ver); - - console.log(`\n${modName}:`, urls); - - return true; - } - else { - return false; - } -}; - -const download = async(url: string, path: string) => Readable - .fromWeb((await fetch(url)).body!).pipe(createWriteStream(path)); - -const main = () => { - const mods = [ - 'badpackets', - 'c2me-fabric', - 'cloth-config', - 'clumps', - 'fabric-api', - 'ferrite-core', - 'leaves-be-gone', - 'lithium', - 'modernfix', - 'no-chat-reports', - 'noisium', - 'vmp-fabric', - 'wthit', - ]; - - if (action === 'check') { - mods.forEach(async(modName) => { - if (!(await showModDownloadUrls(modName))) { - console.error(`No matching releases of ${modName} were found for ${game_version}`); - } - }); - } - else if (action === 'download') { - rmSync('./out', { force: true, recursive: true }); - mkdirSync('./out'); - - mods.forEach(async(modName) => { - const ver = await checkModCompat(modName); - - if (ver === null) { - console.error(`No matching releases of ${modName} were found for ${game_version}`); - - return; - } - - const fileName = - `${modName}-${ver.version_number}.jar`; - - console.log(`Downloading ${fileName}`); - - await download( - ver.files[0].url, - `./out/${fileName}`, - ); - }); - } -}; - -main(); diff --git a/apps/mc-mods/tsconfig.json b/apps/mc-mods/tsconfig.json deleted file mode 100644 index 763e4667..00000000 --- a/apps/mc-mods/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "../config/tsconfig.base.json", - "includes": [ - "*.ts", - "**/*.ts", - "*.js", - "**/*.js" - ] -} diff --git a/apps/packages.nix b/apps/packages.nix deleted file mode 100644 index cae51022..00000000 --- a/apps/packages.nix +++ /dev/null @@ -1,16 +0,0 @@ -{inputs, ...}: (final: prev: { - appsPackages = let - inherit (final.lib) listToAttrs nameValuePair; - - buildApp = attrs: (final.callPackage ./buildApp.nix ({} // inputs // attrs)); - callPackage = file: final.callPackage file ({inherit buildApp;} // inputs); - in - listToAttrs (map (x: nameValuePair x (callPackage ./${x})) [ - "extract-subs" - "gen-docs" - "list2series" - "mc-mods" - "pin-inputs" - "update-sources" - ]); -}) diff --git a/apps/pin-inputs/.envrc b/apps/pin-inputs/.envrc deleted file mode 100644 index a3a97ba6..00000000 --- a/apps/pin-inputs/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -use flake $FLAKE#node -(cd ../config; npm ci) -npm ci diff --git a/apps/pin-inputs/default.nix b/apps/pin-inputs/default.nix deleted file mode 100644 index 4ce7b3ce..00000000 --- a/apps/pin-inputs/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -{buildApp, ...}: -buildApp { - src = ./.; - npmDepsHash = "sha256-7siUjfZbkPZXCwrhWeg2NoThHdBtULJXueXr1+wGmuY="; - - runtimeInputs = []; - - meta.description = '' - Takes a list of inputs to pin to their current rev in `flake.lock`. - ''; -} diff --git a/apps/pin-inputs/eslint.config.ts b/apps/pin-inputs/eslint.config.ts deleted file mode 100644 index 7d0908f3..00000000 --- a/apps/pin-inputs/eslint.config.ts +++ /dev/null @@ -1,3 +0,0 @@ -import eslintConf from 'eslint-conf'; - -export default eslintConf; diff --git a/apps/pin-inputs/package-lock.json b/apps/pin-inputs/package-lock.json deleted file mode 100644 index cdbd314a..00000000 --- a/apps/pin-inputs/package-lock.json +++ /dev/null @@ -1,1533 +0,0 @@ -{ - "name": "pin-inputs", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "pin-inputs", - "version": "0.0.0", - "dependencies": { - "@types/node": "22.14.1", - "esbuild": "0.25.2", - "eslint": "9.25.0", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3" - }, - "bin": { - "pin-inputs": "out/bin/app.cjs" - }, - "devDependencies": { - "eslint-conf": "file:../config" - } - }, - "../config": { - "name": "eslint-conf", - "version": "0.0.0", - "dev": true, - "dependencies": { - "@eslint/js": "9.25.0", - "@stylistic/eslint-plugin": "4.2.0", - "eslint": "9.25.0", - "eslint-plugin-jsdoc": "50.6.9", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3", - "typescript-eslint": "8.30.1" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", - "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz", - "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz", - "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz", - "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz", - "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz", - "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz", - "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz", - "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz", - "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz", - "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz", - "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz", - "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz", - "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz", - "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz", - "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz", - "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz", - "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz", - "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz", - "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz", - "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz", - "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz", - "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz", - "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz", - "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz", - "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.1.tgz", - "integrity": "sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==", - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", - "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.6", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz", - "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", - "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "9.25.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.25.0.tgz", - "integrity": "sha512-iWhsUS8Wgxz9AXNfvfOPFSW4VfMXdVhp1hjkZVhXCrpgh/aLcc45rX6MPu+tIVUWDw0HfNwth7O28M1xDxNf9w==", - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", - "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.13.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", - "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", - "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.14.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz", - "integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/confbox": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", - "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "license": "MIT" - }, - "node_modules/esbuild": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", - "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.2", - "@esbuild/android-arm": "0.25.2", - "@esbuild/android-arm64": "0.25.2", - "@esbuild/android-x64": "0.25.2", - "@esbuild/darwin-arm64": "0.25.2", - "@esbuild/darwin-x64": "0.25.2", - "@esbuild/freebsd-arm64": "0.25.2", - "@esbuild/freebsd-x64": "0.25.2", - "@esbuild/linux-arm": "0.25.2", - "@esbuild/linux-arm64": "0.25.2", - "@esbuild/linux-ia32": "0.25.2", - "@esbuild/linux-loong64": "0.25.2", - "@esbuild/linux-mips64el": "0.25.2", - "@esbuild/linux-ppc64": "0.25.2", - "@esbuild/linux-riscv64": "0.25.2", - "@esbuild/linux-s390x": "0.25.2", - "@esbuild/linux-x64": "0.25.2", - "@esbuild/netbsd-arm64": "0.25.2", - "@esbuild/netbsd-x64": "0.25.2", - "@esbuild/openbsd-arm64": "0.25.2", - "@esbuild/openbsd-x64": "0.25.2", - "@esbuild/sunos-x64": "0.25.2", - "@esbuild/win32-arm64": "0.25.2", - "@esbuild/win32-ia32": "0.25.2", - "@esbuild/win32-x64": "0.25.2" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.25.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.25.0.tgz", - "integrity": "sha512-MsBdObhM4cEwkzCiraDv7A6txFXEqtNXOb877TsSp2FCkBNl8JfVQrmiuDqC1IkejT6JLPzYBXx/xAiYhyzgGA==", - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.20.0", - "@eslint/config-helpers": "^0.2.1", - "@eslint/core": "^0.13.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.25.0", - "@eslint/plugin-kit": "^0.2.8", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.3.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-conf": { - "resolved": "../config", - "link": true - }, - "node_modules/eslint-scope": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", - "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", - "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.14.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/exsolve": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.5.tgz", - "integrity": "sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==", - "license": "MIT" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "license": "MIT" - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "license": "ISC" - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "license": "MIT" - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "license": "MIT" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "license": "MIT" - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "license": "MIT" - }, - "node_modules/pkg-types": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.1.0.tgz", - "integrity": "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==", - "license": "MIT", - "dependencies": { - "confbox": "^0.2.1", - "exsolve": "^1.0.1", - "pathe": "^2.0.3" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "license": "MIT" - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/apps/pin-inputs/package.json b/apps/pin-inputs/package.json deleted file mode 100644 index 9f710d3b..00000000 --- a/apps/pin-inputs/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "pin-inputs", - "version": "0.0.0", - "bin": "out/bin/app.cjs", - "type": "module", - "scripts": { - "build": "node_ver=$(node -v); esbuild src/app.ts --bundle --platform=node --target=\"node${node_ver:1:2}\" --outfile=out/bin/app.cjs" - }, - "dependencies": { - "@types/node": "22.14.1", - "esbuild": "0.25.2", - "eslint": "9.25.0", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3" - }, - "devDependencies": { - "eslint-conf": "file:../config" - } -} diff --git a/apps/pin-inputs/src/app.ts b/apps/pin-inputs/src/app.ts deleted file mode 100644 index f63d9fc0..00000000 --- a/apps/pin-inputs/src/app.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { readFileSync, writeFileSync } from 'fs'; - -export const replaceInFile = (replace: RegExp, replacement: string, file: string) => { - const fileContents = readFileSync(file); - - const replaced = fileContents.toString().replace(replace, replacement); - - writeFileSync(file, replaced); -}; - -/* Constants */ -const FLAKE = process.env.FLAKE; - -if (!FLAKE) { - console.error('Environment variable FLAKE not found'); - process.exit(1); -} - -const FLAKE_LOCK = JSON.parse(readFileSync(`${FLAKE}/flake.lock`, 'utf8')).nodes; -const INPUT_REVS = new Map<string, string>(); - -Object.entries(FLAKE_LOCK).forEach(([key, val]) => { - if (key !== 'root') { - // eslint-disable-next-line - INPUT_REVS.set(key, (val as any).locked.rev); - } -}); - -const INPUTS = process.argv.slice(2); - - -/** - * Gets the commit hash of the specified input in this flake. - * - * @param input the name of the input - * @returns the commit hash - */ -const getCurrentRev = (input: string): string => { - if (!INPUT_REVS.has(input)) { - throw new Error(`Input ${input} could not be found.`); - } - - return INPUT_REVS.get(input) as string; -}; - -INPUTS.forEach((input) => { - try { - const inputsFile = `${FLAKE}/inputs/default.nix`; - const rev = getCurrentRev(input); - - const msg = ['FIX', 'ME'].join(''); - - replaceInFile( - new RegExp(`(\\n[ ]*)${input} =.*\\n.*\\n.*`), - `$&\n$1 # ${msg}: $1 rev = "${rev}";`, - inputsFile, - ); - } - catch (e) { - console.error((e as Error).message); - } -}); diff --git a/apps/pin-inputs/tsconfig.json b/apps/pin-inputs/tsconfig.json deleted file mode 100644 index 763e4667..00000000 --- a/apps/pin-inputs/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "../config/tsconfig.base.json", - "includes": [ - "*.ts", - "**/*.ts", - "*.js", - "**/*.js" - ] -} diff --git a/apps/update-sources/.envrc b/apps/update-sources/.envrc deleted file mode 100644 index a3a97ba6..00000000 --- a/apps/update-sources/.envrc +++ /dev/null @@ -1,3 +0,0 @@ -use flake $FLAKE#node -(cd ../config; npm ci) -npm ci diff --git a/apps/update-sources/default.nix b/apps/update-sources/default.nix deleted file mode 100644 index 87816c24..00000000 --- a/apps/update-sources/default.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ - buildApp, - callPackage, - curl, - findutils, - go, - jq, - nix-update, - nodejs_latest, - prefetch-npm-deps, - ... -}: -buildApp { - src = ./.; - npmDepsHash = "sha256-Eqj0/lxega6zkKwXIxLRjEVXD7Z0chGLo4o0k3Dstk4="; - - runtimeInputs = [ - curl - findutils - go - jq - nix-update - nodejs_latest - prefetch-npm-deps - (callPackage ../../modules/docker/updateImage.nix {}) - ]; - - meta.description = '' - Updates all derivation sources in this repository and - generates a commit message for the changes made. - ''; -} diff --git a/apps/update-sources/eslint.config.ts b/apps/update-sources/eslint.config.ts deleted file mode 100644 index 7d0908f3..00000000 --- a/apps/update-sources/eslint.config.ts +++ /dev/null @@ -1,3 +0,0 @@ -import eslintConf from 'eslint-conf'; - -export default eslintConf; diff --git a/apps/update-sources/package-lock.json b/apps/update-sources/package-lock.json deleted file mode 100644 index 87cc0101..00000000 --- a/apps/update-sources/package-lock.json +++ /dev/null @@ -1,1533 +0,0 @@ -{ - "name": "update-sources", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "update-sources", - "version": "0.0.0", - "dependencies": { - "@types/node": "22.14.1", - "esbuild": "0.25.2", - "eslint": "9.25.0", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3" - }, - "bin": { - "update-sources": "out/bin/app.cjs" - }, - "devDependencies": { - "eslint-conf": "file:../config" - } - }, - "../config": { - "name": "eslint-conf", - "version": "0.0.0", - "dev": true, - "dependencies": { - "@eslint/js": "9.25.0", - "@stylistic/eslint-plugin": "4.2.0", - "eslint": "9.25.0", - "eslint-plugin-jsdoc": "50.6.9", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3", - "typescript-eslint": "8.30.1" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", - "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz", - "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz", - "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz", - "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz", - "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz", - "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz", - "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz", - "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz", - "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz", - "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz", - "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz", - "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz", - "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz", - "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz", - "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz", - "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz", - "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz", - "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz", - "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz", - "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz", - "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz", - "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz", - "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz", - "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz", - "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.1.tgz", - "integrity": "sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==", - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", - "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.6", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz", - "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", - "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "9.25.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.25.0.tgz", - "integrity": "sha512-iWhsUS8Wgxz9AXNfvfOPFSW4VfMXdVhp1hjkZVhXCrpgh/aLcc45rX6MPu+tIVUWDw0HfNwth7O28M1xDxNf9w==", - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", - "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.13.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", - "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", - "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.14.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz", - "integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/confbox": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", - "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "license": "MIT" - }, - "node_modules/esbuild": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", - "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.2", - "@esbuild/android-arm": "0.25.2", - "@esbuild/android-arm64": "0.25.2", - "@esbuild/android-x64": "0.25.2", - "@esbuild/darwin-arm64": "0.25.2", - "@esbuild/darwin-x64": "0.25.2", - "@esbuild/freebsd-arm64": "0.25.2", - "@esbuild/freebsd-x64": "0.25.2", - "@esbuild/linux-arm": "0.25.2", - "@esbuild/linux-arm64": "0.25.2", - "@esbuild/linux-ia32": "0.25.2", - "@esbuild/linux-loong64": "0.25.2", - "@esbuild/linux-mips64el": "0.25.2", - "@esbuild/linux-ppc64": "0.25.2", - "@esbuild/linux-riscv64": "0.25.2", - "@esbuild/linux-s390x": "0.25.2", - "@esbuild/linux-x64": "0.25.2", - "@esbuild/netbsd-arm64": "0.25.2", - "@esbuild/netbsd-x64": "0.25.2", - "@esbuild/openbsd-arm64": "0.25.2", - "@esbuild/openbsd-x64": "0.25.2", - "@esbuild/sunos-x64": "0.25.2", - "@esbuild/win32-arm64": "0.25.2", - "@esbuild/win32-ia32": "0.25.2", - "@esbuild/win32-x64": "0.25.2" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.25.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.25.0.tgz", - "integrity": "sha512-MsBdObhM4cEwkzCiraDv7A6txFXEqtNXOb877TsSp2FCkBNl8JfVQrmiuDqC1IkejT6JLPzYBXx/xAiYhyzgGA==", - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.20.0", - "@eslint/config-helpers": "^0.2.1", - "@eslint/core": "^0.13.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.25.0", - "@eslint/plugin-kit": "^0.2.8", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.3.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-conf": { - "resolved": "../config", - "link": true - }, - "node_modules/eslint-scope": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", - "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", - "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.14.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/exsolve": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.5.tgz", - "integrity": "sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==", - "license": "MIT" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "license": "MIT" - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "license": "ISC" - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "license": "MIT" - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "license": "MIT" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "license": "MIT" - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "license": "MIT" - }, - "node_modules/pkg-types": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.1.0.tgz", - "integrity": "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==", - "license": "MIT", - "dependencies": { - "confbox": "^0.2.1", - "exsolve": "^1.0.1", - "pathe": "^2.0.3" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "license": "MIT" - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/apps/update-sources/package.json b/apps/update-sources/package.json deleted file mode 100644 index a8d812a9..00000000 --- a/apps/update-sources/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "update-sources", - "version": "0.0.0", - "bin": "out/bin/app.cjs", - "type": "module", - "scripts": { - "build": "node_ver=$(node -v); esbuild src/app.ts --bundle --platform=node --target=\"node${node_ver:1:2}\" --outfile=out/bin/app.cjs" - }, - "dependencies": { - "@types/node": "22.14.1", - "esbuild": "0.25.2", - "eslint": "9.25.0", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3" - }, - "devDependencies": { - "eslint-conf": "file:../config" - } -} diff --git a/apps/update-sources/src/app.ts b/apps/update-sources/src/app.ts deleted file mode 100644 index c0a0eee0..00000000 --- a/apps/update-sources/src/app.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { spawnSync } from 'node:child_process'; -import { writeFileSync } from 'node:fs'; -import { styleText } from 'node:util'; - -import { parseArgs } from './lib'; - -import updateCaddyPlugins from './caddy'; -import updateDocker from './docker'; -import updateFirefoxAddons from '././firefox'; -import updateFlakeInputs from './flake'; -import runNixUpdate from './nix-update'; -import updateNodeModules from './node-modules'; -import updateVuetorrent from './vuetorrent'; - - -/* Constants */ -const FLAKE = process.env.FLAKE; - -if (!FLAKE) { - console.error('Env var FLAKE not found'); - process.exit(1); -} - -const args = parseArgs(); - -const main = async() => { - if (args['c'] || args['custom-sidebar']) { - console.log(runNixUpdate('scopedPackages', 'lovelace-components', 'custom-sidebar')); - } - - if (args['cp'] || args['caddy-plugins']) { - console.log(updateCaddyPlugins() ?? ''); - } - - if (args['d'] || args['docker']) { - console.log(updateDocker() ?? ''); - } - - if (args['f'] || args['firefox']) { - console.log(updateFirefoxAddons() ?? ''); - } - - if (args['h'] || args['homepage']) { - console.log(runNixUpdate('homepage')); - } - - if (args['i'] || args['inputs']) { - console.log(updateFlakeInputs() ?? ''); - } - - if (args['j'] || args['jmusicbot']) { - console.log(runNixUpdate('jmusicbot')); - } - - if (args['m'] || args['material-rounded-theme']) { - console.log(runNixUpdate('scopedPackages', 'lovelace-components', 'material-rounded-theme')); - } - - if (args['n'] || args['node_modules']) { - console.log((await updateNodeModules()) ?? ''); - } - - if (args['p'] || args['pam-fprint-grosshack']) { - console.log(runNixUpdate('pam-fprint-grosshack')); - } - - if (args['ph'] || args['protonhax']) { - console.log(runNixUpdate('protonhax')); - } - - if (args['s'] || args['some-sass-language-server']) { - console.log(runNixUpdate('some-sass-language-server')); - } - - if (args['t'] || args['trash-d']) { - console.log(runNixUpdate('trash-d')); - } - - if (args['v'] || args['vuetorrent']) { - console.log(updateVuetorrent() ?? ''); - } - - if (args['a'] || args['all']) { - // Update this first because of nix run cmd - const firefoxOutput = updateFirefoxAddons(); - - console.log(firefoxOutput ?? 'No updates'); - - - const flakeOutput = updateFlakeInputs(); - - console.log(flakeOutput ?? 'No updates'); - - - const dockerOutput = updateDocker(); - - console.log(dockerOutput ?? 'No updates'); - - - const nodeModulesOutput = await updateNodeModules(); - - console.log(nodeModulesOutput ?? 'No updates'); - - - const vuetorrentOutput = updateVuetorrent(); - - console.log(vuetorrentOutput ?? 'No updates'); - - - const caddyPluginsOutput = updateCaddyPlugins(); - - console.log(caddyPluginsOutput ?? 'No updates'); - - - // nix-update executions - const nixUpdateOutputs: string[] = []; - - const updatePackage = ( - attr: string, - scope?: string, - scopeAttr?: string, - ): void => { - const execution = runNixUpdate(attr, scope, scopeAttr); - - if (execution.changelog) { - nixUpdateOutputs.push(execution.changelog); - } - console.log(execution.stderr); - }; - - updatePackage('homepage'); - updatePackage('jmusicbot'); - updatePackage('pam-fprint-grosshack'); - updatePackage('protonhax'); - updatePackage('some-sass-language-server'); - updatePackage('trash-d'); - updatePackage('scopedPackages', 'lovelace-components', 'custom-sidebar'); - updatePackage('scopedPackages', 'lovelace-components', 'material-rounded-theme'); - - - spawnSync('alejandra', ['-q', FLAKE], { shell: true }); - - spawnSync('nixFastBuild', [], { - shell: true, - stdio: [process.stdin, process.stdout, process.stderr], - }); - - const indentOutput = (output: string): string => { - return ` ${output.replace(/\n*$/g, '').split('\n').join('\n ')}`; - }; - - const output = [ - 'chore: update sources', - ]; - - if (flakeOutput) { - output.push(`Flake Inputs:\n${indentOutput(flakeOutput)}\n`); - } - if (dockerOutput) { - output.push(`Docker Images:\n${indentOutput(dockerOutput)}\n`); - } - if (firefoxOutput) { - output.push(`Firefox Addons:\n${indentOutput(firefoxOutput)}\n`); - } - if (nodeModulesOutput) { - output.push(`Node modules:\n${indentOutput(nodeModulesOutput)}\n`); - } - if (vuetorrentOutput) { - output.push(`qBittorrent Sources:\n${indentOutput(vuetorrentOutput)}\n`); - } - if (caddyPluginsOutput) { - output.push(`Caddy Plugins:\n${indentOutput(caddyPluginsOutput)}\n`); - } - if (nixUpdateOutputs.length > 0) { - output.push(`nix-update executions:\n${indentOutput(nixUpdateOutputs.join('\n'))}\n`); - } - - if (args['f']) { - console.log(styleText(['magenta'], `\n\nWriting commit message to ${args['f']}\n`)); - writeFileSync(args['f'], output.join('\n\n')); - } - else { - console.log(styleText(['magenta'], '\n\nCommit message:\n')); - console.log(output.join('\n\n')); - } - } -}; - -main(); diff --git a/apps/update-sources/src/caddy.ts b/apps/update-sources/src/caddy.ts deleted file mode 100644 index ca84f9f6..00000000 --- a/apps/update-sources/src/caddy.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { writeFileSync } from 'node:fs'; -import { spawnSync } from 'node:child_process'; - -import { replaceInFile } from './lib'; -import { styleText } from 'node:util'; - -/* Types */ -interface Plugin { - url: string - version: string - type: 'version' | 'git' -} - - -/* Constants */ -const FLAKE = process.env.FLAKE; - -const genPluginsText = ( - plugins: Record<string, Plugin>, -) => `{ - plugins = { -${Object.entries(plugins) - .map(([key, value]) => ` - ${key} = { - url = "${value.url}"; - version = "${value.version}"; - type = "${value.type}"; - }; - `) - .join('')} - }; - - hash = ""; -} -`; - -export default (): string | null => { - console.log(styleText(['magenta'], '\nUpdating caddy plugins:\n')); - - const updates: string[] = []; - const dir = `${FLAKE}/configurations/cluster/modules/caddy`; - - // Setup workspace - spawnSync( - [ - 'rm -rf /tmp/update-caddy', - 'mkdir -p /tmp/update-caddy', - 'cd /tmp/update-caddy || exit 1', - 'go mod init temp', - ].join('; '), - [], - { shell: true, cwd: '/tmp' }, - ); - - const plugins = JSON.parse(spawnSync('nix', - ['eval', '-f', `${dir}/plugins.nix`, '--json'], - { shell: true }).stdout.toString()).plugins as Record<string, Plugin>; - - // Get most recent versions of plugins - Object.entries(plugins).forEach(([key, value]) => { - const NEW_VERSION = spawnSync([ - 'go mod init temp > /dev/null', - `go get ${value.url}${value.type === 'git' ? '@HEAD' : ''} > /dev/null`, - `grep '${value.url}' go.mod`, - ].join('; '), [], { shell: true, cwd: '/tmp/update-caddy' }) - .stdout - .toString() - .trim() - .replace(' // indirect', '') - .split(' ')[1]; - - if (plugins[key].version !== NEW_VERSION) { - updates.push(`${key}: ${plugins[key].version} -> ${NEW_VERSION}`); - plugins[key].version = NEW_VERSION; - } - }); - - writeFileSync(`${dir}/plugins.nix`, genPluginsText(plugins)); - - // Get new hash - const caddyPkgAttr = 'nixosConfigurations.thingone.config.services.caddy.package'; - - const NEW_HASH = spawnSync( - `nix build "$FLAKE#${caddyPkgAttr}" |& sed -n 's/.*got: *//p'`, - [], - { shell: true }, - ).stdout.toString().trim(); - - replaceInFile(/hash = ".*";/, `hash = "${NEW_HASH}";`, `${dir}/plugins.nix`); - - return updates.length > 0 ? updates.join('\n') : null; -}; diff --git a/apps/update-sources/src/docker.ts b/apps/update-sources/src/docker.ts deleted file mode 100644 index a5683708..00000000 --- a/apps/update-sources/src/docker.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { readdirSync } from 'node:fs'; -import { spawnSync } from 'node:child_process'; -import { styleText } from 'node:util'; - - -/* Constants */ -const FLAKE = process.env.FLAKE; - -const updateImages = (imagePath: string): string | undefined => { - console.log(`Updating ${imagePath.split('/').at(-1)} images`); - - const out = spawnSync('updateImages', [imagePath], { shell: true }).stdout.toString(); - - if (!out.startsWith('# Locked')) { - return out; - } -}; - -export default (): string | null => { - console.log(styleText(['magenta'], '\nUpdating docker images:\n')); - - const updates: string[] = []; - - const jellfyinUpdates = updateImages(`${FLAKE}/configurations/nos/modules/jellyfin`); - - if (jellfyinUpdates) { - updates.push(jellfyinUpdates); - } - - const hassUpdates = updateImages(`${FLAKE}/configurations/homie/modules/home-assistant/netdaemon`); - - if (hassUpdates) { - updates.push(hassUpdates); - } - - const DIR = `${FLAKE}/configurations/nos/modules/docker`; - - readdirSync(DIR, { withFileTypes: true, recursive: true }).forEach((path) => { - if (path.name === 'compose.nix') { - const composeUpdates = updateImages(path.parentPath); - - if (composeUpdates) { - updates.push(composeUpdates); - } - } - }); - - return updates.length > 0 ? - updates.join('') : - null; -}; diff --git a/apps/update-sources/src/firefox.ts b/apps/update-sources/src/firefox.ts deleted file mode 100644 index 8531404c..00000000 --- a/apps/update-sources/src/firefox.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { spawnSync } from 'node:child_process'; -import { readFileSync } from 'node:fs'; -import { styleText } from 'node:util'; - - -/* Constants */ -const FLAKE = process.env.FLAKE; - -export default (): string | null => { - console.log(styleText(['magenta'], '\nUpdating firefox addons using mozilla-addons-to-nix:\n')); - - const DIR = `${FLAKE}/scopedPackages/firefox-addons`; - const GENERATED_FILE = `${DIR}/generated-firefox-addons.nix`; - const SLUGS = `${DIR}/addons.json`; - - const nameMap = Object.fromEntries([...JSON.parse(readFileSync(SLUGS, 'utf-8'))] - .map((addon) => [addon.slug, addon.pname || addon.slug])); - - const nixExpr = `' - x: let - inherit (builtins) attrValues filter hasAttr isAttrs map; - in - map (d: d.name) (filter (y: - isAttrs y && - hasAttr "type" y && - y.type == "derivation") (attrValues x)) - '`; - - const OLD_VERS = Object.fromEntries([...JSON.parse(spawnSync('nix', [ - 'eval', - '.#scopedPackages.x86_64-linux.firefoxAddons', - '--apply', - nixExpr, - '--json', - ], { shell: true }).stdout.toString())] - .map((p) => { - const pname = p.replace(/-[0-9].*$/, ''); - - return [pname, p.replace(`${pname}-`, '')]; - }) - .filter((pinfo) => pinfo[0] !== 'frankerfacez')); - - const NEW_VERS = Object.fromEntries(spawnSync( - 'nix', - ['run', 'sourcehut:~rycee/mozilla-addons-to-nix', - SLUGS, GENERATED_FILE], - { shell: true }, - ).stdout - .toString() - .split('\n') - .map((p) => { - const pinfo = p.replace('Fetched ', '').split(' '); - - return [nameMap[pinfo[0]], pinfo[2]]; - })); - - const changelogs = Object.keys(OLD_VERS) - .sort() - .filter((pname) => OLD_VERS[pname] !== NEW_VERS[pname]) - .map((pname) => `${pname}: ${OLD_VERS[pname]} -> ${NEW_VERS[pname]}`); - - return changelogs.length > 0 ? - changelogs.join('\n') : - null; -}; diff --git a/apps/update-sources/src/flake.ts b/apps/update-sources/src/flake.ts deleted file mode 100644 index 2809f96e..00000000 --- a/apps/update-sources/src/flake.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { spawnSync } from 'node:child_process'; -import { styleText } from 'node:util'; - - -/* Constants */ -const FLAKE = process.env.FLAKE; - -export default (): string | null => { - console.log(styleText(['magenta'], '\nUpdating flake inputs:\n')); - - const output: string = spawnSync( - `git restore flake.lock &> /dev/null; nix flake update --flake ${FLAKE}` + - ' |& grep -v "warning: updating lock file" |& grep -v "unpacking"', - [], - { shell: true }, - ).stdout.toString(); - - const inputsUpdates: string[] = output - // Get an array of each update / change - .split('\n•') - // Filter out some inputs - .filter((input) => ![ - 'systems', - 'flake-compat', - 'flake-utils', - 'flake-parts', - 'treefmt-nix', - 'lib-aggregate', - 'lib-aggregate/nixpkgs-lib', - 'nix-gaming/umu', - 'nix-github-actions', - 'pre-commit-hooks', - ].some((inputName) => input.startsWith(` Updated input '${inputName}'`))); - - const formattedOutput: string = inputsUpdates - // Add an extra blank line between inputs - .join('\n\n•') - // Help readability of git revs - .split('\n') - .map((l) => l - .replace( - /\/(.{40})\?narHash=sha256[^']*(.*)/, - (_, backref1, backref2) => `${backref2} rev: ${backref1}`, - ) - .replace( - /\?ref.*&rev=(.{40})[^'&]*(.*)/, - (_, backref1, backref2) => `${backref2} rev: ${backref1}`, - )) - .join('\n'); - - return inputsUpdates.length > 0 ? - formattedOutput : - null; -}; diff --git a/apps/update-sources/src/lib.ts b/apps/update-sources/src/lib.ts deleted file mode 100644 index 78642ad6..00000000 --- a/apps/update-sources/src/lib.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { spawnSync } from 'node:child_process'; -import { readFileSync, writeFileSync } from 'node:fs'; - -/* Types */ -interface Args { - f: string | undefined - [name: string]: unknown -} - - -export const parseArgs = (): Args => { - const args = {} as Args; - let lastFlag: string | null = null; - - for (let i = 2; i < process.argv.length; ++i) { - const arg = process.argv[i]; - - if (arg.toString().startsWith('-')) { - lastFlag = arg.toString().replace(/^-{1,2}/, ''); - args[lastFlag] = true; - } - else if (lastFlag) { - args[lastFlag] = arg; - lastFlag = null; - } - else { - console.error(`Could not parse args: ${arg.toString()}`); - } - } - - return args; -}; - -export const parseFetchurl = (url: string): string => JSON.parse(spawnSync( - 'nix', ['store', 'prefetch-file', '--refresh', '--json', - '--hash-type', 'sha256', url, '--name', '"escaped"'], { shell: true }, -).stdout.toString()).hash; - -export const replaceInFile = (replace: RegExp, replacement: string, file: string): void => { - const fileContents = readFileSync(file); - - const replaced = fileContents.toString().replace(replace, replacement); - - writeFileSync(file, replaced); -}; - -export const npmRun = (args: string[], workspaceDir: string): string => spawnSync( - 'npm', args, { cwd: workspaceDir }, -).stdout.toString(); diff --git a/apps/update-sources/src/nix-update.ts b/apps/update-sources/src/nix-update.ts deleted file mode 100644 index 7fb6a45d..00000000 --- a/apps/update-sources/src/nix-update.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { spawnSync } from 'node:child_process'; -import { styleText } from 'node:util'; - - -/* Constants */ -const FLAKE = process.env.FLAKE; - -const getAttrVersion = (attr: string): string => spawnSync('nix', - ['eval', '--raw', `${FLAKE}#${attr}.version`], - { shell: true }).stdout.toString(); - -export default ( - attr: string, - scope?: string, - scopeAttr?: string, -): { - changelog: string | null - stdout: string - stderr: string -} => { - const realAttr = scope ? `${attr}.x86_64-linux.${scope}.${scopeAttr}` : attr; - const cleanAttr = scope ? `${attr}.${scope}.${scopeAttr}` : attr; - - console.log(styleText(['magenta'], `\nUpdating ${realAttr}:\n`)); - - const OLD_VERSION = getAttrVersion(realAttr); - - const execution = spawnSync('nix-update', ['--flake', realAttr, '-u'], { cwd: FLAKE }); - - const NEW_VERSION = getAttrVersion(realAttr); - - return { - changelog: OLD_VERSION !== NEW_VERSION ? - `${cleanAttr}: ${OLD_VERSION} -> ${NEW_VERSION}` : - null, - stdout: execution.stdout.toString(), - stderr: execution.stderr.toString(), - }; -}; diff --git a/apps/update-sources/src/node-modules.ts b/apps/update-sources/src/node-modules.ts deleted file mode 100644 index 18264d02..00000000 --- a/apps/update-sources/src/node-modules.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { readPackageJSON, writePackageJSON } from 'pkg-types'; -import { accessSync, constants, existsSync } from 'node:fs'; -import { spawnSync } from 'node:child_process'; -import { styleText } from 'node:util'; - -import { replaceInFile, npmRun } from './lib'; - - -/* Constants */ -const FLAKE = process.env.FLAKE as string; - -const PINS = new Map([]); - -const updatePackageJson = async(workspaceDir: string, updates: object) => { - const currentPackageJson = await readPackageJSON(`${workspaceDir}/package.json`); - - const outdated = JSON.parse(npmRun(['outdated', '--json'], workspaceDir)); - - const updateDeps = (deps: string) => { - Object.keys(currentPackageJson[deps]).forEach(async(dep) => { - if (dep === 'astal') { - const latestCommit = JSON.parse(spawnSync('curl', - ['-s', 'https://api.github.com/repos/Aylur/astal/commits/main'], - { shell: true }).stdout.toString()).sha; - - currentPackageJson[deps][dep] = `https://gitpkg.vercel.app/Aylur/astal/lang/gjs/src?${latestCommit}`; - - return; - } - - if (PINS.has(dep)) { - currentPackageJson[deps][dep] = PINS.get(dep); - - return; - } - - const versions = outdated[dep]; - const current = versions?.wanted || versions?.current; - - if (!current) { - return; - } - - if (current !== versions.latest) { - updates[dep] = `${current} -> ${versions.latest}`; - } - - currentPackageJson[deps][dep] = versions.latest; - }); - }; - - if (currentPackageJson.dependencies) { - updateDeps('dependencies'); - } - - if (currentPackageJson.devDependencies) { - updateDeps('devDependencies'); - } - - await writePackageJSON(`${workspaceDir}/package.json`, currentPackageJson); -}; - - -const prefetchNpmDeps = (workspaceDir: string): string => { - npmRun(['update', '--package-lock-only'], workspaceDir); - - return spawnSync( - 'prefetch-npm-deps', - [`${workspaceDir}/package-lock.json`], - ).stdout.toString().replace('\n', ''); -}; - - -export default async(): Promise<string | null> => { - console.log(styleText(['magenta'], '\nUpdating node modules:\n')); - - const updates = {}; - - const packages = spawnSync('find', [FLAKE, '-name', 'package.json']).stdout.toString().split('\n') - .filter((f) => f !== '') - .filter((f) => ![ - '.direnv', - 'node_modules', - 'results', - ].some((dirName) => f.includes(dirName))); - - for (const path of packages) { - console.log(path); - - try { - accessSync(path, constants.R_OK | constants.W_OK); - - const parentPath = path.replace('/package.json', ''); - - await updatePackageJson(parentPath, updates); - - if (existsSync(`${parentPath}/default.nix`)) { - const hash = prefetchNpmDeps(parentPath); - - replaceInFile( - /npmDepsHash = ".*";/, - `npmDepsHash = "${hash}";`, - `${parentPath}/default.nix`, - ); - } - - // Make sure we update the apps' config package-lock.json - if (parentPath.includes('apps/config')) { - npmRun(['i'], parentPath); - } - } - catch (e) { - console.warn(`Could not write to ${path}`); - console.warn(e); - } - } - - return Object.entries(updates).length > 0 ? - Object.entries(updates) - .map(([key, dep]) => `${key}: ${dep}`) - .join('\n') : - null; -}; diff --git a/apps/update-sources/src/vuetorrent.ts b/apps/update-sources/src/vuetorrent.ts deleted file mode 100644 index fa1d23c5..00000000 --- a/apps/update-sources/src/vuetorrent.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { writeFileSync } from 'node:fs'; -import { spawnSync } from 'node:child_process'; -import { styleText } from 'node:util'; - -import { parseFetchurl } from './lib'; - - -/* Constants */ -const FLAKE = process.env.FLAKE; - -const genVueText = ( - version: string, - hash: string, - url: string, -) => `# This file was autogenerated. DO NOT EDIT! -{ - version = "${version}"; - url = "${url}"; - hash = "${hash}"; -} -`; - -export default (): string | null => { - console.log(styleText(['magenta'], '\nUpdating Vuetorrent:\n')); - - const FILE = `${FLAKE}/configurations/nos/modules/qbittorrent/vuetorrent.nix`; - - const OLD_VERSION = JSON.parse(spawnSync('nix', - ['eval', '-f', FILE, '--json'], - { shell: true }).stdout.toString()).version; - - const VERSION = JSON.parse(spawnSync('curl', - ['-s', 'https://api.github.com/repos/VueTorrent/VueTorrent/releases/latest'], - { shell: true }).stdout.toString()).tag_name.replace('v', ''); - - const URL = `https://github.com/VueTorrent/VueTorrent/releases/download/v${VERSION}/vuetorrent.zip`; - const HASH = parseFetchurl(URL); - - const fileText = genVueText(VERSION, HASH, URL); - - writeFileSync(FILE, fileText); - - return OLD_VERSION !== VERSION ? `Vuetorrent: ${OLD_VERSION} -> ${VERSION}\n` : null; -}; diff --git a/apps/update-sources/tsconfig.json b/apps/update-sources/tsconfig.json deleted file mode 100644 index 763e4667..00000000 --- a/apps/update-sources/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "../config/tsconfig.base.json", - "includes": [ - "*.ts", - "**/*.ts", - "*.js", - "**/*.js" - ] -} diff --git a/config/ags/bin/heart.sh b/config/ags/bin/heart.sh new file mode 100755 index 00000000..be13a822 --- /dev/null +++ b/config/ags/bin/heart.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +FILE="$HOME/.config/.heart" + +toggle() { + if grep -q "$FILE"; then + echo > "$FILE" + else + echo >> "$FILE" + fi +} + +[[ "$1" == "toggle" ]] && toggle diff --git a/config/ags/bin/launch-app.sh b/config/ags/bin/launch-app.sh new file mode 100755 index 00000000..ef79c6dd --- /dev/null +++ b/config/ags/bin/launch-app.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +APP="$1" +EXEC="$2" + +if [[ "$APP" == "thunderbird" ]]; then + hyprctl dispatch togglespecialworkspace thunder +elif [[ "$APP" == "Spotify" ]]; then + hyprctl dispatch togglespecialworkspace spot +elif [[ $(hyprctl clients | grep "$APP") != "" ]]; then + hyprctl dispatch focuswindow "^($APP)$" +else + hyprctl dispatch workspace empty + hyprctl dispatch exec "$EXEC" +fi diff --git a/config/ags/bin/osk-toggle.sh b/config/ags/bin/osk-toggle.sh new file mode 100755 index 00000000..4c5cea13 --- /dev/null +++ b/config/ags/bin/osk-toggle.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +state () { + if [[ $(busctl get-property --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 Visible) == "b true" ]]; then + echo "Running" + else + echo "Stopped" + fi +} + +toggle () { + if [[ $(busctl get-property --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 Visible) == "b true" ]]; then + echo "Running" + busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b false + else + echo "Stopped" + busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b true + fi +} + +if [[ $1 == "getState" ]]; then + while true; do + sleep 0.2 + state + done +fi + +if [[ $1 == "toggle" ]];then + toggle +fi diff --git a/config/ags/bin/qs-toggles.sh b/config/ags/bin/qs-toggles.sh new file mode 100755 index 00000000..b7be84ca --- /dev/null +++ b/config/ags/bin/qs-toggles.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +radio_status () { + radio_status=$(nmcli radio wifi) + if [[ $radio_status == "enabled" ]]; then + echo "on" + else + echo "off" + fi +} + +if [[ $1 == "toggle-radio" ]]; then + stat=$(radio_status) + if [[ $stat == "on" ]]; then + nmcli radio wifi off + else + nmcli radio wifi on + fi +fi + +FILE='/home/matt/.config/.bluetooth' +get_state() { + if [[ "$(rfkill list | grep -A 1 hci0 | grep -o no)" == "no" ]]; then + echo " " > "$FILE" + else + echo " " > "$FILE" + fi +} + +if [[ "$1" == "blue-toggle" ]]; then + rfkill toggle bluetooth + get_state +fi diff --git a/config/ags/bin/startup.sh b/config/ags/bin/startup.sh new file mode 100755 index 00000000..af1ede43 --- /dev/null +++ b/config/ags/bin/startup.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +## Make bluetooth status persistent between reboots +if [[ ! -f "$HOME/.config/.bluetooth" ]]; then + echo > "$FILE" +fi + +if grep -q "$HOME/.config/.bluetooth"; then + rfkill block bluetooth +fi diff --git a/config/ags/bin/tablet-toggle.sh b/config/ags/bin/tablet-toggle.sh new file mode 100755 index 00000000..3b99ddf4 --- /dev/null +++ b/config/ags/bin/tablet-toggle.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +tablet() { + gsettings set org.gnome.desktop.a11y.applications screen-keyboard-enabled true + + brightnessctl -d tpacpi::kbd_backlight s 0 + + "$HYPR_PATH"/autorotate.sh & + + evtest --grab "/dev/input/by-path/platform-i8042-serio-0-event-kbd" & + evtest --grab "/dev/input/by-path/platform-i8042-serio-1-event-mouse" & + evtest --grab "/dev/input/by-path/platform-AMDI0010:02-event-mouse" & + evtest --grab "/dev/input/by-path/platform-thinkpad_acpi-event" & + evtest --grab "/dev/video-bus" & +} + +laptop() { + gsettings set org.gnome.desktop.a11y.applications screen-keyboard-enabled false + + brightnessctl -d tpacpi::kbd_backlight s 2 + + killall -r autorotate.sh + killall -r evtest +} + +toggle () { + if [[ "$(gsettings get org.gnome.desktop.a11y.applications screen-keyboard-enabled)" == "false" ]]; then + echo "Tablet" + tablet > /dev/null + else + echo "Laptop" + laptop > /dev/null + fi +} + +[[ $1 == "toggle" ]] && toggle +[[ $1 == "laptop" ]] && laptop +[[ $1 == "tablet" ]] && tablet diff --git a/config/ags/config.js b/config/ags/config.js new file mode 100644 index 00000000..fc76c657 --- /dev/null +++ b/config/ags/config.js @@ -0,0 +1,44 @@ +import { exec, execAsync } from 'resource:///com/github/Aylur/ags/utils.js'; +import { Powermenu } from './js/powermenu.js'; +import { Bar } from './js/bar/main.js'; +import { NotificationCenter } from './js/notifications/center.js'; +import { NotificationsPopupList } from './js/notifications/popup.js' +import { Calendar } from './js/date.js'; +import { QuickSettings } from './js/quick-settings/main.js'; +import Overview from './js/overview/main.js'; +import AppLauncher from './js/applauncher/main.js'; + +import { Closer, closeAll } from './js/misc/closer.js'; +ags.App.closeAll = () => closeAll(); + +const scss = ags.App.configDir + '/scss/main.scss'; +const css = ags.App.configDir + '/style.css'; + +exec(`sassc ${scss} ${css}`); + +execAsync(['bash', '-c', '$AGS_PATH/startup.sh']).catch(print); + +export default { + style: css, + notificationPopupTimeout: 5000, + cacheNotificationActions: true, + closeWindowDelay: { + 'quick-settings': 500, + 'notification-center': 500, + 'calendar': 500, + 'powermenu': 500, + 'overview': 500, + 'applauncher': 500, + }, + windows: [ + Powermenu, + Bar, + Closer, + NotificationCenter, + NotificationsPopupList, + Calendar, + QuickSettings, + Overview, + AppLauncher, + ], +}; diff --git a/config/ags/js/applauncher/main.js b/config/ags/js/applauncher/main.js new file mode 100644 index 00000000..80e24f22 --- /dev/null +++ b/config/ags/js/applauncher/main.js @@ -0,0 +1,134 @@ +const { App } = ags; +const { Applications } = ags.Service; +const { Label, Box, Icon, Button, Scrollable, Entry, Window, EventBox } = ags.Widget; + +import { Separator } from '../misc/separator.js'; +import { PopUp } from '../misc/popup.js'; + +const icons = { + apps: { + apps: 'view-app-grid-symbolic', + search: 'preferences-system-search-symbolic', + } +}; + +const AppItem = (app, window) => { + if (app.app.get_string('Icon') == 'Nextcloud') + return; + + return Button({ + className: 'app', + connections: [['clicked', () => { + App.closeWindow(window); + app.launch(); + }]], + child: Box({ + children: [ + Icon({ + icon: app.app.get_string('Icon'), + size: 42, + }), + Box({ + vertical: true, + children: [ + Label({ + className: 'title', + label: app.name, + xalign: 0, + valign: 'center', + ellipsize: 3, + }), + Label({ + className: 'description', + label: app.description || '', + wrap: true, + xalign: 0, + justification: 'left', + valign: 'center', + }), + ], + }), + ], + }), + }); +}; + +const Applauncher = ({ windowName = 'applauncher' } = {}) => { + const list = Box({ vertical: true }); + const placeholder = Label({ + label: " Couldn't find a match", + className: 'placeholder', + }); + const entry = Entry({ + hexpand: true, + placeholderText: 'Search', + onAccept: ({ text }) => { + const list = Applications.query(text); + if (list[0]) { + App.toggleWindow(windowName); + list[0].launch(); + } + }, + onChange: ({ text }) => { + list.children = Applications.query(text).map(app => [ + Separator(4), + AppItem(app, windowName), + ]).flat(); + list.add(Separator(4)); + list.show_all(); + + placeholder.visible = list.children.length === 1; + }, + }); + + return Box({ + className: 'applauncher', + properties: [['list', list]], + vertical: true, + children: [ + Box({ + className: 'header', + children: [ + Icon(icons.apps.search), + entry, + ], + }), + Scrollable({ + hscroll: 'never', + child: Box({ + vertical: true, + children: [list, placeholder], + }), + }), + ], + connections: [[App, (_b, name, visible) => { + if (name !== windowName) + return; + + entry.set_text('-'); // force onChange + entry.set_text(''); + if (visible) + entry.grab_focus(); + }]], + }); +}; + +// FIXME: make it so I don't have to click to trigger onHoverLost +export default Window({ + name: 'applauncher', + popup: true, + focusable: true, + layer: 'overlay', + child: EventBox({ + onHover: box => { + box.get_parent().focusable = true + }, + onHoverLost: box => { + box.get_parent().focusable = false + }, + child: PopUp({ + name: 'applauncher', + child: Applauncher(), + }), + }), +}); diff --git a/config/ags/js/bar/audio.js b/config/ags/js/bar/audio.js new file mode 100644 index 00000000..a44aba4e --- /dev/null +++ b/config/ags/js/bar/audio.js @@ -0,0 +1,55 @@ +const { Audio } = ags.Service; +const { Label, Box, Icon, Stack, Button, Slider } = ags.Widget; + +import { Separator } from '../misc/separator.js'; +import { EventBox } from '../misc/cursorbox.js'; + +const items = { + 101: 'audio-volume-overamplified-symbolic', + 67: 'audio-volume-high-symbolic', + 34: 'audio-volume-medium-symbolic', + 1: 'audio-volume-low-symbolic', + 0: 'audio-volume-muted-symbolic', +}; + +const SpeakerIndicator = params => Icon({ + ...params, + icon: '', + connections: [[Audio, icon => { + if (Audio.speaker) { + if (Audio.speaker.isMuted) { + icon.icon = items[0]; + } + else { + const vol = Audio.speaker.volume * 100; + for (const threshold of [-1, 0, 33, 66, 100]) { + if (vol > threshold + 1) { + icon.icon = items[threshold + 1]; + } + } + } + } + }, 'speaker-changed']], +}); + +const SpeakerPercentLabel = params => Label({ + ...params, + connections: [[Audio, label => { + if (Audio.speaker) { + label.label = Math.round(Audio.speaker.volume * 100) + '%'; + } + }, 'speaker-changed']], +}); + +export const AudioIndicator = EventBox({ + onPrimaryClickRelease: 'pavucontrol', + className: 'toggle-off', + child: Box({ + className: 'audio', + children: [ + SpeakerIndicator(), + Separator(5), + SpeakerPercentLabel(), + ], + }), +}); diff --git a/config/ags/js/bar/battery.js b/config/ags/js/bar/battery.js new file mode 100644 index 00000000..bfc9eb22 --- /dev/null +++ b/config/ags/js/bar/battery.js @@ -0,0 +1,58 @@ +const { Battery } = ags.Service; +const { Label, Icon, Stack, Box } = ags.Widget; + +import { Separator } from '../misc/separator.js'; + +const icons = charging => ([ + ...Array.from({ length: 10 }, (_, i) => i * 10).map(i => ([ + `${i}`, Icon({ + className: `${i} ${charging ? 'charging' : 'discharging'}`, + icon: `battery-level-${i}${charging ? '-charging' : ''}-symbolic`, + }), + ])), + ['100', Icon({ + className: `100 ${charging ? 'charging' : 'discharging'}`, + icon: `battery-level-100${charging ? '-charged' : ''}-symbolic`, + })], +]); + +const Indicators = charging => Stack({ + items: icons(charging), + connections: [[Battery, stack => { + stack.shown = `${Math.floor(Battery.percent / 10) * 10}`; + }]], +}); + +const Indicator = ({ + charging = Indicators(true), + discharging = Indicators(false), + ...params +} = {}) => Stack({ + ...params, + className: 'battery-indicator', + items: [ + ['true', charging], + ['false', discharging], + ], + connections: [[Battery, stack => { + stack.shown = `${Battery.charging || Battery.charged}`; + stack.toggleClassName('charging', Battery.charging); + stack.toggleClassName('charged', Battery.charged); + stack.toggleClassName('low', Battery.percent < 20); + }]], +}); + +const LevelLabel = params => Label({ + ...params, + className: 'label', + connections: [[Battery, label => label.label = `${Battery.percent}%`]], +}); + +export const BatteryIndicator = Box({ + className: 'toggle-off battery', + children: [ + Indicator(), + Separator(5), + LevelLabel(), + ], +}); diff --git a/config/ags/js/bar/brightness.js b/config/ags/js/bar/brightness.js new file mode 100644 index 00000000..fabbeba9 --- /dev/null +++ b/config/ags/js/bar/brightness.js @@ -0,0 +1,35 @@ +const { ProgressBar, Overlay, Box } = ags.Widget; +const { execAsync } = ags.Utils; +import { Separator } from '../misc/separator.js'; +import { Heart } from './heart.js'; + +export const Brightness = Overlay({ + setup: widget => { + widget.set_tooltip_text('Brightness'); + }, + child: ProgressBar({ + className: 'toggle-off brightness', + connections: [ + [200, progress => { + execAsync('brightnessctl get').then(out => { + let br = out / 255; + if (br > 0.33) { + progress.value = br; + } + else { + progress.value = 0.33; + } + }).catch(print); + }], + ], + }), + overlays: [ + Box({ + style: 'color: #CBA6F7;', + children: [ + Separator(25), + Heart, + ], + }), + ], +}); diff --git a/config/ags/js/bar/clock.js b/config/ags/js/bar/clock.js new file mode 100644 index 00000000..b62ea686 --- /dev/null +++ b/config/ags/js/bar/clock.js @@ -0,0 +1,34 @@ +const { Box, Label } = ags.Widget; +const { toggleWindow } = ags.App; +const { DateTime } = imports.gi.GLib; + +import { EventBox } from '../misc/cursorbox.js'; + +const ClockModule = ({ + interval = 1000, + ...params +}) => Label({ + ...params, + className: 'clock', + connections: [ + [interval, label => { + var time = DateTime.new_now_local(); + label.label = time.format('%a. ') + time.get_day_of_month() + time.format(' %b. %H:%M'); + }], + ], +}); + +export const Clock = EventBox({ + className: 'toggle-off', + onPrimaryClickRelease: () => toggleWindow('calendar'), + connections: [ + [ags.App, (box, windowName, visible) => { + if (windowName == 'calendar') { + box.toggleClassName('toggle-on', visible); + } + }], + ], + child: Box({ + child: ClockModule({}), + }), +}); diff --git a/config/ags/js/bar/current-window.js b/config/ags/js/bar/current-window.js new file mode 100644 index 00000000..9e60794e --- /dev/null +++ b/config/ags/js/bar/current-window.js @@ -0,0 +1,13 @@ +const { Hyprland } = ags.Service; +const { Label } = ags.Widget; +const { Gtk } = imports.gi; + +export const CurrentWindow = Label({ + style: 'color: #CBA6F7; font-size: 18px', + truncate: 'end', + connections: [ + [Hyprland, label => { + label.label = Hyprland.active.client.title; + }, 'changed'], + ], +}); diff --git a/config/ags/js/bar/gesture.js b/config/ags/js/bar/gesture.js new file mode 100644 index 00000000..a90815f2 --- /dev/null +++ b/config/ags/js/bar/gesture.js @@ -0,0 +1,32 @@ +const { Window, CenterBox, EventBox, Button } = ags.Widget; +const { openWindow } = ags.App; +const { Gtk, Gdk } = imports.gi; +const display = Gdk.Display.get_default(); + +export const Gesture = ({ + child, + ...params +}) => { + let w = EventBox({ + ...params, + }); + + let gesture = Gtk.GestureSwipe.new(w); + + w.child = CenterBox({ + children: [ + child, + ], + connections: [ + + [gesture, box => { + const velocity = gesture.get_velocity()[1]; + if (velocity < -100) + openWindow('quick-settings'); + }, 'update'], + + ], + }); + + return w; +}; diff --git a/config/ags/js/bar/heart.js b/config/ags/js/bar/heart.js new file mode 100644 index 00000000..27be3f5c --- /dev/null +++ b/config/ags/js/bar/heart.js @@ -0,0 +1,26 @@ +const { Box, Label } = ags.Widget; +const { subprocess, execAsync } = ags.Utils; +const deflisten = subprocess; + +import { EventBox } from '../misc/cursorbox.js'; + +deflisten( + ['bash', '-c', 'tail -f /home/matt/.config/.heart'], + (output) => { + Heart.child.children[0].label = ' ' + output; + }, +); +export const Heart = EventBox({ + halign: 'center', + onPrimaryClickRelease: () => { + execAsync(['bash', '-c', '$AGS_PATH/heart.sh toggle']).catch(print); + }, + child: Box({ + className: 'heart-toggle', + vertical: false, + + child: Label({ + label: '', + }), + }), +}); diff --git a/config/ags/js/bar/main.js b/config/ags/js/bar/main.js new file mode 100644 index 00000000..535694ae --- /dev/null +++ b/config/ags/js/bar/main.js @@ -0,0 +1,79 @@ +const { Window, CenterBox, Box } = ags.Widget; + +import { Separator } from '../misc/separator.js'; +import { CurrentWindow } from './current-window.js'; +import { Workspaces } from './workspaces.js'; +import { OskToggle } from './osk-toggle.js'; +import { TabletToggle } from './tablet-toggle.js'; +import { QsToggle } from './quick-settings.js'; +import { NotifButton } from './notif-button.js'; +import { Clock } from './clock.js'; +import { SysTray } from './systray.js'; +import { BatteryIndicator } from './battery.js'; +import { Brightness } from './brightness.js'; +import { AudioIndicator } from './audio.js'; +import { Gesture } from './gesture.js'; + +export const Bar = Window({ + name: 'bar', + layer: 'overlay', + anchor: 'top left right', + exclusive: true, + + child: Gesture({ + child: CenterBox({ + className: 'transparent', + halign: 'fill', + style: 'margin: 5px', + vertical: false, + + startWidget: Box({ + halign: 'start', + children: [ + + OskToggle, + + Separator(12), + + TabletToggle, + + Separator(12), + + SysTray, + + AudioIndicator, + + Separator(12), + + Brightness, + + Separator(12), + + Workspaces, + + ], + }), + + centerWidget: CurrentWindow, + + endWidget: Box({ + halign: 'end', + children: [ + BatteryIndicator, + + Separator(12), + + Clock, + + Separator(12), + + NotifButton, + + Separator(12), + + QsToggle, + ], + }), + }), + }), +}); diff --git a/config/ags/js/bar/notif-button.js b/config/ags/js/bar/notif-button.js new file mode 100644 index 00000000..4647e540 --- /dev/null +++ b/config/ags/js/bar/notif-button.js @@ -0,0 +1,54 @@ +const { Box, Label, Icon } = ags.Widget; +const { toggleWindow } = ags.App; +const { Notifications } = ags.Service; + +import { Separator } from '../misc/separator.js'; +import { EventBox } from '../misc/cursorbox.js'; + +export const NotifButton = EventBox({ + className: 'toggle-off', + onPrimaryClickRelease: () => toggleWindow('notification-center'), + connections: [ + [ags.App, (box, windowName, visible) => { + if (windowName == 'notification-center') { + box.toggleClassName('toggle-on', visible); + } + }], + ], + child: Box({ + className: 'notif-panel', + vertical: false, + children: [ + Separator(28), + + Icon({ + connections: [ + [Notifications, icon => { + if (Notifications.dnd) { + icon.icon = 'notification-disabled-symbolic' + } + else { + if (Notifications.notifications.length > 0) { + icon.icon = 'notification-new-symbolic' + } + else { + icon.icon = 'notification-symbolic' + } + } + }], + ], + }), + + Separator(8), + + Label({ + connections: [ + [Notifications, label => { + label.label = String(Notifications.notifications.length); + }], + ], + }), + + ], + }), +}); diff --git a/config/ags/js/bar/osk-toggle.js b/config/ags/js/bar/osk-toggle.js new file mode 100644 index 00000000..0cb8b9be --- /dev/null +++ b/config/ags/js/bar/osk-toggle.js @@ -0,0 +1,41 @@ +const { Box, Label } = ags.Widget; +const { subprocess } = ags.Utils; +const deflisten = subprocess; + +import { EventBox } from '../misc/cursorbox.js'; + +deflisten( + ['bash', '-c', '$AGS_PATH/osk-toggle.sh getState'], + (output) => { + if (output == 'Running') { + OskToggle.toggleClassName('toggle-on', true); + } else { + OskToggle.toggleClassName('toggle-on', false); + } + }, +); +export const OskToggle = EventBox({ + className: 'toggle-off', + onPrimaryClickRelease: function() { + subprocess( + ['bash', '-c', '$AGS_PATH/osk-toggle.sh toggle'], + (output) => { + if (output == 'Running') { + OskToggle.toggleClassName('toggle-on', false); + } else { + OskToggle.toggleClassName('toggle-on', true); + } + }, + ); + }, + child: Box({ + className: 'osk-toggle', + vertical: false, + + children: [ + Label({ + label: " ", + }), + ], + }), +}); diff --git a/config/ags/js/bar/quick-settings.js b/config/ags/js/bar/quick-settings.js new file mode 100644 index 00000000..3b0e8b26 --- /dev/null +++ b/config/ags/js/bar/quick-settings.js @@ -0,0 +1,23 @@ +const { Box, Label } = ags.Widget; +const { toggleWindow } = ags.App; + +import { EventBox } from '../misc/cursorbox.js'; + +export const QsToggle = EventBox({ + className: 'toggle-off', + onPrimaryClickRelease: () => toggleWindow('quick-settings'), + connections: [ + [ags.App, (box, windowName, visible) => { + if (windowName == 'quick-settings') { + box.toggleClassName('toggle-on', visible); + } + }], + ], + child: Box({ + className: 'quick-settings-toggle', + vertical: false, + child: Label({ + label: " ", + }), + }), +}); diff --git a/config/ags/js/bar/systray.js b/config/ags/js/bar/systray.js new file mode 100644 index 00000000..62bd94c8 --- /dev/null +++ b/config/ags/js/bar/systray.js @@ -0,0 +1,57 @@ +const { SystemTray } = ags.Service; +const { Box, Revealer, Icon, MenuItem } = ags.Widget; +const { Gtk } = imports.gi; + +import { Separator } from '../misc/separator.js'; + +const SysTrayItem = item => MenuItem({ + className: 'tray-item', + child: Icon({ + size: 24, + }), + submenu: item.menu, + connections: [[item, btn => { + btn.child.icon = item.icon; + btn.tooltipMarkup = item.tooltipMarkup; + }]] +}); + +export const SysTray = Revealer({ + transition: 'slide_right', + connections: [[SystemTray, rev => { + rev.revealChild = rev.child.children[0].get_children().length > 0; + }]], + child: Box({ + children: [ + ags.Widget({ + type: Gtk.MenuBar, + className: 'sys-tray', + properties: [ + ['items', new Map()], + ['onAdded', (box, id) => { + const item = SystemTray.getItem(id); + if (box._items.has(id) || !item) + return; + + const widget = SysTrayItem(item); + box._items.set(id, widget); + box.add(widget); + box.show_all(); + }], + ['onRemoved', (box, id) => { + if (!box._items.has(id)) + return; + + box._items.get(id).destroy(); + box._items.delete(id); + }], + ], + connections: [ + [SystemTray, (box, id) => box._onAdded(box, id), 'added'], + [SystemTray, (box, id) => box._onRemoved(box, id), 'removed'], + ], + }), + Separator(12), + ], + }), +}); diff --git a/config/ags/js/bar/tablet-toggle.js b/config/ags/js/bar/tablet-toggle.js new file mode 100644 index 00000000..e1a09b7c --- /dev/null +++ b/config/ags/js/bar/tablet-toggle.js @@ -0,0 +1,28 @@ +const { Box, Label } = ags.Widget; +const { subprocess } = ags.Utils; + +import { EventBox } from '../misc/cursorbox.js'; + +export const TabletToggle = EventBox({ + className: 'toggle-off', + onPrimaryClickRelease: function() { + subprocess( + ['bash', '-c', '$AGS_PATH/tablet-toggle.sh toggle'], + (output) => { + print(output) + if (output == 'Tablet') { + TabletToggle.toggleClassName('toggle-on', true); + } else { + TabletToggle.toggleClassName('toggle-on', false); + } + }, + ); + }, + child: Box({ + className: 'tablet-toggle', + vertical: false, + child: Label({ + label: " ", + }), + }), +}); diff --git a/config/ags/js/bar/workspaces.js b/config/ags/js/bar/workspaces.js new file mode 100644 index 00000000..b9e9c189 --- /dev/null +++ b/config/ags/js/bar/workspaces.js @@ -0,0 +1,70 @@ +const { Hyprland, Applications } = ags.Service; +const { execAsync } = ags.Utils; +const { Box, Button, Label, Revealer } = ags.Widget; + +import { EventBox } from '../misc/cursorbox.js'; + +const Workspace = ({ i } = {}) => +Revealer({ + transition: "slide_right", + properties: [ + ['id', i], + ], + child: EventBox({ + tooltipText: `${i}`, + onPrimaryClickRelease: () => execAsync(`hyprctl dispatch workspace ${i}`).catch(print), + child: Box({ + className: 'button', + child: Label(`${i}`), + connections: [ + [Hyprland, btn => { + const occupied = Hyprland.getWorkspace(i)?.windows > 0; + btn.toggleClassName('active', Hyprland.active.workspace.id === i); + btn.toggleClassName('occupied', occupied); + btn.toggleClassName('empty', !occupied); + }] + ], + }), + }), +}); + +export const Workspaces = Box({ + className: 'workspaces', + children: [EventBox({ + child: Box({ + properties: [ + ['workspaces'], + + ['refresh', box => { + box.children.forEach(rev => rev.reveal_child = false); + box._workspaces.forEach(ws => { + ws.revealChild = true; + }); + }], + + ['updateWs', box => { + Hyprland.workspaces.forEach(ws => { + let currentWs = box.children.find(ch => ch._id == ws.id); + if (!currentWs && ws.id > 0) { + box.add(Workspace({ i: ws.id})); + } + }); + box.show_all(); + + // Make sure the order is correct + box._workspaces.forEach((workspace, i) => { + workspace.get_parent().reorder_child(workspace, i); + }); + }], + ], + connections: [[Hyprland, box => { + box._workspaces = box.children.filter(ch => { + return Hyprland.workspaces.find(ws => ws.id == ch._id) + }).sort((a, b) => a._id - b._id); + + box._updateWs(box); + box._refresh(box); + }]], + }), + })], +}); diff --git a/config/ags/js/date.js b/config/ags/js/date.js new file mode 100644 index 00000000..263b9b96 --- /dev/null +++ b/config/ags/js/date.js @@ -0,0 +1,88 @@ +const { Box, Label, Window } = ags.Widget; +const { Gtk } = imports.gi; +const { DateTime } = imports.gi.GLib; + +import { PopUp } from './misc/popup.js'; + +const Divider = () => Box({ + className: 'divider', + vertical: true, +}); + +const Time = () => Box({ + className: 'timebox', + vertical: true, + children: [ + + Box({ + className: 'time-container', + halign: 'center', + valign: 'center', + children: [ + + Label({ + className: 'content', + label: 'hour', + connections: [[1000, label => { + label.label = DateTime.new_now_local().format('%H'); + }]], + }), + + Divider(), + + Label({ + className: 'content', + label: 'minute', + connections: [[1000, label => { + label.label = DateTime.new_now_local().format('%M'); + }]], + }), + + ], + }), + + Box({ + className: 'date-container', + halign: 'center', + child: Label({ + style: 'font-size: 20px', + label: 'complete date', + connections: [[1000, label => { + var time = DateTime.new_now_local(); + label.label = time.format("%A, %B ") + time.get_day_of_month() + time.format(", %Y"); + }]], + }), + }), + + ], +}); + +const CalendarWidget = () => Box({ + className: 'cal-box', + child: ags.Widget({ + type: Gtk.Calendar, + showDayNames: true, + showHeading: true, + className: 'cal', + connections: [/* */] + }), +}); + +export const Calendar = Window({ + name: 'calendar', + layer: 'overlay', + popup: true, + anchor: 'top right', + margin: [ 8, 182, 0, 0], + child: PopUp({ + name: 'calendar', + child: Box({ + className: 'date', + vertical: true, + children: [ + Time(), + CalendarWidget(), + ], + }), + }), +}); diff --git a/config/ags/js/media-player/gesture.js b/config/ags/js/media-player/gesture.js new file mode 100644 index 00000000..b2798e2b --- /dev/null +++ b/config/ags/js/media-player/gesture.js @@ -0,0 +1,82 @@ +const { Box, Overlay, EventBox } = ags.Widget; +const { Gtk } = imports.gi; + +const MAX_OFFSET = 200; +const OFFSCREEN = 500; +const TRANSITION = 'transition: margin 0.5s ease, opacity 3s ease;'; + +export default ({ properties, connections, params } = {}) => { + let widget = EventBox(); + + let gesture = Gtk.GestureDrag.new(widget) + + widget.child = Overlay({ + ...params, + properties: [ + ...properties, + ['dragging', false], + ], + child: Box({className: 'player'}), + connections: [ + ...connections, + + [gesture, overlay => { + if (overlay.overlays.length <= 1) + return; + + overlay._dragging = true; + const offset = gesture.get_offset()[1]; + + let playerBox = overlay.get_children().at(-1); + if (offset >= 0) { + playerBox.setStyle(`margin-left: ${offset}px; + margin-right: -${offset}px; + ${playerBox._bgStyle}`); + } + else { + let newOffset = Math.abs(offset); + playerBox.setStyle(`margin-left: -${newOffset}px; + margin-right: ${newOffset}px; + ${playerBox._bgStyle}`); + } + overlay._selected = playerBox; + }, 'drag-update'], + + [gesture, overlay => { + if (overlay.overlays.length <= 1) + return; + + overlay._dragging = false; + const offset = gesture.get_offset()[1]; + + let playerBox = overlay.get_children().at(-1); + + if (Math.abs(offset) > MAX_OFFSET) { + if (offset >= 0) { + playerBox.setStyle(`${TRANSITION} + margin-left: ${OFFSCREEN}px; + margin-right: -${OFFSCREEN}px; + opacity: 0; + ${playerBox._bgStyle}`); + } + else { + playerBox.setStyle(`${TRANSITION} + margin-left: -${OFFSCREEN}px; + margin-right: ${OFFSCREEN}px; + opacity: 0; + ${playerBox._bgStyle}`); + } + setTimeout(() => { + overlay.reorder_overlay(playerBox, 0); + playerBox.setStyle(playerBox._bgStyle); + overlay._selected = overlay.get_children().at(-1); + }, 500); + } + else + playerBox.setStyle(`${TRANSITION} ${playerBox._bgStyle}`); + + }, 'drag-end'], + ], + }); + return widget; +}; diff --git a/config/ags/js/media-player/mpris.js b/config/ags/js/media-player/mpris.js new file mode 100644 index 00000000..a5f11da6 --- /dev/null +++ b/config/ags/js/media-player/mpris.js @@ -0,0 +1,345 @@ +const { execAsync, lookUpIcon } = ags.Utils; +const { Mpris } = ags.Service; +const { Button, Icon, Label, Stack, Slider, CenterBox, Box } = ags.Widget; +const { Gdk } = imports.gi; +const display = Gdk.Display.get_default(); + +import { EventBox } from '../misc/cursorbox.js'; +import { Separator } from '../misc/separator.js'; + +const icons = { + mpris: { + fallback: 'audio-x-generic-symbolic', + shuffle: { + enabled: '', + disabled: '', + }, + loop: { + none: '', + track: '', + playlist: '', + }, + playing: ' ', + paused: ' ', + stopped: ' ', + prev: '', + next: '', + }, +} + +export const CoverArt = (player, params) => CenterBox({ + ...params, + vertical: true, + properties: [['bgStyle', '']], + connections: [ + [player, box => { + execAsync(['bash', '-c', `[[ -f "${player.coverPath}" ]] && coloryou "${player.coverPath}"`]) + .then(out => { + if (!Mpris.players.find(p => player === p)) + return; + + player.colors.value = JSON.parse(out); + + box._bgStyle = `background: radial-gradient(circle, + rgba(0, 0, 0, 0.4) 30%, + ${player.colors.value.imageAccent}), + url("${player.coverPath}"); + background-size: cover; + background-position: center;`; + if (!box.get_parent()._dragging) + box.setStyle(box._bgStyle); + }).catch(err => { if (err !== "") print(err) }); + }], + ], +}); + +export const TitleLabel = (player, params) => Label({ + ...params, + xalign: 0, + maxWidthChars: 40, + truncate: 'end', + justification: 'left', + className: 'title', + binds: [['label', player, 'trackTitle']], +}); + +export const ArtistLabel = (player, params) => Label({ + ...params, + xalign: 0, + maxWidthChars: 40, + truncate: 'end', + justification: 'left', + className: 'artist', + connections: [[player, label => { + label.label = player.trackArtists.join(', ') || ''; + }]], +}); + +export const PlayerIcon = (player, { symbolic = true, ...params } = {}) => { + let MainIcon = Icon({ + ...params, + className: 'player-icon', + size: 32, + tooltipText: player.identity || '', + connections: [ + [player, icon => { + const name = `${player.entry}${symbolic ? '-symbolic' : ''}`; + lookUpIcon(name) ? icon.icon = name + : icon.icon = icons.mpris.fallback; + }], + ], + }); + + return Box({ + connections: [ + [Mpris, box => { + let overlays = box.get_parent().get_parent().get_parent().overlays; + let player = overlays.find(overlay => overlay === box.get_parent().get_parent()); + let index = overlays.indexOf(player) + + let children = []; + for (let i = 0; i < overlays.length; ++i) { + if (i === index) { + children.push(MainIcon); + children.push(Separator(2)); + } + else { + children.push(Box({ className: 'position-indicator' })); + children.push(Separator(2)); + } + } + box.children = children; + }], + ], + }); +} + +export const PositionSlider = (player, params) => EventBox({ + child: Slider({ + ...params, + className: 'position-slider', + hexpand: true, + drawValue: false, + onChange: ({ value }) => { + player.position = player.length * value; + }, + properties: [ + ['update', slider => { + if (slider.dragging) { + slider.get_parent().window.set_cursor(Gdk.Cursor.new_from_name(display, 'grabbing')); + } + else { + if (slider.get_parent() && slider.get_parent().window) { + slider.get_parent().window.set_cursor(Gdk.Cursor.new_from_name(display, 'pointer')); + } + + slider.sensitive = player.length > 0; + if (player.length > 0) { + slider.value = player.position / player.length; + } + } + }], + ], + connections: [ + [player, s => s._update(s), 'position'], + [1000, s => s._update(s)], + [player.colors, s => { + if (player.colors.value) + s.setCss(`highlight { background-color: ${player.colors.value.buttonAccent}; } + slider { background-color: ${player.colors.value.buttonAccent}; } + slider:hover { background-color: ${player.colors.value.hoverAccent}; } + trough { background-color: ${player.colors.value.buttonText}; }`); + }], + ], + }), +}); + +function lengthStr(length) { + const min = Math.floor(length / 60); + const sec0 = Math.floor(length % 60) < 10 ? '0' : ''; + const sec = Math.floor(length % 60); + return `${min}:${sec0}${sec}`; +} + +export const PositionLabel = player => Label({ + properties: [['update', label => { + player.length > 0 ? label.label = lengthStr(player.position) + : label.visible = !!player; + }]], + connections: [ + [player, l => l._update(l), 'position'], + [1000, l => l._update(l)], + ], +}); + +export const LengthLabel = player => Label({ + connections: [[player, label => { + player.length > 0 ? label.label = lengthStr(player.length) + : label.visible = !!player; + }]], +}); + +export const Slash = player => Label({ + label: '/', + connections: [[player, label => { + label.visible = player.length > 0; + }]], +}); + +// TODO: use label instead of stack to fix UI issues +const PlayerButton = ({ player, items, onClick, prop }) => Button({ + child: Stack({ items }), + onPrimaryClickRelease: () => player[onClick](), + properties: [['hovered', false]], + onHover: box => { + box._hovered = true; + if (! box.child.sensitive || ! box.sensitive) { + box.window.set_cursor(Gdk.Cursor.new_from_name(display, 'not-allowed')); + } + else { + box.window.set_cursor(Gdk.Cursor.new_from_name(display, 'pointer')); + } + + if (prop == 'playBackStatus') { + items.forEach(item => { + item[1].setStyle(`background-color: ${player.colors.value.hoverAccent}; + color: ${player.colors.value.buttonText}; + min-height: 40px; min-width: 36px; + margin-bottom: 1px; margin-right: 1px;`); + }); + } + }, + onHoverLost: box => { + box._hovered = false; + box.window.set_cursor(null); + if (prop == 'playBackStatus') { + items.forEach(item => { + item[1].setStyle(`background-color: ${player.colors.value.buttonAccent}; + color: ${player.colors.value.buttonText}; + min-height: 42px; min-width: 38px;`); + }); + } + }, + connections: [ + [player, button => { + button.child.shown = `${player[prop]}`; + }], + + [player.colors, button => { + if (!Mpris.players.find(p => player === p)) + return; + + if (player.colors.value) { + if (prop == 'playBackStatus') { + if (button._hovered) { + items.forEach(item => { + item[1].setStyle(`background-color: ${player.colors.value.hoverAccent}; + color: ${player.colors.value.buttonText}; + min-height: 40px; min-width: 36px; + margin-bottom: 1px; margin-right: 1px;`); + }); + } + else { + items.forEach(item => { + item[1].setStyle(`background-color: ${player.colors.value.buttonAccent}; + color: ${player.colors.value.buttonText}; + min-height: 42px; min-width: 38px;`); + }); + } + } + else { + button.setCss(`* { color: ${player.colors.value.buttonAccent}; } + *:hover { color: ${player.colors.value.hoverAccent}; }`); + } + } + }], + ], +}); + +export const ShuffleButton = player => PlayerButton({ + player, + items: [ + ['true', Label({ + className: 'shuffle enabled', + label: icons.mpris.shuffle.enabled, + })], + ['false', Label({ + className: 'shuffle disabled', + label: icons.mpris.shuffle.disabled, + })], + ], + onClick: 'shuffle', + prop: 'shuffleStatus', +}); + +export const LoopButton = player => PlayerButton({ + player, + items: [ + ['None', Label({ + className: 'loop none', + label: icons.mpris.loop.none, + })], + ['Track', Label({ + className: 'loop track', + label: icons.mpris.loop.track, + })], + ['Playlist', Label({ + className: 'loop playlist', + label: icons.mpris.loop.playlist, + })], + ], + onClick: 'loop', + prop: 'loopStatus', +}); + +export const PlayPauseButton = player => PlayerButton({ + player, + items: [ + ['Playing', Label({ + className: 'pausebutton playing', + label: icons.mpris.playing, + })], + ['Paused', Label({ + className: 'pausebutton paused', + label: icons.mpris.paused, + })], + ['Stopped', Label({ + className: 'pausebutton stopped paused', + label: icons.mpris.stopped, + })], + ], + onClick: 'playPause', + prop: 'playBackStatus', +}); + +export const PreviousButton = player => PlayerButton({ + player, + items: [ + ['true', Label({ + className: 'previous', + label: icons.mpris.prev, + })], + ['false', Label({ + className: 'previous', + label: icons.mpris.prev, + })], + ], + onClick: 'previous', + prop: 'canGoPrev', +}); + +export const NextButton = player => PlayerButton({ + player, + items: [ + ['true', Label({ + className: 'next', + label: icons.mpris.next, + })], + ['false', Label({ + className: 'next', + label: icons.mpris.next, + })], + ], + onClick: 'next', + prop: 'canGoNext', +}); diff --git a/config/ags/js/media-player/player.js b/config/ags/js/media-player/player.js new file mode 100644 index 00000000..9d4987c7 --- /dev/null +++ b/config/ags/js/media-player/player.js @@ -0,0 +1,139 @@ +const { Mpris } = ags.Service; +const { Box, CenterBox, Label } = ags.Widget; + +import * as mpris from './mpris.js'; +import PlayerGesture from './gesture.js'; +import { Separator } from '../misc/separator.js'; + +const Top = player => Box({ + className: 'top', + halign: 'start', + valign: 'start', + children: [ + mpris.PlayerIcon(player, { + symbolic: false, + }), + ], +}); + +const Center = player => Box({ + className: 'center', + children: [ + + CenterBox({ + vertical: true, + children: [ + + Box({ + className: 'metadata', + vertical: true, + halign: 'start', + valign: 'center', + hexpand: true, + children: [ + mpris.TitleLabel(player), + mpris.ArtistLabel(player), + ], + }), + + Label(), + Label(), + ], + }), + + CenterBox({ + vertical: true, + children: [ + Label(), + mpris.PlayPauseButton(player), + Label(), + ], + }), + + ], +}); + +const Bottom = player => Box({ + className: 'bottom', + children: [ + + mpris.PreviousButton(player, { + valign: 'end', + halign: 'start', + }), + Separator(8), + mpris.PositionSlider(player), + Separator(8), + mpris.NextButton(player), + Separator(8), + mpris.ShuffleButton(player), + Separator(8), + mpris.LoopButton(player), + + ], +}); + +const PlayerBox = player => mpris.CoverArt(player, { + className: `player ${player.name}`, + hexpand: true, + children: [ + Top(player), + Center(player), + Bottom(player), + ], +}); + +export default () => Box({ + className: 'media', + child: PlayerGesture({ + properties: [ + ['players', new Map()], + ['setup', false], + ['selected'], + ], + connections: [ + [Mpris, (overlay, busName) => { + if (!busName || overlay._players.has(busName)) + return; + + const player = Mpris.getPlayer(busName); + player.colors = ags.Variable(); + overlay._players.set(busName, PlayerBox(player)); + + let result = []; + overlay._players.forEach(widget => { + result.push(widget); + }); + + overlay.overlays = result; + + // Favor spotify + if (!overlay._setup) { + if (overlay._players.has('org.mpris.MediaPlayer2.spotify')) { + overlay._selected = overlay._players.get('org.mpris.MediaPlayer2.spotify'); + } + overlay._setup = true; + } + + if (overlay._selected) + overlay.reorder_overlay(overlay._selected, -1); + }, 'player-added'], + + [Mpris, (overlay, busName) => { + if (!busName || !overlay._players.has(busName)) + return; + + overlay._players.delete(busName); + + let result = []; + overlay._players.forEach(widget => { + result.push(widget); + }); + + overlay.overlays = result; + if (overlay._selected) + overlay.reorder_overlay(overlay._selected, -1); + }, 'player-closed'], + ], + }), +}); diff --git a/config/ags/js/misc/closer.js b/config/ags/js/misc/closer.js new file mode 100644 index 00000000..eeb186b0 --- /dev/null +++ b/config/ags/js/misc/closer.js @@ -0,0 +1,34 @@ +const { Window, EventBox } = ags.Widget; +const { closeWindow } = ags.App; + +const ALWAYS_OPEN = [ + 'closer', + 'bar', + 'notifications', +]; + +// TODO: close on scroll event too? +export const closeAll = () => { + ags.App.windows.forEach(w => { + if (!ALWAYS_OPEN.some(window => window === w.name)) + ags.App.closeWindow(w.name) + }); + closeWindow('closer'); +}; + +export const Closer = Window({ + name: 'closer', + popup: true, + layer: 'top', + anchor: 'top bottom left right', + + child: EventBox({ + onPrimaryClickRelease: () => closeAll(), + connections: [[ags.App, (_b, _w, _v) => { + if (!Array.from(ags.App.windows).some(w => w[1].visible && + !ALWAYS_OPEN.some(window => window === w[0]))) { + closeWindow('closer'); + } + }]], + }), +}); diff --git a/config/ags/js/misc/cursorbox.js b/config/ags/js/misc/cursorbox.js new file mode 100644 index 00000000..32090653 --- /dev/null +++ b/config/ags/js/misc/cursorbox.js @@ -0,0 +1,34 @@ +import Gdk from 'gi://Gdk'; +const display = Gdk.Display.get_default(); + +export const EventBox = ({ reset = true, ...params }) => ags.Widget.EventBox({ + ...params, + onHover: box => { + if (! box.child.sensitive || ! box.sensitive) { + box.window.set_cursor(Gdk.Cursor.new_from_name(display, 'not-allowed')); + } + else { + box.window.set_cursor(Gdk.Cursor.new_from_name(display, 'pointer')); + } + }, + onHoverLost: box => { + if (reset) + box.window.set_cursor(null); + }, +}); + +export const Button = ({ reset = true, ...params }) => ags.Widget.Button({ + ...params, + onHover: box => { + if (! box.child.sensitive || ! box.sensitive) { + box.window.set_cursor(Gdk.Cursor.new_from_name(display, 'not-allowed')); + } + else { + box.window.set_cursor(Gdk.Cursor.new_from_name(display, 'pointer')); + } + }, + onHoverLost: box => { + if (reset) + box.window.set_cursor(null); + }, +}); diff --git a/config/ags/js/misc/drag.js b/config/ags/js/misc/drag.js new file mode 100644 index 00000000..c8b2b2c4 --- /dev/null +++ b/config/ags/js/misc/drag.js @@ -0,0 +1,138 @@ +const { Box, EventBox } = ags.Widget; +const { Gtk, Gdk } = imports.gi; +const display = Gdk.Display.get_default(); + +export const Draggable = ({ + maxOffset = 150, + startMargin = 0, + endMargin = 300, + command = () => {}, + onHover = w => {}, + onHoverLost = w => {}, + child = '', + children = [], + properties = [[]], + ...params +}) => { + let w = EventBox({ + ...params, + properties: [ + ['dragging', false], + ...properties, + ], + onHover: box => { + box.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab')); + onHover(box); + }, + onHoverLost: box => { + box.window.set_cursor(null); + onHoverLost(box); + }, + }); + + let gesture = Gtk.GestureDrag.new(w); + + let leftAnim1 = `transition: margin 0.5s ease, opacity 0.5s ease; + margin-left: -${Number(maxOffset + endMargin)}px; + margin-right: ${Number(maxOffset + endMargin)}px; + opacity: 0;`; + + let leftAnim2 = `transition: margin 0.5s ease, opacity 0.5s ease; + margin-left: -${Number(maxOffset + endMargin)}px; + margin-right: ${Number(maxOffset + endMargin)}px; + margin-bottom: -70px; margin-top: -70px; opacity: 0;`; + + let rightAnim1 = `transition: margin 0.5s ease, opacity 0.5s ease; + margin-left: ${Number(maxOffset + endMargin)}px; + margin-right: -${Number(maxOffset + endMargin)}px; + opacity: 0;`; + + let rightAnim2 = `transition: margin 0.5s ease, opacity 0.5s ease; + margin-left: ${Number(maxOffset + endMargin)}px; + margin-right: -${Number(maxOffset + endMargin)}px; + margin-bottom: -70px; margin-top: -70px; opacity: 0;`; + + w.child = Box({ + properties: [ + ['leftAnim1', leftAnim1], + ['leftAnim2', leftAnim2], + ['rightAnim1', rightAnim1], + ['rightAnim2', rightAnim2], + ['ready', false] + ], + children: [ + ...children, + child, + ], + style: leftAnim2, + connections: [ + + [gesture, box => { + var offset = gesture.get_offset()[1]; + + if (offset >= 0) { + box.setStyle('margin-left: ' + Number(offset + startMargin) + 'px; ' + + 'margin-right: -' + Number(offset + startMargin) + 'px;'); + } + else { + offset = Math.abs(offset); + box.setStyle('margin-right: ' + Number(offset + startMargin) + 'px; ' + + 'margin-left: -' + Number(offset + startMargin) + 'px;'); + } + + box.get_parent()._dragging = Math.abs(offset) > 10; + + if (w.window) + w.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grabbing')); + }, 'drag-update'], + + [gesture, box => { + if (!box._ready) { + box.setStyle(`transition: margin 0.5s ease, opacity 0.5s ease; + margin-left: -${Number(maxOffset + endMargin)}px; + margin-right: ${Number(maxOffset + endMargin)}px; + margin-bottom: 0px; margin-top: 0px; opacity: 0;`); + + setTimeout(() => { + box.setStyle('transition: margin 0.5s ease, opacity 0.5s ease; ' + + 'margin-left: ' + startMargin + 'px; ' + + 'margin-right: ' + startMargin + 'px; ' + + 'margin-bottom: unset; margin-top: unset; opacity: 1;'); + }, 500); + setTimeout(() => box._ready = true, 1000); + return; + } + + const offset = gesture.get_offset()[1]; + + if (Math.abs(offset) > maxOffset) { + if (offset > 0) { + box.setStyle(rightAnim1); + setTimeout(() => box.setStyle(rightAnim2), 500); + } + else { + box.setStyle(leftAnim1); + setTimeout(() => box.setStyle(leftAnim2), 500); + } + setTimeout(() => { + command(); + box.destroy(); + }, 1000); + } + else { + box.setStyle('transition: margin 0.5s ease, opacity 0.5s ease; ' + + 'margin-left: ' + startMargin + 'px; ' + + 'margin-right: ' + startMargin + 'px; ' + + 'margin-bottom: unset; margin-top: unset; opacity: 1;'); + if (w.window) + w.window.set_cursor(Gdk.Cursor.new_from_name(display, 'grab')); + + box.get_parent()._dragging = false; + } + }, 'drag-end'], + + ], + }); + + return w; +}; diff --git a/config/ags/js/misc/popup.js b/config/ags/js/misc/popup.js new file mode 100644 index 00000000..60a19d39 --- /dev/null +++ b/config/ags/js/misc/popup.js @@ -0,0 +1,20 @@ +const { Revealer, Box } = ags.Widget; +const { openWindow } = ags.App; + +export const PopUp = ({name, child, transition = 'slide_down', ...params}) => Box({ + style: 'min-height:1px; min-width:1px', + child: Revealer({ + ...params, + transition, + transitionDuration: 500, + connections: [[ags.App, (revealer, currentName, visible) => { + if (currentName === name) { + revealer.reveal_child = visible; + + if (visible && name !== 'overview') + openWindow('closer'); + } + }]], + child: child, + }), +}); diff --git a/config/ags/js/misc/separator.js b/config/ags/js/misc/separator.js new file mode 100644 index 00000000..8ade2134 --- /dev/null +++ b/config/ags/js/misc/separator.js @@ -0,0 +1,3 @@ +export const Separator = width => ags.Widget.Box({ + style: `min-width: ${width}px;`, +}); diff --git a/config/ags/js/notifications/base.js b/config/ags/js/notifications/base.js new file mode 100644 index 00000000..36f3feed --- /dev/null +++ b/config/ags/js/notifications/base.js @@ -0,0 +1,184 @@ +const { GLib } = imports.gi; +const { Notifications, Applications } = ags.Service; +const { lookUpIcon, exec, execAsync } = ags.Utils; +const { Box, Icon, Label, Button } = ags.Widget; + +import { Draggable } from '../misc/drag.js'; +import { EventBox } from '../misc/cursorbox.js' +import { closeAll } from '../misc/closer.js'; + +const NotificationIcon = ({ appEntry, appIcon, image }) => { + let iconCmd = () => {}; + + if (Applications.query(appEntry).length > 0) { + let app = Applications.query(appEntry)[0]; + + if (app.app.get_string('StartupWMClass') != null) { + iconCmd = box => { + if (!box.get_parent().get_parent().get_parent().get_parent().get_parent()._dragging) { + execAsync(['bash', '-c', `$AGS_PATH/launch-app.sh ${app.app.get_string('StartupWMClass')} ${app.app.get_string('Exec')}`]).catch(print); + closeAll(); + } + } + } + else if (app.app.get_filename().includes('discord')) { + iconCmd = box => { + if (!box.get_parent().get_parent().get_parent().get_parent().get_parent()._dragging) { + execAsync(['bash', '-c', `$AGS_PATH/launch-app.sh discord ${app.app.get_string('Exec')}`]) + .catch(print); + closeAll(); + } + } + } + } + + if (image) { + return EventBox({ + onPrimaryClickRelease: iconCmd, + child: Box({ + valign: 'start', + hexpand: false, + className: 'icon img', + style: ` + background-image: url("${image}"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + min-width: 78px; + min-height: 78px; + `, + }), + }); + } + + let icon = 'dialog-information-symbolic'; + if (lookUpIcon(appIcon)) { + icon = appIcon; + } + + if (lookUpIcon(appEntry)) { + icon = appEntry; + } + + return EventBox({ + onPrimaryClickRelease: iconCmd, + child: Box({ + valign: 'start', + hexpand: false, + className: 'icon', + style: ` + min-width: 78px; + min-height: 78px; + `, + children: [Icon({ + icon, size: 58, + halign: 'center', + hexpand: true, + valign: 'center', + vexpand: true, + })], + }), + }); +}; + +export default ({ id, summary, body, actions, urgency, time, command = i => {}, ...icon }) => { + const BlockedApps = [ + 'Spotify', + ]; + + if (BlockedApps.find(app => app == Notifications.getNotification(id).appName)) { + Notifications.close(id); + return; + } + + return Draggable({ + maxOffset: 200, + command: () => command(id), + properties: [ + ['hovered', false], + ['id', id], + ], + onHover: w => { + if (!w._hovered) { + w._hovered = true; + } + }, + onHoverLost: w => { + if (w._hovered) { + w._hovered = false; + } + }, + + child: Box({ + className: `notification ${urgency}`, + vexpand: false, + // Notification + child: Box({ + vertical: true, + children: [ + // Content + Box({ + children: [ + NotificationIcon(icon), + Box({ + hexpand: true, + vertical: true, + children: [ + // Top of Content + Box({ + children: [ + Label({ + className: 'title', + xalign: 0, + justification: 'left', + hexpand: true, + maxWidthChars: 24, + truncate: 'end', + wrap: true, + label: summary, + useMarkup: summary.startsWith('<'), + }), + Label({ + className: 'time', + valign: 'start', + label: GLib.DateTime.new_from_unix_local(time).format('%H:%M'), + }), + EventBox({ + reset: false, + child: Button({ + className: 'close-button', + valign: 'start', + onClicked: () => Notifications.close(id), + child: Icon('window-close-symbolic'), + }), + }), + ], + }), + Label({ + className: 'description', + hexpand: true, + useMarkup: true, + xalign: 0, + justification: 'left', + label: body, + wrap: true, + }), + ], + }), + ], + }), + // Actions + Box({ + className: 'actions', + children: actions.map(action => Button({ + className: 'action-button', + onClicked: () => Notifications.invoke(id, action.id), + hexpand: true, + child: Label(action.label), + })), + }), + ], + }), + }), + }); +}; diff --git a/config/ags/js/notifications/center.js b/config/ags/js/notifications/center.js new file mode 100644 index 00000000..3ee07080 --- /dev/null +++ b/config/ags/js/notifications/center.js @@ -0,0 +1,145 @@ +const { Notifications } = ags.Service; +const { Button, Label, Box, Icon, Scrollable, Window, Revealer } = ags.Widget; +const { timeout } = ags.Utils; +const { getWindow } = ags.App; + +import Notification from './base.js'; +import { EventBox } from '../misc/cursorbox.js'; +import { PopUp } from '../misc/popup.js'; + +const ClearButton = () => EventBox({ + child: Button({ + onPrimaryClickRelease: button => { + button._popups.children.forEach(ch => ch.child.setStyle(ch.child._leftAnim1)); + button._notifList.children.forEach(ch => { + ch.child.setStyle(ch.child._rightAnim1); + timeout(500, () => { + button._notifList.remove(ch); + Notifications.close(ch._id); + }); + }); + }, + properties: [['notifList'], ['popups']], + connections: [[Notifications, button => { + if (!button._notifList) + button._notifList = NotificationList; + + if (!button._popups) + button._popups = getWindow('notifications').child.children[0].child; + + button.sensitive = Notifications.notifications.length > 0; + }]], + child: Box({ + children: [ + Label('Clear '), + Icon({ + connections: [[Notifications, icon => { + icon.icon = Notifications.notifications.length > 0 + ? 'user-trash-full-symbolic' : 'user-trash-symbolic'; + }]], + }), + ], + }), + }), +}); + +const Header = () => Box({ + className: 'header', + children: [ + Label({ label: 'Notifications', hexpand: true, xalign: 0 }), + ClearButton(), + ], +}); + +const NotificationList = Box({ + vertical: true, + vexpand: true, + connections: [ + [Notifications, (box, id) => { + if (box.children.length == 0) { + box.children = Notifications.notifications + .reverse() + .map(n => Notification({ ...n, command: i => Notifications.close(i), })); + } + else if (id) { + const NewNotif = Notification({ + ...Notifications.getNotification(id), + command: i => Notifications.close(i), + }); + + if (NewNotif) { + box.add(NewNotif); + box.show_all(); + } + } + + }, 'notified'], + + [Notifications, (box, id) => { + for (const ch of box.children) { + if (ch._id == id) { + ch.child.setStyle(ch.child._rightAnim1); + timeout(500, () => box.remove(ch)); + return; + } + } + }, 'closed'], + + [Notifications, box => box.visible = Notifications.notifications.length > 0], + ], +}); + +const Placeholder = () => Revealer({ + transition: 'crossfade', + connections: [[Notifications, box => { + box.revealChild = Notifications.notifications.length === 0; + }]], + child: Box({ + className: 'placeholder', + vertical: true, + valign: 'center', + halign: 'center', + vexpand: true, + hexpand: true, + children: [ + Icon('notification-disabled-symbolic'), + Label('Your inbox is empty'), + ], + }), +}); + +const NotificationCenterWidget = Box({ + className: 'notification-center', + vertical: true, + children: [ + Header(), + Box({ + className: 'notification-wallpaper-box', + children: [Scrollable({ + className: 'notification-list-box', + hscroll: 'never', + vscroll: 'automatic', + child: Box({ + className: 'notification-list', + vertical: true, + children: [ + NotificationList, + Placeholder(), + ], + }), + })], + }), + ], +}); + +export const NotificationCenter = Window({ + name: 'notification-center', + layer: 'overlay', + anchor: 'top right', + popup: true, + margin: [ 8, 60, 0, 0 ], + child: PopUp({ + name: 'notification-center', + child: NotificationCenterWidget, + }), +}); diff --git a/config/ags/js/notifications/popup.js b/config/ags/js/notifications/popup.js new file mode 100644 index 00000000..2b26d726 --- /dev/null +++ b/config/ags/js/notifications/popup.js @@ -0,0 +1,82 @@ +import Notification from './base.js'; +const { Notifications } = ags.Service; +const { Box, Revealer, Window } = ags.Widget; +const { timeout, interval } = ags.Utils; +const { source_remove } = imports.gi.GLib; + +const Popups = () => Box({ + vertical: true, + properties: [ + ['map', new Map()], + ['dismiss', (box, id, force = false) => { + if (!id || !box._map.has(id)) + return; + + if (box._map.get(id)._hovered && !force) + return; + + if (box._map.size - 1 === 0) + box.get_parent().reveal_child = false; + + timeout(200, () => { + if (box._map.get(id)?.interval) { + source_remove(box._map.get(id).interval); + box._map.get(id).interval = undefined; + } + box._map.get(id)?.destroy(); + box._map.delete(id); + }); + }], + ['notify', (box, id) => { + if (!id || Notifications.dnd) + return; + + if (! Notifications.getNotification(id)) + return; + + box._map.delete(id); + + box._map.set(id, Notification({ + ...Notifications.getNotification(id), + command: i => Notifications.dismiss(i), + })); + + box.children = Array.from(box._map.values()).reverse(); + timeout(10, () => { + box.get_parent().revealChild = true; + }); + box._map.get(id).interval = interval(4500, () => { + if (!box._map.get(id)._hovered) { + box._map.get(id).child.setStyle(box._map.get(id).child._leftAnim1); + + if (box._map.get(id).interval) { + source_remove(box._map.get(id).interval); + box._map.get(id).interval = undefined; + } + } + }); + }], + ], + connections: [ + [Notifications, (box, id) => box._notify(box, id), 'notified'], + [Notifications, (box, id) => box._dismiss(box, id), 'dismissed'], + [Notifications, (box, id) => box._dismiss(box, id, true), 'closed'], + ], +}); + +const PopupList = ({ transition = 'none' } = {}) => Box({ + className: 'notifications-popup-list', + style: 'padding: 1px', + children: [ + Revealer({ + transition, + child: Popups(), + }), + ], +}); + +export const NotificationsPopupList = Window({ + name: `notifications`, + anchor: 'top left', + child: PopupList(), +}); diff --git a/config/ags/js/overview/clients.js b/config/ags/js/overview/clients.js new file mode 100644 index 00000000..8cd3da5c --- /dev/null +++ b/config/ags/js/overview/clients.js @@ -0,0 +1,124 @@ +const { Icon, Revealer } = ags.Widget; +const { closeWindow } = ags.App; +const { execAsync } = ags.Utils; +const { Hyprland } = ags.Service; + +import { WindowButton } from './dragndrop.js'; +import * as VARS from './variables.js'; + +Array.prototype.remove = function (el) { this.splice(this.indexOf(el), 1) }; +const IconStyle = app => `min-width: ${app.size[0] * VARS.SCALE - VARS.MARGIN}px; + min-height: ${app.size[1] * VARS.SCALE - VARS.MARGIN}px; + font-size: ${Math.min(app.size[0] * VARS.SCALE - VARS.MARGIN, + app.size[1] * VARS.SCALE - VARS.MARGIN) * VARS.ICON_SCALE}px;`; + +const Client = (client, active, clients) => Revealer({ + transition: 'crossfade', + setup: rev => { + rev.revealChild = true; + }, + properties: [ + ['address', client.address], + ['toDestroy', false] + ], + child: WindowButton({ + address: client.address, + onSecondaryClickRelease: () => { + execAsync(`hyprctl dispatch closewindow address:${client.address}`) + .catch(print) + }, + onPrimaryClickRelease: () => { + if (client.workspace.id < 0) { + if (client.workspace.name === 'special') { + execAsync(`hyprctl dispatch movetoworkspacesilent special:${client.workspace.id},address:${client.address}`) + .then(execAsync(`hyprctl dispatch togglespecialworkspace ${client.workspace.id}`) + .then(() => closeWindow('overview')) + .catch(print)) + .catch(print); + } + else { + execAsync(`hyprctl dispatch togglespecialworkspace ${String(client.workspace.name) + .replace('special:', '')}`) + .then(() => closeWindow('overview')) + .catch(print); + } + } + else { + // close special workspace if one is opened + let activeAddress = Hyprland.active.client.address; + let currentActive = clients.find(c => c.address === activeAddress) + + if (currentActive && currentActive.workspace.id < 0) + execAsync(`hyprctl dispatch togglespecialworkspace ${String(currentActive.workspace.name) + .replace('special:', '')}`).catch(print); + execAsync(`hyprctl dispatch focuswindow address:${client.address}`) + .then(() => closeWindow('overview')) + .catch(print); + } + }, + child: Icon({ + className: `window ${active}`, + style: IconStyle(client) + 'font-size: 10px;', + icon: client.class, + }), + }), +}); + +export function updateClients(box) { + ags.Utils.execAsync('hyprctl clients -j') + .then(result => { + let clients = JSON.parse(result).filter(client => client.class) + + box._workspaces.forEach(workspace => { + let fixed = workspace.child.child.overlays[0].children[0]; + let toRemove = fixed.get_children(); + + clients.filter(client => client.workspace.id == workspace._id).forEach(client => { + let active = ''; + if (client.address == Hyprland.active.client.address) { + active = 'active'; + } + + // Special workspaces that haven't been opened yet + // return a size of 0. We need to set them to default + // values to show the workspace properly + if (client.size[0] === 0) { + client.size[0] = VARS.DEFAULT_SPECIAL.SIZE_X; + client.size[1] = VARS.DEFAULT_SPECIAL.SIZE_Y; + client.at[0] = VARS.DEFAULT_SPECIAL.POS_X; + client.at[1] = VARS.DEFAULT_SPECIAL.POS_Y; + } + + let existingClient = fixed.get_children().find(ch => ch._address == client.address); + toRemove.remove(existingClient); + + if (existingClient) { + fixed.move( + existingClient, + client.at[0] * VARS.SCALE, + client.at[1] * VARS.SCALE, + ); + existingClient.child.child.className = `window ${active}`; + existingClient.child.child.style = IconStyle(client); + } + else { + fixed.put( + Client(client, active, clients), + client.at[0] * VARS.SCALE, + client.at[1] * VARS.SCALE, + ); + } + }); + fixed.show_all(); + toRemove.forEach(ch => { + if (ch._toDestroy) { + ch.destroy(); + } + else { + ch.revealChild = false; + ch._toDestroy = true; + } + }); + }); + }).catch(print); +}; diff --git a/config/ags/js/overview/dragndrop.js b/config/ags/js/overview/dragndrop.js new file mode 100644 index 00000000..5def28b4 --- /dev/null +++ b/config/ags/js/overview/dragndrop.js @@ -0,0 +1,69 @@ +const { Gtk, Gdk } = imports.gi; +const { EventBox } = ags.Widget; +const { execAsync } = ags.Utils; +const { getWindow } = ags.App; +import Cairo from 'cairo'; + +import { Button } from '../misc/cursorbox.js'; + + +const TARGET = [Gtk.TargetEntry.new('text/plain', Gtk.TargetFlags.SAME_APP, 0)]; + +function createSurfaceFromWidget(widget) { + 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; +}; + +let hidden = 0; +export const WorkspaceDrop = params => EventBox({ + ...params, + //tooltipText: `Workspace: ${id}`, + connections: [['drag-data-received', (eventbox, _c, _x, _y, data) => { + let id = eventbox.get_parent()._id; + + if (id < -1) { + id = eventbox.get_parent()._name; + } + else if (id === -1) { + id = `special:${++hidden}`; + } + else if (id === 1000) { + id = "empty"; + } + execAsync(`hyprctl dispatch movetoworkspacesilent ${id},address:${data.get_text()}`) + .catch(print); + }]], + setup: eventbox => { + eventbox.drag_dest_set(Gtk.DestDefaults.ALL, TARGET, Gdk.DragAction.COPY); + }, +}); + +export const WindowButton = ({address, ...params} = {}) => Button({ + ...params, + setup: button => { + button.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, TARGET, Gdk.DragAction.COPY); + button.connect('drag-data-get', (_w, _c, data) => { + data.set_text(address, address.length); + }); + button.connect('drag-begin', (_, context) => { + Gtk.drag_set_icon_surface(context, createSurfaceFromWidget(button)); + button.get_parent().revealChild = false; + }); + button.connect('drag-end', () => { + button.get_parent().destroy(); + let mainBox = getWindow('overview').child.children[0].child; + mainBox._updateClients(mainBox); + }); + }, +}); diff --git a/config/ags/js/overview/main.js b/config/ags/js/overview/main.js new file mode 100644 index 00000000..b998afe0 --- /dev/null +++ b/config/ags/js/overview/main.js @@ -0,0 +1,51 @@ +const { Window, Box } = ags.Widget; +const { Hyprland } = ags.Service; + +import { PopUp } from '../misc/popup.js'; +import { WorkspaceRow, getWorkspaces, updateWorkspaces } from './workspaces.js'; +import { updateClients } from './clients.js'; + +export default Window({ + name: 'overview', + layer: 'overlay', + popup: true, + + child: PopUp({ + name: 'overview', + transition: 'crossfade', + + child: Box({ + className: 'overview', + vertical: true, + children: [ + Box({ + vertical: true, + children: [ + WorkspaceRow('normal', 0), + ], + }), + Box({ + vertical: true, + children: [ + WorkspaceRow('special', 0), + ], + }), + ], + connections: [ + [Hyprland, box => { + box._getWorkspaces(box); + box._updateWorkspaces(box); + box._updateClients(box); + }], + ], + properties: [ + ['workspaces'], + + ['getWorkspaces', getWorkspaces], + ['updateWorkspaces', updateWorkspaces], + ['updateClients', updateClients], + ], + }), + + }), +}); diff --git a/config/ags/js/overview/variables.js b/config/ags/js/overview/variables.js new file mode 100644 index 00000000..5bc871a8 --- /dev/null +++ b/config/ags/js/overview/variables.js @@ -0,0 +1,14 @@ +export const SCALE = 0.11; +export const ICON_SCALE = 0.8; +export const MARGIN = 8; +export const DEFAULT_SPECIAL = { + SIZE_X: 1524, + SIZE_Y: 908, + POS_X: 197, + POS_Y: 170, +}; +export const WORKSPACE_PER_ROW = 6; +export const SCREEN = { + X: 1920, + Y: 1200, +}; diff --git a/config/ags/js/overview/workspaces.js b/config/ags/js/overview/workspaces.js new file mode 100644 index 00000000..ee6af818 --- /dev/null +++ b/config/ags/js/overview/workspaces.js @@ -0,0 +1,187 @@ +const { Revealer, CenterBox, Box, EventBox, Label, Overlay } = ags.Widget; +const { Hyprland } = ags.Service; +const { Gtk } = imports.gi; + +import { WorkspaceDrop } from './dragndrop.js'; +import * as VARS from './variables.js'; + +const DEFAULT_STYLE = `min-width: ${VARS.SCREEN.X * VARS.SCALE}px; + min-height: ${VARS.SCREEN.Y * VARS.SCALE}px;`; + +export function getWorkspaces(box) { + let children = []; + box.children.forEach(type => { + type.children.forEach(row => { + row.child.centerWidget.child.children.forEach(ch => { + children.push(ch); + }); + }); + }); + box._workspaces = children.sort((a, b) => a._id - b._id); +}; + +export const WorkspaceRow = (className, i) => Revealer({ + transition: 'slide_down', + connections: [[Hyprland, rev => { + let minId = i * VARS.WORKSPACE_PER_ROW; + let activeId = Hyprland.active.workspace.id; + + rev.revealChild = Hyprland.workspaces.some(ws => ws.id > minId && + (ws.windows > 0 || + ws.id === activeId)); + }]], + child: CenterBox({ + children: [null, EventBox({ + properties: [['box']], + setup: eventbox => eventbox._box = eventbox.child.children[0], + connections: [[Hyprland, eventbox => { + let maxId = i * VARS.WORKSPACE_PER_ROW + VARS.WORKSPACE_PER_ROW; + let activeId = Hyprland.active.workspace.id; + + eventbox._box.revealChild = className === 'special' || + !Hyprland.workspaces.some(ws => ws.id > maxId && + (ws.windows > 0 || + ws.id === activeId)); + }]], + child: Box({ + className: className, + children: [ + Revealer({ + transition: 'slide_right', + properties: [ + ['id', className === 'special' ? -1 : 1000], + ['name', className === 'special' ? 'special' : ''], + ], + child: WorkspaceDrop({ + child: Overlay({ + child: Box({ + className: 'workspace', + style: DEFAULT_STYLE, + }), + overlays: [Box({ + style: DEFAULT_STYLE, + children: [ + ags.Widget({ + type: Gtk.Fixed, + }), + Label({ + label: ' +', + style: 'font-size: 40px;', + }), + ], + })], + }), + }), + }), + ], + }), + }), null], + }), +}); + +const Workspace = (id, name) => Revealer({ + transition: 'slide_right', + transitionDuration: 500, + properties: [ + ['id', id], + ['name', name], + ['timeouts', []], + ['wasActive', false], + ], + connections: [[Hyprland, box => { + box._timeouts.forEach(clearTimeout); + + let activeId = Hyprland.active.workspace.id; + let active = activeId === box._id; + + let rev = box.child.child.child; + let n = activeId > box._id; + + if (Hyprland.getWorkspace(box._id)?.windows > 0 || active) { + rev.setStyle(DEFAULT_STYLE); + box._timeouts.push(setTimeout(() => { + box.revealChild = true; + }, 100)); + + } + else if (!Hyprland.getWorkspace(box._id)?.windows > 0) { + rev.setStyle(DEFAULT_STYLE); + box._timeouts.push(setTimeout(() => { + box.revealChild = false; + }, 100)); + return; + } + + if (active) { + rev.setStyle(`${DEFAULT_STYLE} + transition: margin 0.5s ease-in-out; + opacity: 1;`); + box._wasActive = true; + } + else if (box._wasActive) { + box._wasActive = false; + box._timeouts.push(setTimeout(() => { + rev.setStyle(`${DEFAULT_STYLE} + transition: margin 0.5s ease-in-out; + opacity: 1; margin-left: ${n ? '' : '-'}300px; + margin-right: ${n ? '-' : ''}300px;`); + }, 120)); + box._timeouts.push(setTimeout(() => { + rev.setStyle(`${DEFAULT_STYLE} opacity: 0; + margin-left: ${n ? '' : '-'}300px; + margin-right: ${n ? '-' : ''}300px;`); + }, 500)); + } + else { + rev.setStyle(`${DEFAULT_STYLE} opacity: 0; + margin-left: ${n ? '' : '-'}300px; + margin-right: ${n ? '-' : ''}300px;`); + } + }]], + child: WorkspaceDrop({ + child: Overlay({ + child: Box({ + className: 'workspace active', + style: `${DEFAULT_STYLE} opacity: 0;`, + }), + overlays: [Box({ + className: 'workspace', + style: DEFAULT_STYLE, + child: ags.Widget({ + type: Gtk.Fixed, + }), + })], + }), + }), +}); + +export function updateWorkspaces(box) { + Hyprland.workspaces.forEach(ws => { + let currentWs = box._workspaces.find(ch => ch._id == ws.id); + if (!currentWs) { + var type = 0; + var rowNo = 0; + + if (ws.id < 0) { + // This means it's a special workspace + type = 1; + } + else { + rowNo = Math.floor((ws.id - 1) / VARS.WORKSPACE_PER_ROW); + if (rowNo >= box.children[type].children.length) { + for (let i = box.children[type].children.length; i <= rowNo; ++i) { + box.children[type].add(WorkspaceRow(type ? 'special' : 'normal', i)); + } + } + } + var row = box.children[type].children[rowNo].child.centerWidget.child; + row.add(Workspace(ws.id, type ? ws.name : '')); + } + }); + box.show_all(); + + // Make sure the order is correct + box._workspaces.forEach((workspace, i) => { + workspace.get_parent().reorder_child(workspace, i) + }); +} diff --git a/config/ags/js/powermenu.js b/config/ags/js/powermenu.js new file mode 100644 index 00000000..381a9273 --- /dev/null +++ b/config/ags/js/powermenu.js @@ -0,0 +1,47 @@ +const { Window, CenterBox, Label } = ags.Widget; + +import { PopUp } from './misc/popup.js'; +import { Button } from './misc/cursorbox.js' + +const PowermenuWidget = CenterBox({ + className: 'powermenu', + vertical: false, + + startWidget: Button({ + className: 'shutdown', + onPrimaryClickRelease: 'systemctl poweroff', + + child: Label({ + label: '襤', + }), + }), + + centerWidget: Button({ + className: 'reboot', + onPrimaryClickRelease: 'systemctl reboot', + + child: Label({ + label: '勒', + }), + }), + + endWidget: Button({ + className: 'logout', + onPrimaryClickRelease: 'hyprctl dispatch exit', + + child: Label({ + label: '', + }), + }), +}); + +export const Powermenu = Window({ + name: 'powermenu', + popup: true, + layer: 'overlay', + child: PopUp({ + name: 'powermenu', + transition: 'crossfade', + child: PowermenuWidget, + }), +}); diff --git a/config/ags/js/quick-settings/button-grid.js b/config/ags/js/quick-settings/button-grid.js new file mode 100644 index 00000000..f8b97e61 --- /dev/null +++ b/config/ags/js/quick-settings/button-grid.js @@ -0,0 +1,212 @@ +const { Box, CenterBox, Label, Icon } = ags.Widget; +const { Network, Bluetooth, Audio } = ags.Service; +const { execAsync } = ags.Utils; +const { openWindow } = ags.App; + +import { EventBox } from '../misc/cursorbox.js'; + +const GridButton = ({ command = () => {}, secondaryCommand = () => {}, icon } = {}) => Box({ + className: 'grid-button', + children: [ + + EventBox({ + className: 'left-part', + onPrimaryClickRelease: () => command(), + child: icon, + }), + + EventBox({ + className: 'right-part', + onPrimaryClickRelease: () => secondaryCommand(), + child: Label({ + label: " ", + className: 'grid-chev', + }), + }), + + ], +}); + +const FirstRow = Box({ + className: 'button-row', + halign: 'center', + style: 'margin-top: 15px; margin-bottom: 7px;', + children: [ + + GridButton({ + command: () => Network.toggleWifi(), + secondaryCommand: () => execAsync(['bash', '-c', 'nm-connection-editor']).catch(print), + icon: Icon({ + className: 'grid-label', + connections: [[Network, icon => { + if (Network.wifi.enabled) { + icon.icon = 'network-wireless-connected-symbolic'; + } + else { + icon.icon = 'network-wireless-offline-symbolic'; + } + }, 'changed']], + }), + }), + + GridButton({ + command: () => execAsync(['bash', '-c', '$AGS_PATH/qs-toggles.sh blue-toggle']).catch(print), + secondaryCommand: () => execAsync(['bash', '-c', 'blueberry']).catch(print), + icon: Icon({ + className: 'grid-label', + connections: [[Bluetooth, icon => { + if (Bluetooth.enabled) { + icon.icon = 'bluetooth-active-symbolic'; + execAsync(['bash', '-c', 'echo > $HOME/.config/.bluetooth']).catch(print); + } + else { + icon.icon = 'bluetooth-disabled-symbolic'; + execAsync(['bash', '-c', 'echo > $HOME/.config/.bluetooth']).catch(print); + } + }, 'changed']], + }) + }), + + GridButton({ + command: () => execAsync(['bash', '-c', '$AGS_PATH/qs-toggles.sh toggle-radio']).catch(print), + secondaryCommand: () => execAsync(['notify-send', 'set this up moron']).catch(print), + icon: Icon({ + className: 'grid-label', + connections: [[Network, icon => { + if (Network.wifi.enabled) { + icon.icon = 'airplane-mode-disabled-symbolic'; + } + else { + icon.icon = 'airplane-mode-symbolic'; + } + }, 'changed']], + }), + }), + + ], +}); + +const SubRow = CenterBox({ + halign: 'start', + children: [ + + Label({ + className: 'sub-label', + truncate: 'end', + maxWidthChars: 12, + connections: [[Network, label => { + label.label = Network.wifi.ssid; + }, 'changed']], + }), + + Label({ + className: 'sub-label', + truncate: 'end', + maxWidthChars: 12, + connections: [[Bluetooth, label => { + label.label = Bluetooth.connectedDevices[0] ? String(Bluetooth.connectedDevices[0]) : + 'Disconnected'; + }, 'changed']], + }), + + Label({ + className: '', + truncate: 'end', + maxWidthChars: 12, + /*connections: [[Network, label => { + label.label = Network.wifi.ssid; + }, 'changed']],*/ + }), + + ], +}); + +const items = { + 101: 'audio-volume-overamplified-symbolic', + 67: 'audio-volume-high-symbolic', + 34: 'audio-volume-medium-symbolic', + 1: 'audio-volume-low-symbolic', + 0: 'audio-volume-muted-symbolic', +}; + +const itemsMic = { + 2: 'audio-input-microphone-high-symbolic', + 1: 'audio-input-microphone-muted-symbolic', + 0: 'audio-input-microphone-muted-symbolic', +}; + +const SecondRow = Box({ + className: 'button-row', + halign: 'center', + style: 'margin-top: 7px; margin-bottom: 15px;', + children: [ + + GridButton({ + command: () => execAsync(['swayosd-client', '--output-volume', 'mute-toggle']).catch(print), + secondaryCommand: () => execAsync(['bash', '-c', 'pavucontrol']).catch(print), + icon: Icon({ + className: 'grid-label', + connections: [[Audio, icon => { + if (Audio.speaker) { + if (Audio.speaker.isMuted) { + icon.icon = items[0]; + } + else { + const vol = Audio.speaker.volume * 100; + for (const threshold of [-1, 0, 33, 66, 100]) { + if (vol > threshold + 1) { + icon.icon = items[threshold + 1]; + } + } + } + } + }, 'speaker-changed']], + }), + }), + + GridButton({ + command: () => execAsync(['swayosd-client', '--input-volume', 'mute-toggle']).catch(print), + secondaryCommand: () => execAsync(['bash', '-c', 'pavucontrol']).catch(print), + icon: Icon({ + className: 'grid-label', + connections: [[Audio, icon => { + if (Audio.microphone) { + if (Audio.microphone.isMuted) { + icon.icon = itemsMic[0]; + } + else { + const vol = Audio.microphone.volume * 100; + for (const threshold of [-1, 0, 1]) { + if (vol > threshold + 1) { + icon.icon = itemsMic[threshold + 1]; + } + } + } + } + }, 'microphone-changed']], + }) + }), + + GridButton({ + command: () => execAsync(['bash', '-c', '$LOCK_PATH/lock.sh']).catch(print), + secondaryCommand: () => openWindow('powermenu'), + icon: Label({ + className: 'grid-label', + label: " ", + }), + }), + + ], +}); + + +export const ButtonGrid = Box({ + className: 'button-grid', + vertical: true, + halign: 'center', + children: [ + FirstRow, + SubRow, + SecondRow, + ], +}); diff --git a/config/ags/js/quick-settings/main.js b/config/ags/js/quick-settings/main.js new file mode 100644 index 00000000..40dc13b4 --- /dev/null +++ b/config/ags/js/quick-settings/main.js @@ -0,0 +1,80 @@ +const { Window, Box, Label, Revealer, Icon } = ags.Widget; +const { Mpris } = ags.Service; +const { ToggleButton } = imports.gi.Gtk; + +import { ButtonGrid } from './button-grid.js'; +import { SliderBox } from './slider-box.js'; +import Player from '../media-player/player.js'; +import { EventBox } from '../misc/cursorbox.js'; +import { PopUp } from '../misc/popup.js'; + +const QuickSettingsWidget = Box({ + className: 'qs-container', + vertical: true, + children: [ + + Box({ + className: 'quick-settings', + vertical: true, + children: [ + + Label({ + label: 'Control Center', + className: 'title', + halign: 'start', + style: 'margin-left: 20px' + }), + + ButtonGrid, + + SliderBox, + + EventBox({ + child: ags.Widget({ + type: ToggleButton, + setup: btn => { + const id = Mpris.instance.connect('changed', () => { + btn.set_active(Mpris.players.length > 0); + Mpris.instance.disconnect(id); + }); + }, + connections: [['toggled', button => { + if (button.get_active()) { + button.child.setStyle("-gtk-icon-transform: rotate(0deg);"); + button.get_parent().get_parent().get_parent().children[1].revealChild = true; + } + else { + button.child.setStyle('-gtk-icon-transform: rotate(180deg);'); + button.get_parent().get_parent().get_parent().children[1].revealChild = false; + } + }]], + child: Icon({ + icon: 'folder-download-symbolic', + className: 'arrow', + style: `-gtk-icon-transform: rotate(180deg);`, + }), + }), + }), + + ], + }), + + Revealer({ + transition: 'slide_down', + child: Player(), + }) + + ], +}); + +export const QuickSettings = Window({ + name: 'quick-settings', + layer: 'overlay', + anchor: 'top right', + popup: true, + margin: [ 8, 5, 0, ], + child: PopUp({ + name: 'quick-settings', + child: QuickSettingsWidget, + }), +}); diff --git a/config/ags/js/quick-settings/slider-box.js b/config/ags/js/quick-settings/slider-box.js new file mode 100644 index 00000000..57b90436 --- /dev/null +++ b/config/ags/js/quick-settings/slider-box.js @@ -0,0 +1,91 @@ +const { Box, Slider, Icon, EventBox } = ags.Widget; +const { Audio } = ags.Service; +const { execAsync } = ags.Utils; + +const items = { + 101: 'audio-volume-overamplified-symbolic', + 67: 'audio-volume-high-symbolic', + 34: 'audio-volume-medium-symbolic', + 1: 'audio-volume-low-symbolic', + 0: 'audio-volume-muted-symbolic', +}; + +export const SliderBox = Box({ + className: 'slider-box', + vertical: true, + halign: 'center', + children: [ + + Box({ + className: 'slider', + valign: 'start', + halign: 'center', + children: [ + Icon({ + size: 26, + className: 'slider-label', + connections: [[Audio, icon => { + if (Audio.speaker) { + if (Audio.speaker.isMuted) { + icon.icon = items[0]; + } + else { + const vol = Audio.speaker.volume * 100; + for (const threshold of [-1, 0, 33, 66, 100]) { + if (vol > threshold + 1) { + icon.icon = items[threshold + 1]; + } + } + } + } + }, 'speaker-changed']], + }), + + Slider({ + connections: [[Audio, slider => { + if (Audio.speaker) { + slider.value = Audio.speaker.volume; + } + }, 'speaker-changed']], + onChange: ({ value }) => Audio.speaker.volume = value, + max: 0.999, + draw_value: false, + }), + ], + }), + + Box({ + className: 'slider', + valign: 'start', + halign: 'center', + children: [ + Icon({ + className: 'slider-label', + icon: 'display-brightness-symbolic', + }), + + EventBox({ + onHover: box => box.child._canChange = false, + onHoverLost: box => box.child._canChange = true, + child: Slider({ + properties: [ + ['canChange', true], + ], + onChange: ({ value }) => { + execAsync(`brightnessctl set ${value}`).catch(print); + }, + connections: [[1000, slider => { + if (slider._canChange) { + execAsync('brightnessctl get').then(out => slider.value = out).catch(print); + } + }]], + min: 0, + max: 255, + draw_value: false, + }), + }), + ], + }), + + ], +}); diff --git a/config/ags/scss/common.scss b/config/ags/scss/common.scss new file mode 100644 index 00000000..e9ab974d --- /dev/null +++ b/config/ags/scss/common.scss @@ -0,0 +1,32 @@ +$darkbg: #0b0d16; +$bg: rgba(40, 42, 54, 0.8); //rgba(69, 71, 90, 0.3); #0d0f18; +$bgfull: rgb(40, 42, 54); +$contrastbg: rgba(189, 147, 249, 0.8); +$bgSecondary: rgba(#382c4a, 0.8); +$bgSecondaryAlt: #a5b6cf; +$fg: #a5b6cf; +$fgDim: #a5b6cf; +$watermelon: #dd6777; + +// Aliases +$background: $bg; +$backgroundSecondary: $bgSecondary; +$backgroundSecondaryAlt: $bgSecondaryAlt; +$foreground: $fg; +$foregroundDim: $fgDim; + +$black: #151720; +$dimblack: #1a1c25; +$lightblack: #262831; +$red: #dd6777; +$blue: #86aaec; +$cyan: #93cee9; +$blue-desaturated: #93cee9; +$magenta: #c296eb; +$purple: #c296eb; +$green: #90ceaa; +$aquamarine: #90ceaa; +$yellow: #ecd3a0; +$accent: $blue; +$javacafeMagenta: #c296eb; +$javacafeBlue: #86aaec; diff --git a/config/ags/scss/main.scss b/config/ags/scss/main.scss new file mode 100644 index 00000000..457431e8 --- /dev/null +++ b/config/ags/scss/main.scss @@ -0,0 +1,16 @@ +* { + all: unset; +} + +@import "./common.scss"; +@import "./widgets/powermenu.scss"; +@import "./widgets/traybuttons.scss"; +@import "./widgets/workspaces.scss"; +@import "./widgets/systray.scss"; +@import "./widgets/notification-center.scss"; +@import "./widgets/notification.scss"; +@import "./widgets/date.scss"; +@import "./widgets/quick-settings.scss"; +@import "./widgets/player.scss"; +@import "./widgets/overview.scss"; +@import "./widgets/applauncher.scss"; diff --git a/config/ags/scss/widgets/applauncher.scss b/config/ags/scss/widgets/applauncher.scss new file mode 100644 index 00000000..d9fe80b3 --- /dev/null +++ b/config/ags/scss/widgets/applauncher.scss @@ -0,0 +1,113 @@ +.applauncher { + all: unset; + box-shadow: 0 0 4.5px 0 rgba(0, 0, 0, 0.6); + margin: 9px; + border: 2px solid $contrastbg; + border-radius: 25px; + background-color: $bg; + color: #f8f8f2; + padding: 16.2px; + + * { + font-size: 16px; + } + + .header { + margin: 16.2px; + margin-bottom: 0; + + image, entry { + all: unset; + border-radius: 9px; + color: #f8f8f2; + background-color: rgba(#44475a, 0.6); + border: 1px solid #44475a; + padding: 4.5px; + } + + image { + margin-right: 9px; + -gtk-icon-transform: scale(0.8); + font-size: 25.6px; + } + } + + scrolledwindow { + padding: 16.2px; + min-width: 700px; + min-height: 450px; + + scrollbar, scrollbar * { + all: unset; + } + scrollbar.vertical { + transition: 200ms; + background-color: rgba(23, 23, 23, 0.3); + + &:hover { + background-color: rgba(23, 23, 23, 0.7); + + slider { + background-color: rgba(238, 238, 238, 0.7); + min-width: .6em; + } + } + slider { + background-color: rgba(238, 238, 238, 0.5); + border-radius: 9px; + min-width: .4em; + min-height: 2em; + transition: 200ms; + } + } + } + + .placeholder { + margin-top: 9px; + color: #f8f8f2; + font-size: 1.2em; + } + + .app { + all: unset; + transition: 200ms; + padding: 9px; + + &:active { + background-color: rgba($contrastbg, 0.5); + border-radius: 9px; + box-shadow: inset 0 0 0 3px rgba(238, 238, 238, 0.03); + + .title { + color: #f8f8f2; + } + } + + &:hover, &:focus { + .title { + color: $contrastbg; + } + + image { + -gtk-icon-shadow: 2px 2px $contrastbg; + } + } + + label { + transition: 200ms; + + &.title { + color: #f8f8f2; + } + + &.description { + color: rgba(238, 238, 238, 0.7); + } + } + + image { + transition: 200ms; + margin-right: 9px; + } + } +} diff --git a/config/ags/scss/widgets/date.scss b/config/ags/scss/widgets/date.scss new file mode 100644 index 00000000..c068f3dc --- /dev/null +++ b/config/ags/scss/widgets/date.scss @@ -0,0 +1,76 @@ +.date { + background-color: $bg; + color: $fg; + border-radius: 30px; + border-top-right-radius: 0px; + border: 2px solid $contrastbg; +} + +.timebox { + margin: 30px 0px; + .time-container { + .content { + font-family: Product Sans; + font-weight: bolder; + font-size: 60px; + } + .divider { + margin: 8px 15px; + padding: 0px 1px; + background: linear-gradient($red, $magenta, $blue, $cyan); + } + } + .date-container { + font-family: Product Sans; + margin-top: 2px; + } +} + +.cal-box { + font-family: Product Sans; + border-radius: 30px; + padding: 0 1rem .2rem; + color: $fg; + background-color: $bgfull; + border-bottom: 2px solid $contrastbg; + border-top: 2px solid $contrastbg; + margin: 0px 12px 18px 12px; + + .cal { + font-size: 20px; + background-color: inherit; + padding: .5rem .10rem 0rem; + margin-left: 10px; + border-radius: 30px; + + & > * { + border: solid 0px transparent; + } + + &.highlight { + padding: 10rem; + } + } +} + +calendar:selected { + color: $cyan; +} + +calendar.header { + color: $cyan; + font-weight: bold; +} + +calendar.button { + color: $cyan; +} + +calendar.highlight { + color: $green; + font-weight: bold; +} + +calendar:indeterminate { + color: $lightblack; +} diff --git a/config/ags/scss/widgets/notification-center.scss b/config/ags/scss/widgets/notification-center.scss new file mode 100644 index 00000000..b5a366c8 --- /dev/null +++ b/config/ags/scss/widgets/notification-center.scss @@ -0,0 +1,100 @@ +.notification-center { + min-height: 700px; + min-width: 524px; + background: $bg; + border-radius: 30px; + border-top-right-radius: 0px; + border: 2px solid $contrastbg; + padding: 0px; + box-shadow: 0 0 4.5px 0 rgba(0, 0, 0, 0.6); + + * { + font-size: 16px; + } + + .header { + padding: 10px; + margin-top: 22px; + margin-bottom: 9px; + label { + font-size: 22px; + } + button { + all: unset; + transition: 200ms; + border-radius: 9px; + color: #eee; + background-color: #664C90; + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + padding: 4.5px 9px; + + &:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-color: rgba(238, 238, 238, 0.154); + color: #f1f1f1; + } + &:disabled { + box-shadow: none; + background-color: rgba(#664C90, 0.3); + color: rgba(238, 238, 238, 0.3); + } + label { + font-size: 1.2em; + } + } + } + + .notification-list-box { + background: $bgfull; + padding: 0 12px 0 12px; + border-radius: 30px; + border-top: 2px solid $contrastbg; + box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.5); + scrollbar { + all: unset; + border-radius: 8px; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + * { + all: unset; + } + &:hover { + border-radius: 8px; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + } + scrollbar.vertical { + transition: 200ms; + background-color: rgba(23, 23, 23, 0.3); + &:hover { + background-color: rgba(23, 23, 23, 0.7); + slider { + background-color: rgba(238, 238, 238, 0.7); + min-width: .6em; + } + } + slider { + background-color: rgba(238, 238, 238, 0.5); + border-radius: 9px; + min-width: .4em; + min-height: 2em; + transition: 200ms; + } + } + } + + .placeholder { + color: white; + image { + font-size: 7em; + text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6); + -gtk-icon-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6); + } + label { + font-size: 1.2em; + text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6); + -gtk-icon-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6); + } + } +} diff --git a/config/ags/scss/widgets/notification.scss b/config/ags/scss/widgets/notification.scss new file mode 100644 index 00000000..7933ddfa --- /dev/null +++ b/config/ags/scss/widgets/notification.scss @@ -0,0 +1,179 @@ +$background-color_1: rgba(238, 238, 238, 0.154); +$background-color_2: rgba(230, 112, 144, 0.5); +$background-color_3: rgba(238, 238, 238, 0.06); +$background-color_4: #51a4e7; +$background-color_5: transparent; +$background-color_6: #171717; +$background-color_7: rgba(23, 23, 23, 0.3); +$background-color_8: rgba(23, 23, 23, 0.7); +$background-color_9: rgba(238, 238, 238, 0.7); +$background-color_10: rgba(238, 238, 238, 0.5); + +.notification.critical { + >box { + box-shadow: inset 0 0 0.5em 0 #e67090; + } +} +.notification { + >box { + all: unset; + box-shadow: 0 0 4.5px 0 rgba(0, 0, 0, 0.4); + margin: 9px 9px 0 9px; + border: 2px solid $contrastbg; + border-radius: 15px; + background-color: $bg; + padding: 16.2px; + * { + font-size: 16px; + } + } + &:hover { + .close-button { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-color: $background-color_1; + background-color: $background-color_2; + } + } + .title { + margin-right: 9px; + font-size: 1.1em; + } + .description { + font-size: .9em; + min-width: 350px; + } + .icon { + border-radius: 7.2px; + margin-right: 9px; + } + .icon.img { + border: 1px solid rgba(238, 238, 238, 0.03); + } + .actions { + button { + all: unset; + transition: all 500ms; + border-radius: 9px; + background-color: $background-color_3; + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + border-radius: 7.2px; + font-size: 1.2em; + padding: 4.5px 9px; + margin: 9px 4.5px 0; + * { + font-size: 16px; + } + &:focus { + box-shadow: inset 0 0 0 1px #51a4e7; + background-color: $background-color_1; + } + &:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-color: $background-color_1; + } + &:active { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-image: linear-gradient(to right, #51a4e7, #6cb2eb); + background-color: $background-color_4; + &:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154); + } + } + &:checked { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-image: linear-gradient(to right, #51a4e7, #6cb2eb); + background-color: $background-color_4; + &:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154); + } + } + &:disabled { + box-shadow: none; + background-color: $background-color_5; + } + &:first-child { + margin-left: 0; + } + &:last-child { + margin-right: 0; + } + } + button.on { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-image: linear-gradient(to right, #51a4e7, #6cb2eb); + background-color: $background-color_4; + &:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154); + } + } + button.active { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-image: linear-gradient(to right, #51a4e7, #6cb2eb); + background-color: $background-color_4; + &:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154); + } + } + } + button.close-button { + all: unset; + transition: all 500ms; + border-radius: 9px; + background-color: $background-color_5; + background-image: none; + box-shadow: none; + margin-left: 9px; + border-radius: 7.2px; + min-width: 1.2em; + min-height: 1.2em; + * { + font-size: 16px; + } + &:focus { + box-shadow: inset 0 0 0 1px #51a4e7; + background-color: $background-color_1; + } + &:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-color: $background-color_1; + background-color: $background-color_2; + } + &:active { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-image: linear-gradient(to right, #51a4e7, #6cb2eb); + background-color: $background-color_4; + background-image: linear-gradient(#e67090, #e67090); + &:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154); + } + } + &:checked { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-image: linear-gradient(to right, #51a4e7, #6cb2eb); + background-color: $background-color_4; + &:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154); + } + } + &:disabled { + box-shadow: none; + background-color: $background-color_5; + } + } + button.close-button.on { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-image: linear-gradient(to right, #51a4e7, #6cb2eb); + background-color: $background-color_4; + &:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154); + } + } + button.close-button.active { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-image: linear-gradient(to right, #51a4e7, #6cb2eb); + background-color: $background-color_4; + &:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154); + } + } +} diff --git a/config/ags/scss/widgets/overview.scss b/config/ags/scss/widgets/overview.scss new file mode 100644 index 00000000..218938a4 --- /dev/null +++ b/config/ags/scss/widgets/overview.scss @@ -0,0 +1,52 @@ +.overview { + + .workspace { + padding: 4px 15px 4px 0px; + border: 2px solid transparent; + border-radius: 10px; + + &.active { + background-color: rgba(lighten($color: black, $amount: 15), 0.8); + border: 2px solid black; + } + } + + .workspace .window { + background-color: $bgfull; + border-radius: 10px; + margin: 0 10px; + transition: min-width 0.2s ease-in-out, + min-height 0.2s ease-in-out, + border-color 0.2s ease-in-out, + font-size 0.2s ease-in-out; + } + + .normal { + margin-bottom: 5px; + + .workspace { + + .window { + border: 2px solid #411C6C; + + &.active { + border: 2px solid purple; + } + } + } + } + .special { + + .workspace { + + .window { + border: 2px solid lighten($color: black, $amount: 20); + + &.active { + border: 2px solid purple; + } + + } + } + } +} diff --git a/config/ags/scss/widgets/player.scss b/config/ags/scss/widgets/player.scss new file mode 100644 index 00000000..ab734c75 --- /dev/null +++ b/config/ags/scss/widgets/player.scss @@ -0,0 +1,111 @@ +.arrow { + transition: -gtk-icon-transform 0.3s ease-in-out; + margin-bottom: 12px; +} + +.media { + margin-top: 9px; +} + +.player { + all: unset; + padding: 10px; + min-width: 400px; + min-height: 200px; + border-radius: 30px; + border-top: 2px solid $contrastbg; + border-bottom: 2px solid $contrastbg; + transition: background 250ms; + .top { + font-size: 23px; + } + .metadata { + .title{ + font-weight: 500; + transition: text 250ms; + } + .artist{ + font-weight: 400; + font-size: 15px; + transition: text 250ms; + } + } + .bottom { + font-size: 30px; + } + + .pausebutton { + transition: background-color ease .2s, + color ease .2s; + font-size: 15px; + padding: 4px 4px 4px 7px; + } + + .playing { + transition: background-color ease .2s, + color ease .2s; + border-radius: 15px; + } + + .stopped, + .paused { + transition: background-color ease .2s, + color ease .2s; + border-radius: 26px; + padding: 4px 4px 4px 10px; + } + button label { + min-width: 35px; + } +} + +.position-indicator { + min-width: 18px; + margin: 7px; + background-color: rgba(255, 255, 255, 0.7); + box-shadow: 0 0 5px 0px rgba(255, 255, 255, 0.3); + border-radius: 100%; +} + +.previous, +.next, +.shuffle, +.loop { + border-radius: 100%; + transition: color 200ms; + &:hover { + border-radius: 100%; + background-color: rgba(127, 132, 156, 0.4); + transition: color 200ms; + } +} + +.loop { + label { + padding-right: 8px; + } +} + +.position-slider { + highlight { + margin: 0px; + border-radius: 2em; + } + + trough { + margin: 0 8px; + border-radius: 2em; + } + + slider { + margin: -8px; + min-height: 20px; + border-radius: 10px; + box-shadow: rgba(0, 0, 0, 0.25) 0px 54px 55px, rgba(0, 0, 0, 0.12) 0px -12px 30px, rgba(0, 0, 0, 0.12) 0px 4px 6px, rgba(0, 0, 0, 0.17) 0px 12px 13px, rgba(0, 0, 0, 0.09) 0px -3px 5px; + transition: background-color 0.5s ease-in-out; + } + slider:hover { + transition: background-color 0.5s ease-in-out; + } +} + diff --git a/config/ags/scss/widgets/powermenu.scss b/config/ags/scss/widgets/powermenu.scss new file mode 100644 index 00000000..9d875edd --- /dev/null +++ b/config/ags/scss/widgets/powermenu.scss @@ -0,0 +1,36 @@ +.powermenu { + background-color: $bg; + color: $fg; + padding: 10px; + font-family: MesloLGS NF; + /*font-family: Iosevka Nerd Font;*/ + font-size: 70px; + border-radius: 30px; + border: 2px solid $contrastbg; + label { + min-width: 140px; + min-height: 130px; + } + button { + margin-right: 10px; + margin-left: 10px; + margin-top: 5px; + margin-bottom: 5px; + border-radius: 12px; + min-width: 80px; + transition: all ease .2s; + &:hover { background-color: $bgSecondary; } + &:active { background-color: $bgSecondary; } + .content { + border-radius: 4px; + padding: 0px 15px 0px 15px; + } + } + .shutdown { color: $red; } + .reboot { color: $magenta; } + .logout { color: $yellow; } +} + +.powermenu-clickhandler { + background-color: black; +} diff --git a/config/ags/scss/widgets/quick-settings.scss b/config/ags/scss/widgets/quick-settings.scss new file mode 100644 index 00000000..d11b98f4 --- /dev/null +++ b/config/ags/scss/widgets/quick-settings.scss @@ -0,0 +1,162 @@ +.quick-settings { + font-size: 30px; + min-width: 500px; + padding: 0px 0px 0px 0px; + background-color: $bg; + border-radius: 30px 0 30px 30px; + border: 2px solid $contrastbg; +} + +.title { + font-size: 22px; + margin-top: 30px; +} + +.grid-label { + font-size: 30px; + margin-left: 15px; + margin-right: 10px; + min-width: 50px; +} + +.sub-label { + font-size: 14px; + margin-top: -10px; + margin-left: 31px; + &:nth-child(1) { + margin-left: 25px; + } + margin-bottom: 10px; + padding: 3px; + border: 2px solid $contrastbg; + border-top-right-radius: 20px; + border-top-left-radius: 10px; + border-bottom-left-radius: 10px; + border-bottom-right-radius: 20px; + min-width: 106px; + background: #1b1b1b; +} + +.grid-chev { + margin-left: 0px; + + font-size: 40px; + margin-right: 5px; +} + +.button-grid { + font-size: 10px; + min-height: 160px; + min-width: 470px; + background-color: $bgfull; + border-top: 2px solid $contrastbg; + border-bottom: 2px solid $contrastbg; + border-radius: 15px; + margin-top: 30px; +} + +.button-row { + min-height: 70px; + min-width: 450px; + margin-left: 20px; +} + +.grid-button { + min-height: 65px; + min-width: 70px; + margin: 5px; + margin-left: 22px; + &:nth-child(1) { + margin-left: 5px; + } +} + +.left-part { + background: #1b1b1b; + border-top-left-radius: 15px; + border-bottom-left-radius: 15px; + border-left: 2px solid $contrastbg; + border-top: 2px solid $contrastbg; + border-bottom: 2px solid $contrastbg; + transition: all 0.5s ease-in-out; +} + +.right-part { + background: #1b1b1b; + border-top-right-radius: 30px; + border-bottom-right-radius: 30px; + border-right: 2px solid $contrastbg; + border-top: 2px solid $contrastbg; + border-bottom: 2px solid $contrastbg; + transition: all 0.5s ease-in-out; +} + +.right-part:hover, .right-part:active { + color: $contrastbg; + border: 2px solid $contrastbg; + border-top-left-radius: 7px; + border-bottom-left-radius: 7px; + transition: all 0.5s ease-in-out; +} + +.left-part:hover, .left-part:active { + color: $contrastbg; + border: 2px solid $contrastbg; + border-top-right-radius: 7px; + border-bottom-right-radius: 7px; + transition: all 0.5s ease-in-out; +} + +.player { + margin-top: 6px; + min-height: 220px; + opacity: 0; +} + +.slider-box { + min-height: 100px; + min-width: 470px; + background-color: $bgfull; + border-top: 2px solid $contrastbg; + border-bottom: 2px solid $contrastbg; + border-radius: 15px; + margin-top: 30px; + margin-bottom: 20px; + + .slider-label { + font-size: 30px; + min-width: 30px; + } + + scale { + min-height: 55px; + min-width: 400px; + margin-left: 18px; + margin-right: 20px; + + highlight { + margin: 0px; + background-color: #79659f; + border-radius: 2em; + } + + trough { + background-color: #363847; + border-radius: 2em; + } + + slider { + margin: -4px; + min-width: 20px; + min-height: 20px; + background: #3e4153; + border-radius: 100%; + box-shadow: rgba(0, 0, 0, 0.25) 0px 54px 55px, rgba(0, 0, 0, 0.12) 0px -12px 30px, rgba(0, 0, 0, 0.12) 0px 4px 6px, rgba(0, 0, 0, 0.17) 0px 12px 13px, rgba(0, 0, 0, 0.09) 0px -3px 5px; + transition: background-color 0.5s ease-in-out; + } + slider:hover { + background-color: #303240; + transition: background-color 0.5s ease-in-out; + } + } +} diff --git a/config/ags/scss/widgets/systray.scss b/config/ags/scss/widgets/systray.scss new file mode 100644 index 00000000..83405815 --- /dev/null +++ b/config/ags/scss/widgets/systray.scss @@ -0,0 +1,54 @@ +.sys-tray { + padding: 5px; + background-color: $bg; + color: #CBA6F7; + border-radius: 80px; + border: 2px solid $bgSecondary; + transition: background-color 0.5s ease-in-out, + border 0.5s ease-in-out; + + .tray-item { + all: unset; + padding: 0px 2px 0px 2px; + font-size: 25px; + border-radius: 100%; + transition: background-color 0.5s ease-in-out, + border 0.5s ease-in-out; + &:hover { + background: rgba(127, 132, 156, 0.4); + border-radius: 100%; + transition: background-color 0.5s ease-in-out, + border 0.5s ease-in-out; + } + } + + menu { + background: $bgfull; + padding-top: 5px; + padding-bottom: 5px; + border: 2px solid #1b1b1b; + border-radius: 10px; + + check { + color: white; + margin-left: 2px; + margin-right: 5px; + min-height: 20px; + min-width: 20px; + -gtk-icon-source: -gtk-icontheme('checkbox-symbolic'); + + &:checked { + -gtk-icon-source: -gtk-icontheme('checkbox-checked-symbolic'); + } + } + } + + menuitem:not(.tray-item) { + padding: 5px; + transition: all 0.2s ease-in-out; + + &:hover { + background: #1b1b1b; + } + } +} diff --git a/config/ags/scss/widgets/traybuttons.scss b/config/ags/scss/widgets/traybuttons.scss new file mode 100644 index 00000000..92e2d1f5 --- /dev/null +++ b/config/ags/scss/widgets/traybuttons.scss @@ -0,0 +1,107 @@ +.osk-toggle, +.tablet-toggle, +.heart-toggle { + font-size: 28px; + min-height: 40px; + min-width: 53px; +} + +.notif-panel { + font-size: 20px; + border-radius: 80px; + min-height: 37px; + min-width: 105px; + padding: 1px 0px 1px 5px; + + .toggle-on { + border-top-left-radius: 22px; + border-top-right-radius: 22px; + border-bottom-left-radius: 0px; + border-bottom-right-radius: 0px; + border-bottom: 0px solid $bg; + } +} + +.quick-settings-toggle { + font-size: 24px; + min-height: 40px; + min-width: 40px; + padding-right: 4px; + margin-left: -3px; +} + +.toggle-off { + background-color: $bg; + color: #CBA6F7; + border-radius: 80px; + border: 2px solid $bgSecondary; + transition: background-color 0.5s ease-in-out, + border 0.5s ease-in-out; +} + +.toggle-on { + background-color: $bg; + color: #CBA6F7; + border-radius: 80px; + border: 2px solid $contrastbg; + transition: background-color 0.5s ease-in-out, + border 0.5s ease-in-out; +} + +.toggle-on:hover, .toggle-off:hover { + background-color: rgba(127, 132, 156, 0.4); + transition: background-color 0.5s ease-in-out, + border 0.5s ease-in-out; +} + +.clock { + font-size: 20px; + padding-left: 10px; + padding-right: 10px; + min-width: 230px; +} + +.audio { + padding: 0 10px 0 10px; + font-size: 20px; +} + +.battery { + padding: 0 10px 0 10px; + font-size: 20px; + + .battery-indicator { + &.charging { + color: green; + } + &.charged {} + &.low { + color: red; + } + } + icon { + .charging {} + .discharging {} + } + .label { + font-size: 20px; + } +} + +.brightness { + trough { + margin-right: -50px; + progress { + margin-right: 50px; + margin-top: -30px; + border-radius: 80px; + min-height: 36px; + background: rgba(#5e497c, 0.8); + } + } +} + +tooltip { + background: rgba(0,0,0, 0.6); + border-radius: 5px; +} diff --git a/config/ags/scss/widgets/workspaces.scss b/config/ags/scss/widgets/workspaces.scss new file mode 100644 index 00000000..38af8f53 --- /dev/null +++ b/config/ags/scss/widgets/workspaces.scss @@ -0,0 +1,30 @@ +.workspaces { + background-color: $bg; + border-radius: 80px; + border: 2px solid $bgSecondary; + padding-top: 3px; + padding-bottom: 3px; + padding-left: 12px; + padding-right: 12px; + + .button { + margin: 2px; + min-width: 20px; + border-radius: 100%; + * {color: transparent;} + } + + .empty { + border: none; + transition: border-color 0.25s linear; + } + .occupied { + border: 2px solid $bg; + background: $contrastbg; + transition: border-color 0.25s linear; + } + .active { + border: 2px solid #50fa7b; + transition: border-color 0.25s linear; + } +} diff --git a/config/ags/services_wip/libinput.js b/config/ags/services_wip/libinput.js new file mode 100644 index 00000000..c678506a --- /dev/null +++ b/config/ags/services_wip/libinput.js @@ -0,0 +1,162 @@ +/* +import Libinput from './libinput.js'; +Libinput.instance.connect('device-init', () => { + let pointers = []; + Libinput.devices.forEach(dev => { + if (dev.Capabilities.includes('pointer')) { + pointers.push(dev); + } + }) + Libinput.addDebugInstance('pointers', pointers) + .connect('new-line', e => print(e.lastLine)) +}); +*/ + +const { Service } = ags; +const { execAsync } = ags.Utils; +import GLib from 'gi://GLib'; +import Gio from 'gi://Gio'; +import GObject from 'gi://GObject'; + +class DebugInstance extends GObject.Object { + static { + GObject.registerClass({ + Signals: { + 'changed': {}, + 'closed': {}, + 'new-line': {}, + }, + }, this); + } + devices = []; + name = ''; + lastLine = ''; + + readOutput(stdout, stdin) { + stdout.read_line_async(GLib.PRIORITY_LOW, null, (stream, result) => { + try { + const [line] = stream.read_line_finish_utf8(result); + + if (line !== null) { + this.lastLine = line; + this.emit('new-line'); + this.readOutput(stdout, stdin); + } + } catch (e) { + logError(e); + } + }); + } + + getOutput(devs) { + try { + let args = []; + devs.forEach(dev => { + if (dev.Kernel) { + args.push('--device'); + args.push(dev.Kernel); + } + }); + + const proc = Gio.Subprocess.new(['libinput', 'debug-events', ...args], + Gio.SubprocessFlags.STDIN_PIPE | Gio.SubprocessFlags.STDOUT_PIPE); + + // Get the `stdin`and `stdout` pipes, wrapping `stdout` to make it easier to + // read lines of text + const stdinStream = proc.get_stdin_pipe(); + const stdoutStream = new Gio.DataInputStream({ + base_stream: proc.get_stdout_pipe(), + close_base_stream: true, + }); + + // Start the loop + this.readOutput(stdoutStream, stdinStream); + } catch (e) { + logError(e); + } + } + + constructor(name, devs) { + super(); + + this.devices = devs; + this.name = name; + + this.getOutput(devs); + } +} + +class LibinputService extends Service { + static { + Service.register(this, { + 'device-init': ['boolean'], + 'instance-closed': ['string'], + 'instance-added': ['string'], + }); + } + + debugInstances = new Map(); + devices = new Map(); + + get devices() { return this._devices; } + + parseOutput(output) { + let lines = output.split('\n'); + let device = null; + + lines.forEach(line => { + let parts = line.split(':'); + + if (parts[0] === 'Device') { + device = {}; + this.devices.set(parts[1].trim(), device); + } + else if (device && parts[1]) { + let key = parts[0].trim(); + let value = parts[1].trim(); + device[key] = value; + } + }); + this.emit('device-init', true); + } + + constructor() { + super(); + this.debugInstances = new Map(); + execAsync(['libinput', 'list-devices']) + .then(out => this.parseOutput(out)) + .catch(console.error); + } + + addDebugInstance(name, devs) { + if (this.debugInstances.get(name)) + return; + + devs = Array(devs); + if (devs.some(dev => dev.Capabilities && dev.Capabilities.includes('pointer'))) { + } + const debugInst = new DebugInstance(name, devs); + + debugInst.connect('closed', () => { + this.debugInstances.delete(name); + this.emit('instance-closed', name); + this.emit('changed'); + }); + + this.debugInstances.set(name, debugInst); + this.emit('instance-added', name); + return debugInst; + } +} + +export default class Libinput { + static { Service.Libinput = this; } + static instance = new LibinputService(); + + static get devices() { return Libinput.instance.devices; } + static get debugInstances() { return Libinput.instance.debugInstances; } + + static addDebugInstance(name, dev) { + return Libinput.instance.addDebugInstance(name, dev); + } +} diff --git a/config/ags/style.css b/config/ags/style.css new file mode 100644 index 00000000..3a9f4382 --- /dev/null +++ b/config/ags/style.css @@ -0,0 +1,770 @@ +* { + all: unset; } + +.powermenu { + background-color: rgba(40, 42, 54, 0.8); + color: #a5b6cf; + padding: 10px; + font-family: MesloLGS NF; + /*font-family: Iosevka Nerd Font;*/ + font-size: 70px; + border-radius: 30px; + border: 2px solid rgba(189, 147, 249, 0.8); } + .powermenu label { + min-width: 140px; + min-height: 130px; } + .powermenu button { + margin-right: 10px; + margin-left: 10px; + margin-top: 5px; + margin-bottom: 5px; + border-radius: 12px; + min-width: 80px; + transition: all ease .2s; } + .powermenu button:hover { + background-color: rgba(56, 44, 74, 0.8); } + .powermenu button:active { + background-color: rgba(56, 44, 74, 0.8); } + .powermenu button .content { + border-radius: 4px; + padding: 0px 15px 0px 15px; } + .powermenu .shutdown { + color: #dd6777; } + .powermenu .reboot { + color: #c296eb; } + .powermenu .logout { + color: #ecd3a0; } + +.powermenu-clickhandler { + background-color: black; } + +.osk-toggle, +.tablet-toggle, +.heart-toggle { + font-size: 28px; + min-height: 40px; + min-width: 53px; } + +.notif-panel { + font-size: 20px; + border-radius: 80px; + min-height: 37px; + min-width: 105px; + padding: 1px 0px 1px 5px; } + .notif-panel .toggle-on { + border-top-left-radius: 22px; + border-top-right-radius: 22px; + border-bottom-left-radius: 0px; + border-bottom-right-radius: 0px; + border-bottom: 0px solid rgba(40, 42, 54, 0.8); } + +.quick-settings-toggle { + font-size: 24px; + min-height: 40px; + min-width: 40px; + padding-right: 4px; + margin-left: -3px; } + +.toggle-off { + background-color: rgba(40, 42, 54, 0.8); + color: #CBA6F7; + border-radius: 80px; + border: 2px solid rgba(56, 44, 74, 0.8); + transition: background-color 0.5s ease-in-out, border 0.5s ease-in-out; } + +.toggle-on { + background-color: rgba(40, 42, 54, 0.8); + color: #CBA6F7; + border-radius: 80px; + border: 2px solid rgba(189, 147, 249, 0.8); + transition: background-color 0.5s ease-in-out, border 0.5s ease-in-out; } + +.toggle-on:hover, .toggle-off:hover { + background-color: rgba(127, 132, 156, 0.4); + transition: background-color 0.5s ease-in-out, border 0.5s ease-in-out; } + +.clock { + font-size: 20px; + padding-left: 10px; + padding-right: 10px; + min-width: 230px; } + +.audio { + padding: 0 10px 0 10px; + font-size: 20px; } + +.battery { + padding: 0 10px 0 10px; + font-size: 20px; } + .battery .battery-indicator.charging { + color: green; } + .battery .battery-indicator.low { + color: red; } + .battery .label { + font-size: 20px; } + +.brightness trough { + margin-right: -50px; } + .brightness trough progress { + margin-right: 50px; + margin-top: -30px; + border-radius: 80px; + min-height: 36px; + background: rgba(94, 73, 124, 0.8); } + +tooltip { + background: rgba(0, 0, 0, 0.6); + border-radius: 5px; } + +.workspaces { + background-color: rgba(40, 42, 54, 0.8); + border-radius: 80px; + border: 2px solid rgba(56, 44, 74, 0.8); + padding-top: 3px; + padding-bottom: 3px; + padding-left: 12px; + padding-right: 12px; } + .workspaces .button { + margin: 2px; + min-width: 20px; + border-radius: 100%; } + .workspaces .button * { + color: transparent; } + .workspaces .empty { + border: none; + transition: border-color 0.25s linear; } + .workspaces .occupied { + border: 2px solid rgba(40, 42, 54, 0.8); + background: rgba(189, 147, 249, 0.8); + transition: border-color 0.25s linear; } + .workspaces .active { + border: 2px solid #50fa7b; + transition: border-color 0.25s linear; } + +.sys-tray { + padding: 5px; + background-color: rgba(40, 42, 54, 0.8); + color: #CBA6F7; + border-radius: 80px; + border: 2px solid rgba(56, 44, 74, 0.8); + transition: background-color 0.5s ease-in-out, border 0.5s ease-in-out; } + .sys-tray .tray-item { + all: unset; + padding: 0px 2px 0px 2px; + font-size: 25px; + border-radius: 100%; + transition: background-color 0.5s ease-in-out, border 0.5s ease-in-out; } + .sys-tray .tray-item:hover { + background: rgba(127, 132, 156, 0.4); + border-radius: 100%; + transition: background-color 0.5s ease-in-out, border 0.5s ease-in-out; } + .sys-tray menu { + background: #282a36; + padding-top: 5px; + padding-bottom: 5px; + border: 2px solid #1b1b1b; + border-radius: 10px; } + .sys-tray menu check { + color: white; + margin-left: 2px; + margin-right: 5px; + min-height: 20px; + min-width: 20px; + -gtk-icon-source: -gtk-icontheme("checkbox-symbolic"); } + .sys-tray menu check:checked { + -gtk-icon-source: -gtk-icontheme("checkbox-checked-symbolic"); } + .sys-tray menuitem:not(.tray-item) { + padding: 5px; + transition: all 0.2s ease-in-out; } + .sys-tray menuitem:not(.tray-item):hover { + background: #1b1b1b; } + +.notification-center { + min-height: 700px; + min-width: 524px; + background: rgba(40, 42, 54, 0.8); + border-radius: 30px; + border-top-right-radius: 0px; + border: 2px solid rgba(189, 147, 249, 0.8); + padding: 0px; + box-shadow: 0 0 4.5px 0 rgba(0, 0, 0, 0.6); } + .notification-center * { + font-size: 16px; } + .notification-center .header { + padding: 10px; + margin-top: 22px; + margin-bottom: 9px; } + .notification-center .header label { + font-size: 22px; } + .notification-center .header button { + all: unset; + transition: 200ms; + border-radius: 9px; + color: #eee; + background-color: #664C90; + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + padding: 4.5px 9px; } + .notification-center .header button:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-color: rgba(238, 238, 238, 0.154); + color: #f1f1f1; } + .notification-center .header button:disabled { + box-shadow: none; + background-color: rgba(102, 76, 144, 0.3); + color: rgba(238, 238, 238, 0.3); } + .notification-center .header button label { + font-size: 1.2em; } + .notification-center .notification-list-box { + background: #282a36; + padding: 0 12px 0 12px; + border-radius: 30px; + border-top: 2px solid rgba(189, 147, 249, 0.8); + box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.5); } + .notification-center .notification-list-box scrollbar { + all: unset; + border-radius: 8px; + border-top-left-radius: 0; + border-bottom-left-radius: 0; } + .notification-center .notification-list-box scrollbar * { + all: unset; } + .notification-center .notification-list-box scrollbar:hover { + border-radius: 8px; + border-top-left-radius: 0; + border-bottom-left-radius: 0; } + .notification-center .notification-list-box scrollbar.vertical { + transition: 200ms; + background-color: rgba(23, 23, 23, 0.3); } + .notification-center .notification-list-box scrollbar.vertical:hover { + background-color: rgba(23, 23, 23, 0.7); } + .notification-center .notification-list-box scrollbar.vertical:hover slider { + background-color: rgba(238, 238, 238, 0.7); + min-width: .6em; } + .notification-center .notification-list-box scrollbar.vertical slider { + background-color: rgba(238, 238, 238, 0.5); + border-radius: 9px; + min-width: .4em; + min-height: 2em; + transition: 200ms; } + .notification-center .placeholder { + color: white; } + .notification-center .placeholder image { + font-size: 7em; + text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6); + -gtk-icon-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6); } + .notification-center .placeholder label { + font-size: 1.2em; + text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6); + -gtk-icon-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6); } + +.notification.critical > box { + box-shadow: inset 0 0 0.5em 0 #e67090; } + +.notification > box { + all: unset; + box-shadow: 0 0 4.5px 0 rgba(0, 0, 0, 0.4); + margin: 9px 9px 0 9px; + border: 2px solid rgba(189, 147, 249, 0.8); + border-radius: 15px; + background-color: rgba(40, 42, 54, 0.8); + padding: 16.2px; } + .notification > box * { + font-size: 16px; } + +.notification:hover .close-button { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-color: rgba(238, 238, 238, 0.154); + background-color: rgba(230, 112, 144, 0.5); } + +.notification .title { + margin-right: 9px; + font-size: 1.1em; } + +.notification .description { + font-size: .9em; + min-width: 350px; } + +.notification .icon { + border-radius: 7.2px; + margin-right: 9px; } + +.notification .icon.img { + border: 1px solid rgba(238, 238, 238, 0.03); } + +.notification .actions button { + all: unset; + transition: all 500ms; + border-radius: 9px; + background-color: rgba(238, 238, 238, 0.06); + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + border-radius: 7.2px; + font-size: 1.2em; + padding: 4.5px 9px; + margin: 9px 4.5px 0; } + .notification .actions button * { + font-size: 16px; } + .notification .actions button:focus { + box-shadow: inset 0 0 0 1px #51a4e7; + background-color: rgba(238, 238, 238, 0.154); } + .notification .actions button:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-color: rgba(238, 238, 238, 0.154); } + .notification .actions button:active { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-image: linear-gradient(to right, #51a4e7, #6cb2eb); + background-color: #51a4e7; } + .notification .actions button:active:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154); } + .notification .actions button:checked { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-image: linear-gradient(to right, #51a4e7, #6cb2eb); + background-color: #51a4e7; } + .notification .actions button:checked:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154); } + .notification .actions button:disabled { + box-shadow: none; + background-color: transparent; } + .notification .actions button:first-child { + margin-left: 0; } + .notification .actions button:last-child { + margin-right: 0; } + +.notification .actions button.on { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-image: linear-gradient(to right, #51a4e7, #6cb2eb); + background-color: #51a4e7; } + .notification .actions button.on:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154); } + +.notification .actions button.active { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-image: linear-gradient(to right, #51a4e7, #6cb2eb); + background-color: #51a4e7; } + .notification .actions button.active:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154); } + +.notification button.close-button { + all: unset; + transition: all 500ms; + border-radius: 9px; + background-color: transparent; + background-image: none; + box-shadow: none; + margin-left: 9px; + border-radius: 7.2px; + min-width: 1.2em; + min-height: 1.2em; } + .notification button.close-button * { + font-size: 16px; } + .notification button.close-button:focus { + box-shadow: inset 0 0 0 1px #51a4e7; + background-color: rgba(238, 238, 238, 0.154); } + .notification button.close-button:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-color: rgba(238, 238, 238, 0.154); + background-color: rgba(230, 112, 144, 0.5); } + .notification button.close-button:active { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-image: linear-gradient(to right, #51a4e7, #6cb2eb); + background-color: #51a4e7; + background-image: linear-gradient(#e67090, #e67090); } + .notification button.close-button:active:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154); } + .notification button.close-button:checked { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-image: linear-gradient(to right, #51a4e7, #6cb2eb); + background-color: #51a4e7; } + .notification button.close-button:checked:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154); } + .notification button.close-button:disabled { + box-shadow: none; + background-color: transparent; } + +.notification button.close-button.on { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-image: linear-gradient(to right, #51a4e7, #6cb2eb); + background-color: #51a4e7; } + .notification button.close-button.on:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154); } + +.notification button.close-button.active { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + background-image: linear-gradient(to right, #51a4e7, #6cb2eb); + background-color: #51a4e7; } + .notification button.close-button.active:hover { + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154); } + +.date { + background-color: rgba(40, 42, 54, 0.8); + color: #a5b6cf; + border-radius: 30px; + border-top-right-radius: 0px; + border: 2px solid rgba(189, 147, 249, 0.8); } + +.timebox { + margin: 30px 0px; } + .timebox .time-container .content { + font-family: Product Sans; + font-weight: bolder; + font-size: 60px; } + .timebox .time-container .divider { + margin: 8px 15px; + padding: 0px 1px; + background: linear-gradient(#dd6777, #c296eb, #86aaec, #93cee9); } + .timebox .date-container { + font-family: Product Sans; + margin-top: 2px; } + +.cal-box { + font-family: Product Sans; + border-radius: 30px; + padding: 0 1rem .2rem; + color: #a5b6cf; + background-color: #282a36; + border-bottom: 2px solid rgba(189, 147, 249, 0.8); + border-top: 2px solid rgba(189, 147, 249, 0.8); + margin: 0px 12px 18px 12px; } + .cal-box .cal { + font-size: 20px; + background-color: inherit; + padding: .5rem .10rem 0rem; + margin-left: 10px; + border-radius: 30px; } + .cal-box .cal > * { + border: solid 0px transparent; } + .cal-box .cal.highlight { + padding: 10rem; } + +calendar:selected { + color: #93cee9; } + +calendar.header { + color: #93cee9; + font-weight: bold; } + +calendar.button { + color: #93cee9; } + +calendar.highlight { + color: #90ceaa; + font-weight: bold; } + +calendar:indeterminate { + color: #262831; } + +.quick-settings { + font-size: 30px; + min-width: 500px; + padding: 0px 0px 0px 0px; + background-color: rgba(40, 42, 54, 0.8); + border-radius: 30px 0 30px 30px; + border: 2px solid rgba(189, 147, 249, 0.8); } + +.title { + font-size: 22px; + margin-top: 30px; } + +.grid-label { + font-size: 30px; + margin-left: 15px; + margin-right: 10px; + min-width: 50px; } + +.sub-label { + font-size: 14px; + margin-top: -10px; + margin-left: 31px; + margin-bottom: 10px; + padding: 3px; + border: 2px solid rgba(189, 147, 249, 0.8); + border-top-right-radius: 20px; + border-top-left-radius: 10px; + border-bottom-left-radius: 10px; + border-bottom-right-radius: 20px; + min-width: 106px; + background: #1b1b1b; } + .sub-label:nth-child(1) { + margin-left: 25px; } + +.grid-chev { + margin-left: 0px; + font-size: 40px; + margin-right: 5px; } + +.button-grid { + font-size: 10px; + min-height: 160px; + min-width: 470px; + background-color: #282a36; + border-top: 2px solid rgba(189, 147, 249, 0.8); + border-bottom: 2px solid rgba(189, 147, 249, 0.8); + border-radius: 15px; + margin-top: 30px; } + +.button-row { + min-height: 70px; + min-width: 450px; + margin-left: 20px; } + +.grid-button { + min-height: 65px; + min-width: 70px; + margin: 5px; + margin-left: 22px; } + .grid-button:nth-child(1) { + margin-left: 5px; } + +.left-part { + background: #1b1b1b; + border-top-left-radius: 15px; + border-bottom-left-radius: 15px; + border-left: 2px solid rgba(189, 147, 249, 0.8); + border-top: 2px solid rgba(189, 147, 249, 0.8); + border-bottom: 2px solid rgba(189, 147, 249, 0.8); + transition: all 0.5s ease-in-out; } + +.right-part { + background: #1b1b1b; + border-top-right-radius: 30px; + border-bottom-right-radius: 30px; + border-right: 2px solid rgba(189, 147, 249, 0.8); + border-top: 2px solid rgba(189, 147, 249, 0.8); + border-bottom: 2px solid rgba(189, 147, 249, 0.8); + transition: all 0.5s ease-in-out; } + +.right-part:hover, .right-part:active { + color: rgba(189, 147, 249, 0.8); + border: 2px solid rgba(189, 147, 249, 0.8); + border-top-left-radius: 7px; + border-bottom-left-radius: 7px; + transition: all 0.5s ease-in-out; } + +.left-part:hover, .left-part:active { + color: rgba(189, 147, 249, 0.8); + border: 2px solid rgba(189, 147, 249, 0.8); + border-top-right-radius: 7px; + border-bottom-right-radius: 7px; + transition: all 0.5s ease-in-out; } + +.player { + margin-top: 6px; + min-height: 220px; + opacity: 0; } + +.slider-box { + min-height: 100px; + min-width: 470px; + background-color: #282a36; + border-top: 2px solid rgba(189, 147, 249, 0.8); + border-bottom: 2px solid rgba(189, 147, 249, 0.8); + border-radius: 15px; + margin-top: 30px; + margin-bottom: 20px; } + .slider-box .slider-label { + font-size: 30px; + min-width: 30px; } + .slider-box scale { + min-height: 55px; + min-width: 400px; + margin-left: 18px; + margin-right: 20px; } + .slider-box scale highlight { + margin: 0px; + background-color: #79659f; + border-radius: 2em; } + .slider-box scale trough { + background-color: #363847; + border-radius: 2em; } + .slider-box scale slider { + margin: -4px; + min-width: 20px; + min-height: 20px; + background: #3e4153; + border-radius: 100%; + box-shadow: rgba(0, 0, 0, 0.25) 0px 54px 55px, rgba(0, 0, 0, 0.12) 0px -12px 30px, rgba(0, 0, 0, 0.12) 0px 4px 6px, rgba(0, 0, 0, 0.17) 0px 12px 13px, rgba(0, 0, 0, 0.09) 0px -3px 5px; + transition: background-color 0.5s ease-in-out; } + .slider-box scale slider:hover { + background-color: #303240; + transition: background-color 0.5s ease-in-out; } + +.arrow { + transition: -gtk-icon-transform 0.3s ease-in-out; + margin-bottom: 12px; } + +.media { + margin-top: 9px; } + +.player { + all: unset; + padding: 10px; + min-width: 400px; + min-height: 200px; + border-radius: 30px; + border-top: 2px solid rgba(189, 147, 249, 0.8); + border-bottom: 2px solid rgba(189, 147, 249, 0.8); + transition: background 250ms; } + .player .top { + font-size: 23px; } + .player .metadata .title { + font-weight: 500; + transition: text 250ms; } + .player .metadata .artist { + font-weight: 400; + font-size: 15px; + transition: text 250ms; } + .player .bottom { + font-size: 30px; } + .player .pausebutton { + transition: background-color ease .2s, color ease .2s; + font-size: 15px; + padding: 4px 4px 4px 7px; } + .player .playing { + transition: background-color ease .2s, color ease .2s; + border-radius: 15px; } + .player .stopped, + .player .paused { + transition: background-color ease .2s, color ease .2s; + border-radius: 26px; + padding: 4px 4px 4px 10px; } + .player button label { + min-width: 35px; } + +.position-indicator { + min-width: 18px; + margin: 7px; + background-color: rgba(255, 255, 255, 0.7); + box-shadow: 0 0 5px 0px rgba(255, 255, 255, 0.3); + border-radius: 100%; } + +.previous, +.next, +.shuffle, +.loop { + border-radius: 100%; + transition: color 200ms; } + .previous:hover, + .next:hover, + .shuffle:hover, + .loop:hover { + border-radius: 100%; + background-color: rgba(127, 132, 156, 0.4); + transition: color 200ms; } + +.loop label { + padding-right: 8px; } + +.position-slider highlight { + margin: 0px; + border-radius: 2em; } + +.position-slider trough { + margin: 0 8px; + border-radius: 2em; } + +.position-slider slider { + margin: -8px; + min-height: 20px; + border-radius: 10px; + box-shadow: rgba(0, 0, 0, 0.25) 0px 54px 55px, rgba(0, 0, 0, 0.12) 0px -12px 30px, rgba(0, 0, 0, 0.12) 0px 4px 6px, rgba(0, 0, 0, 0.17) 0px 12px 13px, rgba(0, 0, 0, 0.09) 0px -3px 5px; + transition: background-color 0.5s ease-in-out; } + +.position-slider slider:hover { + transition: background-color 0.5s ease-in-out; } + +.overview .workspace { + padding: 4px 15px 4px 0px; + border: 2px solid transparent; + border-radius: 10px; } + .overview .workspace.active { + background-color: rgba(38, 38, 38, 0.8); + border: 2px solid black; } + +.overview .workspace .window { + background-color: #282a36; + border-radius: 10px; + margin: 0 10px; + transition: min-width 0.2s ease-in-out, min-height 0.2s ease-in-out, border-color 0.2s ease-in-out, font-size 0.2s ease-in-out; } + +.overview .normal { + margin-bottom: 5px; } + .overview .normal .workspace .window { + border: 2px solid #411C6C; } + .overview .normal .workspace .window.active { + border: 2px solid purple; } + +.overview .special .workspace .window { + border: 2px solid #333333; } + .overview .special .workspace .window.active { + border: 2px solid purple; } + +.applauncher { + all: unset; + box-shadow: 0 0 4.5px 0 rgba(0, 0, 0, 0.6); + margin: 9px; + border: 2px solid rgba(189, 147, 249, 0.8); + border-radius: 25px; + background-color: rgba(40, 42, 54, 0.8); + color: #f8f8f2; + padding: 16.2px; } + .applauncher * { + font-size: 16px; } + .applauncher .header { + margin: 16.2px; + margin-bottom: 0; } + .applauncher .header image, .applauncher .header entry { + all: unset; + border-radius: 9px; + color: #f8f8f2; + background-color: rgba(68, 71, 90, 0.6); + border: 1px solid #44475a; + padding: 4.5px; } + .applauncher .header image { + margin-right: 9px; + -gtk-icon-transform: scale(0.8); + font-size: 25.6px; } + .applauncher scrolledwindow { + padding: 16.2px; + min-width: 700px; + min-height: 450px; } + .applauncher scrolledwindow scrollbar, .applauncher scrolledwindow scrollbar * { + all: unset; } + .applauncher scrolledwindow scrollbar.vertical { + transition: 200ms; + background-color: rgba(23, 23, 23, 0.3); } + .applauncher scrolledwindow scrollbar.vertical:hover { + background-color: rgba(23, 23, 23, 0.7); } + .applauncher scrolledwindow scrollbar.vertical:hover slider { + background-color: rgba(238, 238, 238, 0.7); + min-width: .6em; } + .applauncher scrolledwindow scrollbar.vertical slider { + background-color: rgba(238, 238, 238, 0.5); + border-radius: 9px; + min-width: .4em; + min-height: 2em; + transition: 200ms; } + .applauncher .placeholder { + margin-top: 9px; + color: #f8f8f2; + font-size: 1.2em; } + .applauncher .app { + all: unset; + transition: 200ms; + padding: 9px; } + .applauncher .app:active { + background-color: rgba(189, 147, 249, 0.5); + border-radius: 9px; + box-shadow: inset 0 0 0 3px rgba(238, 238, 238, 0.03); } + .applauncher .app:active .title { + color: #f8f8f2; } + .applauncher .app:hover .title, .applauncher .app:focus .title { + color: rgba(189, 147, 249, 0.8); } + .applauncher .app:hover image, .applauncher .app:focus image { + -gtk-icon-shadow: 2px 2px rgba(189, 147, 249, 0.8); } + .applauncher .app label { + transition: 200ms; } + .applauncher .app label.title { + color: #f8f8f2; } + .applauncher .app label.description { + color: rgba(238, 238, 238, 0.7); } + .applauncher .app image { + transition: 200ms; + margin-right: 9px; } diff --git a/config/discord/settings.json b/config/discord/settings.json new file mode 100644 index 00000000..39e6e03f --- /dev/null +++ b/config/discord/settings.json @@ -0,0 +1,11 @@ +{ + "SKIP_HOST_UPDATE": true, + "IS_MAXIMIZED": false, + "IS_MINIMIZED": false, + "WINDOW_BOUNDS": { + "x": 7, + "y": 57, + "width": 1906, + "height": 1136 + } +} \ No newline at end of file diff --git a/modules/desktop/environment/config/dolphinrc b/config/dolphinrc similarity index 87% rename from modules/desktop/environment/config/dolphinrc rename to config/dolphinrc index dbf5dd3e..edd21d11 100644 --- a/modules/desktop/environment/config/dolphinrc +++ b/config/dolphinrc @@ -9,7 +9,7 @@ Version=202 ViewPropsTimestamp=2023,5,12,19,59,9.33 [Icons] -Theme=Flat-Remix-Violet-Dark +Theme=Adwaita:dark [KFileDialog Settings] Places Icons Auto-resize=false @@ -19,16 +19,13 @@ Places Icons Static Size=22 1920x1200 screen: Height=567 1920x1200 screen: Width=604 1920x1200 screen: Window-Maximized=true -3 screens: Window-Maximized=true [MainWindow] MenuBar=Disabled +ToolBarsMovable=Disabled [PreviewSettings] Plugins=comicbookthumbnail,ebookthumbnail,imagethumbnail,jpegthumbnail,windowsexethumbnail,windowsimagethumbnail,svgthumbnail,textthumbnail [ViewPropertiesDialog] 1920x1200 screen: Window-Maximized=true - -[UiSettings] -ColorScheme=* diff --git a/config/gtklock/config.ini b/config/gtklock/config.ini new file mode 100644 index 00000000..186da3f9 --- /dev/null +++ b/config/gtklock/config.ini @@ -0,0 +1,4 @@ +[main] +modules=/nix/var/nix/profiles/system/sw/lib/gtklock/powerbar-module.so;/nix/var/nix/profiles/system/sw/lib/gtklock/playerctl-module.so + +#;/nix/var/nix/profiles/system/sw/lib/gtklock/userinfo-module.so diff --git a/config/gtklock/scripts/blur.sh b/config/gtklock/scripts/blur.sh new file mode 100755 index 00000000..517ede0a --- /dev/null +++ b/config/gtklock/scripts/blur.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +grim -t jpeg /tmp/image.jpeg +convert /tmp/image.jpeg -blur 0x8 /tmp/image.jpeg + diff --git a/config/gtklock/scripts/lock.sh b/config/gtklock/scripts/lock.sh new file mode 100755 index 00000000..a2bbcf8b --- /dev/null +++ b/config/gtklock/scripts/lock.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +$AGS_PATH/tablet-toggle.sh laptop & +$LOCK_PATH/blur.sh +gtklock diff --git a/config/gtklock/style.css b/config/gtklock/style.css new file mode 100644 index 00000000..1e255785 --- /dev/null +++ b/config/gtklock/style.css @@ -0,0 +1,17 @@ +@define-color accent rgba(189, 147, 249, 0.8); +@define-color background rgb(40, 42, 54); + +window { + background-image: url("/tmp/image.jpeg"); + background-size: cover; + background-repeat: no-repeat; + background-position: center; + background-color: rgba(0, 0, 0, 0); +} + +#window-box { + padding: 64px; + border: 2px solid @accent; + border-radius: 30px; + background-color: @background; +} diff --git a/config/hypr/hyprpaper.conf b/config/hypr/hyprpaper.conf new file mode 100644 index 00000000..d37a22fa --- /dev/null +++ b/config/hypr/hyprpaper.conf @@ -0,0 +1,2 @@ +preload = ~/Pictures/BG/bonzai.jpg +wallpaper = eDP-1, ~/Pictures/BG/bonzai.jpg diff --git a/config/hypr/main.conf b/config/hypr/main.conf new file mode 100644 index 00000000..3d41bc31 --- /dev/null +++ b/config/hypr/main.conf @@ -0,0 +1,234 @@ +# Plugins +plugin { + touch_gestures { + # default sensitivity is probably too low on tablet screens, + # I recommend turning it up to 4.0 + sensitivity = 20.0 + } +} + +# See https://wiki.hyprland.org/Configuring/Monitors/ +monitor=eDP-1,1920x1200@60,0x0,1 + +exec-once = $HYPR_PATH/lisgd.sh & + +# See https://wiki.hyprland.org/Configuring/Keywords/ for more + +# Execute your favorite apps at launch +exec-once = bash -c "sleep 3; XDG_DATA_DIRS=$kora nm-applet" +exec-once = bash -c "sleep 4; blueberry-tray" +exec-once = bash -c "sleep 5; nextcloud --background" + +exec-once = XDG_DATA_DIRS=$kora ags + +exec-once = gnome-keyring-daemon --start --components=secrets +exec-once = squeekboard + +exec-once = bash -c "sleep 1; ags -t applauncher" +exec-once = hyprpaper + +exec-once = wl-paste --watch cliphist store + +# OSD window +exec-once = swayosd-server + +# Change HandleLidSwitch to lock in logind.conf +exec-once = swayidle -w lock $LOCK_PATH/lock.sh + +# Special window apps +exec-once = thunderbird & sleep 5; hyprctl dispatch movetoworkspacesilent special:thunder,"^(thunderbird)$" +exec-once = spotify & sleep 5; hyprctl dispatch movetoworkspacesilent special:spot,"^(Spotify)$" + +# Some default env vars. +env = XCURSOR_SIZE,24 + +# For all categories, see https://wiki.hyprland.org/Configuring/Variables/ +input { + kb_layout = ca + kb_variant = multix + kb_model = + kb_options = + kb_rules = + + follow_mouse = 1 + + touchpad { + natural_scroll = yes + } + + sensitivity = 0 # -1.0 - 1.0, 0 means no modification. +} + +general { + # See https://wiki.hyprland.org/Configuring/Variables/ for more + + gaps_in = 5 + gaps_out = 5 + border_size = 2 + col.active_border = rgb(411C6C) + #col.active_border = rgba(33ccffee) rgba(00ff99ee) 45deg + col.inactive_border = rgba(595959aa) + + layout = dwindle +} + +misc { + disable_hyprland_logo = true + disable_splash_rendering = true + vfr = true +} + +decoration { + # See https://wiki.hyprland.org/Configuring/Variables/ for more + + rounding = 20 + + blur { + enabled = true + size = 3 + passes = 1 + } + + drop_shadow = false + #shadow_range = 4 + #shadow_render_power = 3 + #col.shadow = rgba(1a1a1aee) +} + +animations { + enabled = yes + + # Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more + + bezier = myBezier, 0.05, 0.9, 0.1, 1.05 + + animation = windows, 1, 7, myBezier + animation = windowsOut, 1, 7, default, popin 80% + animation = border, 1, 10, default + animation = borderangle, 1, 8, default + animation = fade, 1, 7, default + animation = workspaces, 1, 6, default +} + +dwindle { + # See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more + pseudotile = yes # master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below + preserve_split = yes # you probably want this +} + +master { + # See https://wiki.hyprland.org/Configuring/Master-Layout/ for more + new_is_master = true +} + +gestures { + # See https://wiki.hyprland.org/Configuring/Variables/ for more + workspace_swipe = yes + workspace_swipe_fingers = 3 + workspace_swipe_cancel_ratio = 0.15 + #workspace_swipe_forever = yes +} + +# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more + +windowrule = noborder,^(wofi)$ +windowrule = workspace special silent,^(Spotify)$ +windowrule = workspace special silent,^(thunderbird)$ + +windowrule = float,^(org.kde.polkit-kde-authentication-agent-1)$ +windowrule = size 741 288,^(org.kde.polkit-kde-authentication-agent-1)$ +windowrule = center,^(org.kde.polkit-kde-authentication-agent-1)$ + +windowrule = size 741 288,^(org.kde.ksshaskpass)$ +windowrule = move cursor -370 -144,^(org.kde.ksshaskpass)$ + +windowrule = float,^(org.gnome.Calculator)$ + +windowrule = size 1231 950,title:^(Open Folder)$ +windowrule = float,title:^(Open Folder)$ + +windowrule = size 1231 950,title:^(Open File)$ +windowrule = float,title:^(Open File)$ + +windowrule = float,^(com.nextcloud.desktopclient.nextcloud)$ +windowrule = move cursor -15 -10,^(com.nextcloud.desktopclient.nextcloud)$ +windowrule = size 400 581,^(com.nextcloud.desktopclient.nextcloud)$ + +windowrule = tile,^(photoshop.exe)$ + +# See https://wiki.hyprland.org/Configuring/Keywords/ for more +$mainMod = SUPER + +bind = SUPER, F, fullscreen + +bind = $mainMod, V, exec, cliphist list | wofi --dmenu | cliphist decode | wl-copy + +# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more +bind = $mainMod, Q, exec, alacritty +bind = $mainMod, S, togglespecialworkspace, spot +bind = $mainMod, T, togglespecialworkspace, thunder +bind = $mainMod, C, killactive, + +bind = $mainMod, L, exec, $LOCK_PATH/lock.sh +bind = $mainMod SHIFT, E, exec, ags run-js 'ags.App.openWindow("powermenu")' +bindn =, Escape, exec, ags run-js 'ags.App.closeAll()' +bind = $mainMod SHIFT, SPACE, togglefloating, +bind = $mainMod, D, exec, ags -t applauncher +bind = $mainMod, P, pseudo, # dwindle +bind = $mainMod, J, togglesplit, # dwindle + +# Move focus with mainMod + arrow keys +bind = $mainMod, left, movefocus, l +bind = $mainMod, right, movefocus, r +bind = $mainMod, up, movefocus, u +bind = $mainMod, down, movefocus, d + +bind = ALT, Tab, exec, ags -t overview + +# Switch workspaces with mainMod + [0-9] +bind = $mainMod, 1, workspace, 1 +bind = $mainMod, 2, workspace, 2 +bind = $mainMod, 3, workspace, 3 +bind = $mainMod, 4, workspace, 4 +bind = $mainMod, 5, workspace, 5 +bind = $mainMod, 6, workspace, 6 +bind = $mainMod, 7, workspace, 7 +bind = $mainMod, 8, workspace, 8 +bind = $mainMod, 9, workspace, 9 +bind = $mainMod, 0, workspace, 10 + +# Move active window to a workspace with mainMod + SHIFT + [0-9] +bind = $mainMod SHIFT, 1, movetoworkspace, 1 +bind = $mainMod SHIFT, 2, movetoworkspace, 2 +bind = $mainMod SHIFT, 3, movetoworkspace, 3 +bind = $mainMod SHIFT, 4, movetoworkspace, 4 +bind = $mainMod SHIFT, 5, movetoworkspace, 5 +bind = $mainMod SHIFT, 6, movetoworkspace, 6 +bind = $mainMod SHIFT, 7, movetoworkspace, 7 +bind = $mainMod SHIFT, 8, movetoworkspace, 8 +bind = $mainMod SHIFT, 9, movetoworkspace, 9 +bind = $mainMod SHIFT, 0, movetoworkspace, 10 + +# Scroll through existing workspaces with mainMod + scroll +bind = $mainMod, mouse_down, workspace, e+1 +bind = $mainMod, mouse_up, workspace, e-1 + +# Move/resize windows with mainMod + LMB/RMB and dragging +bindm = $mainMod, mouse:272, movewindow +bindm = $mainMod, mouse:273, resizewindow + +# Take a screenshot +bind =, Print, exec, bash -c 'grim -g "$(slurp)" - | swappy -f -' +bind = $mainMod SHIFT, C, exec, wl-color-picker + +# Volume control +binde =, XF86AudioRaiseVolume, exec, swayosd-client --output-volume raise +binde =, XF86AudioLowerVolume, exec, swayosd-client --output-volume lower +bind =, XF86AudioMute, exec, swayosd-client --output-volume mute-toggle +bind =, XF86AudioMicMute, exec, swayosd-client --input-volume mute-toggle + +bindr = CAPS, Caps_Lock, exec, swayosd-client --caps-lock + +# Brightness control +binde =, XF86MonBrightnessUp, exec, swayosd-client --brightness 5 +binde =, XF86MonBrightnessDown, exec, swayosd-client --brightness -5 diff --git a/config/hypr/scripts/autorotate.sh b/config/hypr/scripts/autorotate.sh new file mode 100755 index 00000000..347b58b3 --- /dev/null +++ b/config/hypr/scripts/autorotate.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +# This script was forked from https://gitlab.com/snippets/1793649 by Fishonadish + + +SCREEN="eDP-1" +WAYLANDINPUT=("wacom-hid-52eb-finger" + "wacom-hid-52eb-pen") + + + +function rotate_ms { + if [[ $(hyprctl activewindow | grep Waydroid) == "" ]]; then + case $1 in + "normal") + rotate 0 + ;; + "right-up") + rotate 3 + ;; + "bottom-up") + rotate 2 + ;; + "left-up") + rotate 1 + ;; + esac + elif [[ $(hyprctl monitors | grep "transform: 0") == "" ]]; then + rotate 0 + fi +} + +function rotate { + TARGET_ORIENTATION=$1 + + echo "Rotating to" $TARGET_ORIENTATION + + hyprctl keyword monitor $SCREEN,transform,$TARGET_ORIENTATION + + for i in "${WAYLANDINPUT[@]}" + do + hyprctl keyword device:"$i":transform $TARGET_ORIENTATION + done + + $HYPR_PATH/lisgd.sh & +} + +while IFS='$\n' read -r line; do + rotation="$(echo $line | sed -En "s/^.*orientation changed: (.*)/\1/p")" + [[ ! -z $rotation ]] && rotate_ms $rotation +done < <(stdbuf -oL monitor-sensor) diff --git a/config/hypr/scripts/lisgd.sh b/config/hypr/scripts/lisgd.sh new file mode 100755 index 00000000..3d3cd1c5 --- /dev/null +++ b/config/hypr/scripts/lisgd.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +## https://www.reddit.com/r/swaywm/comments/ocec7k/comment/i93s0ma/ +## https://git.sr.ht/~mil/lisgd/tree/0.3.7/item/config.def.h + +function gestures { + lisgd -d /dev/input/by-path/platform-AMDI0010\:00-event -o 0 -t 125 -r 25 -m 3200 \ + -g "1,UD,B,*,R,bash -c 'busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b false'" \ + -g "1,DU,B,*,R,bash -c 'busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b true'" \ + -g "1,RL,R,*,R,bash -c 'hyprctl dispatch togglespecialworkspace spot'" \ + -g "1,LR,R,*,R,bash -c 'hyprctl dispatch togglespecialworkspace spot'" +} + +if pgrep lisgd ; then + killall -r lisgd + gestures +else + gestures +fi diff --git a/config/hypr/scripts/lose-focus.sh b/config/hypr/scripts/lose-focus.sh new file mode 100755 index 00000000..6cfec7d3 --- /dev/null +++ b/config/hypr/scripts/lose-focus.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +while true +do + while killall -0 .blueman-manage > /dev/null 2>&1 + do + if bluetoothctl show | grep Powered | grep -q yes; then + if [[ $(hyprctl activewindow | grep blueman-manager) == "" && $(hyprctl clients | grep blueman-manager) != "" ]]; then + killall .blueman-manage + break + fi + sleep 0.1 + fi + done + sleep 0.1 +done diff --git a/modules/desktop/environment/config/kdeglobals b/config/kdeglobals similarity index 84% rename from modules/desktop/environment/config/kdeglobals rename to config/kdeglobals index 719dadad..e3b20276 100644 --- a/modules/desktop/environment/config/kdeglobals +++ b/config/kdeglobals @@ -1,10 +1,10 @@ [General] -TerminalApplication=foot +TerminalApplication=alacritty [KFileDialog Settings] Allow Expansion=false Automatically select filename extension=true -Breadcrumb Navigation=false +Breadcrumb Navigation=true Decoration position=2 LocationCombo Completionmode=5 PathCombo Completionmode=5 @@ -13,7 +13,7 @@ Show Full Path=false Show Inline Previews=true Show Preview=false Show Speedbar=true -Show hidden files=true +Show hidden files=false Sort by=Name Sort directories first=true Sort hidden files last=false diff --git a/modules/desktop/environment/config/kiorc b/config/kiorc similarity index 100% rename from modules/desktop/environment/config/kiorc rename to config/kiorc diff --git a/config/mimeapps.list b/config/mimeapps.list new file mode 100644 index 00000000..6eef6e0f --- /dev/null +++ b/config/mimeapps.list @@ -0,0 +1,8 @@ +[Default Applications] +x-scheme-handler/mailto=userapp-Thunderbird-9ME591.desktop +message/rfc822=userapp-Thunderbird-9ME591.desktop +x-scheme-handler/mid=userapp-Thunderbird-9ME591.desktop + +[Added Associations] +x-scheme-handler/mailto=userapp-Thunderbird-9ME591.desktop; +x-scheme-handler/mid=userapp-Thunderbird-9ME591.desktop; diff --git a/config/neofetch/config.conf b/config/neofetch/config.conf new file mode 100644 index 00000000..8407209d --- /dev/null +++ b/config/neofetch/config.conf @@ -0,0 +1,880 @@ +# See this wiki page for more info: +# https://github.com/dylanaraps/neofetch/wiki/Customizing-Info +print_info() { + info title + info underline + + info "OS" distro + #info "Host" model + info "Kernel" kernel + #info "Uptime" uptime + info "Packages" packages + #info "Shell" shell + #info "Resolution" resolution + info "DE" de + #info "WM" wm + #info "WM Theme" wm_theme + #info "Theme" theme + #info "Icons" icons + #info "Terminal" term + #info "Terminal Font" term_font + info "CPU" cpu + info "GPU" gpu + info "Memory" memory + + # info "GPU Driver" gpu_driver # Linux/macOS only + # info "Disk" disk + # info "Battery" battery + # info "Font" font + # info "Song" song + # [[ "$player" ]] && prin "Music Player" "$player" + # info "Local IP" local_ip + # info "Public IP" public_ip + # info "Users" users + # info "Locale" locale # This only works on glibc systems. + + info cols +} + +# Title + + +# Hide/Show Fully qualified domain name. +# +# Default: 'off' +# Values: 'on', 'off' +# Flag: --title_fqdn +title_fqdn="off" + + +# Kernel + + +# Shorten the output of the kernel function. +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --kernel_shorthand +# Supports: Everything except *BSDs (except PacBSD and PC-BSD) +# +# Example: +# on: '4.8.9-1-ARCH' +# off: 'Linux 4.8.9-1-ARCH' +kernel_shorthand="on" + + +# Distro + + +# Shorten the output of the distro function +# +# Default: 'off' +# Values: 'on', 'tiny', 'off' +# Flag: --distro_shorthand +# Supports: Everything except Windows and Haiku +distro_shorthand="off" + +# Show/Hide OS Architecture. +# Show 'x86_64', 'x86' and etc in 'Distro:' output. +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --os_arch +# +# Example: +# on: 'Arch Linux x86_64' +# off: 'Arch Linux' +os_arch="on" + + +# Uptime + + +# Shorten the output of the uptime function +# +# Default: 'on' +# Values: 'on', 'tiny', 'off' +# Flag: --uptime_shorthand +# +# Example: +# on: '2 days, 10 hours, 3 mins' +# tiny: '2d 10h 3m' +# off: '2 days, 10 hours, 3 minutes' +uptime_shorthand="on" + + +# Memory + + +# Show memory percentage in output. +# +# Default: 'off' +# Values: 'on', 'off' +# Flag: --memory_percent +# +# Example: +# on: '1801MiB / 7881MiB (22%)' +# off: '1801MiB / 7881MiB' +memory_percent="off" + +# Change memory output unit. +# +# Default: 'mib' +# Values: 'kib', 'mib', 'gib' +# Flag: --memory_unit +# +# Example: +# kib '1020928KiB / 7117824KiB' +# mib '1042MiB / 6951MiB' +# gib: ' 0.98GiB / 6.79GiB' +memory_unit="mib" + + +# Packages + + +# Show/Hide Package Manager names. +# +# Default: 'tiny' +# Values: 'on', 'tiny' 'off' +# Flag: --package_managers +# +# Example: +# on: '998 (pacman), 8 (flatpak), 4 (snap)' +# tiny: '908 (pacman, flatpak, snap)' +# off: '908' +package_managers="on" + + +# Shell + + +# Show the path to $SHELL +# +# Default: 'off' +# Values: 'on', 'off' +# Flag: --shell_path +# +# Example: +# on: '/bin/bash' +# off: 'bash' +shell_path="off" + +# Show $SHELL version +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --shell_version +# +# Example: +# on: 'bash 4.4.5' +# off: 'bash' +shell_version="on" + + +# CPU + + +# CPU speed type +# +# Default: 'bios_limit' +# Values: 'scaling_cur_freq', 'scaling_min_freq', 'scaling_max_freq', 'bios_limit'. +# Flag: --speed_type +# Supports: Linux with 'cpufreq' +# NOTE: Any file in '/sys/devices/system/cpu/cpu0/cpufreq' can be used as a value. +speed_type="bios_limit" + +# CPU speed shorthand +# +# Default: 'off' +# Values: 'on', 'off'. +# Flag: --speed_shorthand +# NOTE: This flag is not supported in systems with CPU speed less than 1 GHz +# +# Example: +# on: 'i7-6500U (4) @ 3.1GHz' +# off: 'i7-6500U (4) @ 3.100GHz' +speed_shorthand="off" + +# Enable/Disable CPU brand in output. +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --cpu_brand +# +# Example: +# on: 'Intel i7-6500U' +# off: 'i7-6500U (4)' +cpu_brand="on" + +# CPU Speed +# Hide/Show CPU speed. +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --cpu_speed +# +# Example: +# on: 'Intel i7-6500U (4) @ 3.1GHz' +# off: 'Intel i7-6500U (4)' +cpu_speed="on" + +# CPU Cores +# Display CPU cores in output +# +# Default: 'logical' +# Values: 'logical', 'physical', 'off' +# Flag: --cpu_cores +# Support: 'physical' doesn't work on BSD. +# +# Example: +# logical: 'Intel i7-6500U (4) @ 3.1GHz' (All virtual cores) +# physical: 'Intel i7-6500U (2) @ 3.1GHz' (All physical cores) +# off: 'Intel i7-6500U @ 3.1GHz' +cpu_cores="logical" + +# CPU Temperature +# Hide/Show CPU temperature. +# Note the temperature is added to the regular CPU function. +# +# Default: 'off' +# Values: 'C', 'F', 'off' +# Flag: --cpu_temp +# Supports: Linux, BSD +# NOTE: For FreeBSD and NetBSD-based systems, you'll need to enable +# coretemp kernel module. This only supports newer Intel processors. +# +# Example: +# C: 'Intel i7-6500U (4) @ 3.1GHz [27.2°C]' +# F: 'Intel i7-6500U (4) @ 3.1GHz [82.0°F]' +# off: 'Intel i7-6500U (4) @ 3.1GHz' +cpu_temp="off" + + +# GPU + + +# Enable/Disable GPU Brand +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --gpu_brand +# +# Example: +# on: 'AMD HD 7950' +# off: 'HD 7950' +gpu_brand="on" + +# Which GPU to display +# +# Default: 'all' +# Values: 'all', 'dedicated', 'integrated' +# Flag: --gpu_type +# Supports: Linux +# +# Example: +# all: +# GPU1: AMD HD 7950 +# GPU2: Intel Integrated Graphics +# +# dedicated: +# GPU1: AMD HD 7950 +# +# integrated: +# GPU1: Intel Integrated Graphics +gpu_type="all" + + +# Resolution + + +# Display refresh rate next to each monitor +# Default: 'off' +# Values: 'on', 'off' +# Flag: --refresh_rate +# Supports: Doesn't work on Windows. +# +# Example: +# on: '1920x1080 @ 60Hz' +# off: '1920x1080' +refresh_rate="off" + + +# Gtk Theme / Icons / Font + + +# Shorten output of GTK Theme / Icons / Font +# +# Default: 'off' +# Values: 'on', 'off' +# Flag: --gtk_shorthand +# +# Example: +# on: 'Numix, Adwaita' +# off: 'Numix [GTK2], Adwaita [GTK3]' +gtk_shorthand="off" + + +# Enable/Disable gtk2 Theme / Icons / Font +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --gtk2 +# +# Example: +# on: 'Numix [GTK2], Adwaita [GTK3]' +# off: 'Adwaita [GTK3]' +gtk2="on" + +# Enable/Disable gtk3 Theme / Icons / Font +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --gtk3 +# +# Example: +# on: 'Numix [GTK2], Adwaita [GTK3]' +# off: 'Numix [GTK2]' +gtk3="on" + + +# IP Address + + +# Website to ping for the public IP +# +# Default: 'http://ident.me' +# Values: 'url' +# Flag: --ip_host +public_ip_host="http://ident.me" + +# Public IP timeout. +# +# Default: '2' +# Values: 'int' +# Flag: --ip_timeout +public_ip_timeout=2 + +# Local IP interface +# +# Default: 'auto' (interface of default route) +# Values: 'auto', 'en0', 'en1' +# Flag: --ip_interface +local_ip_interface=('auto') + + +# Desktop Environment + + +# Show Desktop Environment version +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --de_version +de_version="on" + + +# Disk + + +# Which disks to display. +# The values can be any /dev/sdXX, mount point or directory. +# NOTE: By default we only show the disk info for '/'. +# +# Default: '/' +# Values: '/', '/dev/sdXX', '/path/to/drive'. +# Flag: --disk_show +# +# Example: +# disk_show=('/' '/dev/sdb1'): +# 'Disk (/): 74G / 118G (66%)' +# 'Disk (/mnt/Videos): 823G / 893G (93%)' +# +# disk_show=('/'): +# 'Disk (/): 74G / 118G (66%)' +# +disk_show=('/') + +# Disk subtitle. +# What to append to the Disk subtitle. +# +# Default: 'mount' +# Values: 'mount', 'name', 'dir', 'none' +# Flag: --disk_subtitle +# +# Example: +# name: 'Disk (/dev/sda1): 74G / 118G (66%)' +# 'Disk (/dev/sdb2): 74G / 118G (66%)' +# +# mount: 'Disk (/): 74G / 118G (66%)' +# 'Disk (/mnt/Local Disk): 74G / 118G (66%)' +# 'Disk (/mnt/Videos): 74G / 118G (66%)' +# +# dir: 'Disk (/): 74G / 118G (66%)' +# 'Disk (Local Disk): 74G / 118G (66%)' +# 'Disk (Videos): 74G / 118G (66%)' +# +# none: 'Disk: 74G / 118G (66%)' +# 'Disk: 74G / 118G (66%)' +# 'Disk: 74G / 118G (66%)' +disk_subtitle="mount" + +# Disk percent. +# Show/Hide disk percent. +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --disk_percent +# +# Example: +# on: 'Disk (/): 74G / 118G (66%)' +# off: 'Disk (/): 74G / 118G' +disk_percent="on" + + +# Song + + +# Manually specify a music player. +# +# Default: 'auto' +# Values: 'auto', 'player-name' +# Flag: --music_player +# +# Available values for 'player-name': +# +# amarok +# audacious +# banshee +# bluemindo +# clementine +# cmus +# deadbeef +# deepin-music +# dragon +# elisa +# exaile +# gnome-music +# gmusicbrowser +# gogglesmm +# guayadeque +# io.elementary.music +# iTunes +# Music +# juk +# lollypop +# MellowPlayer +# mocp +# mopidy +# mpd +# muine +# netease-cloud-music +# olivia +# playerctl +# pogo +# pragha +# qmmp +# quodlibet +# rhythmbox +# sayonara +# smplayer +# spotify +# strawberry +# tauonmb +# tomahawk +# vlc +# xmms2d +# xnoise +# yarock +music_player="auto" + +# Format to display song information. +# +# Default: '%artist% - %album% - %title%' +# Values: '%artist%', '%album%', '%title%' +# Flag: --song_format +# +# Example: +# default: 'Song: Jet - Get Born - Sgt Major' +song_format="%artist% - %album% - %title%" + +# Print the Artist, Album and Title on separate lines +# +# Default: 'off' +# Values: 'on', 'off' +# Flag: --song_shorthand +# +# Example: +# on: 'Artist: The Fratellis' +# 'Album: Costello Music' +# 'Song: Chelsea Dagger' +# +# off: 'Song: The Fratellis - Costello Music - Chelsea Dagger' +song_shorthand="off" + +# 'mpc' arguments (specify a host, password etc). +# +# Default: '' +# Example: mpc_args=(-h HOST -P PASSWORD) +mpc_args=() + + +# Text Colors + + +# Text Colors +# +# Default: 'distro' +# Values: 'distro', 'num' 'num' 'num' 'num' 'num' 'num' +# Flag: --colors +# +# Each number represents a different part of the text in +# this order: 'title', '@', 'underline', 'subtitle', 'colon', 'info' +# +# Example: +# colors=(distro) - Text is colored based on Distro colors. +# colors=(4 6 1 8 8 6) - Text is colored in the order above. +colors=(distro) + + +# Text Options + + +# Toggle bold text +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --bold +bold="on" + +# Enable/Disable Underline +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --underline +underline_enabled="on" + +# Underline character +# +# Default: '-' +# Values: 'string' +# Flag: --underline_char +underline_char="-" + + +# Info Separator +# Replace the default separator with the specified string. +# +# Default: ':' +# Flag: --separator +# +# Example: +# separator="->": 'Shell-> bash' +# separator=" =": 'WM = dwm' +separator=":" + + +# Color Blocks + + +# Color block range +# The range of colors to print. +# +# Default: '0', '15' +# Values: 'num' +# Flag: --block_range +# +# Example: +# +# Display colors 0-7 in the blocks. (8 colors) +# neofetch --block_range 0 7 +# +# Display colors 0-15 in the blocks. (16 colors) +# neofetch --block_range 0 15 +block_range=(0 15) + +# Toggle color blocks +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --color_blocks +color_blocks="on" + +# Color block width in spaces +# +# Default: '3' +# Values: 'num' +# Flag: --block_width +block_width=3 + +# Color block height in lines +# +# Default: '1' +# Values: 'num' +# Flag: --block_height +block_height=1 + +# Color Alignment +# +# Default: 'auto' +# Values: 'auto', 'num' +# Flag: --col_offset +# +# Number specifies how far from the left side of the terminal (in spaces) to +# begin printing the columns, in case you want to e.g. center them under your +# text. +# Example: +# col_offset="auto" - Default behavior of neofetch +# col_offset=7 - Leave 7 spaces then print the colors +col_offset="auto" + +# Progress Bars + + +# Bar characters +# +# Default: '-', '=' +# Values: 'string', 'string' +# Flag: --bar_char +# +# Example: +# neofetch --bar_char 'elapsed' 'total' +# neofetch --bar_char '-' '=' +bar_char_elapsed="-" +bar_char_total="=" + +# Toggle Bar border +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --bar_border +bar_border="on" + +# Progress bar length in spaces +# Number of chars long to make the progress bars. +# +# Default: '15' +# Values: 'num' +# Flag: --bar_length +bar_length=15 + +# Progress bar colors +# When set to distro, uses your distro's logo colors. +# +# Default: 'distro', 'distro' +# Values: 'distro', 'num' +# Flag: --bar_colors +# +# Example: +# neofetch --bar_colors 3 4 +# neofetch --bar_colors distro 5 +bar_color_elapsed="distro" +bar_color_total="distro" + + +# Info display +# Display a bar with the info. +# +# Default: 'off' +# Values: 'bar', 'infobar', 'barinfo', 'off' +# Flags: --memory_display +# --battery_display +# --disk_display +# +# Example: +# bar: '[---=======]' +# infobar: 'info [---=======]' +# barinfo: '[---=======] info' +# off: 'info' +memory_display="off" +battery_display="off" +disk_display="off" + + +# Backend Settings + + +# Image backend. +# +# Default: 'ascii' +# Values: 'ascii', 'caca', 'catimg', 'chafa', 'jp2a', 'iterm2', 'off', +# 'pot', 'termpix', 'pixterm', 'tycat', 'w3m', 'kitty', 'ueberzug', +# 'viu' + +# Flag: --backend +image_backend="ascii" + +# Image Source +# +# Which image or ascii file to display. +# +# Default: 'auto' +# Values: 'auto', 'ascii', 'wallpaper', '/path/to/img', '/path/to/ascii', '/path/to/dir/' +# 'command output (neofetch --ascii "$(fortune | cowsay -W 30)")' +# Flag: --source +# +# NOTE: 'auto' will pick the best image source for whatever image backend is used. +# In ascii mode, distro ascii art will be used and in an image mode, your +# wallpaper will be used. +image_source="auto" + + +# Ascii Options + + +# Ascii distro +# Which distro's ascii art to display. +# +# Default: 'auto' +# Values: 'auto', 'distro_name' +# Flag: --ascii_distro +# NOTE: AIX, Hash, Alpine, AlterLinux, Amazon, Anarchy, Android, instantOS, +# Antergos, antiX, "AOSC OS", "AOSC OS/Retro", Apricity, ArchCraft, +# ArcoLinux, ArchBox, ARCHlabs, ArchStrike, XFerience, ArchMerge, Arch, +# Artix, Arya, Bedrock, Bitrig, BlackArch, BLAG, BlankOn, BlueLight, +# Bodhi, bonsai, BSD, BunsenLabs, Calculate, Carbs, CentOS, Chakra, ChaletOS, +# Chapeau, Chrom*, Cleanjaro, ClearOS, Clear_Linux, Clover, Condres, +# Container_Linux, Crystal Linux, CRUX, Cucumber, dahlia, Debian, Deepin, +# DesaOS, Devuan, DracOS, DarkOs, Itc, DragonFly, Drauger, Elementary, +# EndeavourOS, Endless, EuroLinux, Exherbo, Fedora, Feren, FreeBSD, +# FreeMiNT, Frugalware, Funtoo, GalliumOS, Garuda, Gentoo, Pentoo, +# gNewSense, GNOME, GNU, GoboLinux, Grombyang, Guix, Haiku, Huayra, HydroOS +# Hyperbola, iglunix, janus, Kali, KaOS, KDE_neon, Kibojoe, Kogaion, Korora, +# KSLinux, Kubuntu, LEDE, LaxerOS, LibreELEC, LFS, Linux_Lite, LMDE, +# Lubuntu, Lunar, macos, Mageia, MagpieOS, Mandriva, Manjaro, TeArch, Maui, +# Mer, Minix, LinuxMint, Live_Raizo, MX_Linux, Namib, Neptune, NetBSD, +# Netrunner, Nitrux, NixOS, Nurunner, NuTyX, OBRevenge, OpenBSD, +# openEuler, OpenIndiana, openmamba, OpenMandriva, OpenStage, OpenWrt, +# osmc, Oracle, OS Elbrus, PacBSD, Parabola, Pardus, Parrot, Parsix, +# TrueOS, PCLinuxOS, Pengwin, Peppermint, Pisi, popos, Porteus, PostMarketOS, +# Proxmox, PuffOS, Puppy, PureOS, Qubes, Qubyt, Quibian, Radix, Raspbian, +# Reborn_OS, Redstar, Redcore, Redhat, Refracted_Devuan, Regata, Regolith, +# Rocky, Rosa, sabotage, Sabayon, Sailfish, SalentOS, Scientific, Septor, +# SereneLinux, SharkLinux, Siduction, SkiffOS, Slackware, SliTaz, SmartOS, +# Solus, Source_Mage, Sparky, Star, SteamOS, SunOS, openSUSE_Leap, t2, +# openSUSE_Tumbleweed, openSUSE, SwagArch, Tails, Trisquel, +# Ubuntu-Cinnamon, Ubuntu-Budgie, Ubuntu-GNOME, Ubuntu-MATE, +# Ubuntu-Studio, Ubuntu, Univention, Venom, Void, VNux, LangitKetujuh, semc, +# Obarun, windows10, Windows7, Xubuntu, Zorin, and IRIX have ascii logos. +# NOTE: Arch, Ubuntu, Redhat, Fedora and Dragonfly have 'old' logo variants. +# Use '{distro name}_old' to use the old logos. +# NOTE: Ubuntu has flavor variants. +# Change this to Lubuntu, Kubuntu, Xubuntu, Ubuntu-GNOME, +# Ubuntu-Studio, Ubuntu-Mate or Ubuntu-Budgie to use the flavors. +# NOTE: Arcolinux, Dragonfly, Fedora, Alpine, Arch, Ubuntu, +# CRUX, Debian, Gentoo, FreeBSD, Mac, NixOS, OpenBSD, android, +# Artix, CentOS, Cleanjaro, ElementaryOS, GUIX, Hyperbola, +# Manjaro, MXLinux, NetBSD, Parabola, POP_OS, PureOS, +# Slackware, SunOS, LinuxLite, OpenSUSE, Raspbian, +# postmarketOS, and Void have a smaller logo variant. +# Use '{distro name}_small' to use the small variants. +ascii_distro="auto" + +# Ascii Colors +# +# Default: 'distro' +# Values: 'distro', 'num' 'num' 'num' 'num' 'num' 'num' +# Flag: --ascii_colors +# +# Example: +# ascii_colors=(distro) - Ascii is colored based on Distro colors. +# ascii_colors=(4 6 1 8 8 6) - Ascii is colored using these colors. +ascii_colors=(distro) + +# Bold ascii logo +# Whether or not to bold the ascii logo. +# +# Default: 'on' +# Values: 'on', 'off' +# Flag: --ascii_bold +ascii_bold="on" + + +# Image Options + + +# Image loop +# Setting this to on will make neofetch redraw the image constantly until +# Ctrl+C is pressed. This fixes display issues in some terminal emulators. +# +# Default: 'off' +# Values: 'on', 'off' +# Flag: --loop +image_loop="off" + +# Thumbnail directory +# +# Default: '~/.cache/thumbnails/neofetch' +# Values: 'dir' +thumbnail_dir="${XDG_CACHE_HOME:-${HOME}/.cache}/thumbnails/neofetch" + +# Crop mode +# +# Default: 'normal' +# Values: 'normal', 'fit', 'fill' +# Flag: --crop_mode +# +# See this wiki page to learn about the fit and fill options. +# https://github.com/dylanaraps/neofetch/wiki/What-is-Waifu-Crop%3F +crop_mode="normal" + +# Crop offset +# Note: Only affects 'normal' crop mode. +# +# Default: 'center' +# Values: 'northwest', 'north', 'northeast', 'west', 'center' +# 'east', 'southwest', 'south', 'southeast' +# Flag: --crop_offset +crop_offset="center" + +# Image size +# The image is half the terminal width by default. +# +# Default: 'auto' +# Values: 'auto', '00px', '00%', 'none' +# Flags: --image_size +# --size +image_size="auto" + +# Catimg block size. +# Control the resolution of catimg. +# +# Default: '2' +# Values: '1', '2' +# Flags: --catimg_size +catimg_size="2" + +# Gap between image and text +# +# Default: '3' +# Values: 'num', '-num' +# Flag: --gap +gap=3 + +# Image offsets +# Only works with the w3m backend. +# +# Default: '0' +# Values: 'px' +# Flags: --xoffset +# --yoffset +yoffset=0 +xoffset=0 + +# Image background color +# Only works with the w3m backend. +# +# Default: '' +# Values: 'color', 'blue' +# Flag: --bg_color +background_color= + + +# Misc Options + +# Stdout mode +# Turn off all colors and disables image backend (ASCII/Image). +# Useful for piping into another command. +# Default: 'off' +# Values: 'on', 'off' +stdout="off" diff --git a/config/nvim/base.vim b/config/nvim/base.vim new file mode 100644 index 00000000..df2f18e7 --- /dev/null +++ b/config/nvim/base.vim @@ -0,0 +1,33 @@ +" make tabs only 2 spaces +set tabstop=2 +set shiftwidth=2 +set expandtab +set smartindent + +set number +set relativenumber + +set undofile +set undodir=/home/matt/.cache/nvim/ + +" set dot icon in place of trailing whitespaces +set list listchars=tab:\ \ ,nbsp:␣,trail:•,extends:⟩,precedes:⟨ + +" use vscode keybinds for snippets completion +inoremap <silent><expr> <TAB> + \ coc#pum#visible() ? coc#_select_confirm() : + \ coc#expandableOrJumpable() ? "\<C-r>=coc#rpc#request('doKeymap', ['snippets-expand-jump',''])\<CR>" : + \ CheckBackspace() ? "\<TAB>" : + \ coc#refresh() + +function! CheckBackspace() abort + let col = col('.') - 1 + return !col || getline('.')[col - 1] =~# '\s' +endfunction + +let g:coc_snippet_next = '<tab>' + +" support scss @ +autocmd FileType scss setl iskeyword+=@-@ + +nnoremap <silent> <esc> :noh<cr><esc> diff --git a/config/nvim/config.lua b/config/nvim/config.lua new file mode 100644 index 00000000..d8a7ee5b --- /dev/null +++ b/config/nvim/config.lua @@ -0,0 +1,9 @@ +vim.opt.fillchars = {eob = " "} +vim.cmd[[colorscheme dracula]] + +-- https://github.com/AstroNvim/AstroNvim/issues/648#issuecomment-1511728897 + +vim.g.loaded_netrw = 0 +vim.g.loaded_netrwPlugin = 0 + +-- https://github.com/nvim-neo-tree/neo-tree.nvim/issues/983#issuecomment-1637372234 diff --git a/config/nvim/lsp.lua b/config/nvim/lsp.lua new file mode 100644 index 00000000..51f7bc40 --- /dev/null +++ b/config/nvim/lsp.lua @@ -0,0 +1,59 @@ +require'nvim-treesitter.configs'.setup { + highlight = { + enable = true, + -- Setting this to true will run `:h syntax` and tree-sitter at the same time. + -- Set this to `true` if you depend on 'syntax' being enabled (like for indentation). + -- Using this option may slow down your editor, and you may see some duplicate highlights. + -- Instead of true it can also be a list of languages + additional_vim_regex_highlighting = false, + }, +} + +require('gitsigns').setup() +require('lualine').setup { + options = { + theme = 'dracula', + globalstatus = true + } +} +require("neo-tree").setup({ + close_if_last_window = true, + window = { + width = 30, + }, + filesystem = { + filtered_items = { + visible = false, -- when true, they will just be displayed differently than normal items + hide_dotfiles = false, + hide_gitignored = true, + hide_by_name = {}, + hide_by_pattern = {}, + always_show = {}, + never_show = {}, + never_show_by_pattern = {}, + }, + }, + follow_current_file = { + enabled = true, + leave_dirs_open = true, + } +}) +require('todo-comments').setup() +require("scrollbar").setup() + +-- Auto indent when pressing Enter between brackets +local remap = vim.api.nvim_set_keymap +local npairs = require('nvim-autopairs') +npairs.setup({map_cr=false}) + +_G.MUtils= {} + +MUtils.completion_confirm=function() + if vim.fn["coc#pum#visible"]() ~= 0 then + return vim.fn["coc#pum#confirm"]() + else + return npairs.autopairs_cr() + end +end + +remap('i' , '<CR>','v:lua.MUtils.completion_confirm()', {expr = true , noremap = true}) diff --git a/config/ripgrep/README.md b/config/ripgrep/README.md new file mode 100644 index 00000000..9500162a --- /dev/null +++ b/config/ripgrep/README.md @@ -0,0 +1 @@ +This empty config is to prevent the error message when running ripgrep without config diff --git a/homeManagerModules/neovim/.luarc.json b/config/ripgrep/ripgreprc similarity index 100% rename from homeManagerModules/neovim/.luarc.json rename to config/ripgrep/ripgreprc diff --git a/config/swappy/config b/config/swappy/config new file mode 100644 index 00000000..05702a4d --- /dev/null +++ b/config/swappy/config @@ -0,0 +1,10 @@ +[Default] +save_dir=$HOME/Pictures/Screenshots +save_filename_format=swappy-%Y%m%d-%H%M%S.png +show_panel=false +line_size=5 +text_size=20 +text_font=Ubuntu-Mono +paint_mode=brush +early_exit=false +fill_shape=false diff --git a/config/swayosd/style.css b/config/swayosd/style.css new file mode 100644 index 00000000..f8f00c43 --- /dev/null +++ b/config/swayosd/style.css @@ -0,0 +1,51 @@ +window { + background: rgba(40, 42, 54, 0.8); + border: 2px solid rgba(189, 147, 249, 0.8); +} + +trough { + background: #363847; +} + +progress { + background: #79659f; +} + +/* DEFAULT STYLE +window { + padding: 12px 20px; + border-radius: 999px; + border: none; +} + +#container { + margin: 16px; +} + +image, label { + color: @theme_fg_color; +} + +progressbar:disabled, +image:disabled { + opacity: 0.5; +} + +progressbar { + min-height: 6px; + border-radius: 999px; + background: transparent; + border: none; +} +trough { + min-height: inherit; + border-radius: inherit; + border: none; + background: alpha(@theme_fg_color, 0.5); +} +progress { + min-height: inherit; + border-radius: inherit; + border: none; + background: @theme_fg_color; +}*/ diff --git a/configurations/README.md b/configurations/README.md deleted file mode 100644 index 24d4b2b3..00000000 --- a/configurations/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# NixosConfigurations - -This directory contains every device's main configuration file, their `hardware-configuration.nix` and some custom modules -unique to them. - -## List of my devices - -| Name | Model / Specs | Description | -| --------- | ------------- | ------------------------------------------------------------------------------------------------ | -| `android` | OnePlus 9 Pro | [Nix-On-Droid](https://github.com/nix-community/nix-on-droid) configuration for my OnePlus 9 Pro | -| `bbsteamie` | 512GB OLED | My wife's SteamDeck that has a pink case (it took a lot of convincing for this) | -| `binto` | NVIDIA 3070 with Ryzen 7 3700X | Desktop PC with a multi-monitor setup | -| `homie` | Lenovo Thinkcentre M910q | Mini PC that serves as a Home-assistant server | -| `live-image` | USB key | Basic configuration that serves as my custom ISO target | -| `nos` | NVIDIA 3060 with i5-3600 | Custom built NAS and seedbox for Linux ISOs ;) | -| `servivi` | Headless Ryzen 5 3600 | Gaming PC in a previous life, it is now used as a build farm and hosts game servers | -| `thingone` | Lenovo ThinkCentre M900 | Mini PC that makes use of [NixOS-pcsd](https://github.com/matt1432/nixos-pcsd) to form a cluster with its twin. Files located in `cluster` | -| `thingtwo` | Lenovo ThinkCentre M900 | Mini PC that makes use of [NixOS-pcsd](https://github.com/matt1432/nixos-pcsd) to form a cluster with its twin. Files located in `cluster` | -| `wim` | ThinkPad L13 Yoga Gen 3 (Ryzen 7 PRO 5875U) | 2-1 Lenovo Laptop that I use for university | diff --git a/configurations/android/default.nix b/configurations/android/default.nix deleted file mode 100644 index 54dd7ee3..00000000 --- a/configurations/android/default.nix +++ /dev/null @@ -1,56 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) attrValues concatStringsSep; -in { - imports = [./nix-on-droid.nix]; - - environment.variables.FLAKE = "/data/data/com.termux.nix/files/home/.nix"; - - terminal.font = "${ - pkgs.nerd-fonts.jetbrains-mono - }/share/fonts/truetype/NerdFonts/JetBrainsMono/JetBrainsMonoNerdFontMono-Regular.ttf"; - - environment.packages = [ - (pkgs.writeShellApplication { - name = "switch"; - - runtimeInputs = attrValues { - inherit - (pkgs) - coreutils - nix-output-monitor - nvd - ; - }; - - text = '' - oldProfile=$(realpath /nix/var/nix/profiles/per-user/nix-on-droid/profile) - - nix-on-droid ${concatStringsSep " " [ - "switch" - "--flake ${config.environment.variables.FLAKE}" - "--builders ssh-ng://matt@100.64.0.7" - ''"$@"'' - "|&" - "nom" - ]} && - - nvd diff "$oldProfile" "$(realpath /nix/var/nix/profiles/per-user/nix-on-droid/profile)" - ''; - }) - ]; - - environment.etcBackupExtension = ".bak"; - environment.motd = null; - home-manager.backupFileExtension = "hm-bak"; - - # Set your time zone. - time.timeZone = "America/Montreal"; - - # No touchy - system.stateVersion = "23.05"; -} diff --git a/configurations/android/nix-on-droid.nix b/configurations/android/nix-on-droid.nix deleted file mode 100644 index 3cc85ab6..00000000 --- a/configurations/android/nix-on-droid.nix +++ /dev/null @@ -1,98 +0,0 @@ -{ - config, - self, - ... -}: { - imports = [ - self.nixosModules.base-droid - { - roles.base = { - enable = true; - user = "nix-on-droid"; - }; - } - - self.nixosModules.tmux - {programs.tmux.enableCustomConf = true;} - ]; - - nix = { - # Edit nix.conf - extraOptions = '' - experimental-features = nix-command flakes - keep-outputs = true - keep-derivations = true - warn-dirty = false - ''; - - substituters = [ - # Nix-community - "https://nix-community.cachix.org" - - # Personal cache - "https://cache.nelim.org" - ]; - - trustedPublicKeys = [ - # Nix-community - "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" - - # Personal cache - "cache.nelim.org:JmFqkUdH11EA9EZOFAGVHuRYp7EbsdJDHvTQzG2pPyY=" - ]; - }; - - # Global hm settings - home-manager.config = { - imports = [ - self.homeManagerModules.neovim - { - programs.neovim = { - enable = true; - user = "nix-on-droid"; - - ideConfig = { - enableGolang = false; - enableJava = false; - enableNix = false; - enablePython = false; - }; - }; - } - - self.homeManagerModules.shell - {programs.bash.enable = true;} - - { - programs.bash.sessionVariables = { - FLAKE = config.environment.variables.FLAKE; - }; - - programs.bash.shellAliases = { - # Make ping work on nix-on-droid - # https://github.com/nix-community/nix-on-droid/issues/185#issuecomment-1659294700 - ping = "/android/system/bin/linker64 /android/system/bin/ping"; - - # SSH - # Desktop - pc = "ssh -t matt@100.64.0.6 'tmux -2u new -At phone'"; - - # NAS - nos = "ssh -t matt@100.64.0.4 'tmux -2u new -At phone'"; - - # Experimenting server - servivi = "ssh -t matt@100.64.0.7 'tmux -2u new -At phone'"; - - # Home-assistant - homie = "ssh -t matt@100.64.0.10 'tmux -2u new -At phone'"; - - # Cluster nodes - thingone = "ssh -t matt@100.64.0.8 'tmux -2u new -At phone'"; - thingtwo = "ssh -t matt@100.64.0.9 'tmux -2u new -At phone'"; - }; - } - ]; - - home.stateVersion = "23.05"; - }; -} diff --git a/configurations/bbsteamie/default.nix b/configurations/bbsteamie/default.nix deleted file mode 100644 index fee65c5a..00000000 --- a/configurations/bbsteamie/default.nix +++ /dev/null @@ -1,81 +0,0 @@ -{ - mainUser, - self, - ... -}: { - # ------------------------------------------------ - # Imports - # ------------------------------------------------ - imports = [ - ./hardware-configuration.nix - - ./modules - - self.nixosModules.base - self.nixosModules.meta - self.nixosModules.plymouth - self.nixosModules.server - ]; - - # State Version: DO NOT CHANGE - system.stateVersion = "24.11"; - - # ------------------------------------------------ - # User Settings - # ------------------------------------------------ - users.users.${mainUser} = { - isNormalUser = true; - uid = 1000; - - hashedPassword = "$y$j9T$b6YdvHx1b/HOD6Kt3Tw1W.$yIy5Km1xBViJA2kra9l38S/0auhEHPdXOMb6RBhgxID"; - - extraGroups = [ - "wheel" - "adm" - ]; - }; - - networking = { - hostName = "bbsteamie"; - networkmanager.enable = true; - }; - - time.timeZone = "America/Montreal"; - - # ------------------------------------------------ - # `Self` Modules configuration - # ------------------------------------------------ - meta = { - roleDescription = "My wife's SteamDeck that has a pink case (it took a lot of convincing for this)"; - hardwareDescription = "512GB OLED"; - }; - - roles.base = { - enable = true; - user = mainUser; - }; - - roles.server = { - enable = true; - user = mainUser; - sshd.enable = true; - }; - - boot.plymouth = { - enable = true; - theme = "bgrt"; - }; - - home-manager.users.${mainUser} = { - imports = [ - self.homeManagerModules.shell - ]; - - programs = { - bash = { - enable = true; - promptMainColor = "pink"; - }; - }; - }; -} diff --git a/configurations/bbsteamie/hardware-configuration.nix b/configurations/bbsteamie/hardware-configuration.nix deleted file mode 100644 index e1eefa6d..00000000 --- a/configurations/bbsteamie/hardware-configuration.nix +++ /dev/null @@ -1,61 +0,0 @@ -{ - config, - jovian, - modulesPath, - ... -}: { - nixpkgs.hostPlatform = "x86_64-linux"; - - imports = [ - (modulesPath + "/installer/scan/not-detected.nix") - jovian.nixosModules.default - ]; - - jovian = { - steamos.useSteamOSConfig = true; - - devices.steamdeck = { - enable = true; - enableGyroDsuService = true; - }; - hardware.has.amd.gpu = true; - }; - - boot = { - kernelModules = ["kvm-amd"]; - initrd.availableKernelModules = ["nvme" "xhci_pci" "usbhid" "sdhci_pci"]; - - loader = { - efi.canTouchEfiVariables = true; - - systemd-boot = { - enable = true; - configurationLimit = 30; - }; - }; - }; - - virtualisation.waydroid.enable = true; - - fileSystems = { - "/" = { - device = "/dev/disk/by-label/NIXROOT"; - fsType = "ext4"; - }; - - "/boot" = { - device = "/dev/disk/by-label/NIXBOOT"; - fsType = "vfat"; - options = ["fmask=0022" "dmask=0022"]; - }; - }; - - swapDevices = [ - { - device = "/.swapfile"; - size = 16 * 1024; # 16GB - } - ]; - - hardware.cpu.amd.updateMicrocode = config.hardware.enableRedistributableFirmware; -} diff --git a/configurations/bbsteamie/modules/default.nix b/configurations/bbsteamie/modules/default.nix deleted file mode 100644 index 35db9a5a..00000000 --- a/configurations/bbsteamie/modules/default.nix +++ /dev/null @@ -1,5 +0,0 @@ -{...}: { - imports = [ - ./desktop - ]; -} diff --git a/configurations/bbsteamie/modules/desktop/default.nix b/configurations/bbsteamie/modules/desktop/default.nix deleted file mode 100644 index 65659a1e..00000000 --- a/configurations/bbsteamie/modules/desktop/default.nix +++ /dev/null @@ -1,40 +0,0 @@ -{pkgs, ...}: let - defaultSession = "plasma"; -in { - imports = [ - (import ./session-switching.nix defaultSession) - (import ./steam.nix defaultSession) - ]; - - services.desktopManager.plasma6.enable = true; - - programs = { - kdeconnect.enable = true; - xwayland.enable = true; - }; - - # Flatpak support for Discover - services.flatpak.enable = true; - services.packagekit.enable = true; - - # Wayland env vars - environment.variables = { - NIXOS_OZONE_WL = "1"; - ELECTRON_OZONE_PLATFORM_HINT = "auto"; - }; - - environment.systemPackages = builtins.attrValues { - inherit - (pkgs) - firefox - wl-clipboard - xclip - ; - - inherit - (pkgs.kdePackages) - discover - krfb - ; - }; -} diff --git a/configurations/bbsteamie/modules/desktop/install_palia_map.md b/configurations/bbsteamie/modules/desktop/install_palia_map.md deleted file mode 100755 index 17e9f578..00000000 --- a/configurations/bbsteamie/modules/desktop/install_palia_map.md +++ /dev/null @@ -1,81 +0,0 @@ -# How to install Palia Map and Overwolf on Linux - -Dependencies: -- latest GE-Proton: https://github.com/GloriousEggroll/proton-ge-custom -- protontricks: https://github.com/Matoking/protontricks -- protonhax: https://github.com/jcnils/protonhax - - -## First Step: Install and run Palia at least once - - -## Second Step: Setup Palia WINEPREFIX with latest GE-Proton - -1. Delete prefix at /home/"$USER"/.steam/steam/steamapps/compatdata/2707930/pfx - -```bash -rm -r /home/"$USER"/.steam/steam/steamapps/compatdata/2707930/pfx -``` - -2. Launch Palia with GE-Proton by going to game properties -> Compatibility -> Force the use ... -> Select GE-Proton... - -3. Install dotnet48 and other Windows deps to allow for Overwolf installation - -```bash -# Force proton version of protontricks -export PROTON_VERSION="GE-Proton9-10" -protontricks 2707930 dotnet48 - -# If VC is needed -protontricks 2707930 vcrun2010 -protontricks 2707930 vcrun2012 -protontricks 2707930 vcrun2013 -``` - - -## Third Step: Install Overwolf - -1. Get this older version that worked for me here: https://overwolf.en.uptodown.com/windows/download/4714215 - -2. Install it with protontricks. Follow the GUI installer as if you were on Windows - -```bash -export PROTON_VERSION="GE-Proton9-10" -protontricks-launch --appid 2707930 Downloads/overwolf-0-195-0-18.exe -``` - - -## Fourth Step: Install Palia Map - -1. Get the installer from here: https://www.overwolf.com/app/Leon_Machens-Palia_Map - -2. Install it with protontricks. - -```bash -export PROTON_VERSION="GE-Proton9-10" -protontricks-launch --appid 2707930 Downloads/Palia\ Map\ -\ Installer.exe -``` - -3. An error should popup saying `Installation failed` or something along those lines. -Close it and wait. You should see the Overwolf overlay on the left side of your screen -with the Palia Map icon saying `Installing` and then when it's done: `Palia Map`. - -If nothing happens, try rebooting your PC and retrying the above shell commands until it works. - - -## Final Step: Setting it up in Steam - -1. Add this line to Palia launch options -```bash -protonhax init %command% -``` - -2. Add random non-steam game to your library and then edit its properties: - -Change the name to `Palia Map` or anything you like - -Change the target to this command: - -```bash -protonhax run 2707930 "/home/$USER/.local/share/Steam/steamapps/compatdata/2707930/pfx/drive_c/users/steamuser/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Overwolf/Palia Map.lnk" -``` diff --git a/configurations/bbsteamie/modules/desktop/session-switching.nix b/configurations/bbsteamie/modules/desktop/session-switching.nix deleted file mode 100644 index 76c93a86..00000000 --- a/configurations/bbsteamie/modules/desktop/session-switching.nix +++ /dev/null @@ -1,134 +0,0 @@ -defaultSession: { - config, - lib, - mainUser, - pkgs, - ... -}: { - config = let - inherit (lib) findFirst getExe mkForce; - - restartNetwork = getExe (pkgs.writeShellApplication { - name = "restart-network"; - runtimeInputs = with pkgs; [systemd]; - text = "systemctl restart NetworkManager"; - }); - - switch-session = pkgs.writeShellApplication { - name = "switch-session"; - - text = '' - mkdir -p /etc/sddm.conf.d - - cat <<EOF | tee /etc/sddm.conf.d/autologin.conf - [Autologin] - User=${mainUser} - Session=$1 - Relogin=true - EOF - ''; - }; - - gaming-mode = pkgs.writeShellScriptBin "gaming-mode" '' - sudo ${pkgs.systemd}/bin/systemctl start to-gaming-mode.service - ''; - in { - services.displayManager.sddm = { - enable = true; - autoLogin.relogin = true; - - wayland = { - enable = true; - compositorCommand = "kwin"; - }; - }; - - # Sets the default session at launch - systemd.services."set-session" = { - wantedBy = ["multi-user.target"]; - before = ["display-manager.service"]; - - path = [switch-session]; - - script = '' - switch-session "${defaultSession}" - ''; - }; - - # Disable getty on tty1 for seamless DE transitions - systemd.services.display-manager.conflicts = ["getty@tty1.service"]; - - # Allows switching to gaming mode - systemd.services."to-gaming-mode" = { - wantedBy = mkForce []; - - path = [switch-session]; - - script = '' - switch-session "gamescope-wayland" - systemctl restart display-manager - sleep 10 - switch-session "${defaultSession}" - ''; - }; - - security.sudo.extraRules = [ - { - users = [mainUser]; - groups = [100]; - commands = [ - # Make it so we don't need root to switch to gaming mode - { - command = "${pkgs.systemd}/bin/systemctl start to-gaming-mode.service"; - options = ["SETENV" "NOPASSWD"]; - } - # Make it so we don't need root to restart the network on launch - { - command = restartNetwork; - options = ["SETENV" "NOPASSWD"]; - } - ]; - } - ]; - - home-manager.users.${mainUser} = { - # Add desktop entry to make it GUI friendly - xdg.desktopEntries."Gaming Mode" = { - name = "Gaming Mode"; - exec = getExe gaming-mode; - icon = "steam"; - terminal = false; - type = "Application"; - }; - - home.file."Desktop/Gaming Mode.desktop".source = - ( - findFirst - (x: x.meta.name == "Gaming Mode.desktop") {} - config.home-manager.users.mariah.home.packages - ) - + "/share/applications/Gaming Mode.desktop"; - - # Fix remote control prompt showing up everytime - xdg.configFile = let - mkAutostart = name: exe: { - "autostart/${name}.desktop".text = "[Desktop Entry]\nType=Application\nExec=${exe}"; - }; - in ( - (mkAutostart "restart-network" "sudo ${restartNetwork}") - // (mkAutostart "steam" "steam -silent %U") - // (mkAutostart "krfb" "krfb --nodialog %c") - // (mkAutostart "kde-authorize-steam" (getExe (pkgs.writeShellApplication { - name = "kde-authorize-steam"; - text = '' - flatpak permission-set kde-authorized remote-desktop org.kde.krdpserver yes - flatpak permission-set kde-authorized remote-desktop "" yes - ''; - }))) - ); - }; - }; - - # For accurate stack trace - _file = ./session-switching.nix; -} diff --git a/configurations/bbsteamie/modules/desktop/steam.nix b/configurations/bbsteamie/modules/desktop/steam.nix deleted file mode 100644 index 84edd01d..00000000 --- a/configurations/bbsteamie/modules/desktop/steam.nix +++ /dev/null @@ -1,86 +0,0 @@ -defaultSession: { - config, - lib, - mainUser, - pkgs, - ... -}: let - inherit (lib) attrValues makeSearchPathOutput; -in { - config = { - # Normal Steam Stuff - programs.steam = { - enable = true; - protontricks.enable = true; - - remotePlay.openFirewall = true; - extraCompatPackages = [ - pkgs.selfPackages.proton-ge-latest - ]; - - # https://github.com/NixOS/nixpkgs/issues/25444#issuecomment-1977416787 - extraPackages = with pkgs; [ - kdePackages.breeze - ]; - }; - - # Jovian Steam settings - jovian.steam = { - # Steam > Settings > System > Enable Developer Mode - # Steam > Developer > CEF Remote Debugging - enable = true; - user = mainUser; - - environment = { - STEAM_EXTRA_COMPAT_TOOLS_PATHS = - makeSearchPathOutput - "steamcompattool" - "" - config.programs.steam.extraCompatPackages; - }; - - desktopSession = defaultSession; - }; - - # Decky settings - jovian.decky-loader = { - enable = true; - user = mainUser; - stateDir = "/home/${mainUser}/.local/share/decky"; # Keep scoped to user - # https://github.com/Jovian-Experiments/Jovian-NixOS/blob/1171169117f63f1de9ef2ea36efd8dcf377c6d5a/modules/decky-loader.nix#L80-L84 - - extraPackages = attrValues { - inherit - (pkgs) - curl - unzip - util-linux - gnugrep - readline - procps - pciutils - libpulseaudio - ; - }; - - extraPythonPackages = p: - with p; [ - click - ]; - }; - - # Misc Packages - environment.systemPackages = [ - pkgs.steam-rom-manager - pkgs.r2modman - - pkgs.selfPackages.protonhax - - # Ryujinx ACNH crashes on Vulkan - pkgs.ryujinx - ]; - }; - - # For accurate stack trace - _file = ./steam.nix; -} diff --git a/configurations/binto/default.nix b/configurations/binto/default.nix deleted file mode 100644 index 916e8934..00000000 --- a/configurations/binto/default.nix +++ /dev/null @@ -1,107 +0,0 @@ -{ - mainUser, - self, - ... -}: { - # ------------------------------------------------ - # Imports - # ------------------------------------------------ - imports = [ - ./hardware-configuration.nix - - ./modules - - self.nixosModules.base - self.nixosModules.desktop - self.nixosModules.kmscon - self.nixosModules.meta - self.nixosModules.server - ]; - - # State Version: DO NOT CHANGE - system.stateVersion = "23.11"; - - # ------------------------------------------------ - # User Settings - # ------------------------------------------------ - users.users.${mainUser} = { - isNormalUser = true; - uid = 1000; - - hashedPassword = "$y$j9T$uCv3kB5LI3Shj/5liU9cS0$4s3wWoH4iY29DLC3lJwNaIcurcjsj8L02cMY4EDtnC6"; - - extraGroups = [ - "wheel" - "input" - "uinput" - "adm" - "video" - "libvirtd" - "adbusers" - ]; - }; - - programs.adb.enable = true; - - networking = { - hostName = "binto"; - networkmanager.enable = true; - firewall.enable = false; - }; - - time.timeZone = "America/Montreal"; - - # ------------------------------------------------ - # `Self` Modules configuration - # ------------------------------------------------ - meta = { - roleDescription = "Desktop PC with a multi-monitor setup"; - hardwareDescription = "NVIDIA 3070 with Ryzen 7 3700X"; - }; - - roles.base = { - enable = true; - user = mainUser; - }; - - roles.desktop = { - enable = true; - user = mainUser; - - ags.enable = true; - mainMonitor = "desc:GIGA-BYTE TECHNOLOGY CO. LTD. G27QC 0x00000B1D"; - - fontSize = 12.5; - }; - - roles.server = { - enable = true; - user = mainUser; - tailscale.enable = true; - sshd.enable = true; - }; - - services.kmscon.enable = true; - - home-manager.users.${mainUser} = { - imports = [ - self.homeManagerModules.firefox - self.homeManagerModules.neovim - self.homeManagerModules.shell - ]; - - programs = { - bash = { - enable = true; - promptMainColor = "purple"; - }; - - firefox.enableCustomConf = true; - - neovim = { - enable = true; - user = mainUser; - }; - }; - }; -} diff --git a/configurations/binto/hardware-configuration.nix b/configurations/binto/hardware-configuration.nix deleted file mode 100644 index 275e09e2..00000000 --- a/configurations/binto/hardware-configuration.nix +++ /dev/null @@ -1,117 +0,0 @@ -{ - config, - modulesPath, - pkgs, - ... -}: { - nixpkgs.hostPlatform = "x86_64-linux"; - imports = [(modulesPath + "/installer/scan/not-detected.nix")]; - - boot = { - kernelPackages = pkgs.linuxPackages_zen; - - kernelParams = [ - "amd_pstate=active" - - # Remove these if I use plymouth module - "quiet" - "splash" - "boot.shell_on_fail" - "i915.fastboot=1" - "loglevel=3" - "rd.systemd.show_status=false" - "rd.udev.log_level=3" - "udev.log_priority=3" - ]; - kernelModules = ["kvm-amd"]; - - # Zenpower for ryzen cpu monitoring - extraModulePackages = builtins.attrValues { - inherit - (config.boot.kernelPackages) - v4l2loopback - zenpower - ; - }; - blacklistedKernelModules = ["k10temp"]; - - supportedFilesystems = ["ntfs"]; - - consoleLogLevel = 0; - - initrd = { - verbose = false; - systemd.enable = true; - availableKernelModules = ["nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod"]; - }; - - loader = { - efi.canTouchEfiVariables = true; - timeout = 0; - - systemd-boot = { - enable = true; - consoleMode = "max"; - configurationLimit = 30; - }; - }; - }; - - fileSystems = { - "/" = { - device = "/dev/disk/by-label/NIXROOT"; - fsType = "btrfs"; - }; - - # sudo btrfs subvolume create /@swap - "/swap" = { - device = "/dev/disk/by-label/NIXROOT"; - fsType = "btrfs"; - # Idk why this is the subvol - options = ["subvol=@/@swap"]; - }; - - "/boot" = { - device = "/dev/disk/by-label/NIXBOOT"; - fsType = "vfat"; - }; - - "/run/media/matt/Games" = { - device = "/dev/disk/by-uuid/da62f4ee-d4a6-4fdd-ab12-9c5e131c6f30"; - fsType = "ext4"; - }; - }; - - swapDevices = [ - { - device = "/swap/swapfile"; - size = 16 * 1024; - } - ]; - - zramSwap.enable = true; - - hardware = { - cpu.amd.updateMicrocode = config.hardware.enableRedistributableFirmware; - uinput.enable = true; - }; - - virtualisation = { - libvirtd.enable = true; - spiceUSBRedirection.enable = true; - }; - environment.systemPackages = builtins.attrValues { - inherit - (pkgs) - qemu - virtiofsd - ; - }; - - nvidia = { - enable = true; - enableNvidiaSettings = true; - enableWayland = true; - enableCUDA = true; - }; -} diff --git a/configurations/binto/modules/default.nix b/configurations/binto/modules/default.nix deleted file mode 100644 index 0605892d..00000000 --- a/configurations/binto/modules/default.nix +++ /dev/null @@ -1,6 +0,0 @@ -{...}: { - imports = [ - ./gpu-replay - ./nix-gaming - ]; -} diff --git a/configurations/binto/modules/gpu-replay/default.nix b/configurations/binto/modules/gpu-replay/default.nix deleted file mode 100644 index 352a3ec3..00000000 --- a/configurations/binto/modules/gpu-replay/default.nix +++ /dev/null @@ -1,98 +0,0 @@ -{ - config, - lib, - mainUser, - pkgs, - ... -}: let - inherit (lib) concatStringsSep getExe removePrefix; - inherit (pkgs.selfPackages) gpu-screen-recorder gsr-kms-server; - - hyprPkgs = config.home-manager.users.${mainUser}.wayland.windowManager.hyprland.finalPackage; - - cfgDesktop = config.roles.desktop; -in { - security.wrappers = { - gpu-screen-recorder = { - owner = "root"; - group = "video"; - capabilities = "cap_sys_nice+ep"; - source = getExe gpu-screen-recorder; - }; - - gsr-kms-server = { - owner = "root"; - group = "video"; - capabilities = "cap_sys_admin+ep"; - source = getExe gsr-kms-server; - }; - }; - - home-manager.users.${mainUser} = { - home.packages = [ - (pkgs.writeShellApplication { - name = "gpu-save-replay"; - - runtimeInputs = with pkgs; [procps]; - - text = '' - pkill --signal SIGUSR1 -f gpu-screen-recorder - ''; - }) - - (pkgs.writeShellApplication { - name = "gsr-start"; - - runtimeInputs = [ - pkgs.pulseaudio - pkgs.xorg.xrandr - - hyprPkgs - ]; - - text = '' - main="${removePrefix "desc:" cfgDesktop.mainMonitor}" - WINDOW=$(hyprctl -j monitors | jq '.[] |= (.description |= gsub(","; ""))' | jq -r ".[] | select(.description | test(\"$main\")) | .name") - - # Fix fullscreen game resolution - xrandr --output "$WINDOW" --primary - - gpu-screen-recorder ${concatStringsSep " " [ - # Prints fps and damage info once per second. - "-v no" - - # Replay buffer time in seconds. - "-r 1200" - - # Organise replays in folders based on the current date. - "-df yes" - "-o /home/matt/Videos/Replay" - - # Audio codec to use. - "-ac aac" - - # Audio device or application to record from (pulse audio device). - "-a desktop/default_output" - "-a microphone/default_input" - - # Window id to record, display (monitor name), "screen", "screen-direct", "focused" or "portal". - "-w \"$WINDOW\"" - - # Frame rate to record at. - "-f 60" - - # Container format for output file. - "-c mkv" - - # Video codec to use. - "-k hevc" - ]} - ''; - }) - ]; - - wayland.windowManager.hyprland.settings = { - bind = [",F8, exec, ags request 'save-replay'"]; - }; - }; -} diff --git a/configurations/binto/modules/nix-gaming/default.nix b/configurations/binto/modules/nix-gaming/default.nix deleted file mode 100644 index 435942bb..00000000 --- a/configurations/binto/modules/nix-gaming/default.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ - nix-gaming, - pkgs, - ... -}: { - imports = [ - nix-gaming.nixosModules.platformOptimizations - ]; - - programs = { - steam = { - enable = true; - protontricks.enable = true; - remotePlay.openFirewall = true; - - extraCompatPackages = [ - pkgs.selfPackages.proton-ge-latest - ]; - - platformOptimizations.enable = true; - }; - }; - - environment.systemPackages = [ - (pkgs.lutris.override { - extraLibraries = pkgs: [ - # List library dependencies here - ]; - extraPkgs = pkgs: [ - # List extra packages available to lutris here - ]; - }) - - pkgs.r2modman - pkgs.ryujinx - ]; -} diff --git a/configurations/cluster/default.nix b/configurations/cluster/default.nix deleted file mode 100644 index 6af2cb61..00000000 --- a/configurations/cluster/default.nix +++ /dev/null @@ -1,113 +0,0 @@ -deviceName: { - config, - mainUser, - self, - ... -}: let - clusterIP = (builtins.head config.services.pcsd.virtualIps).ip; -in { - # ------------------------------------------------ - # Imports - # ------------------------------------------------ - imports = [ - ./hardware-configuration.nix - - ./modules - - self.nixosModules.base - self.nixosModules.kmscon - self.nixosModules.meta - self.nixosModules.server - ]; - - config = { - # State Version: DO NOT CHANGE - system.stateVersion = "24.05"; - - # ------------------------------------------------ - # User Settings - # ------------------------------------------------ - users.users.${mainUser} = { - isNormalUser = true; - uid = 1000; - - hashedPassword = - if deviceName == "thingone" - then "$y$j9T$H.Uu5T7k5OLomqiPtFkVX0$ojaLWjxi.MDjxY00rT5r2dhJkt.9h.pXHgOtlhf3sN/" - else "$y$j9T$dXC7oiLsG7fCBXS1HUxo21$JjDm17jEwM41gnjMUaFdvgSzWXoGYQbqm867VtDAjF7"; - - extraGroups = [ - "wheel" - "adm" - ]; - }; - - networking = { - hostName = deviceName; - resolvconf.enable = true; - nameservers = [ - clusterIP - "1.0.0.1" - ]; - extraHosts = '' - 10.0.0.244 thingone - 10.0.0.159 thingtwo - ''; - firewall.enable = false; - }; - - time.timeZone = "America/Montreal"; - - # ------------------------------------------------ - # `Self` Modules configuration - # ------------------------------------------------ - meta = { - roleDescription = '' - Mini PC that makes use of [NixOS-pcsd](https://github.com/matt1432/nixos-pcsd) - to form a cluster with its twin. Files located in `cluster` - ''; - hardwareDescription = "Lenovo ThinkCentre M900"; - }; - - roles.base = { - enable = true; - user = mainUser; - }; - - roles.server = { - enable = true; - user = mainUser; - tailscale.enable = true; - sshd.enable = true; - }; - - services.kmscon.enable = true; - - home-manager.users.${mainUser} = { - imports = [ - self.homeManagerModules.neovim - self.homeManagerModules.shell - ]; - - programs = { - bash = { - enable = true; - promptMainColor = - if deviceName == "thingone" - then "green" - else if deviceName == "thingtwo" - then "red" - else "purple"; - }; - - neovim = { - enable = true; - user = mainUser; - }; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/configurations/cluster/hardware-configuration.nix b/configurations/cluster/hardware-configuration.nix deleted file mode 100644 index ae6d0ab3..00000000 --- a/configurations/cluster/hardware-configuration.nix +++ /dev/null @@ -1,59 +0,0 @@ -{ - config, - modulesPath, - ... -}: { - nixpkgs.hostPlatform = "x86_64-linux"; - imports = [(modulesPath + "/installer/scan/not-detected.nix")]; - - boot = { - loader = { - efi.canTouchEfiVariables = true; - timeout = 2; - - systemd-boot = { - enable = true; - consoleMode = "max"; - configurationLimit = 30; - }; - }; - - initrd.availableKernelModules = [ - "xhci_pci" - "ahci" - "usbhid" - "usb_storage" - "sd_mod" - ]; - }; - - fileSystems = { - "/" = { - device = "/dev/disk/by-label/NIXROOT"; - fsType = "btrfs"; - }; - - # sudo btrfs subvolume create /@swap - "/swap" = { - device = "/dev/disk/by-label/NIXROOT"; - fsType = "btrfs"; - options = ["subvol=@swap"]; - }; - - "/boot" = { - device = "/dev/disk/by-label/NIXBOOT"; - fsType = "vfat"; - }; - }; - - swapDevices = [ - { - device = "/swap/swapfile"; - size = 16 * 1024; - } - ]; - - zramSwap.enable = true; - - hardware.cpu.intel.updateMicrocode = config.hardware.enableRedistributableFirmware; -} diff --git a/configurations/cluster/modules/blocky/default.nix b/configurations/cluster/modules/blocky/default.nix deleted file mode 100644 index be838b12..00000000 --- a/configurations/cluster/modules/blocky/default.nix +++ /dev/null @@ -1,24 +0,0 @@ -{...}: { - services = { - blocky = { - enable = true; - - settings = { - upstream = { - default = [ - "127.0.0.1:5335" - "127.0.0.1:5335" - ]; - }; - - blocking = { - blackLists = { - ads = [ - "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts" - ]; - }; - }; - }; - }; - }; -} diff --git a/configurations/cluster/modules/caddy/default.nix b/configurations/cluster/modules/caddy/default.nix deleted file mode 100644 index 710a0877..00000000 --- a/configurations/cluster/modules/caddy/default.nix +++ /dev/null @@ -1,186 +0,0 @@ -{ - config, - lib, - mainUser, - pkgs, - self, - ... -}: let - inherit (lib) attrValues head removeAttrs; - - inherit (config.sops) secrets; - inherit (config.networking) hostName; -in { - imports = [self.nixosModules.caddy-plus]; - - users.users.${mainUser}.extraGroups = ["caddy"]; - - boot.kernel.sysctl."net.ipv4.ip_nonlocal_bind" = 1; - - systemd.services.caddy.serviceConfig = { - EnvironmentFile = secrets.caddy-cloudflare.path; - }; - - services.caddy = { - enable = true; - enableReload = false; - - package = let - pluginsInfo = import ./plugins.nix; - in - pkgs.caddy.withPlugins { - plugins = map (x: "${x.url}@${x.version}") (attrValues pluginsInfo.plugins); - inherit (pluginsInfo) hash; - }; - - virtualHosts = let - clusterIP = (head config.services.pcsd.virtualIps).ip; - nosIP = "10.0.0.121"; - serviviIP = "10.0.0.249"; - homieIP = "100.64.0.10"; - - tlsConf = '' - tls { - dns cloudflare {$CLOUDFLARE_API_TOKEN} - resolvers 1.0.0.1 - } - ''; - - mkPublicReverseProxy = subdomain: ip: extraConf: - { - hostName = "${subdomain}.nelim.org"; - reverseProxy = ip; - listenAddresses = [clusterIP]; - extraConfig = tlsConf + (extraConf.extraConfig or ""); - } - // (removeAttrs extraConf ["extraConfig"]); - in { - # Public - "Home-Assistant" = mkPublicReverseProxy "homie" "${homieIP}:8123" {}; - "Vaultwarden" = mkPublicReverseProxy "vault" "${nosIP}:8781" {}; - "Hauk" = mkPublicReverseProxy "hauk" "${nosIP}:3003" {}; - "Headscale" = mkPublicReverseProxy "headscale" "${clusterIP}:8085" {}; - "SearXNG" = mkPublicReverseProxy "search" "${clusterIP}:8080" {}; - - "Jellyfin" = mkPublicReverseProxy "jelly" "${nosIP}:8096" { - subDirectories.jfa-go = { - subDirName = "accounts"; - reverseProxy = "${nosIP}:8056"; - }; - }; - - "Jellyseer" = mkPublicReverseProxy "seerr" "${nosIP}:5055" {}; - - "Komga" = mkPublicReverseProxy "komga" "${nosIP}:7080" {}; - - "Gameyfin" = mkPublicReverseProxy "games" "${nosIP}:8074" {}; - - "Forgejo" = mkPublicReverseProxy "git" "${nosIP}:3000" {}; - - "Nextcloud" = mkPublicReverseProxy "cloud" "${nosIP}:8042" { - extraConfig = '' - redir /.well-known/carddav /remote.php/dav 301 - redir /.well-known/caldav /remote.php/dav 301 - redir /.well-known/webfinger /index.php/.well-known/webfinger 301 - redir /.well-known/nodeinfo /index.php/.well-known/nodeinfo 301 - ''; - }; - "OnlyOffice" = mkPublicReverseProxy "office" "http://${nosIP}:8055" {}; - - "Immich" = mkPublicReverseProxy "photos" "${nosIP}:2283" {}; - - "Binary Cache" = mkPublicReverseProxy "cache" "${serviviIP}:5000" {}; - - # Private - "nelim.org" = { - serverAliases = ["*.nelim.org"]; - extraConfig = tlsConf; - listenAddresses = [ - ( - if hostName == "thingone" - then "100.64.0.8" - else "100.64.0.9" - ) - ]; - - subDomains = { - esphome.reverseProxy = "${homieIP}:6052"; - pr-tracker.reverseProxy = "${serviviIP}:3000"; - - pcsd = { - extraConfig = '' - reverse_proxy https://${clusterIP}:2224 { - transport http { - tls_insecure_skip_verify - } - } - ''; - }; - - komf.reverseProxy = "${nosIP}:8085"; - - # Resume builder - resume.reverseProxy = "${nosIP}:3060"; - resauth.reverseProxy = "${nosIP}:3100"; - - # FreshRSS & Co - bridge.reverseProxy = "${nosIP}:3006"; - drss.reverseProxy = "${nosIP}:3007"; - freshrss = { - subDomainName = "rss"; - reverseProxy = "${nosIP}:2800"; - }; - - wgui.reverseProxy = "${nosIP}:51821"; - - lan = { - reverseProxy = "${nosIP}:3020"; - extraConfig = '' - redir /index.html / - ''; - - subDirectories = { - bazarr.reverseProxy = "${nosIP}:6767"; - jellystat.reverseProxy = "${nosIP}:3070"; - prowlarr.reverseProxy = "${nosIP}:9696"; - radarr.reverseProxy = "${nosIP}:7878"; - sonarr.reverseProxy = "${nosIP}:8989"; - kapowarr.reverseProxy = "${nosIP}:5676"; - - jdownloader2 = { - subDirName = "jd2"; - experimental = true; - reverseProxy = "${nosIP}:5800"; - }; - - qbittorent = { - subDirName = "qbt"; - experimental = true; - reverseProxy = "${nosIP}:8080"; - }; - - vaultwarden = { - subDirName = "vault"; - experimental = true; - reverseProxy = "${nosIP}:8780"; - }; - }; - }; - - # Top secret Business - joal.extraConfig = '' - route { - rewrite * /joal/ui{uri} - reverse_proxy * ${nosIP}:5656 - } - ''; - joalws.extraConfig = '' - route { - reverse_proxy ${nosIP}:5656 - } - ''; - }; - }; - }; - }; -} diff --git a/configurations/cluster/modules/caddy/plugins.nix b/configurations/cluster/modules/caddy/plugins.nix deleted file mode 100644 index d5aab9c1..00000000 --- a/configurations/cluster/modules/caddy/plugins.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ - plugins = { - certmagic = { - url = "github.com/caddyserver/certmagic"; - version = "v0.23.1-0.20250416233037-0d908a37e8f8"; - type = "git"; - }; - - cloudflare = { - url = "github.com/caddy-dns/cloudflare"; - version = "v0.2.2-0.20250419192618-6207298f499a"; - type = "git"; - }; - }; - - hash = "sha256-C3sYu0ezjBocdsC6U76gv0UOZCID2jDIiyQBywLlOS4="; -} diff --git a/configurations/cluster/modules/default.nix b/configurations/cluster/modules/default.nix deleted file mode 100644 index eac8f5ca..00000000 --- a/configurations/cluster/modules/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -{...}: { - imports = [ - ./blocky - ./caddy - ./headscale - ./nfs-client - ./pcsd - ./searxng - ./unbound - ]; -} diff --git a/configurations/cluster/modules/headscale/default.nix b/configurations/cluster/modules/headscale/default.nix deleted file mode 100644 index 079bee36..00000000 --- a/configurations/cluster/modules/headscale/default.nix +++ /dev/null @@ -1,70 +0,0 @@ -{ - config, - mainUser, - ... -}: let - inherit (config.networking) hostName; - - clusterIP = (builtins.head config.services.pcsd.virtualIps).ip; -in { - users.users.${mainUser}.extraGroups = ["headscale"]; - - services.headscale = { - enable = true; - - settings = { - server_url = "https://headscale.nelim.org"; - listen_addr = "${clusterIP}:8085"; - prefixes = { - v4 = "100.64.0.0/10"; - v6 = "fd7a:115c:a1e0::/48"; - }; - metrics_listen_addr = "127.0.0.1:9090"; - grpc_listen_addr = "0.0.0.0:50443"; - grpc_allow_insecure = false; - disable_check_updates = true; - ephemeral_node_inactivity_timeout = "30m"; - unix_socket = "/run/headscale/headscale.sock"; - unix_socket_permission = "0770"; - - database = { - type = "sqlite"; - sqlite.path = "/var/lib/headscale/db.sqlite"; - }; - - private_key_path = "/var/lib/headscale/private.key"; - noise.private_key_path = "/var/lib/headscale/noise_private.key"; - - dns = let - caddyIp = - if hostName == "thingone" - then "100.64.0.8" - else "100.64.0.9"; - in { - magic_dns = false; - override_local_dns = true; - nameservers.global = [caddyIp]; - }; - - log = { - format = "text"; - level = "info"; - }; - - derp = { - auto_update_enable = true; - update_frequency = "24h"; - - server = { - enabled = true; - stun_listen_addr = "${clusterIP}:3479"; - private_key_path = "/var/lib/headscale/derp_server_private.key"; - - region_id = 995; - region_code = "mon"; - region_name = "montreal"; - }; - }; - }; - }; -} diff --git a/configurations/cluster/modules/nfs-client/default.nix b/configurations/cluster/modules/nfs-client/default.nix deleted file mode 100644 index 34a2e86d..00000000 --- a/configurations/cluster/modules/nfs-client/default.nix +++ /dev/null @@ -1,32 +0,0 @@ -{pkgs, ...}: { - # NFS client setup - services.rpcbind.enable = true; - boot.supportedFilesystems = ["nfs"]; - environment.systemPackages = builtins.attrValues { - inherit (pkgs) nfs-utils; - }; - - systemd.mounts = let - host = "10.0.0.249"; - in [ - { - type = "nfs"; - mountConfig = { - Options = "noatime"; - }; - what = "${host}:/caddy"; - where = "/var/lib/caddy"; - requiredBy = ["caddy.service"]; - } - - { - type = "nfs"; - mountConfig = { - Options = "noatime"; - }; - what = "${host}:/headscale"; - where = "/var/lib/headscale"; - requiredBy = ["headscale.service"]; - } - ]; -} diff --git a/configurations/cluster/modules/pcsd/default.nix b/configurations/cluster/modules/pcsd/default.nix deleted file mode 100644 index dd262eaf..00000000 --- a/configurations/cluster/modules/pcsd/default.nix +++ /dev/null @@ -1,73 +0,0 @@ -{ - config, - pcsd, - ... -}: let - inherit (config.sops) secrets; -in { - imports = [pcsd.nixosModules.default]; - - services.pcsd = { - enable = true; - enableWebUI = true; - - clusterName = "thingies"; - - corosyncKeyFile = secrets.corosync.path; - clusterUserPasswordFile = secrets.pcs-pass.path; - - virtualIps = [ - { - id = "caddy-vip"; - ip = "10.0.0.130"; - interface = "eno1"; - group = "caddy-grp"; - } - ]; - - systemdResources = [ - { - systemdName = "unbound"; - enable = true; - group = "caddy-grp"; - } - - { - systemdName = "blocky"; - enable = true; - group = "caddy-grp"; - } - - { - systemdName = "headscale"; - enable = true; - group = "caddy-grp"; - } - - { - systemdName = "caddy"; - enable = true; - group = "caddy-grp"; - } - - { - systemdName = "searx"; - enable = true; - group = "caddy-grp"; - } - ]; - - nodes = [ - { - name = "thingone"; - nodeid = 1; - ring_addrs = ["10.0.0.244"]; - } - { - name = "thingtwo"; - nodeid = 2; - ring_addrs = ["10.0.0.159"]; - } - ]; - }; -} diff --git a/configurations/cluster/modules/searxng/default.nix b/configurations/cluster/modules/searxng/default.nix deleted file mode 100644 index 9b9b6e4f..00000000 --- a/configurations/cluster/modules/searxng/default.nix +++ /dev/null @@ -1,73 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) head mapAttrsToList; -in { - services.searx = { - enable = true; - - package = pkgs.searxng.overrideAttrs (o: { - postInstall = '' - ${o.postInstall or ""} - # Replace logo - cp ${./logo.png} $out/${pkgs.python3.sitePackages}/searx/static/themes/simple/img/searxng.png - ''; - }); - - environmentFile = config.sops.secrets.searxng.path; - - settings = { - general = { - instance_name = "Search"; - debug = false; - enable_metrics = false; - }; - - search = { - autocomplete = "google"; - favicon_resolver = "google"; - - safe_search = 0; - - default_lang = "en-CA"; - }; - - ui = { - infinite_scroll = true; - query_in_title = true; - hotkeys = "vim"; - }; - - server = { - port = 8080; - bind_address = (head config.services.pcsd.virtualIps).ip; - - secret_key = "@SEARXNG_SECRET@"; - - public_instance = false; - }; - - engines = mapAttrsToList (name: value: {inherit name;} // value) { - "duckduckgo".disabled = false; - "duckduckgo images".disabled = false; - "gitlab".disabled = false; - "qwant".disabled = false; - "reddit".disabled = false; - - "wikipedia" = { - engine = "wikipedia"; - shortcut = "w"; - base_url = "https://wikipedia.org/"; - }; - - "github" = { - engine = "github"; - shortcut = "gh"; - }; - }; - }; - }; -} diff --git a/configurations/cluster/modules/searxng/logo.png b/configurations/cluster/modules/searxng/logo.png deleted file mode 100644 index 4f817882..00000000 Binary files a/configurations/cluster/modules/searxng/logo.png and /dev/null differ diff --git a/configurations/cluster/modules/unbound/default.nix b/configurations/cluster/modules/unbound/default.nix deleted file mode 100644 index 23114988..00000000 --- a/configurations/cluster/modules/unbound/default.nix +++ /dev/null @@ -1,94 +0,0 @@ -{ - config, - lib, - mainUser, - self, - ... -}: let - inherit (self.lib) mergeAttrsList; - - inherit (lib) mapAttrsToList remove; - - inherit (config.networking) hostName; - - serviviIP = "100.64.0.7"; - caddyIp = - if hostName == "thingone" - then "100.64.0.8" - else "100.64.0.9"; -in { - # https://github.com/MatthewVance/unbound-docker-rpi/issues/4#issuecomment-1001879602 - boot.kernel.sysctl."net.core.rmem_max" = 1048576; - - users.users.${mainUser}.extraGroups = ["unbound"]; - - services.unbound = { - enable = true; - enableRootTrustAnchor = true; - resolveLocalQueries = false; - - settings = { - server = let - mkLocalEntry = domain: ip: { - local-zone = ["${domain} redirect"]; - local-data = ["\"${domain} IN A ${ip}\""]; - }; - - mkMinecraftEntry = domain: port: { - local-zone = ["${domain} transparent"]; - local-data = [ - "\"${domain} IN A ${serviviIP}\"" - "\"_minecraft._tcp.${domain}. 180 IN SRV 0 0 ${toString port} ${domain}.\"" - ]; - }; - - forceResolveEntry = domain: { - local-zone = ["${domain} always_transparent"]; - }; - - publicApps = remove "nelim.org" (mapAttrsToList (n: v: v.hostName) config.services.caddy.virtualHosts); - in - mergeAttrsList ( - [] - ++ (map forceResolveEntry publicApps) - ++ [ - (mkMinecraftEntry "mc.nelim.org" 25569) - (mkMinecraftEntry "mc2.nelim.org" 25560) - (mkMinecraftEntry "cv.nelim.org" 25566) - - (mkLocalEntry "nelim.org" caddyIp) - - { - interface = ["127.0.0.1"]; - port = 5335; - - do-ip4 = true; - do-ip6 = false; - prefer-ip6 = false; - do-udp = true; - do-tcp = true; - - # Performance - prefetch = true; - num-threads = 1; - - private-address = [ - "172.16.0.0/12" - "10.0.0.0/8" - "100.64.0.0/8" - "fd00::/8" - "fe80::/10" - ]; - - # Default stuff - harden-glue = true; - harden-dnssec-stripped = true; - use-caps-for-id = false; - edns-buffer-size = 1232; - so-rcvbuf = "1m"; - } - ] - ); - }; - }; -} diff --git a/configurations/homie/default.nix b/configurations/homie/default.nix deleted file mode 100644 index ef792300..00000000 --- a/configurations/homie/default.nix +++ /dev/null @@ -1,115 +0,0 @@ -{ - mainUser, - pkgs, - self, - ... -}: { - # ------------------------------------------------ - # Imports - # ------------------------------------------------ - imports = [ - ./hardware-configuration.nix - - ./modules - - self.nixosModules.base - self.nixosModules.docker - self.nixosModules.kmscon - self.nixosModules.meta - self.nixosModules.server - ]; - - # State Version: DO NOT CHANGE - system.stateVersion = "24.11"; - - # ------------------------------------------------ - # User Settings - # ------------------------------------------------ - users.users.${mainUser} = { - isNormalUser = true; - uid = 1000; - - hashedPassword = "$y$j9T$CBC0wX9ZrZeXE296CWTvK.$xTJE54Pd4EPrv/Q4TQ42ahIDXQYoavcnwcsItw0hk.B"; - - extraGroups = [ - "wheel" - "adm" - ]; - }; - - networking = { - hostName = "homie"; - resolvconf.enable = true; - firewall.enable = false; - }; - - # temporary fix while I figure out the issue with the Network Card - systemd.services."temp-fix-nic" = { - wantedBy = ["multi-user.target"]; - after = ["tailscaled.service"]; - path = [pkgs.ripgrep pkgs.systemd "/run/wrappers"]; - script = '' - # Wait for boot to finish - sleep 60 - - echo "start listening to journalctl" - - journalctl -fb | while read -r line; do - if echo "$line" | rg 'NIC Link is Up' &> /dev/null; then - echo "restarting tailscaled" - systemctl restart tailscaled.service - machinectl shell ${mainUser}@ ${pkgs.systemd}/bin/systemctl --user restart spotifyd - fi - done - ''; - serviceConfig = { - User = "root"; - AmbientCapabilities = "CAP_SYS_ADMIN CAP_SYSLOG"; - }; - }; - - time.timeZone = "America/Montreal"; - - # ------------------------------------------------ - # `Self` Modules configuration - # ------------------------------------------------ - meta = { - roleDescription = "Mini PC that serves as a Home-assistant server"; - hardwareDescription = "Lenovo Thinkcentre M910q"; - }; - - roles.base = { - enable = true; - user = mainUser; - }; - - roles.server = { - enable = true; - user = mainUser; - tailscale.enable = true; - sshd.enable = true; - }; - - roles.docker.enable = true; - - services.kmscon.enable = true; - - home-manager.users.${mainUser} = { - imports = [ - self.homeManagerModules.neovim - self.homeManagerModules.shell - ]; - - programs = { - bash = { - enable = true; - promptMainColor = "yellow"; - }; - - neovim = { - enable = true; - user = mainUser; - }; - }; - }; -} diff --git a/configurations/homie/hardware-configuration.nix b/configurations/homie/hardware-configuration.nix deleted file mode 100644 index 06c79aec..00000000 --- a/configurations/homie/hardware-configuration.nix +++ /dev/null @@ -1,61 +0,0 @@ -{ - config, - modulesPath, - ... -}: { - nixpkgs.hostPlatform = "x86_64-linux"; - imports = [(modulesPath + "/installer/scan/not-detected.nix")]; - - boot = { - loader = { - efi.canTouchEfiVariables = true; - timeout = 2; - - systemd-boot = { - enable = true; - consoleMode = "max"; - configurationLimit = 30; - }; - }; - - initrd.availableKernelModules = [ - "xhci_pci" - "ahci" - "nvme" - "usbhid" - "usb_storage" - "sd_mod" - ]; - }; - - fileSystems = { - "/" = { - device = "/dev/disk/by-label/NIXROOT"; - fsType = "btrfs"; - }; - - # sudo btrfs subvolume create /@swap - "/swap" = { - device = "/dev/disk/by-label/NIXROOT"; - fsType = "btrfs"; - options = ["subvol=@swap"]; - }; - - "/boot" = { - device = "/dev/disk/by-label/NIXBOOT"; - fsType = "vfat"; - options = ["fmask=0022" "dmask=0022"]; - }; - }; - - swapDevices = [ - { - device = "/swap/swapfile"; - size = 16 * 1024; - } - ]; - - zramSwap.enable = true; - - hardware.cpu.intel.updateMicrocode = config.hardware.enableRedistributableFirmware; -} diff --git a/configurations/homie/modules/androidtv/default.nix b/configurations/homie/modules/androidtv/default.nix deleted file mode 100644 index 090bf597..00000000 --- a/configurations/homie/modules/androidtv/default.nix +++ /dev/null @@ -1,103 +0,0 @@ -# Unfortunately I had some hardware issues but this does work -{ - lib, - pkgs, - ... -}: let - inherit (lib) mkForce getExe; - - connectControllers = getExe (pkgs.writeShellApplication { - name = "connectControllers"; - runtimeInputs = with pkgs; [gnugrep usbutils]; - text = '' - set +o errexit - - for dev in /sys/bus/usb/devices/*; do - vendor="$(cat "$dev/idVendor" 2>/dev/null)" - prod="$(cat "$dev/idProduct" 2>/dev/null)" - - if [[ "$vendor" != "" && "$prod" != "" ]]; then - if [[ "$(lsusb -d "$vendor:$prod" | grep "Microsoft Corp. Xbox Controller")" != "" ]]; then - echo 0 > "$dev/authorized" - echo 1 > "$dev/authorized" - fi - fi - done - ''; - }); - - hyprConf = pkgs.writeText "greetd-hypr-config" '' - cursor { - inactive_timeout = 1 - } - - misc { - disable_hyprland_logo = true - disable_splash_rendering = true - } - - decoration { - blur { - enabled = false - } - } - - animations { - enabled = false - first_launch_animation = false - } - - bind = SUPER, Q, exec, kitty - - windowrule = fullscreen, ^(.*)$ - exec-once = waydroid show-full-ui - exec-once = sleep 10; sudo ${connectControllers} - ''; - - user = "matt"; - command = "Hyprland --config ${hyprConf}"; - - session = {inherit command user;}; -in { - # Make it so we don't need root to connect controllers - security.sudo.extraRules = [ - { - users = [user]; - groups = [user]; - commands = [ - { - command = connectControllers; - options = ["SETENV" "NOPASSWD"]; - } - ]; - } - ]; - - # Stuff missing for complete declarative setup: - # - make the following declarative and also make the image declarative - # - Add this to /var/lib/waydroid/waydroid.cfg for controller support - # persist.waydroid.udev = true - # persist.waydroid.uevent = true - virtualisation.waydroid.enable = true; - - users.users."greeter" = { - home = "/var/lib/greeter"; - }; - - programs.hyprland.enable = true; - - services = { - greetd = { - enable = true; - - settings = { - default_session = session; - initial_session = session; - }; - }; - - pipewire.enable = mkForce false; - }; - - environment.systemPackages = [pkgs.kitty]; -} diff --git a/configurations/homie/modules/default.nix b/configurations/homie/modules/default.nix deleted file mode 100644 index d8fa2972..00000000 --- a/configurations/homie/modules/default.nix +++ /dev/null @@ -1,6 +0,0 @@ -{...}: { - imports = [ - ./home-assistant - ./music - ]; -} diff --git a/configurations/homie/modules/home-assistant/assist.nix b/configurations/homie/modules/home-assistant/assist.nix deleted file mode 100644 index 2552222c..00000000 --- a/configurations/homie/modules/home-assistant/assist.nix +++ /dev/null @@ -1,82 +0,0 @@ -{ - pkgs, - self, - wakewords-src, - ... -}: { - imports = [ - self.nixosModules.esphome-plus - self.nixosModules.wyoming-plus - ]; - - services = { - home-assistant = { - package = pkgs.home-assistant.override { - packageOverrides = final: prev: { - # HassTimer has way too many collisions with my custom timer sentences - home-assistant-intents = prev.home-assistant-intents.overrideAttrs (o: { - nativeBuildInputs = o.nativeBuildInputs ++ [pkgs.findutils]; - postPatch = '' - find ./. -name "*Timer*" -delete - find ./. -name "*Start*" -delete - ''; - }); - }; - }; - - customComponents = builtins.attrValues { - inherit - (pkgs.scopedPackages.hass-components) - extended-ollama-conversation # url is without subdirectory - tuya-local - ; - }; - - extraComponents = [ - "esphome" - "ollama" - "wyoming" - "scrape" - ]; - - config = { - assist_pipeline = {}; - conversation = {}; - media_source = {}; - }; - }; - - wyoming = { - piper.servers."en" = { - enable = true; - uri = "tcp://127.0.0.1:10200"; - - # see https://github.com/rhasspy/rhasspy3/blob/master/programs/tts/piper/script/download.py - voice = "en_US-hfc_male-medium"; - speaker = 0; - }; - - openwakeword = { - enable = true; - uri = "tcp://127.0.0.1:10400"; - - threshold = 0.55; - vadThreshold = 0.50; - - customModelsDirectories = ["${wakewords-src}/en/yo_homie"]; - preloadModels = ["yo_homie"]; - - extraArgs = ["--debug"]; - }; - }; - - esphome = { - enable = true; - address = "100.64.0.10"; - port = 6052; - }; - }; - - # In case tailscale is down - boot.kernel.sysctl."net.ipv4.ip_nonlocal_bind" = 1; -} diff --git a/configurations/homie/modules/home-assistant/bluetooth.nix b/configurations/homie/modules/home-assistant/bluetooth.nix deleted file mode 100644 index 7ed044e5..00000000 --- a/configurations/homie/modules/home-assistant/bluetooth.nix +++ /dev/null @@ -1,78 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) getExe; - - turnOnUE = pkgs.writeShellApplication { - name = "turnOnUE"; - - runtimeInputs = [config.hardware.bluetooth.package]; - - text = '' - cmd=0x0003 - bt_device_addr=88:C6:26:93:4B:77 - - # This is the MAC address on the first line of `bluetootctl show` - # without the `:` and with `01` added at the end - bt_controller_addr=E848B8C8200001 - - exec gatttool -b $bt_device_addr --char-write-req --handle=$cmd --value=$bt_controller_addr - ''; - }; -in { - environment.systemPackages = [turnOnUE]; - - services.home-assistant = { - extraComponents = [ - "mpd" - - # BT components - "ibeacon" - "led_ble" - "kegtron" - "xiaomi_ble" - ]; - - # Turn On the speaker automatically when openwakeword is used - config = { - shell_command.turn_on_ue = getExe turnOnUE; - script.turn_on_ue = { - alias = "Music - TurnOnUE"; - description = "Script for turning on the UE Boom 2 speaker."; - icon = "mdi:music"; - mode = "single"; - - sequence = [ - { - alias = "Run shell command"; - service = "shell_command.turn_on_ue"; - } - ]; - }; - - automation = [ - { - alias = "Turn On UE"; - mode = "single"; - trigger = [ - { - platform = "state"; - entity_id = "wake_word.openwakeword"; - } - ]; - condition = []; - action = [ - { - action = "shell_command.turn_on_ue"; - metadata = {}; - data = {}; - } - ]; - } - ]; - }; - }; -} diff --git a/configurations/homie/modules/home-assistant/default.nix b/configurations/homie/modules/home-assistant/default.nix deleted file mode 100644 index 37d43319..00000000 --- a/configurations/homie/modules/home-assistant/default.nix +++ /dev/null @@ -1,119 +0,0 @@ -{ - pkgs, - self, - ... -}: { - imports = [ - ./assist.nix - ./bluetooth.nix - ./firmware.nix - ./frontend.nix - ./zigbee.nix - - ./netdaemon - ./spotify - ./timer - - self.nixosModules.ha-plus - ]; - - services.home-assistant = { - enable = true; - - extraComponents = [ - "androidtv" - "androidtv_remote" - "caldav" - "cast" - "holiday" - "isal" - "met" - "switchbot" - "upnp" - "yamaha_musiccast" - ]; - - customComponents = builtins.attrValues { - inherit - (pkgs.scopedPackages.hass-components) - yamaha-soundbar - ; - }; - - config = { - homeassistant = { - name = "Home"; - unit_system = "metric"; - currency = "CAD"; - country = "CA"; - time_zone = "America/Montreal"; - external_url = "https://homie.nelim.org"; - }; - - media_player = [ - { - platform = "yamaha_soundbar"; - host = "192.168.0.96"; - name = "Living Room Speaker"; - sources = { - HDMI = "TV"; - }; - } - ]; - - # Proxy settings - http = { - server_host = "0.0.0.0"; - trusted_proxies = ["100.64.0.8" "100.64.0.9"]; - use_x_forwarded_for = true; - }; - - # `default_config` enables too much stuff. this is what I want from it - config = {}; - dhcp = {}; - history = {}; - image_upload = {}; - logbook = {}; - mobile_app = {}; - my = {}; - sun = {}; - zeroconf = {}; - }; - }; - - environment.systemPackages = [ - (pkgs.writeShellApplication { - name = "yaml2nix"; - runtimeInputs = with pkgs; [yj]; - text = '' - input="$(yj < "$1")" - output="''${2:-""}" - - nixCode="$(nix eval --expr "builtins.fromJSON '''$input'''" --impure | alejandra -q | sed 's/ = null;/ = {};/g')" - - if [[ "$output" != "" ]]; then - echo "$nixCode" > "$output" - else - echo "$nixCode" - fi - ''; - }) - - (pkgs.writeShellApplication { - name = "nix2yaml"; - runtimeInputs = with pkgs; [remarshal]; - text = '' - input="$1" - output="''${2:-""}" - - yamlCode="$(nix eval --json --file "$input" | remarshal --if json --of yaml)" - - if [[ "$output" != "" ]]; then - echo "$yamlCode" > "$output" - else - echo "$yamlCode" - fi - ''; - }) - ]; -} diff --git a/configurations/homie/modules/home-assistant/docs/functions.nix b/configurations/homie/modules/home-assistant/docs/functions.nix deleted file mode 100644 index 93b90aa3..00000000 --- a/configurations/homie/modules/home-assistant/docs/functions.nix +++ /dev/null @@ -1,26 +0,0 @@ -# I use nix2yaml from ../default.nix to convert this to YAML and place it in the functions of extended_ollama_conversation -[ - { - spec = { - name = "get_attributes"; - description = "Get attributes of any home assistant entity"; - parameters = { - type = "object"; - - properties = { - entity_id = { - type = "string"; - description = "entity_id"; - }; - }; - - required = ["entity_id"]; - }; - }; - - function = { - type = "template"; - value_template = "{{ states[entity_id] }}"; - }; - } -] diff --git a/configurations/homie/modules/home-assistant/docs/prompt b/configurations/homie/modules/home-assistant/docs/prompt deleted file mode 100644 index 0d32ab55..00000000 --- a/configurations/homie/modules/home-assistant/docs/prompt +++ /dev/null @@ -1,53 +0,0 @@ -{%- set customize_glob_exposed_attributes = { - ".*": { - "friendly_name": true, - "temperature": true, - "current_temperature": true, - "temperature_unit": true, - "brightness": true, - "humidity": true, - "unit_of_measurement": true, - "device_class": true, - "current_position": true, - "percentage": true, - "volume_level": true, - "media_title": true, - "media_artist": true, - "media_album_name": true, - }, -} %} - -{%- macro get_exposed_attributes(entity_id) -%} - {%- set ns = namespace(exposed_attributes = {}, result = {}) %} - {%- for pattern, attributes in customize_glob_exposed_attributes.items() -%} - {%- if entity_id | regex_match(pattern) -%} - {%- set ns.exposed_attributes = dict(ns.exposed_attributes, **attributes) -%} - {%- endif -%} - {%- endfor -%} - {%- for attribute_key, should_include in ns.exposed_attributes.items() -%} - {%- if should_include and state_attr(entity_id, attribute_key) != None -%} - {%- set temp = {attribute_key: state_attr(entity_id, attribute_key)} if should_include is boolean else {attribute_key: should_include} -%} - {%- set ns.result = dict(ns.result, **temp) -%} - {%- endif -%} - {%- endfor -%} - {%- set result = ns.result | to_json if ns.result!={} else None -%} - {{"'" + result + "'" if result != None else ''}} -{%- endmacro -%} - -I want you to act as a personal assistant who is aware of my smart home. -You will truthfully answer in one sentence in everyday language. - -Current Time: {{now()}} - -Available Devices: -```csv -entity_id,name,state,aliases,attributes -{% for entity in exposed_entities -%} -{{ entity.entity_id }},{{ entity.name }},{{ entity.state }},{{entity.aliases | join('/')}},{{get_exposed_attributes(entity.entity_id)}} -{% endfor -%} -``` - -The current state of devices is provided in available devices. -Do not restate what user says. - -Before your response, add "Your local AI says". diff --git a/configurations/homie/modules/home-assistant/firmware.nix b/configurations/homie/modules/home-assistant/firmware.nix deleted file mode 100644 index 1d45d4b5..00000000 --- a/configurations/homie/modules/home-assistant/firmware.nix +++ /dev/null @@ -1,387 +0,0 @@ -{config, ...}: { - services.esphome = { - secretsFile = config.sops.secrets.esphome.path; - - firmwareConfigs = { - # ------------------------------------------------------------- - "AtomEcho" = { - # Device specific settings - api.encryption.key = "!secret api_key"; - - ota = [ - { - platform = "esphome"; - password = "!secret ota_pass"; - } - ]; - - wifi = { - ssid = "!secret wifi_ssid"; - password = "!secret wifi_password"; - - manual_ip = { - static_ip = "192.168.0.92"; - gateway = "192.168.0.1"; - subnet = "255.255.255.0"; - }; - - ap = { - ssid = "Esp1 Fallback Hotspot"; - password = "!secret ap_fallback"; - }; - }; - - # Hardware Declaration - esphome = { - friendly_name = "M5Stack Atom Echo"; - min_version = "2024.9.0"; - name = "m5stack-atom-echo"; - name_add_mac_suffix = true; - }; - - esp32 = { - board = "m5stack-atom"; - framework = { - type = "esp-idf"; - version = "4.4.8"; - platform_version = "5.4.0"; - }; - }; - - esp_adf = {}; - - button = [ - { - id = "button_safe_mode"; - name = "Safe Mode Boot"; - platform = "safe_mode"; - } - { - id = "factory_reset_btn"; - name = "Factory reset"; - platform = "factory_reset"; - } - ]; - - microphone = [ - { - adc_type = "external"; - i2s_din_pin = "GPIO23"; - id = "echo_microphone"; - pdm = true; - platform = "i2s_audio"; - } - ]; - - speaker = [ - { - dac_type = "external"; - i2s_dout_pin = "GPIO21"; # "GPIO22"; turn off speaker - id = "echo_speaker"; - channel = "mono"; - platform = "i2s_audio"; - } - ]; - - i2s_audio = [ - { - id = "i2s_audio_bus"; - i2s_bclk_pin = "GPIO19"; - i2s_lrclk_pin = "GPIO33"; - } - ]; - - light = [ - { - id = "led"; - name = "None"; - entity_category = "config"; - - chipset = "SK6812"; - pin = "GPIO27"; - platform = "esp32_rmt_led_strip"; - - default_transition_length = "0s"; - disabled_by_default = false; - num_leds = 1; - rgb_order = "grb"; - rmt_channel = 0; - - effects = [ - { - pulse = { - name = "Slow Pulse"; - - max_brightness = "100%"; - min_brightness = "50%"; - transition_length = "250ms"; - update_interval = "250ms"; - }; - } - { - pulse = { - name = "Fast Pulse"; - - max_brightness = "100%"; - min_brightness = "50%"; - transition_length = "100ms"; - update_interval = "100ms"; - }; - } - ]; - } - ]; - - # Home-assistant buttons - switch = [ - { - id = "use_wake_word"; - name = "Use wake word"; - entity_category = "config"; - - optimistic = true; - platform = "template"; - restore_mode = "RESTORE_DEFAULT_ON"; - - on_turn_on = [ - {lambda = "id(va).set_use_wake_word(true);";} - { - "if" = { - condition.not = ["voice_assistant.is_running"]; - "then" = ["voice_assistant.start_continuous"]; - }; - } - {"script.execute" = "reset_led";} - ]; - - on_turn_off = [ - "voice_assistant.stop" - {lambda = "id(va).set_use_wake_word(false);";} - {"script.execute" = "reset_led";} - ]; - } - - { - id = "use_listen_light"; - name = "Use listen light"; - entity_category = "config"; - - optimistic = true; - platform = "template"; - restore_mode = "RESTORE_DEFAULT_ON"; - - on_turn_on = [{"script.execute" = "reset_led";}]; - on_turn_off = [{"script.execute" = "reset_led";}]; - } - ]; - - binary_sensor = [ - { - id = "echo_button"; - name = "Button"; - entity_category = "diagnostic"; - - disabled_by_default = false; - - platform = "gpio"; - pin = { - inverted = true; - number = "GPIO39"; - }; - - on_multi_click = [ - { - timing = ["ON for at least 50ms" "OFF for at least 50ms"]; - "then" = [ - { - "if" = { - condition = {"switch.is_off" = "use_wake_word";}; - "then" = [ - { - "if" = { - condition = "voice_assistant.is_running"; - "then" = [ - {"voice_assistant.stop" = {};} - {"script.execute" = "reset_led";} - ]; - "else" = [{"voice_assistant.start" = {};}]; - }; - } - ]; - "else" = [ - "voice_assistant.stop" - {delay = "1s";} - {"script.execute" = "reset_led";} - {"script.wait" = "reset_led";} - {"voice_assistant.start_continuous" = {};} - ]; - }; - } - ]; - } - { - timing = ["ON for at least 10s"]; - "then" = [{"button.press" = "factory_reset_btn";}]; - } - ]; - } - ]; - - # Misc - logger = {}; - - external_components = [ - { - source = "github://pr#5230"; - components = ["esp_adf"]; - refresh = "0s"; - } - ]; - - # Configs - script = [ - { - id = "reset_led"; - "then" = [ - { - "if" = { - condition = [ - {"switch.is_on" = "use_wake_word";} - {"switch.is_on" = "use_listen_light";} - ]; - "then" = [ - { - "light.turn_on" = { - id = "led"; - brightness = "60%"; - effect = "none"; - - red = "100%"; - green = "89%"; - blue = "71%"; - }; - } - ]; - "else" = [{"light.turn_off" = "led";}]; - }; - } - ]; - } - ]; - - voice_assistant = { - id = "va"; - speaker = "echo_speaker"; - microphone = "echo_microphone"; - auto_gain = "31dBFS"; - - noise_suppression_level = 2; - vad_threshold = 3; - volume_multiplier = 2; - - on_listening = [ - { - "light.turn_on" = { - id = "led"; - effect = "Slow Pulse"; - - green = "0%"; - red = "0%"; - blue = "100%"; - }; - } - ]; - - on_stt_vad_end = [ - { - "light.turn_on" = { - id = "led"; - effect = "Fast Pulse"; - - red = "0%"; - green = "0%"; - blue = "100%"; - }; - } - ]; - - on_tts_start = [ - { - "light.turn_on" = { - id = "led"; - brightness = "100%"; - effect = "none"; - - red = "0%"; - green = "0%"; - blue = "100%"; - }; - } - ]; - - # Play audio from bluetooth speaker - on_tts_end = [ - { - "homeassistant.service" = { - service = "media_player.play_media"; - data = { - entity_id = "media_player.music_player_daemon"; - media_content_id = "!lambda \"return x;\""; - media_content_type = "music"; - announce = "\"true\""; - }; - }; - } - ]; - - on_end = [ - {delay = "100ms";} - {wait_until.not."speaker.is_playing" = {};} - {"script.execute" = "reset_led";} - ]; - - on_error = [ - { - "light.turn_on" = { - id = "led"; - brightness = "100%"; - effect = "none"; - - red = "100%"; - green = "0%"; - blue = "0%"; - }; - } - {delay = "1s";} - {"script.execute" = "reset_led";} - ]; - - on_client_connected = [ - { - "if" = { - condition = {"switch.is_on" = "use_wake_word";}; - "then" = [ - {"voice_assistant.start_continuous" = {};} - {"script.execute" = "reset_led";} - ]; - }; - } - ]; - - on_client_disconnected = [ - { - "if" = { - condition = {"switch.is_on" = "use_wake_word";}; - "then" = [ - {"voice_assistant.stop" = {};} - {"light.turn_off" = "led";} - ]; - }; - } - ]; - }; - }; - # ------------------------------------------------------------- - }; - }; -} diff --git a/configurations/homie/modules/home-assistant/frontend.nix b/configurations/homie/modules/home-assistant/frontend.nix deleted file mode 100644 index 1e84fb19..00000000 --- a/configurations/homie/modules/home-assistant/frontend.nix +++ /dev/null @@ -1,391 +0,0 @@ -{ - caule-themes-src, - dracul-ha-src, - lib, - pkgs, - ... -}: let - inherit (lib) attrValues singleton; - inherit (pkgs.writers) writeYAML; -in { - services.home-assistant = { - configFiles = { - "themes/caule.yaml".source = "${caule-themes-src}/themes/caule-themes-pack-1.yaml"; - "themes/dracul-ha.yaml".source = "${dracul-ha-src}/themes/dracul-ha.yaml"; - "themes/material_you.yaml".source = "${pkgs.scopedPackages.lovelace-components.material-rounded-theme}/share/material_you.yaml"; - - "www/sidebar-config.yaml".source = writeYAML "sidebar" { - id = "my-sidebar"; - - order = [ - # Top - { - item = "overview"; - order = 1; - } - { - match = "href"; - item = "calendar"; - order = 2; - } - { - match = "href"; - item = "todo"; - order = 3; - } - - # Bottom - { - bottom = true; - item = "esphome"; - order = 5; - } - { - bottom = true; - item = "logbook"; - order = 7; - } - { - bottom = true; - icon = "mdi:tools"; - item = "developer tools"; - name = "Developer tools"; - order = 9; - } - { - bottom = true; - item = "settings"; - order = 11; - } - - # Hidden - { - hide = true; - item = "map"; - } - { - hide = true; - item = "energy"; - } - { - hide = true; - item = "history"; - } - { - hide = true; - item = "media"; - } - ]; - }; - }; - - customComponents = attrValues { - inherit - (pkgs.scopedPackages.hass-components) - material-symbols - ; - }; - - customLovelaceModules = attrValues { - inherit - (pkgs.home-assistant-custom-lovelace-modules) - card-mod - light-entity-card - universal-remote-card - ; - - inherit - (pkgs.scopedPackages.lovelace-components) - big-slider-card - custom-sidebar - material-you-utilities - ; - }; - - config.frontend = { - themes = "!include_dir_merge_named themes"; - extra_module_url = map (p: "/local/nixos-lovelace-modules/${p}.js") [ - "big-slider-card" - "card-mod" - "custom-sidebar-yaml" - "material-you-utilities" - ]; - }; - - config.panel_custom = [ - { - name = "material-you-panel"; - url_path = "material-you-configuration"; - sidebar_title = "Material You Utilities"; - sidebar_icon = "mdi:material-design"; - module_url = "/local/nixos-lovelace-modules/material-you-utilities.js"; - } - ]; - - config.template = [ - { - sensor = singleton { - name = "Material Rounded Base Color Matt"; - unique_id = "material_rounded_base_color_matt"; - state = ''{{ states("sensor.pixel_8_accent_color") }}''; - }; - } - ]; - - config.input_text = { - bathroom_light_brightness = { - name = "BathroomLightBrightness"; - icon = "mdi:lightbulb"; - # restricts to 0-100 - pattern = "^(0|[1-9][0-9]?|100)$"; - initial = "0"; - max = 3; - }; - - bathroom_light_temperature = { - name = "BathroomLightTemperature"; - pattern = "[0-9]*"; - initial = "0"; - }; - }; - - lovelaceConfig = { - title = "Our House"; - # I don't want multiple views - views = singleton { - path = "home"; - title = "Home"; - cards = [ - { - type = "entities"; - entities = [ - "switch.smartplug1" - "switch.smartplug2" - "switch.smartplug3" - ]; - } - { - type = "entities"; - entities = [ - "timer.assist_timer1" - "timer.assist_timer2" - "timer.assist_timer3" - ]; - } - - { - type = "custom:light-entity-card"; - entity = "light.bathroomceiling"; - - shorten_cards = false; - consolidate_entities = false; - child_card = false; - hide_header = false; - show_header_icon = false; - header = ""; - color_wheel = true; - persist_features = true; - brightness = true; - color_temp = true; - white_value = true; - color_picker = true; - speed = true; - intensity = false; - force_features = false; - show_slider_percent = true; - full_width_sliders = true; - brightness_icon = "weather-sunny"; - white_icon = "file-word-box"; - temperature_icon = "thermometer"; - speed_icon = "speedometer"; - intensity_icon = "transit-connection-horizontal"; - } - - { - type = "custom:android-tv-card"; - - visibility = singleton { - condition = "state"; - entity = "remote.onn_4k_streaming_box"; - state_not = ["unavailable" "unknown"]; - }; - - media_player_id = "media_player.living_room_speaker"; - keyboard_id = "remote.android_tv_192_168_0_106"; - remote_id = "remote.onn_4k_streaming_box"; - - rows = [ - "navigation_buttons" - [null "slider" null] - [null] - ["jellyfin" "home" "back" "keyboard"] - [null] - ]; - - custom_actions = [ - { - name = "center"; - type = "button"; - icon = "mdi:checkbox-blank-circle"; - - styles = '' - :host { - --icon-color: rgb(94, 94, 94); - --size: 200px; - background: rgb(31, 31, 31); - border-radius: 200px; - margin: -70px; - padding: 70px; - } - ''; - - tap_action = { - action = "key"; - key = "DPAD_CENTER"; - }; - } - - { - name = "up"; - type = "button"; - icon = "mdi:chevron-up"; - - styles = '' - :host { - --icon-color: rgb(197, 199, 197); - z-index: 2; - top: 25px; - height: 90px; - width: 300px; - } - ''; - - hold_action = {action = "repeat";}; - tap_action = { - action = "key"; - key = "DPAD_UP"; - }; - } - - { - name = "down"; - type = "button"; - icon = "mdi:chevron-down"; - - styles = '' - :host { - --icon-color: rgb(197, 199, 197); - z-index: 2; - bottom: 25px; - height: 90px; - width: 300px; - } - ''; - - hold_action = {action = "repeat";}; - tap_action = { - action = "key"; - key = "DPAD_DOWN"; - }; - } - - { - name = "left"; - type = "button"; - icon = "mdi:chevron-left"; - - styles = '' - :host { - --icon-color: rgb(197, 199, 197); - z-index: 2; - left: 30px; - height: 170px; - width: 90px; - } - ''; - - hold_action = {action = "repeat";}; - tap_action = { - action = "key"; - key = "DPAD_LEFT"; - }; - } - - { - name = "right"; - type = "button"; - icon = "mdi:chevron-right"; - - styles = '' - :host { - --icon-color: rgb(197, 199, 197); - z-index: 2; - right: 30px; - height: 170px; - width: 90px; - } - ''; - - hold_action = {action = "repeat";}; - tap_action = { - action = "key"; - key = "DPAD_RIGHT"; - }; - } - - { - name = "slider"; - type = "slider"; - icon = "mdi:volume-high"; - - range = [0 1]; - step = 0.01; - - tap_action = { - action = "perform-action"; - perform_action = "media_player.volume_set"; - data = { - volume_level = "{{ value | float }}"; - }; - }; - value_attribute = "volume_level"; - } - ]; - - styles = '' - #row-1 { - justify-content: center; - } - - #row-2 { - justify-content: center; - } - - #row-3 { - justify-content: center; - } - ''; - } - ]; - }; - }; - - config.lovelace.dashboards = { - esphome-dash = { - title = "ESPHome"; - icon = "mdi:car-esp"; - mode = "yaml"; - - show_in_sidebar = true; - require_admin = true; - - filename = writeYAML "esphome.yaml" { - strategy = { - type = "iframe"; - url = "https://esphome.nelim.org"; - }; - }; - }; - }; - }; -} diff --git a/configurations/homie/modules/home-assistant/netdaemon/.editorconfig b/configurations/homie/modules/home-assistant/netdaemon/.editorconfig deleted file mode 100644 index 371fa8c8..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/.editorconfig +++ /dev/null @@ -1,360 +0,0 @@ -root = true - -# All files -[*] -indent_style = space - -# C# files -[*.cs] - -#### Core EditorConfig Options #### - -# Indentation and spacing -indent_size = 4 -tab_width = 4 - -# New line preferences -end_of_line = lf -insert_final_newline = true - -#### .NET Coding Conventions #### -[*.{cs,vb}] - -# Organize usings -dotnet_separate_import_directive_groups = true -dotnet_sort_system_directives_first = true -file_header_template = unset - -# this. and Me. preferences -dotnet_style_qualification_for_event = true -dotnet_style_qualification_for_field = true -dotnet_style_qualification_for_method = true -dotnet_style_qualification_for_property = true - -# Language keywords vs BCL types preferences -dotnet_style_predefined_type_for_locals_parameters_members = true:silent -dotnet_style_predefined_type_for_member_access = true:silent - -# Parentheses preferences -dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent -dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent - -# Modifier preferences -dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent - -# Expression-level preferences -dotnet_style_coalesce_expression = true:suggestion -dotnet_style_collection_initializer = true:suggestion -dotnet_style_explicit_tuple_names = true:suggestion -dotnet_style_null_propagation = true:suggestion -dotnet_style_object_initializer = true:suggestion -dotnet_style_operator_placement_when_wrapping = beginning_of_line -dotnet_style_prefer_auto_properties = true:suggestion -dotnet_style_prefer_compound_assignment = true:suggestion -dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion -dotnet_style_prefer_conditional_expression_over_return = true:suggestion -dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion -dotnet_style_prefer_inferred_tuple_names = true:suggestion -dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion -dotnet_style_prefer_simplified_boolean_expressions = true:suggestion -dotnet_style_prefer_simplified_interpolation = true:suggestion - -# Field preferences -dotnet_style_readonly_field = true:warning - -# Parameter preferences -dotnet_code_quality_unused_parameters = all:suggestion - -# Suppression preferences -dotnet_remove_unnecessary_suppression_exclusions = none - -#### C# Coding Conventions #### -[*.cs] - -# var preferences -csharp_style_var_elsewhere = false:silent -csharp_style_var_for_built_in_types = false:silent -csharp_style_var_when_type_is_apparent = false:silent - -# Expression-bodied members -csharp_style_expression_bodied_accessors = true:silent -csharp_style_expression_bodied_constructors = false:silent -csharp_style_expression_bodied_indexers = true:silent -csharp_style_expression_bodied_lambdas = true:suggestion -csharp_style_expression_bodied_local_functions = false:silent -csharp_style_expression_bodied_methods = false:silent -csharp_style_expression_bodied_operators = false:silent -csharp_style_expression_bodied_properties = true:silent - -# Pattern matching preferences -csharp_style_pattern_matching_over_as_with_null_check = true:suggestion -csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion -csharp_style_prefer_not_pattern = true:suggestion -csharp_style_prefer_pattern_matching = true:silent -csharp_style_prefer_switch_expression = true:suggestion - -# Null-checking preferences -csharp_style_conditional_delegate_call = true:suggestion - -# Modifier preferences -csharp_prefer_static_local_function = true:warning -csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent - -# Code-block preferences -csharp_prefer_braces = true:silent -csharp_prefer_simple_using_statement = true:suggestion - -# Expression-level preferences -csharp_prefer_simple_default_expression = true:suggestion -csharp_style_deconstructed_variable_declaration = true:suggestion -csharp_style_inlined_variable_declaration = true:suggestion -csharp_style_pattern_local_over_anonymous_function = true:suggestion -csharp_style_prefer_index_operator = true:suggestion -csharp_style_prefer_range_operator = true:suggestion -csharp_style_throw_expression = true:suggestion -csharp_style_unused_value_assignment_preference = discard_variable:suggestion -csharp_style_unused_value_expression_statement_preference = discard_variable:silent - -# 'using' directive preferences -csharp_using_directive_placement = outside_namespace:silent - -#### C# Formatting Rules #### - -# New line preferences -csharp_new_line_before_catch = true -csharp_new_line_before_else = true -csharp_new_line_before_finally = true -csharp_new_line_before_members_in_anonymous_types = true -csharp_new_line_before_members_in_object_initializers = true -csharp_new_line_before_open_brace = all -csharp_new_line_between_query_expression_clauses = true - -# Indentation preferences -csharp_indent_block_contents = true -csharp_indent_braces = false -csharp_indent_case_contents = true -csharp_indent_case_contents_when_block = true -csharp_indent_labels = one_less_than_current -csharp_indent_switch_labels = true - -# Space preferences -csharp_space_after_cast = false -csharp_space_after_colon_in_inheritance_clause = true -csharp_space_after_comma = true -csharp_space_after_dot = false -csharp_space_after_keywords_in_control_flow_statements = true -csharp_space_after_semicolon_in_for_statement = true -csharp_space_around_binary_operators = before_and_after -csharp_space_around_declaration_statements = false -csharp_space_before_colon_in_inheritance_clause = true -csharp_space_before_comma = false -csharp_space_before_dot = false -csharp_space_before_open_square_brackets = false -csharp_space_before_semicolon_in_for_statement = false -csharp_space_between_empty_square_brackets = false -csharp_space_between_method_call_empty_parameter_list_parentheses = false -csharp_space_between_method_call_name_and_opening_parenthesis = false -csharp_space_between_method_call_parameter_list_parentheses = false -csharp_space_between_method_declaration_empty_parameter_list_parentheses = false -csharp_space_between_method_declaration_name_and_open_parenthesis = false -csharp_space_between_method_declaration_parameter_list_parentheses = false -csharp_space_between_parentheses = false -csharp_space_between_square_brackets = false - -# Wrapping preferences -csharp_preserve_single_line_blocks = true -csharp_preserve_single_line_statements = true - -#### Naming styles #### -[*.{cs,vb}] - -# Naming rules - -dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.severity = suggestion -dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.symbols = types_and_namespaces -dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.style = pascalcase - -dotnet_naming_rule.interfaces_should_be_ipascalcase.severity = suggestion -dotnet_naming_rule.interfaces_should_be_ipascalcase.symbols = interfaces -dotnet_naming_rule.interfaces_should_be_ipascalcase.style = ipascalcase - -dotnet_naming_rule.type_parameters_should_be_tpascalcase.severity = suggestion -dotnet_naming_rule.type_parameters_should_be_tpascalcase.symbols = type_parameters -dotnet_naming_rule.type_parameters_should_be_tpascalcase.style = tpascalcase - -dotnet_naming_rule.methods_should_be_pascalcase.severity = suggestion -dotnet_naming_rule.methods_should_be_pascalcase.symbols = methods -dotnet_naming_rule.methods_should_be_pascalcase.style = pascalcase - -dotnet_naming_rule.properties_should_be_pascalcase.severity = none -dotnet_naming_rule.properties_should_be_pascalcase.symbols = properties -dotnet_naming_rule.properties_should_be_pascalcase.style = pascalcase - -dotnet_naming_rule.events_should_be_pascalcase.severity = suggestion -dotnet_naming_rule.events_should_be_pascalcase.symbols = events -dotnet_naming_rule.events_should_be_pascalcase.style = pascalcase - -dotnet_naming_rule.local_variables_should_be_camelcase.severity = suggestion -dotnet_naming_rule.local_variables_should_be_camelcase.symbols = local_variables -dotnet_naming_rule.local_variables_should_be_camelcase.style = camelcase - -dotnet_naming_rule.local_constants_should_be_camelcase.severity = suggestion -dotnet_naming_rule.local_constants_should_be_camelcase.symbols = local_constants -dotnet_naming_rule.local_constants_should_be_camelcase.style = camelcase - -dotnet_naming_rule.parameters_should_be_camelcase.severity = suggestion -dotnet_naming_rule.parameters_should_be_camelcase.symbols = parameters -dotnet_naming_rule.parameters_should_be_camelcase.style = camelcase - -dotnet_naming_rule.public_fields_should_be_pascalcase.severity = suggestion -dotnet_naming_rule.public_fields_should_be_pascalcase.symbols = public_fields -dotnet_naming_rule.public_fields_should_be_pascalcase.style = pascalcase - -dotnet_naming_rule.private_fields_should_be__camelcase.severity = suggestion -dotnet_naming_rule.private_fields_should_be__camelcase.symbols = private_fields -dotnet_naming_rule.private_fields_should_be__camelcase.style = _camelcase - -dotnet_naming_rule.private_static_fields_should_be_s_camelcase.severity = suggestion -dotnet_naming_rule.private_static_fields_should_be_s_camelcase.symbols = private_static_fields -dotnet_naming_rule.private_static_fields_should_be_s_camelcase.style = s_camelcase - -dotnet_naming_rule.public_constant_fields_should_be_pascalcase.severity = suggestion -dotnet_naming_rule.public_constant_fields_should_be_pascalcase.symbols = public_constant_fields -dotnet_naming_rule.public_constant_fields_should_be_pascalcase.style = pascalcase - -dotnet_naming_rule.private_constant_fields_should_be_pascalcase.severity = suggestion -dotnet_naming_rule.private_constant_fields_should_be_pascalcase.symbols = private_constant_fields -dotnet_naming_rule.private_constant_fields_should_be_pascalcase.style = pascalcase - -dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.severity = suggestion -dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.symbols = public_static_readonly_fields -dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.style = pascalcase - -dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.severity = suggestion -dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.symbols = private_static_readonly_fields -dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.style = pascalcase - -dotnet_naming_rule.enums_should_be_pascalcase.severity = suggestion -dotnet_naming_rule.enums_should_be_pascalcase.symbols = enums -dotnet_naming_rule.enums_should_be_pascalcase.style = pascalcase - -dotnet_naming_rule.local_functions_should_be_pascalcase.severity = suggestion -dotnet_naming_rule.local_functions_should_be_pascalcase.symbols = local_functions -dotnet_naming_rule.local_functions_should_be_pascalcase.style = pascalcase - -dotnet_naming_rule.non_field_members_should_be_pascalcase.severity = suggestion -dotnet_naming_rule.non_field_members_should_be_pascalcase.symbols = non_field_members -dotnet_naming_rule.non_field_members_should_be_pascalcase.style = pascalcase - -# Symbol specifications - -dotnet_naming_symbols.interfaces.applicable_kinds = interface -dotnet_naming_symbols.interfaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.interfaces.required_modifiers = - -dotnet_naming_symbols.enums.applicable_kinds = enum -dotnet_naming_symbols.enums.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.enums.required_modifiers = - -dotnet_naming_symbols.events.applicable_kinds = event -dotnet_naming_symbols.events.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.events.required_modifiers = - -dotnet_naming_symbols.methods.applicable_kinds = method -dotnet_naming_symbols.methods.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.methods.required_modifiers = - -dotnet_naming_symbols.properties.applicable_kinds = property -dotnet_naming_symbols.properties.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.properties.required_modifiers = - -dotnet_naming_symbols.public_fields.applicable_kinds = field -dotnet_naming_symbols.public_fields.applicable_accessibilities = public, internal -dotnet_naming_symbols.public_fields.required_modifiers = - -dotnet_naming_symbols.private_fields.applicable_kinds = field -dotnet_naming_symbols.private_fields.applicable_accessibilities = private, protected, protected_internal, private_protected -dotnet_naming_symbols.private_fields.required_modifiers = - -dotnet_naming_symbols.private_static_fields.applicable_kinds = field -dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private, protected, protected_internal, private_protected -dotnet_naming_symbols.private_static_fields.required_modifiers = static - -dotnet_naming_symbols.types_and_namespaces.applicable_kinds = namespace, class, struct, interface, enum -dotnet_naming_symbols.types_and_namespaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.types_and_namespaces.required_modifiers = - -dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method -dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.non_field_members.required_modifiers = - -dotnet_naming_symbols.type_parameters.applicable_kinds = namespace -dotnet_naming_symbols.type_parameters.applicable_accessibilities = * -dotnet_naming_symbols.type_parameters.required_modifiers = - -dotnet_naming_symbols.private_constant_fields.applicable_kinds = field -dotnet_naming_symbols.private_constant_fields.applicable_accessibilities = private, protected, protected_internal, private_protected -dotnet_naming_symbols.private_constant_fields.required_modifiers = const - -dotnet_naming_symbols.local_variables.applicable_kinds = local -dotnet_naming_symbols.local_variables.applicable_accessibilities = local -dotnet_naming_symbols.local_variables.required_modifiers = - -dotnet_naming_symbols.local_constants.applicable_kinds = local -dotnet_naming_symbols.local_constants.applicable_accessibilities = local -dotnet_naming_symbols.local_constants.required_modifiers = const - -dotnet_naming_symbols.parameters.applicable_kinds = parameter -dotnet_naming_symbols.parameters.applicable_accessibilities = * -dotnet_naming_symbols.parameters.required_modifiers = - -dotnet_naming_symbols.public_constant_fields.applicable_kinds = field -dotnet_naming_symbols.public_constant_fields.applicable_accessibilities = public, internal -dotnet_naming_symbols.public_constant_fields.required_modifiers = const - -dotnet_naming_symbols.public_static_readonly_fields.applicable_kinds = field -dotnet_naming_symbols.public_static_readonly_fields.applicable_accessibilities = public, internal -dotnet_naming_symbols.public_static_readonly_fields.required_modifiers = readonly, static - -dotnet_naming_symbols.private_static_readonly_fields.applicable_kinds = field -dotnet_naming_symbols.private_static_readonly_fields.applicable_accessibilities = private, protected, protected_internal, private_protected -dotnet_naming_symbols.private_static_readonly_fields.required_modifiers = readonly, static - -dotnet_naming_symbols.local_functions.applicable_kinds = local_function -dotnet_naming_symbols.local_functions.applicable_accessibilities = * -dotnet_naming_symbols.local_functions.required_modifiers = - -# Naming styles - -dotnet_naming_style.pascalcase.required_prefix = -dotnet_naming_style.pascalcase.required_suffix = -dotnet_naming_style.pascalcase.word_separator = -dotnet_naming_style.pascalcase.capitalization = pascal_case - -dotnet_naming_style.ipascalcase.required_prefix = I -dotnet_naming_style.ipascalcase.required_suffix = -dotnet_naming_style.ipascalcase.word_separator = -dotnet_naming_style.ipascalcase.capitalization = pascal_case - -dotnet_naming_style.tpascalcase.required_prefix = T -dotnet_naming_style.tpascalcase.required_suffix = -dotnet_naming_style.tpascalcase.word_separator = -dotnet_naming_style.tpascalcase.capitalization = pascal_case - -dotnet_naming_style._camelcase.required_prefix = _ -dotnet_naming_style._camelcase.required_suffix = -dotnet_naming_style._camelcase.word_separator = -dotnet_naming_style._camelcase.capitalization = camel_case - -dotnet_naming_style.camelcase.required_prefix = -dotnet_naming_style.camelcase.required_suffix = -dotnet_naming_style.camelcase.word_separator = -dotnet_naming_style.camelcase.capitalization = camel_case - -dotnet_naming_style.s_camelcase.required_prefix = s_ -dotnet_naming_style.s_camelcase.required_suffix = -dotnet_naming_style.s_camelcase.word_separator = -dotnet_naming_style.s_camelcase.capitalization = camel_case - diff --git a/configurations/homie/modules/home-assistant/netdaemon/.envrc b/configurations/homie/modules/home-assistant/netdaemon/.envrc deleted file mode 100644 index 6c6e7886..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/.envrc +++ /dev/null @@ -1,2 +0,0 @@ -use flake "$FLAKE#netdaemon" -cp -rf ./HomeAssistantGenerated ./HomeAssistantGenerated.cs diff --git a/configurations/homie/modules/home-assistant/netdaemon/.gitignore b/configurations/homie/modules/home-assistant/netdaemon/.gitignore deleted file mode 100644 index 3d6d7307..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -obj -bin -NetDaemonCodegen -HomeAssistantGenerated.cs diff --git a/configurations/homie/modules/home-assistant/netdaemon/.version b/configurations/homie/modules/home-assistant/netdaemon/.version deleted file mode 100644 index a3b77523..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/.version +++ /dev/null @@ -1 +0,0 @@ -25.14.1 diff --git a/configurations/homie/modules/home-assistant/netdaemon/HomeAssistantGenerated b/configurations/homie/modules/home-assistant/netdaemon/HomeAssistantGenerated deleted file mode 100644 index 8d1b0d88..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/HomeAssistantGenerated +++ /dev/null @@ -1,13567 +0,0 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// Generated using NetDaemon CodeGenerator nd-codegen v25.14.1.0 -// At: 2025-04-14T14:05:15.5864843-04:00 -// -// *** Make sure the version of the codegen tool and your nugets NetDaemon.* have the same version.*** -// You can use following command to keep it up to date with the latest version: -// dotnet tool update NetDaemon.HassModel.CodeGen -// -// To update this file with latest entities run this command in your project directory: -// dotnet tool run nd-codegen -// -// In the template projects we provided a convenience powershell script that will update -// the codegen and nugets to latest versions update_all_dependencies.ps1. -// -// For more information: https://netdaemon.xyz/docs/user/hass_model/hass_model_codegen -// For more information about NetDaemon: https://netdaemon.xyz/ -// </auto-generated> -//------------------------------------------------------------------------------ -#nullable enable -using System; -using System.Linq; -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using System.Text.Json; -using System.Text.Json.Serialization; -using NetDaemon.HassModel; -using NetDaemon.HassModel.Entities; -using NetDaemon.HassModel.Entities.Core; - -namespace HomeAssistantGenerated; -public static class GeneratedExtensions -{ - ///<summary>Registers all injectable generated types in the serviceCollection</summary> - public static IServiceCollection AddHomeAssistantGenerated(this IServiceCollection serviceCollection) - { - serviceCollection.AddTransient<IEntityFactory, GeneratedEntityFactory>(); - serviceCollection.AddTransient<Entities>(); - serviceCollection.AddTransient<LightEntities>(); - serviceCollection.AddTransient<MediaPlayerEntities>(); - serviceCollection.AddTransient<AssistSatelliteEntities>(); - serviceCollection.AddTransient<AutomationEntities>(); - serviceCollection.AddTransient<BinarySensorEntities>(); - serviceCollection.AddTransient<ButtonEntities>(); - serviceCollection.AddTransient<CalendarEntities>(); - serviceCollection.AddTransient<ConversationEntities>(); - serviceCollection.AddTransient<DeviceTrackerEntities>(); - serviceCollection.AddTransient<InputBooleanEntities>(); - serviceCollection.AddTransient<InputTextEntities>(); - serviceCollection.AddTransient<LockEntities>(); - serviceCollection.AddTransient<NumberEntities>(); - serviceCollection.AddTransient<PersonEntities>(); - serviceCollection.AddTransient<RemoteEntities>(); - serviceCollection.AddTransient<ScriptEntities>(); - serviceCollection.AddTransient<SelectEntities>(); - serviceCollection.AddTransient<SensorEntities>(); - serviceCollection.AddTransient<SensorEntities>(); - serviceCollection.AddTransient<SttEntities>(); - serviceCollection.AddTransient<SunEntities>(); - serviceCollection.AddTransient<SwitchEntities>(); - serviceCollection.AddTransient<TimerEntities>(); - serviceCollection.AddTransient<TodoEntities>(); - serviceCollection.AddTransient<TtsEntities>(); - serviceCollection.AddTransient<WakeWordEntities>(); - serviceCollection.AddTransient<WeatherEntities>(); - serviceCollection.AddTransient<ZoneEntities>(); - serviceCollection.AddTransient<UpdateEntities>(); - serviceCollection.AddTransient<InputNumberEntities>(); - serviceCollection.AddTransient<Services>(); - serviceCollection.AddTransient<AndroidtvServices>(); - serviceCollection.AddTransient<AssistSatelliteServices>(); - serviceCollection.AddTransient<AutomationServices>(); - serviceCollection.AddTransient<BackupServices>(); - serviceCollection.AddTransient<ButtonServices>(); - serviceCollection.AddTransient<CalendarServices>(); - serviceCollection.AddTransient<CastServices>(); - serviceCollection.AddTransient<ClimateServices>(); - serviceCollection.AddTransient<ConversationServices>(); - serviceCollection.AddTransient<CounterServices>(); - serviceCollection.AddTransient<DeviceTrackerServices>(); - serviceCollection.AddTransient<ExtendedOllamaConversationServices>(); - serviceCollection.AddTransient<FfmpegServices>(); - serviceCollection.AddTransient<FrontendServices>(); - serviceCollection.AddTransient<HomeassistantServices>(); - serviceCollection.AddTransient<InputBooleanServices>(); - serviceCollection.AddTransient<InputButtonServices>(); - serviceCollection.AddTransient<InputDatetimeServices>(); - serviceCollection.AddTransient<InputNumberServices>(); - serviceCollection.AddTransient<InputSelectServices>(); - serviceCollection.AddTransient<InputTextServices>(); - serviceCollection.AddTransient<IntentScriptServices>(); - serviceCollection.AddTransient<LightServices>(); - serviceCollection.AddTransient<LockServices>(); - serviceCollection.AddTransient<LogbookServices>(); - serviceCollection.AddTransient<LoggerServices>(); - serviceCollection.AddTransient<LovelaceServices>(); - serviceCollection.AddTransient<MediaPlayerServices>(); - serviceCollection.AddTransient<MqttServices>(); - serviceCollection.AddTransient<NetdaemonServices>(); - serviceCollection.AddTransient<NotifyServices>(); - serviceCollection.AddTransient<NumberServices>(); - serviceCollection.AddTransient<PersistentNotificationServices>(); - serviceCollection.AddTransient<PersonServices>(); - serviceCollection.AddTransient<RecorderServices>(); - serviceCollection.AddTransient<RemoteServices>(); - serviceCollection.AddTransient<RestServices>(); - serviceCollection.AddTransient<SceneServices>(); - serviceCollection.AddTransient<ScheduleServices>(); - serviceCollection.AddTransient<ScriptServices>(); - serviceCollection.AddTransient<SelectServices>(); - serviceCollection.AddTransient<ShellCommandServices>(); - serviceCollection.AddTransient<ShoppingListServices>(); - serviceCollection.AddTransient<SpotifyplusServices>(); - serviceCollection.AddTransient<SwitchServices>(); - serviceCollection.AddTransient<SystemLogServices>(); - serviceCollection.AddTransient<TemplateServices>(); - serviceCollection.AddTransient<TimerServices>(); - serviceCollection.AddTransient<TodoServices>(); - serviceCollection.AddTransient<TtsServices>(); - serviceCollection.AddTransient<UpdateServices>(); - serviceCollection.AddTransient<WeatherServices>(); - serviceCollection.AddTransient<YamahaSoundbarServices>(); - serviceCollection.AddTransient<ZoneServices>(); - return serviceCollection; - } -} - -/// <summary> -/// Allows HassModel to instantiate the correct generated Entity types -/// </summary> -public class GeneratedEntityFactory : IEntityFactory -{ - public Entity CreateEntity(IHaContext haContext, string entityId) - { - var dot = entityId.IndexOf('.', StringComparison.Ordinal); - var domain = dot < 0 ? entityId.AsSpan() : entityId[..dot]; - return domain switch - { - "assist_satellite" => new AssistSatelliteEntity(haContext, entityId), - "automation" => new AutomationEntity(haContext, entityId), - "binary_sensor" => new BinarySensorEntity(haContext, entityId), - "button" => new ButtonEntity(haContext, entityId), - "calendar" => new CalendarEntity(haContext, entityId), - "conversation" => new ConversationEntity(haContext, entityId), - "device_tracker" => new DeviceTrackerEntity(haContext, entityId), - "input_boolean" => new InputBooleanEntity(haContext, entityId), - "input_number" => new InputNumberEntity(haContext, entityId), - "input_text" => new InputTextEntity(haContext, entityId), - "light" => new LightEntity(haContext, entityId), - "lock" => new LockEntity(haContext, entityId), - "media_player" => new MediaPlayerEntity(haContext, entityId), - "number" => new NumberEntity(haContext, entityId), - "person" => new PersonEntity(haContext, entityId), - "remote" => new RemoteEntity(haContext, entityId), - "script" => new ScriptEntity(haContext, entityId), - "select" => new SelectEntity(haContext, entityId), - "sensor" when IsNumeric() => new NumericSensorEntity(haContext, entityId), - "sensor" => new SensorEntity(haContext, entityId), - "stt" => new SttEntity(haContext, entityId), - "sun" => new SunEntity(haContext, entityId), - "switch" => new SwitchEntity(haContext, entityId), - "timer" => new TimerEntity(haContext, entityId), - "todo" => new TodoEntity(haContext, entityId), - "tts" => new TtsEntity(haContext, entityId), - "update" => new UpdateEntity(haContext, entityId), - "wake_word" => new WakeWordEntity(haContext, entityId), - "weather" => new WeatherEntity(haContext, entityId), - "zone" => new ZoneEntity(haContext, entityId), - _ => new Entity(haContext, entityId)}; - bool IsNumeric() => haContext.GetState(entityId)?.AttributesJson?.TryGetProperty("unit_of_measurement", out _) ?? false; - } -} - -public interface IEntities -{ - LightEntities Light { get; } - - MediaPlayerEntities MediaPlayer { get; } - - AssistSatelliteEntities AssistSatellite { get; } - - AutomationEntities Automation { get; } - - BinarySensorEntities BinarySensor { get; } - - ButtonEntities Button { get; } - - CalendarEntities Calendar { get; } - - ConversationEntities Conversation { get; } - - DeviceTrackerEntities DeviceTracker { get; } - - InputBooleanEntities InputBoolean { get; } - - InputTextEntities InputText { get; } - - LockEntities Lock { get; } - - NumberEntities Number { get; } - - PersonEntities Person { get; } - - RemoteEntities Remote { get; } - - ScriptEntities Script { get; } - - SelectEntities Select { get; } - - SensorEntities Sensor { get; } - - SttEntities Stt { get; } - - SunEntities Sun { get; } - - SwitchEntities Switch { get; } - - TimerEntities Timer { get; } - - TodoEntities Todo { get; } - - TtsEntities Tts { get; } - - WakeWordEntities WakeWord { get; } - - WeatherEntities Weather { get; } - - ZoneEntities Zone { get; } - - UpdateEntities Update { get; } - - InputNumberEntities InputNumber { get; } -} - -public partial class Entities : IEntities -{ - private readonly IHaContext _haContext; - public Entities(IHaContext haContext) - { - _haContext = haContext; - } - - public LightEntities Light => new(_haContext); - public MediaPlayerEntities MediaPlayer => new(_haContext); - public AssistSatelliteEntities AssistSatellite => new(_haContext); - public AutomationEntities Automation => new(_haContext); - public BinarySensorEntities BinarySensor => new(_haContext); - public ButtonEntities Button => new(_haContext); - public CalendarEntities Calendar => new(_haContext); - public ConversationEntities Conversation => new(_haContext); - public DeviceTrackerEntities DeviceTracker => new(_haContext); - public InputBooleanEntities InputBoolean => new(_haContext); - public InputTextEntities InputText => new(_haContext); - public LockEntities Lock => new(_haContext); - public NumberEntities Number => new(_haContext); - public PersonEntities Person => new(_haContext); - public RemoteEntities Remote => new(_haContext); - public ScriptEntities Script => new(_haContext); - public SelectEntities Select => new(_haContext); - public SensorEntities Sensor => new(_haContext); - public SttEntities Stt => new(_haContext); - public SunEntities Sun => new(_haContext); - public SwitchEntities Switch => new(_haContext); - public TimerEntities Timer => new(_haContext); - public TodoEntities Todo => new(_haContext); - public TtsEntities Tts => new(_haContext); - public WakeWordEntities WakeWord => new(_haContext); - public WeatherEntities Weather => new(_haContext); - public ZoneEntities Zone => new(_haContext); - public UpdateEntities Update => new(_haContext); - public InputNumberEntities InputNumber => new(_haContext); -} - -public partial class LightEntities -{ - private readonly IHaContext _haContext; - public LightEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all light entities currently registered (at runtime) in Home Assistant as LightEntity</summary> - public IEnumerable<LightEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("light.")).Select(e => new LightEntity(e)); - ///<summary>BathroomCeiling</summary> - public LightEntity Bathroomceiling => new(_haContext, "light.bathroomceiling"); - ///<summary>M5Stack Atom Echo 31196c </summary> - public LightEntity M5stackAtomEcho31196cM5stackAtomEcho31196c => new(_haContext, "light.m5stack_atom_echo_31196c_m5stack_atom_echo_31196c"); -} - -public partial class MediaPlayerEntities -{ - private readonly IHaContext _haContext; - public MediaPlayerEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all media_player entities currently registered (at runtime) in Home Assistant as MediaPlayerEntity</summary> - public IEnumerable<MediaPlayerEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("media_player.")).Select(e => new MediaPlayerEntity(e)); - ///<summary>Android TV 192.168.0.106</summary> - public MediaPlayerEntity AndroidTv1921680106 => new(_haContext, "media_player.android_tv_192_168_0_106"); - ///<summary>YAS_209</summary> - public MediaPlayerEntity LivingRoomSpeaker => new(_haContext, "media_player.living_room_speaker"); - ///<summary>UE Boom 2</summary> - public MediaPlayerEntity MusicPlayerDaemon => new(_haContext, "media_player.music_player_daemon"); - ///<summary>Living room TV</summary> - public MediaPlayerEntity Onn4kStreamingBox => new(_haContext, "media_player.onn_4k_streaming_box"); - ///<summary>Living room TV</summary> - public MediaPlayerEntity Onn4kStreamingBox2 => new(_haContext, "media_player.onn_4k_streaming_box_2"); - ///<summary>Spotify matt</summary> - public MediaPlayerEntity SpotifyMatt => new(_haContext, "media_player.spotify_matt"); - ///<summary>SpotifyPlus matt</summary> - public MediaPlayerEntity Spotifyplus => new(_haContext, "media_player.spotifyplus"); -} - -public partial class AssistSatelliteEntities -{ - private readonly IHaContext _haContext; - public AssistSatelliteEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all assist_satellite entities currently registered (at runtime) in Home Assistant as AssistSatelliteEntity</summary> - public IEnumerable<AssistSatelliteEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("assist_satellite.")).Select(e => new AssistSatelliteEntity(e)); - ///<summary>M5Stack Atom Echo 31196c Assist satellite</summary> - public AssistSatelliteEntity M5stackAtomEcho31196cAssistSatellite => new(_haContext, "assist_satellite.m5stack_atom_echo_31196c_assist_satellite"); -} - -public partial class AutomationEntities -{ - private readonly IHaContext _haContext; - public AutomationEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all automation entities currently registered (at runtime) in Home Assistant as AutomationEntity</summary> - public IEnumerable<AutomationEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("automation.")).Select(e => new AutomationEntity(e)); - ///<summary>Assist - TimerFinished</summary> - public AutomationEntity AssistTimerfinished => new(_haContext, "automation.assist_timerfinished"); - ///<summary>Assist - TimerReached</summary> - public AutomationEntity AssistTimerreached => new(_haContext, "automation.assist_timerreached"); - ///<summary>Turn On UE</summary> - public AutomationEntity TurnOnUe => new(_haContext, "automation.turn_on_ue"); -} - -public partial class BinarySensorEntities -{ - private readonly IHaContext _haContext; - public BinarySensorEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all binary_sensor entities currently registered (at runtime) in Home Assistant as BinarySensorEntity</summary> - public IEnumerable<BinarySensorEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("binary_sensor.")).Select(e => new BinarySensorEntity(e)); - ///<summary>CODA-4680-FIZ WAN status</summary> - public BinarySensorEntity Coda4680FizWanStatus => new(_haContext, "binary_sensor.coda_4680_fiz_wan_status"); - ///<summary>M5Stack Atom Echo 31196c Button</summary> - public BinarySensorEntity M5stackAtomEcho31196cButton => new(_haContext, "binary_sensor.m5stack_atom_echo_31196c_button"); - ///<summary>Pixel 8 Bluetooth state</summary> - public BinarySensorEntity Pixel8BluetoothState => new(_haContext, "binary_sensor.pixel_8_bluetooth_state"); - ///<summary>Pixel 8 Headphones</summary> - public BinarySensorEntity Pixel8Headphones => new(_haContext, "binary_sensor.pixel_8_headphones"); - ///<summary>Pixel 8 Hotspot state</summary> - public BinarySensorEntity Pixel8HotspotState => new(_haContext, "binary_sensor.pixel_8_hotspot_state"); - ///<summary>Pixel 8 Is charging</summary> - public BinarySensorEntity Pixel8IsCharging => new(_haContext, "binary_sensor.pixel_8_is_charging"); - ///<summary>Pixel 8 Mic muted</summary> - public BinarySensorEntity Pixel8MicMuted => new(_haContext, "binary_sensor.pixel_8_mic_muted"); - ///<summary>Pixel 8 Mobile data</summary> - public BinarySensorEntity Pixel8MobileData => new(_haContext, "binary_sensor.pixel_8_mobile_data"); - ///<summary>Pixel 8 Mobile data roaming</summary> - public BinarySensorEntity Pixel8MobileDataRoaming => new(_haContext, "binary_sensor.pixel_8_mobile_data_roaming"); - ///<summary>Pixel 8 Music active</summary> - public BinarySensorEntity Pixel8MusicActive => new(_haContext, "binary_sensor.pixel_8_music_active"); - ///<summary>Pixel 8 NFC state</summary> - public BinarySensorEntity Pixel8NfcState => new(_haContext, "binary_sensor.pixel_8_nfc_state"); - ///<summary>Pixel 8 Speakerphone</summary> - public BinarySensorEntity Pixel8Speakerphone => new(_haContext, "binary_sensor.pixel_8_speakerphone"); - ///<summary>Pixel 8 Wi-Fi state</summary> - public BinarySensorEntity Pixel8WifiState => new(_haContext, "binary_sensor.pixel_8_wifi_state"); - ///<summary>SLZB-06p7 Ethernet</summary> - public BinarySensorEntity Slzb06p7Ethernet => new(_haContext, "binary_sensor.slzb_06p7_ethernet"); - ///<summary>SLZB-06p7 Internet</summary> - public BinarySensorEntity Slzb06p7Internet => new(_haContext, "binary_sensor.slzb_06p7_internet"); - ///<summary>Zigbee2MQTT Bridge Connection state</summary> - public BinarySensorEntity Zigbee2mqttBridgeConnectionState => new(_haContext, "binary_sensor.zigbee2mqtt_bridge_connection_state"); -} - -public partial class ButtonEntities -{ - private readonly IHaContext _haContext; - public ButtonEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all button entities currently registered (at runtime) in Home Assistant as ButtonEntity</summary> - public IEnumerable<ButtonEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("button.")).Select(e => new ButtonEntity(e)); - ///<summary>M5Stack Atom Echo 31196c Factory reset</summary> - public ButtonEntity M5stackAtomEcho31196cFactoryReset => new(_haContext, "button.m5stack_atom_echo_31196c_factory_reset"); - ///<summary>M5Stack Atom Echo 31196c Safe Mode Boot</summary> - public ButtonEntity M5stackAtomEcho31196cSafeModeBoot => new(_haContext, "button.m5stack_atom_echo_31196c_safe_mode_boot"); - ///<summary>SLZB-06p7 Core restart</summary> - public ButtonEntity Slzb06p7CoreRestart => new(_haContext, "button.slzb_06p7_core_restart"); - ///<summary>SLZB-06p7 Zigbee restart</summary> - public ButtonEntity Slzb06p7ZigbeeRestart => new(_haContext, "button.slzb_06p7_zigbee_restart"); - ///<summary>Zigbee2MQTT Bridge Restart</summary> - public ButtonEntity Zigbee2mqttBridgeRestart => new(_haContext, "button.zigbee2mqtt_bridge_restart"); -} - -public partial class CalendarEntities -{ - private readonly IHaContext _haContext; - public CalendarEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all calendar entities currently registered (at runtime) in Home Assistant as CalendarEntity</summary> - public IEnumerable<CalendarEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("calendar.")).Select(e => new CalendarEntity(e)); - ///<summary>Canada, QC</summary> - public CalendarEntity CanadaQc => new(_haContext, "calendar.canada_qc"); - ///<summary>Contact birthdays</summary> - public CalendarEntity ContactBirthdays => new(_haContext, "calendar.contact_birthdays"); - ///<summary>Personal</summary> - public CalendarEntity Personal => new(_haContext, "calendar.personal"); -} - -public partial class ConversationEntities -{ - private readonly IHaContext _haContext; - public ConversationEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all conversation entities currently registered (at runtime) in Home Assistant as ConversationEntity</summary> - public IEnumerable<ConversationEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("conversation.")).Select(e => new ConversationEntity(e)); - ///<summary>Home Assistant</summary> - public ConversationEntity HomeAssistant => new(_haContext, "conversation.home_assistant"); -} - -public partial class DeviceTrackerEntities -{ - private readonly IHaContext _haContext; - public DeviceTrackerEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all device_tracker entities currently registered (at runtime) in Home Assistant as DeviceTrackerEntity</summary> - public IEnumerable<DeviceTrackerEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("device_tracker.")).Select(e => new DeviceTrackerEntity(e)); - public DeviceTrackerEntity Care4b6b => new(_haContext, "device_tracker.care_4b6b"); - public DeviceTrackerEntity Mc2000103066422c1 => new(_haContext, "device_tracker.mc200_01_030664_22c1"); - public DeviceTrackerEntity Mc200010318862a53 => new(_haContext, "device_tracker.mc200_01_031886_2a53"); - public DeviceTrackerEntity Mc20001070702B39d => new(_haContext, "device_tracker.mc200_01_070702_b39d"); - public DeviceTrackerEntity Mc20001142816Ce44 => new(_haContext, "device_tracker.mc200_01_142816_ce44"); - public DeviceTrackerEntity Mc200011585562218 => new(_haContext, "device_tracker.mc200_01_158556_2218"); - public DeviceTrackerEntity Mc200011595051493 => new(_haContext, "device_tracker.mc200_01_159505_1493"); - public DeviceTrackerEntity Mc20001177515458e => new(_haContext, "device_tracker.mc200_01_177515_458e"); - ///<summary>Pixel 8</summary> - public DeviceTrackerEntity Pixel8 => new(_haContext, "device_tracker.pixel_8"); - ///<summary>Z Flip 6</summary> - public DeviceTrackerEntity SmF741w => new(_haContext, "device_tracker.sm_f741w"); -} - -public partial class InputBooleanEntities -{ - private readonly IHaContext _haContext; - public InputBooleanEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all input_boolean entities currently registered (at runtime) in Home Assistant as InputBooleanEntity</summary> - public IEnumerable<InputBooleanEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("input_boolean.")).Select(e => new InputBooleanEntity(e)); - ///<summary>netdaemon_net_daemon_config_apps_frontend_bathroom_light_bathroom_light</summary> - public InputBooleanEntity NetdaemonNetDaemonConfigAppsFrontendBathroomLightBathroomLight => new(_haContext, "input_boolean.netdaemon_net_daemon_config_apps_frontend_bathroom_light_bathroom_light"); - ///<summary>netdaemon_net_daemon_config_apps_spotify_pause_unpause_pause_unpause</summary> - public InputBooleanEntity NetdaemonNetDaemonConfigAppsSpotifyPauseUnpausePauseUnpause => new(_haContext, "input_boolean.netdaemon_net_daemon_config_apps_spotify_pause_unpause_pause_unpause"); - ///<summary>netdaemon_net_daemon_config_apps_spotify_play_album_play_album</summary> - public InputBooleanEntity NetdaemonNetDaemonConfigAppsSpotifyPlayAlbumPlayAlbum => new(_haContext, "input_boolean.netdaemon_net_daemon_config_apps_spotify_play_album_play_album"); - ///<summary>netdaemon_net_daemon_config_apps_spotify_play_artist_play_artist</summary> - public InputBooleanEntity NetdaemonNetDaemonConfigAppsSpotifyPlayArtistPlayArtist => new(_haContext, "input_boolean.netdaemon_net_daemon_config_apps_spotify_play_artist_play_artist"); - ///<summary>netdaemon_net_daemon_config_apps_spotify_play_playlist_play_playlist</summary> - public InputBooleanEntity NetdaemonNetDaemonConfigAppsSpotifyPlayPlaylistPlayPlaylist => new(_haContext, "input_boolean.netdaemon_net_daemon_config_apps_spotify_play_playlist_play_playlist"); - ///<summary>netdaemon_net_daemon_config_apps_spotify_play_song_play_song</summary> - public InputBooleanEntity NetdaemonNetDaemonConfigAppsSpotifyPlaySongPlaySong => new(_haContext, "input_boolean.netdaemon_net_daemon_config_apps_spotify_play_song_play_song"); - ///<summary>netdaemon_net_daemon_config_apps_timer_setup_setup</summary> - public InputBooleanEntity NetdaemonNetDaemonConfigAppsTimerSetupSetup => new(_haContext, "input_boolean.netdaemon_net_daemon_config_apps_timer_setup_setup"); -} - -public partial class InputTextEntities -{ - private readonly IHaContext _haContext; - public InputTextEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all input_text entities currently registered (at runtime) in Home Assistant as InputTextEntity</summary> - public IEnumerable<InputTextEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("input_text.")).Select(e => new InputTextEntity(e)); - ///<summary>Assist - Timer 1 Location</summary> - public InputTextEntity AssistTimer1Location => new(_haContext, "input_text.assist_timer1_location"); - ///<summary>Assist - Timer 2 Location</summary> - public InputTextEntity AssistTimer2Location => new(_haContext, "input_text.assist_timer2_location"); - ///<summary>Assist - Timer 3 Location</summary> - public InputTextEntity AssistTimer3Location => new(_haContext, "input_text.assist_timer3_location"); - ///<summary>BathroomLightBrightness</summary> - public InputTextEntity BathroomLightBrightness => new(_haContext, "input_text.bathroom_light_brightness"); - ///<summary>BathroomLightTemperature</summary> - public InputTextEntity BathroomLightTemperature => new(_haContext, "input_text.bathroom_light_temperature"); -} - -public partial class LockEntities -{ - private readonly IHaContext _haContext; - public LockEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all lock entities currently registered (at runtime) in Home Assistant as LockEntity</summary> - public IEnumerable<LockEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("lock.")).Select(e => new LockEntity(e)); - ///<summary>Smartplug1 Child lock</summary> - public LockEntity Smartplug1ChildLock => new(_haContext, "lock.smartplug_1_child_lock"); - ///<summary>Smartplug2 Child lock</summary> - public LockEntity Smartplug2ChildLock => new(_haContext, "lock.smartplug2_child_lock"); - ///<summary>Smartplug3 Child lock</summary> - public LockEntity Smartplug3ChildLock => new(_haContext, "lock.smartplug3_child_lock"); -} - -public partial class NumberEntities -{ - private readonly IHaContext _haContext; - public NumberEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all number entities currently registered (at runtime) in Home Assistant as NumberEntity</summary> - public IEnumerable<NumberEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("number.")).Select(e => new NumberEntity(e)); - ///<summary>Smartplug1 Timer</summary> - public NumberEntity Smartplug1Timer => new(_haContext, "number.smartplug_1_timer"); - ///<summary>Smartplug2 Timer</summary> - public NumberEntity Smartplug2Timer => new(_haContext, "number.smartplug2_timer"); - ///<summary>Smartplug3 Timer</summary> - public NumberEntity Smartplug3Timer => new(_haContext, "number.smartplug3_timer"); -} - -public partial class PersonEntities -{ - private readonly IHaContext _haContext; - public PersonEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all person entities currently registered (at runtime) in Home Assistant as PersonEntity</summary> - public IEnumerable<PersonEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("person.")).Select(e => new PersonEntity(e)); - ///<summary>Matt</summary> - public PersonEntity Matt => new(_haContext, "person.matt"); - ///<summary>Wifey <3</summary> - public PersonEntity Wifey => new(_haContext, "person.wifey"); -} - -public partial class RemoteEntities -{ - private readonly IHaContext _haContext; - public RemoteEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all remote entities currently registered (at runtime) in Home Assistant as RemoteEntity</summary> - public IEnumerable<RemoteEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("remote.")).Select(e => new RemoteEntity(e)); - ///<summary>Android TV 192.168.0.106</summary> - public RemoteEntity AndroidTv1921680106 => new(_haContext, "remote.android_tv_192_168_0_106"); - ///<summary>Living room TV</summary> - public RemoteEntity Onn4kStreamingBox => new(_haContext, "remote.onn_4k_streaming_box"); -} - -public partial class ScriptEntities -{ - private readonly IHaContext _haContext; - public ScriptEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all script entities currently registered (at runtime) in Home Assistant as ScriptEntity</summary> - public IEnumerable<ScriptEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("script.")).Select(e => new ScriptEntity(e)); - ///<summary>Assist - TimerPause</summary> - public ScriptEntity AssistTimerpause => new(_haContext, "script.assist_timerpause"); - ///<summary>Assist - TimerStart</summary> - public ScriptEntity AssistTimerstart => new(_haContext, "script.assist_timerstart"); - ///<summary>Assist - TimerStop</summary> - public ScriptEntity AssistTimerstop => new(_haContext, "script.assist_timerstop"); - ///<summary>Music - TurnOnUE</summary> - public ScriptEntity TurnOnUe => new(_haContext, "script.turn_on_ue"); -} - -public partial class SelectEntities -{ - private readonly IHaContext _haContext; - public SelectEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all select entities currently registered (at runtime) in Home Assistant as SelectEntity</summary> - public IEnumerable<SelectEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("select.")).Select(e => new SelectEntity(e)); - ///<summary>BathroomCeiling Color power on behavior</summary> - public SelectEntity BathroomceilingColorPowerOnBehavior => new(_haContext, "select.bathroomceiling_color_power_on_behavior"); - ///<summary>M5Stack Atom Echo 31196c Assistant</summary> - public SelectEntity M5stackAtomEcho31196cAssistant => new(_haContext, "select.m5stack_atom_echo_31196c_assistant"); - ///<summary>M5Stack Atom Echo 31196c Finished speaking detection</summary> - public SelectEntity M5stackAtomEcho31196cFinishedSpeakingDetection => new(_haContext, "select.m5stack_atom_echo_31196c_finished_speaking_detection"); - ///<summary>M5Stack Atom Echo 31196c Wake word</summary> - public SelectEntity M5stackAtomEcho31196cWakeWord => new(_haContext, "select.m5stack_atom_echo_31196c_wake_word"); - ///<summary>Smartplug1 Initial state</summary> - public SelectEntity Smartplug1InitialState => new(_haContext, "select.smartplug_1_initial_state"); - ///<summary>Smartplug1 Light mode</summary> - public SelectEntity Smartplug1LightMode => new(_haContext, "select.smartplug_1_light_mode"); - ///<summary>Smartplug2 Initial state</summary> - public SelectEntity Smartplug2InitialState => new(_haContext, "select.smartplug2_initial_state"); - ///<summary>Smartplug2 Light mode</summary> - public SelectEntity Smartplug2LightMode => new(_haContext, "select.smartplug2_light_mode"); - ///<summary>Smartplug3 Initial state</summary> - public SelectEntity Smartplug3InitialState => new(_haContext, "select.smartplug3_initial_state"); - ///<summary>Smartplug3 Light mode</summary> - public SelectEntity Smartplug3LightMode => new(_haContext, "select.smartplug3_light_mode"); - ///<summary>Zigbee2MQTT Bridge Log level</summary> - public SelectEntity Zigbee2mqttBridgeLogLevel => new(_haContext, "select.zigbee2mqtt_bridge_log_level"); -} - -public partial class SensorEntities -{ - private readonly IHaContext _haContext; - public SensorEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all sensor entities currently registered (at runtime) in Home Assistant as SensorEntity</summary> - public IEnumerable<SensorEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("sensor.")).Select(e => new SensorEntity(e)); - /// <summary>Enumerates all non-numeric sensor entities currently registered (at runtime) in Home Assistant as SensorEntity</summary> - public IEnumerable<SensorEntity> EnumerateAllNonNumeric() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("sensor.") && !(e.EntityState?.AttributesJson?.TryGetProperty("unit_of_measurement", out _) ?? false)).Select(e => new SensorEntity(e)); - /// <summary>Enumerates all numeric sensor entities currently registered (at runtime) in Home Assistant as NumericSensorEntity</summary> - public IEnumerable<NumericSensorEntity> EnumerateAllNumeric() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("sensor.") && (e.EntityState?.AttributesJson?.TryGetProperty("unit_of_measurement", out _) ?? false)).Select(e => new NumericSensorEntity(e)); - ///<summary>CODA-4680-FIZ External IP</summary> - public SensorEntity Coda4680FizExternalIp => new(_haContext, "sensor.coda_4680_fiz_external_ip"); - ///<summary>Material Rounded Base Color Matt</summary> - public SensorEntity MaterialRoundedBaseColorMatt => new(_haContext, "sensor.material_rounded_base_color_matt"); - ///<summary>Pixel 8 Accent color</summary> - public SensorEntity Pixel8AccentColor => new(_haContext, "sensor.pixel_8_accent_color"); - ///<summary>Pixel 8 Audio mode</summary> - public SensorEntity Pixel8AudioMode => new(_haContext, "sensor.pixel_8_audio_mode"); - ///<summary>Pixel 8 Battery health</summary> - public SensorEntity Pixel8BatteryHealth => new(_haContext, "sensor.pixel_8_battery_health"); - ///<summary>Pixel 8 Battery state</summary> - public SensorEntity Pixel8BatteryState => new(_haContext, "sensor.pixel_8_battery_state"); - ///<summary>Pixel 8 Beacon monitor</summary> - public SensorEntity Pixel8BeaconMonitor => new(_haContext, "sensor.pixel_8_beacon_monitor"); - ///<summary>Pixel 8 BLE transmitter</summary> - public SensorEntity Pixel8BleTransmitter => new(_haContext, "sensor.pixel_8_ble_transmitter"); - ///<summary>Pixel 8 Charger type</summary> - public SensorEntity Pixel8ChargerType => new(_haContext, "sensor.pixel_8_charger_type"); - ///<summary>Pixel 8 Current version</summary> - public SensorEntity Pixel8CurrentVersion => new(_haContext, "sensor.pixel_8_current_version"); - ///<summary>Pixel 8 Do Not Disturb sensor</summary> - public SensorEntity Pixel8DoNotDisturbSensor => new(_haContext, "sensor.pixel_8_do_not_disturb_sensor"); - ///<summary>Pixel 8 Last notification</summary> - public SensorEntity Pixel8LastNotification => new(_haContext, "sensor.pixel_8_last_notification"); - ///<summary>Pixel 8 Last reboot</summary> - public SensorEntity Pixel8LastReboot => new(_haContext, "sensor.pixel_8_last_reboot"); - ///<summary>Pixel 8 Last removed notification</summary> - public SensorEntity Pixel8LastRemovedNotification => new(_haContext, "sensor.pixel_8_last_removed_notification"); - ///<summary>Pixel 8 Last update trigger</summary> - public SensorEntity Pixel8LastUpdateTrigger => new(_haContext, "sensor.pixel_8_last_update_trigger"); - ///<summary>Pixel 8 Last used app</summary> - public SensorEntity Pixel8LastUsedApp => new(_haContext, "sensor.pixel_8_last_used_app"); - ///<summary>Pixel 8 Media session</summary> - public SensorEntity Pixel8MediaSession => new(_haContext, "sensor.pixel_8_media_session"); - ///<summary>Pixel 8 Network type</summary> - public SensorEntity Pixel8NetworkType => new(_haContext, "sensor.pixel_8_network_type"); - ///<summary>Pixel 8 Next alarm</summary> - public SensorEntity Pixel8NextAlarm => new(_haContext, "sensor.pixel_8_next_alarm"); - ///<summary>Pixel 8 OS version</summary> - public SensorEntity Pixel8OsVersion => new(_haContext, "sensor.pixel_8_os_version"); - ///<summary>Pixel 8 Public IP address</summary> - public SensorEntity Pixel8PublicIpAddress => new(_haContext, "sensor.pixel_8_public_ip_address"); - ///<summary>Pixel 8 Ringer mode</summary> - public SensorEntity Pixel8RingerMode => new(_haContext, "sensor.pixel_8_ringer_mode"); - ///<summary>Pixel 8 Screen brightness</summary> - public SensorEntity Pixel8ScreenBrightness => new(_haContext, "sensor.pixel_8_screen_brightness"); - ///<summary>Pixel 8 Volume level accessibility</summary> - public SensorEntity Pixel8VolumeLevelAccessibility => new(_haContext, "sensor.pixel_8_volume_level_accessibility"); - ///<summary>Pixel 8 Volume level alarm</summary> - public SensorEntity Pixel8VolumeLevelAlarm => new(_haContext, "sensor.pixel_8_volume_level_alarm"); - ///<summary>Pixel 8 Volume level call</summary> - public SensorEntity Pixel8VolumeLevelCall => new(_haContext, "sensor.pixel_8_volume_level_call"); - ///<summary>Pixel 8 Volume level DTMF</summary> - public SensorEntity Pixel8VolumeLevelDtmf => new(_haContext, "sensor.pixel_8_volume_level_dtmf"); - ///<summary>Pixel 8 Volume level music</summary> - public SensorEntity Pixel8VolumeLevelMusic => new(_haContext, "sensor.pixel_8_volume_level_music"); - ///<summary>Pixel 8 Volume level notification</summary> - public SensorEntity Pixel8VolumeLevelNotification => new(_haContext, "sensor.pixel_8_volume_level_notification"); - ///<summary>Pixel 8 Volume level ringer</summary> - public SensorEntity Pixel8VolumeLevelRinger => new(_haContext, "sensor.pixel_8_volume_level_ringer"); - ///<summary>Pixel 8 Volume level system</summary> - public SensorEntity Pixel8VolumeLevelSystem => new(_haContext, "sensor.pixel_8_volume_level_system"); - ///<summary>Pixel 8 Wi-Fi BSSID</summary> - public SensorEntity Pixel8WifiBssid => new(_haContext, "sensor.pixel_8_wifi_bssid"); - ///<summary>Pixel 8 Wi-Fi connection</summary> - public SensorEntity Pixel8WifiConnection => new(_haContext, "sensor.pixel_8_wifi_connection"); - ///<summary>Pixel 8 Wi-Fi IP address</summary> - public SensorEntity Pixel8WifiIpAddress => new(_haContext, "sensor.pixel_8_wifi_ip_address"); - ///<summary>SLZB-06p7 Connection mode</summary> - public SensorEntity Slzb06p7ConnectionMode => new(_haContext, "sensor.slzb_06p7_connection_mode"); - ///<summary>SLZB-06p7 Firmware channel</summary> - public SensorEntity Slzb06p7FirmwareChannel => new(_haContext, "sensor.slzb_06p7_firmware_channel"); - ///<summary>SLZB-06p7 Zigbee type</summary> - public SensorEntity Slzb06p7ZigbeeType => new(_haContext, "sensor.slzb_06p7_zigbee_type"); - ///<summary>Z Flip 6 Battery state</summary> - public SensorEntity SmF741wBatteryState => new(_haContext, "sensor.sm_f741w_battery_state"); - ///<summary>Z Flip 6 Charger type</summary> - public SensorEntity SmF741wChargerType => new(_haContext, "sensor.sm_f741w_charger_type"); - ///<summary>Sun Next dawn</summary> - public SensorEntity SunNextDawn => new(_haContext, "sensor.sun_next_dawn"); - ///<summary>Sun Next dusk</summary> - public SensorEntity SunNextDusk => new(_haContext, "sensor.sun_next_dusk"); - ///<summary>Sun Next midnight</summary> - public SensorEntity SunNextMidnight => new(_haContext, "sensor.sun_next_midnight"); - ///<summary>Sun Next noon</summary> - public SensorEntity SunNextNoon => new(_haContext, "sensor.sun_next_noon"); - ///<summary>Sun Next rising</summary> - public SensorEntity SunNextRising => new(_haContext, "sensor.sun_next_rising"); - ///<summary>Sun Next setting</summary> - public SensorEntity SunNextSetting => new(_haContext, "sensor.sun_next_setting"); - ///<summary>Zigbee2MQTT Bridge Version</summary> - public SensorEntity Zigbee2mqttBridgeVersion => new(_haContext, "sensor.zigbee2mqtt_bridge_version"); - ///<summary>Estimated distance</summary> - public NumericSensorEntity Care4b6bEstimatedDistance => new(_haContext, "sensor.care_4b6b_estimated_distance"); - ///<summary>CODA-4680-FIZ Data received</summary> - public NumericSensorEntity Coda4680FizDataReceived => new(_haContext, "sensor.coda_4680_fiz_data_received"); - ///<summary>CODA-4680-FIZ Data sent</summary> - public NumericSensorEntity Coda4680FizDataSent => new(_haContext, "sensor.coda_4680_fiz_data_sent"); - ///<summary>CODA-4680-FIZ Download speed</summary> - public NumericSensorEntity Coda4680FizDownloadSpeed => new(_haContext, "sensor.coda_4680_fiz_download_speed"); - ///<summary>CODA-4680-FIZ Upload speed</summary> - public NumericSensorEntity Coda4680FizUploadSpeed => new(_haContext, "sensor.coda_4680_fiz_upload_speed"); - ///<summary>Estimated distance</summary> - public NumericSensorEntity Mc2000103066422c1EstimatedDistance => new(_haContext, "sensor.mc200_01_030664_22c1_estimated_distance"); - ///<summary>Estimated distance</summary> - public NumericSensorEntity Mc200010318862a53EstimatedDistance => new(_haContext, "sensor.mc200_01_031886_2a53_estimated_distance"); - ///<summary>Estimated distance</summary> - public NumericSensorEntity Mc20001070702B39dEstimatedDistance => new(_haContext, "sensor.mc200_01_070702_b39d_estimated_distance"); - ///<summary>Estimated distance</summary> - public NumericSensorEntity Mc20001142816Ce44EstimatedDistance => new(_haContext, "sensor.mc200_01_142816_ce44_estimated_distance"); - ///<summary>Estimated distance</summary> - public NumericSensorEntity Mc200011585562218EstimatedDistance => new(_haContext, "sensor.mc200_01_158556_2218_estimated_distance"); - ///<summary>Estimated distance</summary> - public NumericSensorEntity Mc200011595051493EstimatedDistance => new(_haContext, "sensor.mc200_01_159505_1493_estimated_distance"); - ///<summary>Estimated distance</summary> - public NumericSensorEntity Mc20001177515458eEstimatedDistance => new(_haContext, "sensor.mc200_01_177515_458e_estimated_distance"); - ///<summary>Pixel 8 Battery level</summary> - public NumericSensorEntity Pixel8BatteryLevel => new(_haContext, "sensor.pixel_8_battery_level"); - ///<summary>Pixel 8 Battery power</summary> - public NumericSensorEntity Pixel8BatteryPower => new(_haContext, "sensor.pixel_8_battery_power"); - ///<summary>Pixel 8 Battery temperature</summary> - public NumericSensorEntity Pixel8BatteryTemperature => new(_haContext, "sensor.pixel_8_battery_temperature"); - ///<summary>Pixel 8 Bluetooth connection</summary> - public NumericSensorEntity Pixel8BluetoothConnection => new(_haContext, "sensor.pixel_8_bluetooth_connection"); - ///<summary>Pixel 8 IPv6 addresses</summary> - public NumericSensorEntity Pixel8Ipv6Addresses => new(_haContext, "sensor.pixel_8_ipv6_addresses"); - ///<summary>Pixel 8 Light sensor</summary> - public NumericSensorEntity Pixel8LightSensor => new(_haContext, "sensor.pixel_8_light_sensor"); - ///<summary>Pixel 8 Remaining charge time</summary> - public NumericSensorEntity Pixel8RemainingChargeTime => new(_haContext, "sensor.pixel_8_remaining_charge_time"); - ///<summary>Pixel 8 Wi-Fi frequency</summary> - public NumericSensorEntity Pixel8WifiFrequency => new(_haContext, "sensor.pixel_8_wifi_frequency"); - ///<summary>Pixel 8 Wi-Fi link speed</summary> - public NumericSensorEntity Pixel8WifiLinkSpeed => new(_haContext, "sensor.pixel_8_wifi_link_speed"); - ///<summary>Pixel 8 Wi-Fi signal strength</summary> - public NumericSensorEntity Pixel8WifiSignalStrength => new(_haContext, "sensor.pixel_8_wifi_signal_strength"); - ///<summary>SLZB-06p7 Core chip temp</summary> - public NumericSensorEntity Slzb06p7CoreChipTemp => new(_haContext, "sensor.slzb_06p7_core_chip_temp"); - ///<summary>SLZB-06p7 Zigbee chip temp</summary> - public NumericSensorEntity Slzb06p7ZigbeeChipTemp => new(_haContext, "sensor.slzb_06p7_zigbee_chip_temp"); - ///<summary>Z Flip 6 Battery level</summary> - public NumericSensorEntity SmF741wBatteryLevel => new(_haContext, "sensor.sm_f741w_battery_level"); - ///<summary>Song tempo</summary> - public NumericSensorEntity SpotifyMattSongTempo => new(_haContext, "sensor.spotify_matt_song_tempo"); - ///<summary>Zigbee2MQTT Bridge Permit join timeout</summary> - public NumericSensorEntity Zigbee2mqttBridgePermitJoinTimeout => new(_haContext, "sensor.zigbee2mqtt_bridge_permit_join_timeout"); -} - -public partial class SttEntities -{ - private readonly IHaContext _haContext; - public SttEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all stt entities currently registered (at runtime) in Home Assistant as SttEntity</summary> - public IEnumerable<SttEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("stt.")).Select(e => new SttEntity(e)); - ///<summary>faster-whisper</summary> - public SttEntity FasterWhisper => new(_haContext, "stt.faster_whisper"); -} - -public partial class SunEntities -{ - private readonly IHaContext _haContext; - public SunEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all sun entities currently registered (at runtime) in Home Assistant as SunEntity</summary> - public IEnumerable<SunEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("sun.")).Select(e => new SunEntity(e)); - ///<summary>Sun</summary> - public SunEntity Sun => new(_haContext, "sun.sun"); -} - -public partial class SwitchEntities -{ - private readonly IHaContext _haContext; - public SwitchEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all switch entities currently registered (at runtime) in Home Assistant as SwitchEntity</summary> - public IEnumerable<SwitchEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("switch.")).Select(e => new SwitchEntity(e)); - ///<summary>BathroomCeiling Do not disturb</summary> - public SwitchEntity BathroomceilingDoNotDisturb => new(_haContext, "switch.bathroomceiling_do_not_disturb"); - ///<summary>M5Stack Atom Echo 31196c Use listen light</summary> - public SwitchEntity M5stackAtomEcho31196cUseListenLight => new(_haContext, "switch.m5stack_atom_echo_31196c_use_listen_light"); - ///<summary>M5Stack Atom Echo 31196c Use wake word</summary> - public SwitchEntity M5stackAtomEcho31196cUseWakeWord => new(_haContext, "switch.m5stack_atom_echo_31196c_use_wake_word"); - ///<summary>SLZB-06p7 Disable LEDs</summary> - public SwitchEntity Slzb06p7DisableLeds => new(_haContext, "switch.slzb_06p7_disable_leds"); - ///<summary>SLZB-06p7 LED night mode</summary> - public SwitchEntity Slzb06p7LedNightMode => new(_haContext, "switch.slzb_06p7_led_night_mode"); - ///<summary>Middle Base Station</summary> - public SwitchEntity Smartplug1 => new(_haContext, "switch.smartplug1"); - ///<summary>Window Base Station</summary> - public SwitchEntity Smartplug2 => new(_haContext, "switch.smartplug2"); - ///<summary>Office Lamp</summary> - public SwitchEntity Smartplug3 => new(_haContext, "switch.smartplug3"); - ///<summary>Zigbee2MQTT Bridge Permit join</summary> - public SwitchEntity Zigbee2mqttBridgePermitJoin => new(_haContext, "switch.zigbee2mqtt_bridge_permit_join"); -} - -public partial class TimerEntities -{ - private readonly IHaContext _haContext; - public TimerEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all timer entities currently registered (at runtime) in Home Assistant as TimerEntity</summary> - public IEnumerable<TimerEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("timer.")).Select(e => new TimerEntity(e)); - ///<summary>Assist - Timer 1</summary> - public TimerEntity AssistTimer1 => new(_haContext, "timer.assist_timer1"); - ///<summary>Assist - Timer 2</summary> - public TimerEntity AssistTimer2 => new(_haContext, "timer.assist_timer2"); - ///<summary>Assist - Timer 3</summary> - public TimerEntity AssistTimer3 => new(_haContext, "timer.assist_timer3"); -} - -public partial class TodoEntities -{ - private readonly IHaContext _haContext; - public TodoEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all todo entities currently registered (at runtime) in Home Assistant as TodoEntity</summary> - public IEnumerable<TodoEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("todo.")).Select(e => new TodoEntity(e)); - ///<summary>Shopping List</summary> - public TodoEntity ShoppingList => new(_haContext, "todo.shopping_list"); -} - -public partial class TtsEntities -{ - private readonly IHaContext _haContext; - public TtsEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all tts entities currently registered (at runtime) in Home Assistant as TtsEntity</summary> - public IEnumerable<TtsEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("tts.")).Select(e => new TtsEntity(e)); - ///<summary>piper</summary> - public TtsEntity Piper => new(_haContext, "tts.piper"); -} - -public partial class WakeWordEntities -{ - private readonly IHaContext _haContext; - public WakeWordEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all wake_word entities currently registered (at runtime) in Home Assistant as WakeWordEntity</summary> - public IEnumerable<WakeWordEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("wake_word.")).Select(e => new WakeWordEntity(e)); - ///<summary>openwakeword</summary> - public WakeWordEntity Openwakeword => new(_haContext, "wake_word.openwakeword"); -} - -public partial class WeatherEntities -{ - private readonly IHaContext _haContext; - public WeatherEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all weather entities currently registered (at runtime) in Home Assistant as WeatherEntity</summary> - public IEnumerable<WeatherEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("weather.")).Select(e => new WeatherEntity(e)); - ///<summary>Home</summary> - public WeatherEntity ForecastHome => new(_haContext, "weather.forecast_home"); - ///<summary>Forecast Home</summary> - public WeatherEntity ForecastHome2 => new(_haContext, "weather.forecast_home_2"); -} - -public partial class ZoneEntities -{ - private readonly IHaContext _haContext; - public ZoneEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all zone entities currently registered (at runtime) in Home Assistant as ZoneEntity</summary> - public IEnumerable<ZoneEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("zone.")).Select(e => new ZoneEntity(e)); - ///<summary>Home</summary> - public ZoneEntity Home => new(_haContext, "zone.home"); -} - -public partial class UpdateEntities -{ - private readonly IHaContext _haContext; - public UpdateEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all update entities currently registered (at runtime) in Home Assistant as UpdateEntity</summary> - public IEnumerable<UpdateEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("update.")).Select(e => new UpdateEntity(e)); - ///<summary>SLZB-06p7 Core firmware</summary> - public UpdateEntity Slzb06p7CoreFirmware => new(_haContext, "update.slzb_06p7_core_firmware"); - ///<summary>SLZB-06p7 Zigbee firmware</summary> - public UpdateEntity Slzb06p7ZigbeeFirmware => new(_haContext, "update.slzb_06p7_zigbee_firmware"); -} - -public partial class InputNumberEntities -{ - private readonly IHaContext _haContext; - public InputNumberEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all input_number entities currently registered (at runtime) in Home Assistant as InputNumberEntity</summary> - public IEnumerable<InputNumberEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("input_number.")).Select(e => new InputNumberEntity(e)); - ///<summary>BathroomLightBrightness</summary> - public InputNumberEntity BathroomLightBrightness => new(_haContext, "input_number.bathroom_light_brightness"); - ///<summary>BathroomLightTemperature</summary> - public InputNumberEntity BathroomLightTemperature => new(_haContext, "input_number.bathroom_light_temperature"); -} - -public partial record LightEntity : Entity<LightEntity, EntityState<LightAttributes>, LightAttributes>, ILightEntityCore -{ - public LightEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public LightEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record LightAttributes -{ - [JsonPropertyName("supported_color_modes")] - public IReadOnlyList<string>? SupportedColorModes { get; init; } - - [JsonPropertyName("supported_features")] - public double? SupportedFeatures { get; init; } - - [JsonPropertyName("color_mode")] - public string? ColorMode { get; init; } - - [JsonPropertyName("min_color_temp_kelvin")] - public double? MinColorTempKelvin { get; init; } - - [JsonPropertyName("max_color_temp_kelvin")] - public double? MaxColorTempKelvin { get; init; } - - [JsonPropertyName("min_mireds")] - public double? MinMireds { get; init; } - - [JsonPropertyName("max_mireds")] - public double? MaxMireds { get; init; } - - [JsonPropertyName("brightness")] - public double? Brightness { get; init; } - - [JsonPropertyName("color_temp_kelvin")] - public double? ColorTempKelvin { get; init; } - - [JsonPropertyName("color_temp")] - public double? ColorTemp { get; init; } - - [JsonPropertyName("hs_color")] - public IReadOnlyList<double>? HsColor { get; init; } - - [JsonPropertyName("rgb_color")] - public IReadOnlyList<double>? RgbColor { get; init; } - - [JsonPropertyName("xy_color")] - public IReadOnlyList<double>? XyColor { get; init; } - - [JsonPropertyName("entity_id")] - public IReadOnlyList<string>? EntityId { get; init; } - - [JsonPropertyName("effect_list")] - public IReadOnlyList<string>? EffectList { get; init; } - - [JsonPropertyName("color")] - public object? Color { get; init; } - - [JsonPropertyName("effect")] - public string? Effect { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("off_with_transition")] - public bool? OffWithTransition { get; init; } - - [JsonPropertyName("off_brightness")] - public object? OffBrightness { get; init; } - - [JsonPropertyName("restored")] - public bool? Restored { get; init; } - - [JsonPropertyName("color_options")] - public object? ColorOptions { get; init; } - - [JsonPropertyName("color_power_on_behavior")] - public object? ColorPowerOnBehavior { get; init; } - - [JsonPropertyName("do_not_disturb")] - public object? DoNotDisturb { get; init; } - - [JsonPropertyName("linkquality")] - public double? Linkquality { get; init; } -} - -public partial record MediaPlayerEntity : Entity<MediaPlayerEntity, EntityState<MediaPlayerAttributes>, MediaPlayerAttributes>, IMediaPlayerEntityCore -{ - public MediaPlayerEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public MediaPlayerEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record MediaPlayerAttributes -{ - [JsonPropertyName("app_id")] - public string? AppId { get; init; } - - [JsonPropertyName("app_name")] - public string? AppName { get; init; } - - [JsonPropertyName("device_class")] - public string? DeviceClass { get; init; } - - [JsonPropertyName("entity_picture_local")] - public string? EntityPictureLocal { get; init; } - - [JsonPropertyName("entity_picture")] - public string? EntityPicture { get; init; } - - [JsonPropertyName("icon")] - public string? Icon { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("supported_features")] - public double? SupportedFeatures { get; init; } - - [JsonPropertyName("volume_level")] - public double? VolumeLevel { get; init; } - - [JsonPropertyName("is_volume_muted")] - public bool? IsVolumeMuted { get; init; } - - [JsonPropertyName("media_content_id")] - public string? MediaContentId { get; init; } - - [JsonPropertyName("media_content_type")] - public string? MediaContentType { get; init; } - - [JsonPropertyName("media_duration")] - public double? MediaDuration { get; init; } - - [JsonPropertyName("media_position")] - public double? MediaPosition { get; init; } - - [JsonPropertyName("media_position_updated_at")] - public string? MediaPositionUpdatedAt { get; init; } - - [JsonPropertyName("media_title")] - public string? MediaTitle { get; init; } - - [JsonPropertyName("media_album_name")] - public string? MediaAlbumName { get; init; } - - [JsonPropertyName("media_image_url")] - public string? MediaImageUrl { get; init; } - - [JsonPropertyName("media_artist")] - public string? MediaArtist { get; init; } - - [JsonPropertyName("sound_mode_list")] - public IReadOnlyList<string>? SoundModeList { get; init; } - - [JsonPropertyName("media_track")] - public object? MediaTrack { get; init; } - - [JsonPropertyName("shuffle")] - public bool? Shuffle { get; init; } - - [JsonPropertyName("repeat")] - public string? Repeat { get; init; } - - [JsonPropertyName("source_list")] - public IReadOnlyList<string>? SourceList { get; init; } - - [JsonPropertyName("source")] - public string? Source { get; init; } - - [JsonPropertyName("adb_response")] - public object? AdbResponse { get; init; } - - [JsonPropertyName("hdmi_input")] - public object? HdmiInput { get; init; } - - [JsonPropertyName("sound_mode")] - public string? SoundMode { get; init; } - - [JsonPropertyName("sound_mode_raw")] - public string? SoundModeRaw { get; init; } - - [JsonPropertyName("assumed_state")] - public bool? AssumedState { get; init; } - - [JsonPropertyName("group_members")] - public object? GroupMembers { get; init; } - - [JsonPropertyName("master")] - public bool? Master { get; init; } - - [JsonPropertyName("uuid")] - public string? Uuid { get; init; } - - [JsonPropertyName("tts_active")] - public bool? TtsActive { get; init; } - - [JsonPropertyName("snapshot_active")] - public bool? SnapshotActive { get; init; } - - [JsonPropertyName("snapshot_spotify")] - public bool? SnapshotSpotify { get; init; } - - [JsonPropertyName("media_position_mass")] - public double? MediaPositionMass { get; init; } - - [JsonPropertyName("debug_info")] - public string? DebugInfo { get; init; } - - [JsonPropertyName("firmware")] - public string? Firmware { get; init; } - - [JsonPropertyName("sp_device_id")] - public object? SpDeviceId { get; init; } - - [JsonPropertyName("sp_device_name")] - public object? SpDeviceName { get; init; } - - [JsonPropertyName("sp_device_is_brand_sonos")] - public bool? SpDeviceIsBrandSonos { get; init; } - - [JsonPropertyName("sp_item_type")] - public string? SpItemType { get; init; } - - [JsonPropertyName("sp_playing_type")] - public string? SpPlayingType { get; init; } - - [JsonPropertyName("sp_track_is_explicit")] - public bool? SpTrackIsExplicit { get; init; } - - [JsonPropertyName("sp_user_country")] - public string? SpUserCountry { get; init; } - - [JsonPropertyName("sp_user_display_name")] - public string? SpUserDisplayName { get; init; } - - [JsonPropertyName("sp_user_email")] - public string? SpUserEmail { get; init; } - - [JsonPropertyName("sp_user_id")] - public string? SpUserId { get; init; } - - [JsonPropertyName("sp_user_product")] - public string? SpUserProduct { get; init; } - - [JsonPropertyName("sp_user_uri")] - public string? SpUserUri { get; init; } - - [JsonPropertyName("sp_device_is_chromecast")] - public bool? SpDeviceIsChromecast { get; init; } - - [JsonPropertyName("sp_device_music_source")] - public object? SpDeviceMusicSource { get; init; } - - [JsonPropertyName("sp_source_list_hide")] - public IReadOnlyList<object>? SpSourceListHide { get; init; } - - [JsonPropertyName("restored")] - public bool? Restored { get; init; } - - [JsonPropertyName("sp_user_has_web_player_credentials")] - public bool? SpUserHasWebPlayerCredentials { get; init; } - - [JsonPropertyName("volume_step")] - public double? VolumeStep { get; init; } - - [JsonPropertyName("sp_play_time_remaining_est")] - public object? SpPlayTimeRemainingEst { get; init; } - - [JsonPropertyName("media_playlist")] - public string? MediaPlaylist { get; init; } -} - -public partial record AssistSatelliteEntity : Entity<AssistSatelliteEntity, EntityState<AssistSatelliteAttributes>, AssistSatelliteAttributes> -{ - public AssistSatelliteEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public AssistSatelliteEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record AssistSatelliteAttributes -{ - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("supported_features")] - public double? SupportedFeatures { get; init; } - - [JsonPropertyName("restored")] - public bool? Restored { get; init; } -} - -public partial record AutomationEntity : Entity<AutomationEntity, EntityState<AutomationAttributes>, AutomationAttributes>, IAutomationEntityCore -{ - public AutomationEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public AutomationEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record AutomationAttributes -{ - [JsonPropertyName("last_triggered")] - public string? LastTriggered { get; init; } - - [JsonPropertyName("mode")] - public string? Mode { get; init; } - - [JsonPropertyName("current")] - public double? Current { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("id")] - public string? Id { get; init; } - - [JsonPropertyName("max")] - public double? Max { get; init; } - - [JsonPropertyName("restored")] - public bool? Restored { get; init; } - - [JsonPropertyName("supported_features")] - public double? SupportedFeatures { get; init; } -} - -public partial record BinarySensorEntity : Entity<BinarySensorEntity, EntityState<BinarySensorAttributes>, BinarySensorAttributes>, IBinarySensorEntityCore -{ - public BinarySensorEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public BinarySensorEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record BinarySensorAttributes -{ - [JsonPropertyName("device_class")] - public string? DeviceClass { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("icon")] - public string? Icon { get; init; } -} - -public partial record ButtonEntity : Entity<ButtonEntity, EntityState<ButtonAttributes>, ButtonAttributes>, IButtonEntityCore -{ - public ButtonEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public ButtonEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record ButtonAttributes -{ - [JsonPropertyName("device_class")] - public string? DeviceClass { get; init; } - - [JsonPropertyName("icon")] - public string? Icon { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("restored")] - public bool? Restored { get; init; } - - [JsonPropertyName("supported_features")] - public double? SupportedFeatures { get; init; } -} - -public partial record CalendarEntity : Entity<CalendarEntity, EntityState<CalendarAttributes>, CalendarAttributes>, ICalendarEntityCore -{ - public CalendarEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public CalendarEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record CalendarAttributes -{ - [JsonPropertyName("message")] - public string? Message { get; init; } - - [JsonPropertyName("all_day")] - public bool? AllDay { get; init; } - - [JsonPropertyName("start_time")] - public string? StartTime { get; init; } - - [JsonPropertyName("end_time")] - public string? EndTime { get; init; } - - [JsonPropertyName("location")] - public string? Location { get; init; } - - [JsonPropertyName("description")] - public string? Description { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } -} - -public partial record ConversationEntity : Entity<ConversationEntity, EntityState<ConversationAttributes>, ConversationAttributes> -{ - public ConversationEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public ConversationEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record ConversationAttributes -{ - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("supported_features")] - public double? SupportedFeatures { get; init; } -} - -public partial record DeviceTrackerEntity : Entity<DeviceTrackerEntity, EntityState<DeviceTrackerAttributes>, DeviceTrackerAttributes>, IDeviceTrackerEntityCore -{ - public DeviceTrackerEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public DeviceTrackerEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record DeviceTrackerAttributes -{ - [JsonPropertyName("source_type")] - public string? SourceType { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("latitude")] - public double? Latitude { get; init; } - - [JsonPropertyName("longitude")] - public double? Longitude { get; init; } - - [JsonPropertyName("gps_accuracy")] - public double? GpsAccuracy { get; init; } - - [JsonPropertyName("altitude")] - public double? Altitude { get; init; } - - [JsonPropertyName("course")] - public double? Course { get; init; } - - [JsonPropertyName("speed")] - public double? Speed { get; init; } - - [JsonPropertyName("vertical_accuracy")] - public double? VerticalAccuracy { get; init; } - - [JsonPropertyName("restored")] - public bool? Restored { get; init; } - - [JsonPropertyName("supported_features")] - public double? SupportedFeatures { get; init; } -} - -public partial record InputBooleanEntity : Entity<InputBooleanEntity, EntityState<InputBooleanAttributes>, InputBooleanAttributes>, IInputBooleanEntityCore -{ - public InputBooleanEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public InputBooleanEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record InputBooleanAttributes -{ - [JsonPropertyName("editable")] - public bool? Editable { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } -} - -public partial record InputTextEntity : Entity<InputTextEntity, EntityState<InputTextAttributes>, InputTextAttributes>, IInputTextEntityCore -{ - public InputTextEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public InputTextEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record InputTextAttributes -{ - [JsonPropertyName("editable")] - public bool? Editable { get; init; } - - [JsonPropertyName("min")] - public double? Min { get; init; } - - [JsonPropertyName("max")] - public double? Max { get; init; } - - [JsonPropertyName("pattern")] - public string? Pattern { get; init; } - - [JsonPropertyName("mode")] - public string? Mode { get; init; } - - [JsonPropertyName("icon")] - public string? Icon { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } -} - -public partial record LockEntity : Entity<LockEntity, EntityState<LockAttributes>, LockAttributes>, ILockEntityCore -{ - public LockEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public LockEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record LockAttributes -{ - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("supported_features")] - public double? SupportedFeatures { get; init; } - - [JsonPropertyName("restored")] - public bool? Restored { get; init; } -} - -public partial record NumberEntity : NumericEntity<NumberEntity, NumericEntityState<NumberAttributes>, NumberAttributes>, INumberEntityCore -{ - public NumberEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public NumberEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record NumberAttributes -{ - [JsonPropertyName("min")] - public double? Min { get; init; } - - [JsonPropertyName("max")] - public double? Max { get; init; } - - [JsonPropertyName("step")] - public double? Step { get; init; } - - [JsonPropertyName("mode")] - public string? Mode { get; init; } - - [JsonPropertyName("unit_of_measurement")] - public string? UnitOfMeasurement { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("restored")] - public bool? Restored { get; init; } - - [JsonPropertyName("supported_features")] - public double? SupportedFeatures { get; init; } - - [JsonPropertyName("device_class")] - public string? DeviceClass { get; init; } -} - -public partial record PersonEntity : Entity<PersonEntity, EntityState<PersonAttributes>, PersonAttributes>, IPersonEntityCore -{ - public PersonEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public PersonEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record PersonAttributes -{ - [JsonPropertyName("editable")] - public bool? Editable { get; init; } - - [JsonPropertyName("id")] - public string? Id { get; init; } - - [JsonPropertyName("device_trackers")] - public IReadOnlyList<string>? DeviceTrackers { get; init; } - - [JsonPropertyName("user_id")] - public string? UserId { get; init; } - - [JsonPropertyName("icon")] - public string? Icon { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("latitude")] - public double? Latitude { get; init; } - - [JsonPropertyName("longitude")] - public double? Longitude { get; init; } - - [JsonPropertyName("gps_accuracy")] - public double? GpsAccuracy { get; init; } - - [JsonPropertyName("source")] - public string? Source { get; init; } -} - -public partial record RemoteEntity : Entity<RemoteEntity, EntityState<RemoteAttributes>, RemoteAttributes>, IRemoteEntityCore -{ - public RemoteEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public RemoteEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record RemoteAttributes -{ - [JsonPropertyName("activity_list")] - public IReadOnlyList<object>? ActivityList { get; init; } - - [JsonPropertyName("current_activity")] - public string? CurrentActivity { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("supported_features")] - public double? SupportedFeatures { get; init; } -} - -public partial record ScriptEntity : Entity<ScriptEntity, EntityState<ScriptAttributes>, ScriptAttributes>, IScriptEntityCore -{ - public ScriptEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public ScriptEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record ScriptAttributes -{ - [JsonPropertyName("last_triggered")] - public string? LastTriggered { get; init; } - - [JsonPropertyName("mode")] - public string? Mode { get; init; } - - [JsonPropertyName("current")] - public double? Current { get; init; } - - [JsonPropertyName("icon")] - public string? Icon { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("settings")] - public object? Settings { get; init; } -} - -public partial record SelectEntity : Entity<SelectEntity, EntityState<SelectAttributes>, SelectAttributes>, ISelectEntityCore -{ - public SelectEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public SelectEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record SelectAttributes -{ - [JsonPropertyName("options")] - public IReadOnlyList<string>? Options { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("icon")] - public string? Icon { get; init; } - - [JsonPropertyName("restored")] - public bool? Restored { get; init; } - - [JsonPropertyName("supported_features")] - public double? SupportedFeatures { get; init; } - - [JsonPropertyName("brightness")] - public double? Brightness { get; init; } - - [JsonPropertyName("color")] - public object? Color { get; init; } - - [JsonPropertyName("color_mode")] - public string? ColorMode { get; init; } - - [JsonPropertyName("color_options")] - public object? ColorOptions { get; init; } - - [JsonPropertyName("color_power_on_behavior")] - public object? ColorPowerOnBehavior { get; init; } - - [JsonPropertyName("color_temp")] - public double? ColorTemp { get; init; } - - [JsonPropertyName("do_not_disturb")] - public object? DoNotDisturb { get; init; } - - [JsonPropertyName("linkquality")] - public double? Linkquality { get; init; } -} - -public partial record SensorEntity : Entity<SensorEntity, EntityState<SensorAttributes>, SensorAttributes>, ISensorEntityCore -{ - public SensorEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public SensorEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record SensorAttributes -{ - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("device_class")] - public string? DeviceClass { get; init; } - - [JsonPropertyName("icon")] - public string? Icon { get; init; } - - [JsonPropertyName("options")] - public IReadOnlyList<string>? Options { get; init; } - - [JsonPropertyName("Advertise mode")] - public string? Advertisemode { get; init; } - - [JsonPropertyName("Measured power")] - public double? Measuredpower { get; init; } - - [JsonPropertyName("Supports transmitter")] - public bool? Supportstransmitter { get; init; } - - [JsonPropertyName("Transmitting power")] - public string? Transmittingpower { get; init; } - - [JsonPropertyName("id")] - public string? Id { get; init; } - - [JsonPropertyName("automatic")] - public bool? Automatic { get; init; } - - [JsonPropertyName("rgb_color")] - public IReadOnlyList<double>? RgbColor { get; init; } - - [JsonPropertyName("Label")] - public string? Label { get; init; } - - [JsonPropertyName("Local Time")] - public string? LocalTime { get; init; } - - [JsonPropertyName("Time in Milliseconds")] - public double? TimeinMilliseconds { get; init; } - - [JsonPropertyName("is_hidden")] - public bool? IsHidden { get; init; } - - [JsonPropertyName("metered")] - public bool? Metered { get; init; } - - [JsonPropertyName("speech")] - public object? Speech { get; init; } - - [JsonPropertyName("card")] - public object? Card { get; init; } - - [JsonPropertyName("language")] - public string? Language { get; init; } - - [JsonPropertyName("response_type")] - public string? ResponseType { get; init; } - - [JsonPropertyName("data")] - public object? Data { get; init; } - - [JsonPropertyName("Full State")] - public string? FullState { get; init; } - - [JsonPropertyName("album_org.kde.kdeconnect_tp")] - public string? AlbumOrg_kde_kdeconnectTp { get; init; } - - [JsonPropertyName("artist_org.kde.kdeconnect_tp")] - public string? ArtistOrg_kde_kdeconnectTp { get; init; } - - [JsonPropertyName("duration_org.kde.kdeconnect_tp")] - public double? DurationOrg_kde_kdeconnectTp { get; init; } - - [JsonPropertyName("media_id_org.kde.kdeconnect_tp")] - public string? MediaIdOrg_kde_kdeconnectTp { get; init; } - - [JsonPropertyName("playback_position_org.kde.kdeconnect_tp")] - public double? PlaybackPositionOrg_kde_kdeconnectTp { get; init; } - - [JsonPropertyName("playback_state_org.kde.kdeconnect_tp")] - public string? PlaybackStateOrg_kde_kdeconnectTp { get; init; } - - [JsonPropertyName("title_org.kde.kdeconnect_tp")] - public string? TitleOrg_kde_kdeconnectTp { get; init; } - - [JsonPropertyName("total_media_session_count")] - public double? TotalMediaSessionCount { get; init; } - - [JsonPropertyName("1ca92e23-f087-4df7-b9a2-fd4b716a4bf6_19987_0")] - public double? _1ca92e23f0874df7b9a2fd4b716a4bf6199870 { get; init; } - - [JsonPropertyName("74278bda-b644-4520-8f0c-720eaf059935_0_50585")] - public double? _74278bdab64445208f0c720eaf059935050585 { get; init; } -} - -public partial record NumericSensorEntity : NumericEntity<NumericSensorEntity, NumericEntityState<NumericSensorAttributes>, NumericSensorAttributes>, ISensorEntityCore -{ - public NumericSensorEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public NumericSensorEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record NumericSensorAttributes -{ - [JsonPropertyName("state_class")] - public string? StateClass { get; init; } - - [JsonPropertyName("unit_of_measurement")] - public string? UnitOfMeasurement { get; init; } - - [JsonPropertyName("device_class")] - public string? DeviceClass { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("icon")] - public string? Icon { get; init; } - - [JsonPropertyName("current")] - public double? Current { get; init; } - - [JsonPropertyName("voltage")] - public double? Voltage { get; init; } - - [JsonPropertyName("connected_not_paired_devices")] - public IReadOnlyList<object>? ConnectedNotPairedDevices { get; init; } - - [JsonPropertyName("connected_paired_devices")] - public IReadOnlyList<object>? ConnectedPairedDevices { get; init; } - - [JsonPropertyName("paired_devices")] - public IReadOnlyList<string>? PairedDevices { get; init; } - - [JsonPropertyName("ip6_addresses")] - public IReadOnlyList<string>? Ip6Addresses { get; init; } - - [JsonPropertyName("restored")] - public bool? Restored { get; init; } - - [JsonPropertyName("supported_features")] - public double? SupportedFeatures { get; init; } -} - -public partial record SttEntity : Entity<SttEntity, EntityState<SttAttributes>, SttAttributes> -{ - public SttEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public SttEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record SttAttributes -{ - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } -} - -public partial record SunEntity : Entity<SunEntity, EntityState<SunAttributes>, SunAttributes>, ISunEntityCore -{ - public SunEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public SunEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record SunAttributes -{ - [JsonPropertyName("next_dawn")] - public string? NextDawn { get; init; } - - [JsonPropertyName("next_dusk")] - public string? NextDusk { get; init; } - - [JsonPropertyName("next_midnight")] - public string? NextMidnight { get; init; } - - [JsonPropertyName("next_noon")] - public string? NextNoon { get; init; } - - [JsonPropertyName("next_rising")] - public string? NextRising { get; init; } - - [JsonPropertyName("next_setting")] - public string? NextSetting { get; init; } - - [JsonPropertyName("elevation")] - public double? Elevation { get; init; } - - [JsonPropertyName("azimuth")] - public double? Azimuth { get; init; } - - [JsonPropertyName("rising")] - public bool? Rising { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } -} - -public partial record SwitchEntity : Entity<SwitchEntity, EntityState<SwitchAttributes>, SwitchAttributes>, ISwitchEntityCore -{ - public SwitchEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public SwitchEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record SwitchAttributes -{ - [JsonPropertyName("cyclic_schedule")] - public string? CyclicSchedule { get; init; } - - [JsonPropertyName("random_schedule")] - public string? RandomSchedule { get; init; } - - [JsonPropertyName("inching")] - public string? Inching { get; init; } - - [JsonPropertyName("device_class")] - public string? DeviceClass { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("restored")] - public bool? Restored { get; init; } - - [JsonPropertyName("supported_features")] - public double? SupportedFeatures { get; init; } - - [JsonPropertyName("icon")] - public string? Icon { get; init; } - - [JsonPropertyName("brightness")] - public double? Brightness { get; init; } - - [JsonPropertyName("color")] - public object? Color { get; init; } - - [JsonPropertyName("color_mode")] - public string? ColorMode { get; init; } - - [JsonPropertyName("color_options")] - public object? ColorOptions { get; init; } - - [JsonPropertyName("color_power_on_behavior")] - public object? ColorPowerOnBehavior { get; init; } - - [JsonPropertyName("color_temp")] - public double? ColorTemp { get; init; } - - [JsonPropertyName("do_not_disturb")] - public object? DoNotDisturb { get; init; } - - [JsonPropertyName("linkquality")] - public double? Linkquality { get; init; } -} - -public partial record TimerEntity : Entity<TimerEntity, EntityState<TimerAttributes>, TimerAttributes>, ITimerEntityCore -{ - public TimerEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public TimerEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record TimerAttributes -{ - [JsonPropertyName("duration")] - public string? Duration { get; init; } - - [JsonPropertyName("editable")] - public bool? Editable { get; init; } - - [JsonPropertyName("restore")] - public bool? Restore { get; init; } - - [JsonPropertyName("icon")] - public string? Icon { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } -} - -public partial record TodoEntity : Entity<TodoEntity, EntityState<TodoAttributes>, TodoAttributes> -{ - public TodoEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public TodoEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record TodoAttributes -{ - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("supported_features")] - public double? SupportedFeatures { get; init; } -} - -public partial record TtsEntity : Entity<TtsEntity, EntityState<TtsAttributes>, TtsAttributes> -{ - public TtsEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public TtsEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record TtsAttributes -{ - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } -} - -public partial record WakeWordEntity : Entity<WakeWordEntity, EntityState<WakeWordAttributes>, WakeWordAttributes> -{ - public WakeWordEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public WakeWordEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record WakeWordAttributes -{ - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } -} - -public partial record WeatherEntity : Entity<WeatherEntity, EntityState<WeatherAttributes>, WeatherAttributes>, IWeatherEntityCore -{ - public WeatherEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public WeatherEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record WeatherAttributes -{ - [JsonPropertyName("temperature")] - public double? Temperature { get; init; } - - [JsonPropertyName("dew_point")] - public double? DewPoint { get; init; } - - [JsonPropertyName("temperature_unit")] - public string? TemperatureUnit { get; init; } - - [JsonPropertyName("humidity")] - public double? Humidity { get; init; } - - [JsonPropertyName("cloud_coverage")] - public double? CloudCoverage { get; init; } - - [JsonPropertyName("uv_index")] - public double? UvIndex { get; init; } - - [JsonPropertyName("pressure")] - public double? Pressure { get; init; } - - [JsonPropertyName("pressure_unit")] - public string? PressureUnit { get; init; } - - [JsonPropertyName("wind_bearing")] - public double? WindBearing { get; init; } - - [JsonPropertyName("wind_speed")] - public double? WindSpeed { get; init; } - - [JsonPropertyName("wind_speed_unit")] - public string? WindSpeedUnit { get; init; } - - [JsonPropertyName("visibility_unit")] - public string? VisibilityUnit { get; init; } - - [JsonPropertyName("precipitation_unit")] - public string? PrecipitationUnit { get; init; } - - [JsonPropertyName("attribution")] - public string? Attribution { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("supported_features")] - public double? SupportedFeatures { get; init; } - - [JsonPropertyName("restored")] - public bool? Restored { get; init; } -} - -public partial record ZoneEntity : Entity<ZoneEntity, EntityState<ZoneAttributes>, ZoneAttributes>, IZoneEntityCore -{ - public ZoneEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public ZoneEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record ZoneAttributes -{ - [JsonPropertyName("latitude")] - public double? Latitude { get; init; } - - [JsonPropertyName("longitude")] - public double? Longitude { get; init; } - - [JsonPropertyName("radius")] - public double? Radius { get; init; } - - [JsonPropertyName("passive")] - public bool? Passive { get; init; } - - [JsonPropertyName("persons")] - public IReadOnlyList<string>? Persons { get; init; } - - [JsonPropertyName("editable")] - public bool? Editable { get; init; } - - [JsonPropertyName("icon")] - public string? Icon { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } -} - -public partial record UpdateEntity : Entity<UpdateEntity, EntityState<UpdateAttributes>, UpdateAttributes>, IUpdateEntityCore -{ - public UpdateEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public UpdateEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record UpdateAttributes -{ - [JsonPropertyName("auto_update")] - public bool? AutoUpdate { get; init; } - - [JsonPropertyName("display_precision")] - public double? DisplayPrecision { get; init; } - - [JsonPropertyName("installed_version")] - public string? InstalledVersion { get; init; } - - [JsonPropertyName("in_progress")] - public bool? InProgress { get; init; } - - [JsonPropertyName("latest_version")] - public string? LatestVersion { get; init; } - - [JsonPropertyName("release_summary")] - public object? ReleaseSummary { get; init; } - - [JsonPropertyName("release_url")] - public object? ReleaseUrl { get; init; } - - [JsonPropertyName("skipped_version")] - public object? SkippedVersion { get; init; } - - [JsonPropertyName("title")] - public object? Title { get; init; } - - [JsonPropertyName("update_percentage")] - public object? UpdatePercentage { get; init; } - - [JsonPropertyName("device_class")] - public string? DeviceClass { get; init; } - - [JsonPropertyName("entity_picture")] - public string? EntityPicture { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("supported_features")] - public double? SupportedFeatures { get; init; } - - [JsonPropertyName("restored")] - public bool? Restored { get; init; } -} - -public partial record InputNumberEntity : NumericEntity<InputNumberEntity, NumericEntityState<InputNumberAttributes>, InputNumberAttributes>, IInputNumberEntityCore -{ - public InputNumberEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public InputNumberEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record InputNumberAttributes -{ - [JsonPropertyName("restored")] - public bool? Restored { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("supported_features")] - public double? SupportedFeatures { get; init; } -} - -public interface IServices -{ - AndroidtvServices Androidtv { get; } - - AssistSatelliteServices AssistSatellite { get; } - - AutomationServices Automation { get; } - - BackupServices Backup { get; } - - ButtonServices Button { get; } - - CalendarServices Calendar { get; } - - CastServices Cast { get; } - - ClimateServices Climate { get; } - - ConversationServices Conversation { get; } - - CounterServices Counter { get; } - - DeviceTrackerServices DeviceTracker { get; } - - ExtendedOllamaConversationServices ExtendedOllamaConversation { get; } - - FfmpegServices Ffmpeg { get; } - - FrontendServices Frontend { get; } - - HomeassistantServices Homeassistant { get; } - - InputBooleanServices InputBoolean { get; } - - InputButtonServices InputButton { get; } - - InputDatetimeServices InputDatetime { get; } - - InputNumberServices InputNumber { get; } - - InputSelectServices InputSelect { get; } - - InputTextServices InputText { get; } - - IntentScriptServices IntentScript { get; } - - LightServices Light { get; } - - LockServices Lock { get; } - - LogbookServices Logbook { get; } - - LoggerServices Logger { get; } - - LovelaceServices Lovelace { get; } - - MediaPlayerServices MediaPlayer { get; } - - MqttServices Mqtt { get; } - - NetdaemonServices Netdaemon { get; } - - NotifyServices Notify { get; } - - NumberServices Number { get; } - - PersistentNotificationServices PersistentNotification { get; } - - PersonServices Person { get; } - - RecorderServices Recorder { get; } - - RemoteServices Remote { get; } - - RestServices Rest { get; } - - SceneServices Scene { get; } - - ScheduleServices Schedule { get; } - - ScriptServices Script { get; } - - SelectServices Select { get; } - - ShellCommandServices ShellCommand { get; } - - ShoppingListServices ShoppingList { get; } - - SpotifyplusServices Spotifyplus { get; } - - SwitchServices Switch { get; } - - SystemLogServices SystemLog { get; } - - TemplateServices Template { get; } - - TimerServices Timer { get; } - - TodoServices Todo { get; } - - TtsServices Tts { get; } - - UpdateServices Update { get; } - - WeatherServices Weather { get; } - - YamahaSoundbarServices YamahaSoundbar { get; } - - ZoneServices Zone { get; } -} - -public partial class Services : IServices -{ - private readonly IHaContext _haContext; - public Services(IHaContext haContext) - { - _haContext = haContext; - } - - public AndroidtvServices Androidtv => new(_haContext); - public AssistSatelliteServices AssistSatellite => new(_haContext); - public AutomationServices Automation => new(_haContext); - public BackupServices Backup => new(_haContext); - public ButtonServices Button => new(_haContext); - public CalendarServices Calendar => new(_haContext); - public CastServices Cast => new(_haContext); - public ClimateServices Climate => new(_haContext); - public ConversationServices Conversation => new(_haContext); - public CounterServices Counter => new(_haContext); - public DeviceTrackerServices DeviceTracker => new(_haContext); - public ExtendedOllamaConversationServices ExtendedOllamaConversation => new(_haContext); - public FfmpegServices Ffmpeg => new(_haContext); - public FrontendServices Frontend => new(_haContext); - public HomeassistantServices Homeassistant => new(_haContext); - public InputBooleanServices InputBoolean => new(_haContext); - public InputButtonServices InputButton => new(_haContext); - public InputDatetimeServices InputDatetime => new(_haContext); - public InputNumberServices InputNumber => new(_haContext); - public InputSelectServices InputSelect => new(_haContext); - public InputTextServices InputText => new(_haContext); - public IntentScriptServices IntentScript => new(_haContext); - public LightServices Light => new(_haContext); - public LockServices Lock => new(_haContext); - public LogbookServices Logbook => new(_haContext); - public LoggerServices Logger => new(_haContext); - public LovelaceServices Lovelace => new(_haContext); - public MediaPlayerServices MediaPlayer => new(_haContext); - public MqttServices Mqtt => new(_haContext); - public NetdaemonServices Netdaemon => new(_haContext); - public NotifyServices Notify => new(_haContext); - public NumberServices Number => new(_haContext); - public PersistentNotificationServices PersistentNotification => new(_haContext); - public PersonServices Person => new(_haContext); - public RecorderServices Recorder => new(_haContext); - public RemoteServices Remote => new(_haContext); - public RestServices Rest => new(_haContext); - public SceneServices Scene => new(_haContext); - public ScheduleServices Schedule => new(_haContext); - public ScriptServices Script => new(_haContext); - public SelectServices Select => new(_haContext); - public ShellCommandServices ShellCommand => new(_haContext); - public ShoppingListServices ShoppingList => new(_haContext); - public SpotifyplusServices Spotifyplus => new(_haContext); - public SwitchServices Switch => new(_haContext); - public SystemLogServices SystemLog => new(_haContext); - public TemplateServices Template => new(_haContext); - public TimerServices Timer => new(_haContext); - public TodoServices Todo => new(_haContext); - public TtsServices Tts => new(_haContext); - public UpdateServices Update => new(_haContext); - public WeatherServices Weather => new(_haContext); - public YamahaSoundbarServices YamahaSoundbar => new(_haContext); - public ZoneServices Zone => new(_haContext); -} - -public partial class AndroidtvServices -{ - private readonly IHaContext _haContext; - public AndroidtvServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Sends an ADB command to an Android / Fire TV device.</summary> - ///<param name="target">The target for this service call</param> - public void AdbCommand(ServiceTarget target, AndroidtvAdbCommandParameters data) - { - _haContext.CallService("androidtv", "adb_command", target, data); - } - - ///<summary>Sends an ADB command to an Android / Fire TV device.</summary> - ///<param name="command">Either a key command or an ADB shell command. eg: HOME</param> - public void AdbCommand(ServiceTarget target, string command) - { - _haContext.CallService("androidtv", "adb_command", target, new AndroidtvAdbCommandParameters { Command = command }); - } - - ///<summary>Downloads a file from your Android / Fire TV device to your Home Assistant instance.</summary> - ///<param name="target">The target for this service call</param> - public void Download(ServiceTarget target, AndroidtvDownloadParameters data) - { - _haContext.CallService("androidtv", "download", target, data); - } - - ///<summary>Downloads a file from your Android / Fire TV device to your Home Assistant instance.</summary> - ///<param name="devicePath">The filepath on the Android / Fire TV device. eg: /storage/emulated/0/Download/example.txt</param> - ///<param name="localPath">The filepath on your Home Assistant instance. eg: /config/www/example.txt</param> - public void Download(ServiceTarget target, string devicePath, string localPath) - { - _haContext.CallService("androidtv", "download", target, new AndroidtvDownloadParameters { DevicePath = devicePath, LocalPath = localPath }); - } - - ///<summary>Translates a key press on a remote into ADB 'sendevent' commands. You must press one button on the remote within 8 seconds of performing this action.</summary> - ///<param name="target">The target for this service call</param> - public void LearnSendevent(ServiceTarget target, object? data = null) - { - _haContext.CallService("androidtv", "learn_sendevent", target, data); - } - - ///<summary>Uploads a file from your Home Assistant instance to an Android / Fire TV device.</summary> - ///<param name="target">The target for this service call</param> - public void Upload(ServiceTarget target, AndroidtvUploadParameters data) - { - _haContext.CallService("androidtv", "upload", target, data); - } - - ///<summary>Uploads a file from your Home Assistant instance to an Android / Fire TV device.</summary> - ///<param name="devicePath">The filepath on the Android / Fire TV device. eg: /storage/emulated/0/Download/example.txt</param> - ///<param name="localPath">The filepath on your Home Assistant instance. eg: /config/www/example.txt</param> - public void Upload(ServiceTarget target, string devicePath, string localPath) - { - _haContext.CallService("androidtv", "upload", target, new AndroidtvUploadParameters { DevicePath = devicePath, LocalPath = localPath }); - } -} - -public partial record AndroidtvAdbCommandParameters -{ - ///<summary>Either a key command or an ADB shell command. eg: HOME</summary> - [JsonPropertyName("command")] - public string? Command { get; init; } -} - -public partial record AndroidtvDownloadParameters -{ - ///<summary>The filepath on the Android / Fire TV device. eg: /storage/emulated/0/Download/example.txt</summary> - [JsonPropertyName("device_path")] - public string? DevicePath { get; init; } - - ///<summary>The filepath on your Home Assistant instance. eg: /config/www/example.txt</summary> - [JsonPropertyName("local_path")] - public string? LocalPath { get; init; } -} - -public partial record AndroidtvUploadParameters -{ - ///<summary>The filepath on the Android / Fire TV device. eg: /storage/emulated/0/Download/example.txt</summary> - [JsonPropertyName("device_path")] - public string? DevicePath { get; init; } - - ///<summary>The filepath on your Home Assistant instance. eg: /config/www/example.txt</summary> - [JsonPropertyName("local_path")] - public string? LocalPath { get; init; } -} - -public partial class AssistSatelliteServices -{ - private readonly IHaContext _haContext; - public AssistSatelliteServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Lets a satellite announce a message.</summary> - ///<param name="target">The target for this service call</param> - public void Announce(ServiceTarget target, AssistSatelliteAnnounceParameters data) - { - _haContext.CallService("assist_satellite", "announce", target, data); - } - - ///<summary>Lets a satellite announce a message.</summary> - ///<param name="message">The message to announce. eg: Time to wake up!</param> - ///<param name="mediaId">The media ID to announce instead of using text-to-speech.</param> - public void Announce(ServiceTarget target, string? message = null, string? mediaId = null) - { - _haContext.CallService("assist_satellite", "announce", target, new AssistSatelliteAnnounceParameters { Message = message, MediaId = mediaId }); - } - - ///<summary>Starts a conversation from a satellite.</summary> - ///<param name="target">The target for this service call</param> - public void StartConversation(ServiceTarget target, AssistSatelliteStartConversationParameters data) - { - _haContext.CallService("assist_satellite", "start_conversation", target, data); - } - - ///<summary>Starts a conversation from a satellite.</summary> - ///<param name="startMessage">The message to start with. eg: You left the lights on in the living room. Turn them off?</param> - ///<param name="startMediaId">The media ID to start with instead of using text-to-speech.</param> - ///<param name="extraSystemPrompt">Provide background information to the AI about the request.</param> - public void StartConversation(ServiceTarget target, string? startMessage = null, string? startMediaId = null, string? extraSystemPrompt = null) - { - _haContext.CallService("assist_satellite", "start_conversation", target, new AssistSatelliteStartConversationParameters { StartMessage = startMessage, StartMediaId = startMediaId, ExtraSystemPrompt = extraSystemPrompt }); - } -} - -public partial record AssistSatelliteAnnounceParameters -{ - ///<summary>The message to announce. eg: Time to wake up!</summary> - [JsonPropertyName("message")] - public string? Message { get; init; } - - ///<summary>The media ID to announce instead of using text-to-speech.</summary> - [JsonPropertyName("media_id")] - public string? MediaId { get; init; } -} - -public partial record AssistSatelliteStartConversationParameters -{ - ///<summary>The message to start with. eg: You left the lights on in the living room. Turn them off?</summary> - [JsonPropertyName("start_message")] - public string? StartMessage { get; init; } - - ///<summary>The media ID to start with instead of using text-to-speech.</summary> - [JsonPropertyName("start_media_id")] - public string? StartMediaId { get; init; } - - ///<summary>Provide background information to the AI about the request.</summary> - [JsonPropertyName("extra_system_prompt")] - public string? ExtraSystemPrompt { get; init; } -} - -public partial class AutomationServices -{ - private readonly IHaContext _haContext; - public AutomationServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Reloads the automation configuration.</summary> - public void Reload(object? data = null) - { - _haContext.CallService("automation", "reload", null, data); - } - - ///<summary>Toggles (enable / disable) an automation.</summary> - ///<param name="target">The target for this service call</param> - public void Toggle(ServiceTarget target, object? data = null) - { - _haContext.CallService("automation", "toggle", target, data); - } - - ///<summary>Triggers the actions of an automation.</summary> - ///<param name="target">The target for this service call</param> - public void Trigger(ServiceTarget target, AutomationTriggerParameters data) - { - _haContext.CallService("automation", "trigger", target, data); - } - - ///<summary>Triggers the actions of an automation.</summary> - ///<param name="skipCondition">Defines whether or not the conditions will be skipped.</param> - public void Trigger(ServiceTarget target, bool? skipCondition = null) - { - _haContext.CallService("automation", "trigger", target, new AutomationTriggerParameters { SkipCondition = skipCondition }); - } - - ///<summary>Disables an automation.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOff(ServiceTarget target, AutomationTurnOffParameters data) - { - _haContext.CallService("automation", "turn_off", target, data); - } - - ///<summary>Disables an automation.</summary> - ///<param name="stopActions">Stops currently running actions.</param> - public void TurnOff(ServiceTarget target, bool? stopActions = null) - { - _haContext.CallService("automation", "turn_off", target, new AutomationTurnOffParameters { StopActions = stopActions }); - } - - ///<summary>Enables an automation.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOn(ServiceTarget target, object? data = null) - { - _haContext.CallService("automation", "turn_on", target, data); - } -} - -public partial record AutomationTriggerParameters -{ - ///<summary>Defines whether or not the conditions will be skipped.</summary> - [JsonPropertyName("skip_condition")] - public bool? SkipCondition { get; init; } -} - -public partial record AutomationTurnOffParameters -{ - ///<summary>Stops currently running actions.</summary> - [JsonPropertyName("stop_actions")] - public bool? StopActions { get; init; } -} - -public partial class BackupServices -{ - private readonly IHaContext _haContext; - public BackupServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Creates a new backup.</summary> - public void Create(object? data = null) - { - _haContext.CallService("backup", "create", null, data); - } - - ///<summary>Creates a new backup with automatic backup settings.</summary> - public void CreateAutomatic(object? data = null) - { - _haContext.CallService("backup", "create_automatic", null, data); - } -} - -public partial class ButtonServices -{ - private readonly IHaContext _haContext; - public ButtonServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Press the button entity.</summary> - ///<param name="target">The target for this service call</param> - public void Press(ServiceTarget target, object? data = null) - { - _haContext.CallService("button", "press", target, data); - } -} - -public partial class CalendarServices -{ - private readonly IHaContext _haContext; - public CalendarServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Adds a new calendar event.</summary> - ///<param name="target">The target for this service call</param> - public void CreateEvent(ServiceTarget target, CalendarCreateEventParameters data) - { - _haContext.CallService("calendar", "create_event", target, data); - } - - ///<summary>Adds a new calendar event.</summary> - ///<param name="summary">Defines the short summary or subject for the event. eg: Department Party</param> - ///<param name="description">A more complete description of the event than the one provided by the summary. eg: Meeting to provide technical review for 'Phoenix' design.</param> - ///<param name="startDateTime">The date and time the event should start. eg: 2022-03-22 20:00:00</param> - ///<param name="endDateTime">The date and time the event should end. eg: 2022-03-22 22:00:00</param> - ///<param name="startDate">The date the all-day event should start. eg: 2022-03-22</param> - ///<param name="endDate">The date the all-day event should end (exclusive). eg: 2022-03-23</param> - ///<param name="in">Days or weeks that you want to create the event in. eg: {"days": 2} or {"weeks": 2}</param> - ///<param name="location">The location of the event. eg: Conference Room - F123, Bldg. 002</param> - public void CreateEvent(ServiceTarget target, string summary, string? description = null, DateTime? startDateTime = null, DateTime? endDateTime = null, DateOnly? startDate = null, DateOnly? endDate = null, object? @in = null, string? location = null) - { - _haContext.CallService("calendar", "create_event", target, new CalendarCreateEventParameters { Summary = summary, Description = description, StartDateTime = startDateTime, EndDateTime = endDateTime, StartDate = startDate, EndDate = endDate, In = @in, Location = location }); - } - - ///<summary>Get events on a calendar within a time range.</summary> - ///<param name="target">The target for this service call</param> - public void GetEvents(ServiceTarget target, CalendarGetEventsParameters data) - { - _haContext.CallService("calendar", "get_events", target, data); - } - - ///<summary>Get events on a calendar within a time range.</summary> - ///<param name="startDateTime">Returns active events after this time (exclusive). When not set, defaults to now. eg: 2022-03-22 20:00:00</param> - ///<param name="endDateTime">Returns active events before this time (exclusive). Cannot be used with Duration. eg: 2022-03-22 22:00:00</param> - ///<param name="duration">Returns active events from Start time for the specified duration.</param> - public void GetEvents(ServiceTarget target, DateTime? startDateTime = null, DateTime? endDateTime = null, object? duration = null) - { - _haContext.CallService("calendar", "get_events", target, new CalendarGetEventsParameters { StartDateTime = startDateTime, EndDateTime = endDateTime, Duration = duration }); - } - - ///<summary>Get events on a calendar within a time range.</summary> - ///<param name="target">The target for this service call</param> - public Task<JsonElement?> GetEventsAsync(ServiceTarget target, CalendarGetEventsParameters data) - { - return _haContext.CallServiceWithResponseAsync("calendar", "get_events", target, data); - } - - ///<summary>Get events on a calendar within a time range.</summary> - ///<param name="target">The target for this service call</param> - ///<param name="startDateTime">Returns active events after this time (exclusive). When not set, defaults to now. eg: 2022-03-22 20:00:00</param> - ///<param name="endDateTime">Returns active events before this time (exclusive). Cannot be used with Duration. eg: 2022-03-22 22:00:00</param> - ///<param name="duration">Returns active events from Start time for the specified duration.</param> - public Task<JsonElement?> GetEventsAsync(ServiceTarget target, DateTime? startDateTime = null, DateTime? endDateTime = null, object? duration = null) - { - return _haContext.CallServiceWithResponseAsync("calendar", "get_events", target, new CalendarGetEventsParameters { StartDateTime = startDateTime, EndDateTime = endDateTime, Duration = duration }); - } -} - -public partial record CalendarCreateEventParameters -{ - ///<summary>Defines the short summary or subject for the event. eg: Department Party</summary> - [JsonPropertyName("summary")] - public string? Summary { get; init; } - - ///<summary>A more complete description of the event than the one provided by the summary. eg: Meeting to provide technical review for 'Phoenix' design.</summary> - [JsonPropertyName("description")] - public string? Description { get; init; } - - ///<summary>The date and time the event should start. eg: 2022-03-22 20:00:00</summary> - [JsonPropertyName("start_date_time")] - public DateTime? StartDateTime { get; init; } - - ///<summary>The date and time the event should end. eg: 2022-03-22 22:00:00</summary> - [JsonPropertyName("end_date_time")] - public DateTime? EndDateTime { get; init; } - - ///<summary>The date the all-day event should start. eg: 2022-03-22</summary> - [JsonPropertyName("start_date")] - public DateOnly? StartDate { get; init; } - - ///<summary>The date the all-day event should end (exclusive). eg: 2022-03-23</summary> - [JsonPropertyName("end_date")] - public DateOnly? EndDate { get; init; } - - ///<summary>Days or weeks that you want to create the event in. eg: {"days": 2} or {"weeks": 2}</summary> - [JsonPropertyName("in")] - public object? In { get; init; } - - ///<summary>The location of the event. eg: Conference Room - F123, Bldg. 002</summary> - [JsonPropertyName("location")] - public string? Location { get; init; } -} - -public partial record CalendarGetEventsParameters -{ - ///<summary>Returns active events after this time (exclusive). When not set, defaults to now. eg: 2022-03-22 20:00:00</summary> - [JsonPropertyName("start_date_time")] - public DateTime? StartDateTime { get; init; } - - ///<summary>Returns active events before this time (exclusive). Cannot be used with Duration. eg: 2022-03-22 22:00:00</summary> - [JsonPropertyName("end_date_time")] - public DateTime? EndDateTime { get; init; } - - ///<summary>Returns active events from Start time for the specified duration.</summary> - [JsonPropertyName("duration")] - public object? Duration { get; init; } -} - -public partial class CastServices -{ - private readonly IHaContext _haContext; - public CastServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Shows a dashboard view on a Chromecast device.</summary> - public void ShowLovelaceView(CastShowLovelaceViewParameters data) - { - _haContext.CallService("cast", "show_lovelace_view", null, data); - } - - ///<summary>Shows a dashboard view on a Chromecast device.</summary> - ///<param name="entityId">Media player entity to show the dashboard view on.</param> - ///<param name="dashboardPath">The URL path of the dashboard to show, defaults to lovelace if not specified. eg: lovelace-cast</param> - ///<param name="viewPath">The URL path of the dashboard view to show. eg: downstairs</param> - public void ShowLovelaceView(string entityId, string dashboardPath, string? viewPath = null) - { - _haContext.CallService("cast", "show_lovelace_view", null, new CastShowLovelaceViewParameters { EntityId = entityId, DashboardPath = dashboardPath, ViewPath = viewPath }); - } -} - -public partial record CastShowLovelaceViewParameters -{ - ///<summary>Media player entity to show the dashboard view on.</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The URL path of the dashboard to show, defaults to lovelace if not specified. eg: lovelace-cast</summary> - [JsonPropertyName("dashboard_path")] - public string? DashboardPath { get; init; } - - ///<summary>The URL path of the dashboard view to show. eg: downstairs</summary> - [JsonPropertyName("view_path")] - public string? ViewPath { get; init; } -} - -public partial class ClimateServices -{ - private readonly IHaContext _haContext; - public ClimateServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Turns auxiliary heater on/off.</summary> - ///<param name="target">The target for this service call</param> - public void SetAuxHeat(ServiceTarget target, ClimateSetAuxHeatParameters data) - { - _haContext.CallService("climate", "set_aux_heat", target, data); - } - - ///<summary>Turns auxiliary heater on/off.</summary> - ///<param name="auxHeat">New value of auxiliary heater.</param> - public void SetAuxHeat(ServiceTarget target, bool auxHeat) - { - _haContext.CallService("climate", "set_aux_heat", target, new ClimateSetAuxHeatParameters { AuxHeat = auxHeat }); - } - - ///<summary>Sets fan operation mode.</summary> - ///<param name="target">The target for this service call</param> - public void SetFanMode(ServiceTarget target, ClimateSetFanModeParameters data) - { - _haContext.CallService("climate", "set_fan_mode", target, data); - } - - ///<summary>Sets fan operation mode.</summary> - ///<param name="fanMode">Fan operation mode. eg: low</param> - public void SetFanMode(ServiceTarget target, string fanMode) - { - _haContext.CallService("climate", "set_fan_mode", target, new ClimateSetFanModeParameters { FanMode = fanMode }); - } - - ///<summary>Sets target humidity.</summary> - ///<param name="target">The target for this service call</param> - public void SetHumidity(ServiceTarget target, ClimateSetHumidityParameters data) - { - _haContext.CallService("climate", "set_humidity", target, data); - } - - ///<summary>Sets target humidity.</summary> - ///<param name="humidity">Target humidity.</param> - public void SetHumidity(ServiceTarget target, double humidity) - { - _haContext.CallService("climate", "set_humidity", target, new ClimateSetHumidityParameters { Humidity = humidity }); - } - - ///<summary>Sets HVAC operation mode.</summary> - ///<param name="target">The target for this service call</param> - public void SetHvacMode(ServiceTarget target, ClimateSetHvacModeParameters data) - { - _haContext.CallService("climate", "set_hvac_mode", target, data); - } - - ///<summary>Sets HVAC operation mode.</summary> - ///<param name="hvacMode">HVAC operation mode.</param> - public void SetHvacMode(ServiceTarget target, object? hvacMode = null) - { - _haContext.CallService("climate", "set_hvac_mode", target, new ClimateSetHvacModeParameters { HvacMode = hvacMode }); - } - - ///<summary>Sets preset mode.</summary> - ///<param name="target">The target for this service call</param> - public void SetPresetMode(ServiceTarget target, ClimateSetPresetModeParameters data) - { - _haContext.CallService("climate", "set_preset_mode", target, data); - } - - ///<summary>Sets preset mode.</summary> - ///<param name="presetMode">Preset mode. eg: away</param> - public void SetPresetMode(ServiceTarget target, string presetMode) - { - _haContext.CallService("climate", "set_preset_mode", target, new ClimateSetPresetModeParameters { PresetMode = presetMode }); - } - - ///<summary>Sets horizontal swing operation mode.</summary> - ///<param name="target">The target for this service call</param> - public void SetSwingHorizontalMode(ServiceTarget target, ClimateSetSwingHorizontalModeParameters data) - { - _haContext.CallService("climate", "set_swing_horizontal_mode", target, data); - } - - ///<summary>Sets horizontal swing operation mode.</summary> - ///<param name="swingHorizontalMode">Horizontal swing operation mode. eg: on</param> - public void SetSwingHorizontalMode(ServiceTarget target, string swingHorizontalMode) - { - _haContext.CallService("climate", "set_swing_horizontal_mode", target, new ClimateSetSwingHorizontalModeParameters { SwingHorizontalMode = swingHorizontalMode }); - } - - ///<summary>Sets swing operation mode.</summary> - ///<param name="target">The target for this service call</param> - public void SetSwingMode(ServiceTarget target, ClimateSetSwingModeParameters data) - { - _haContext.CallService("climate", "set_swing_mode", target, data); - } - - ///<summary>Sets swing operation mode.</summary> - ///<param name="swingMode">Swing operation mode. eg: on</param> - public void SetSwingMode(ServiceTarget target, string swingMode) - { - _haContext.CallService("climate", "set_swing_mode", target, new ClimateSetSwingModeParameters { SwingMode = swingMode }); - } - - ///<summary>Sets the temperature setpoint.</summary> - ///<param name="target">The target for this service call</param> - public void SetTemperature(ServiceTarget target, ClimateSetTemperatureParameters data) - { - _haContext.CallService("climate", "set_temperature", target, data); - } - - ///<summary>Sets the temperature setpoint.</summary> - ///<param name="temperature">The temperature setpoint.</param> - ///<param name="targetTempHigh">The max temperature setpoint.</param> - ///<param name="targetTempLow">The min temperature setpoint.</param> - ///<param name="hvacMode">HVAC operation mode.</param> - public void SetTemperature(ServiceTarget target, double? temperature = null, double? targetTempHigh = null, double? targetTempLow = null, object? hvacMode = null) - { - _haContext.CallService("climate", "set_temperature", target, new ClimateSetTemperatureParameters { Temperature = temperature, TargetTempHigh = targetTempHigh, TargetTempLow = targetTempLow, HvacMode = hvacMode }); - } - - ///<summary>Toggles climate device, from on to off, or off to on.</summary> - ///<param name="target">The target for this service call</param> - public void Toggle(ServiceTarget target, object? data = null) - { - _haContext.CallService("climate", "toggle", target, data); - } - - ///<summary>Turns climate device off.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOff(ServiceTarget target, object? data = null) - { - _haContext.CallService("climate", "turn_off", target, data); - } - - ///<summary>Turns climate device on.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOn(ServiceTarget target, object? data = null) - { - _haContext.CallService("climate", "turn_on", target, data); - } -} - -public partial record ClimateSetAuxHeatParameters -{ - ///<summary>New value of auxiliary heater.</summary> - [JsonPropertyName("aux_heat")] - public bool? AuxHeat { get; init; } -} - -public partial record ClimateSetFanModeParameters -{ - ///<summary>Fan operation mode. eg: low</summary> - [JsonPropertyName("fan_mode")] - public string? FanMode { get; init; } -} - -public partial record ClimateSetHumidityParameters -{ - ///<summary>Target humidity.</summary> - [JsonPropertyName("humidity")] - public double? Humidity { get; init; } -} - -public partial record ClimateSetHvacModeParameters -{ - ///<summary>HVAC operation mode.</summary> - [JsonPropertyName("hvac_mode")] - public object? HvacMode { get; init; } -} - -public partial record ClimateSetPresetModeParameters -{ - ///<summary>Preset mode. eg: away</summary> - [JsonPropertyName("preset_mode")] - public string? PresetMode { get; init; } -} - -public partial record ClimateSetSwingHorizontalModeParameters -{ - ///<summary>Horizontal swing operation mode. eg: on</summary> - [JsonPropertyName("swing_horizontal_mode")] - public string? SwingHorizontalMode { get; init; } -} - -public partial record ClimateSetSwingModeParameters -{ - ///<summary>Swing operation mode. eg: on</summary> - [JsonPropertyName("swing_mode")] - public string? SwingMode { get; init; } -} - -public partial record ClimateSetTemperatureParameters -{ - ///<summary>The temperature setpoint.</summary> - [JsonPropertyName("temperature")] - public double? Temperature { get; init; } - - ///<summary>The max temperature setpoint.</summary> - [JsonPropertyName("target_temp_high")] - public double? TargetTempHigh { get; init; } - - ///<summary>The min temperature setpoint.</summary> - [JsonPropertyName("target_temp_low")] - public double? TargetTempLow { get; init; } - - ///<summary>HVAC operation mode.</summary> - [JsonPropertyName("hvac_mode")] - public object? HvacMode { get; init; } -} - -public partial class ConversationServices -{ - private readonly IHaContext _haContext; - public ConversationServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Launches a conversation from a transcribed text.</summary> - public void Process(ConversationProcessParameters data) - { - _haContext.CallService("conversation", "process", null, data); - } - - ///<summary>Launches a conversation from a transcribed text.</summary> - ///<param name="text">Transcribed text input. eg: Turn all lights on</param> - ///<param name="language">Language of text. Defaults to server language. eg: NL</param> - ///<param name="agentId">Conversation agent to process your request. The conversation agent is the brains of your assistant. It processes the incoming text commands. eg: homeassistant</param> - ///<param name="conversationId">ID of the conversation, to be able to continue a previous conversation eg: my_conversation_1</param> - public void Process(string text, string? language = null, object? agentId = null, string? conversationId = null) - { - _haContext.CallService("conversation", "process", null, new ConversationProcessParameters { Text = text, Language = language, AgentId = agentId, ConversationId = conversationId }); - } - - ///<summary>Launches a conversation from a transcribed text.</summary> - public Task<JsonElement?> ProcessAsync(ConversationProcessParameters data) - { - return _haContext.CallServiceWithResponseAsync("conversation", "process", null, data); - } - - ///<summary>Launches a conversation from a transcribed text.</summary> - ///<param name="text">Transcribed text input. eg: Turn all lights on</param> - ///<param name="language">Language of text. Defaults to server language. eg: NL</param> - ///<param name="agentId">Conversation agent to process your request. The conversation agent is the brains of your assistant. It processes the incoming text commands. eg: homeassistant</param> - ///<param name="conversationId">ID of the conversation, to be able to continue a previous conversation eg: my_conversation_1</param> - public Task<JsonElement?> ProcessAsync(string text, string? language = null, object? agentId = null, string? conversationId = null) - { - return _haContext.CallServiceWithResponseAsync("conversation", "process", null, new ConversationProcessParameters { Text = text, Language = language, AgentId = agentId, ConversationId = conversationId }); - } - - ///<summary>Reloads the intent configuration.</summary> - public void Reload(ConversationReloadParameters data) - { - _haContext.CallService("conversation", "reload", null, data); - } - - ///<summary>Reloads the intent configuration.</summary> - ///<param name="language">Language to clear cached intents for. Defaults to server language. eg: NL</param> - ///<param name="agentId">Conversation agent to reload. eg: homeassistant</param> - public void Reload(string? language = null, object? agentId = null) - { - _haContext.CallService("conversation", "reload", null, new ConversationReloadParameters { Language = language, AgentId = agentId }); - } -} - -public partial record ConversationProcessParameters -{ - ///<summary>Transcribed text input. eg: Turn all lights on</summary> - [JsonPropertyName("text")] - public string? Text { get; init; } - - ///<summary>Language of text. Defaults to server language. eg: NL</summary> - [JsonPropertyName("language")] - public string? Language { get; init; } - - ///<summary>Conversation agent to process your request. The conversation agent is the brains of your assistant. It processes the incoming text commands. eg: homeassistant</summary> - [JsonPropertyName("agent_id")] - public object? AgentId { get; init; } - - ///<summary>ID of the conversation, to be able to continue a previous conversation eg: my_conversation_1</summary> - [JsonPropertyName("conversation_id")] - public string? ConversationId { get; init; } -} - -public partial record ConversationReloadParameters -{ - ///<summary>Language to clear cached intents for. Defaults to server language. eg: NL</summary> - [JsonPropertyName("language")] - public string? Language { get; init; } - - ///<summary>Conversation agent to reload. eg: homeassistant</summary> - [JsonPropertyName("agent_id")] - public object? AgentId { get; init; } -} - -public partial class CounterServices -{ - private readonly IHaContext _haContext; - public CounterServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Decrements a counter by its step size.</summary> - ///<param name="target">The target for this service call</param> - public void Decrement(ServiceTarget target, object? data = null) - { - _haContext.CallService("counter", "decrement", target, data); - } - - ///<summary>Increments a counter by its step size.</summary> - ///<param name="target">The target for this service call</param> - public void Increment(ServiceTarget target, object? data = null) - { - _haContext.CallService("counter", "increment", target, data); - } - - ///<summary>Resets a counter to its initial value.</summary> - ///<param name="target">The target for this service call</param> - public void Reset(ServiceTarget target, object? data = null) - { - _haContext.CallService("counter", "reset", target, data); - } - - ///<summary>Sets the counter to a specific value.</summary> - ///<param name="target">The target for this service call</param> - public void SetValue(ServiceTarget target, CounterSetValueParameters data) - { - _haContext.CallService("counter", "set_value", target, data); - } - - ///<summary>Sets the counter to a specific value.</summary> - ///<param name="value">The new counter value the entity should be set to.</param> - public void SetValue(ServiceTarget target, double value) - { - _haContext.CallService("counter", "set_value", target, new CounterSetValueParameters { Value = value }); - } -} - -public partial record CounterSetValueParameters -{ - ///<summary>The new counter value the entity should be set to.</summary> - [JsonPropertyName("value")] - public double? Value { get; init; } -} - -public partial class DeviceTrackerServices -{ - private readonly IHaContext _haContext; - public DeviceTrackerServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Manually update the records of a seen legacy device tracker in the known_devices.yaml file.</summary> - public void See(DeviceTrackerSeeParameters data) - { - _haContext.CallService("device_tracker", "see", null, data); - } - - ///<summary>Manually update the records of a seen legacy device tracker in the known_devices.yaml file.</summary> - ///<param name="mac">MAC address of the device. eg: FF:FF:FF:FF:FF:FF</param> - ///<param name="devId">ID of the device (find the ID in `known_devices.yaml`). eg: phonedave</param> - ///<param name="hostName">Hostname of the device. eg: Dave</param> - ///<param name="locationName">Name of the location where the device is located. The options are: `home`, `not_home`, or the name of the zone. eg: home</param> - ///<param name="gps">GPS coordinates where the device is located, specified by latitude and longitude (for example: [51.513845, -0.100539]). eg: [51.509802, -0.086692]</param> - ///<param name="gpsAccuracy">Accuracy of the GPS coordinates.</param> - ///<param name="battery">Battery level of the device.</param> - public void See(string? mac = null, string? devId = null, string? hostName = null, string? locationName = null, object? gps = null, double? gpsAccuracy = null, double? battery = null) - { - _haContext.CallService("device_tracker", "see", null, new DeviceTrackerSeeParameters { Mac = mac, DevId = devId, HostName = hostName, LocationName = locationName, Gps = gps, GpsAccuracy = gpsAccuracy, Battery = battery }); - } -} - -public partial record DeviceTrackerSeeParameters -{ - ///<summary>MAC address of the device. eg: FF:FF:FF:FF:FF:FF</summary> - [JsonPropertyName("mac")] - public string? Mac { get; init; } - - ///<summary>ID of the device (find the ID in `known_devices.yaml`). eg: phonedave</summary> - [JsonPropertyName("dev_id")] - public string? DevId { get; init; } - - ///<summary>Hostname of the device. eg: Dave</summary> - [JsonPropertyName("host_name")] - public string? HostName { get; init; } - - ///<summary>Name of the location where the device is located. The options are: `home`, `not_home`, or the name of the zone. eg: home</summary> - [JsonPropertyName("location_name")] - public string? LocationName { get; init; } - - ///<summary>GPS coordinates where the device is located, specified by latitude and longitude (for example: [51.513845, -0.100539]). eg: [51.509802, -0.086692]</summary> - [JsonPropertyName("gps")] - public object? Gps { get; init; } - - ///<summary>Accuracy of the GPS coordinates.</summary> - [JsonPropertyName("gps_accuracy")] - public double? GpsAccuracy { get; init; } - - ///<summary>Battery level of the device.</summary> - [JsonPropertyName("battery")] - public double? Battery { get; init; } -} - -public partial class ExtendedOllamaConversationServices -{ - private readonly IHaContext _haContext; - public ExtendedOllamaConversationServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Take in images and answer questions about them</summary> - public void QueryImage(ExtendedOllamaConversationQueryImageParameters data) - { - _haContext.CallService("extended_ollama_conversation", "query_image", null, data); - } - - ///<summary>Take in images and answer questions about them</summary> - ///<param name="configEntry">The config entry to use for this service</param> - ///<param name="model">The model eg: gpt-4-vision-preview</param> - ///<param name="prompt">The text to ask about image eg: What’s in this image?</param> - ///<param name="images">A list of images that would be asked eg: {"url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"}</param> - ///<param name="maxTokens">The maximum tokens eg: 300</param> - public void QueryImage(object configEntry, string prompt, object images, string? model = null, double? maxTokens = null) - { - _haContext.CallService("extended_ollama_conversation", "query_image", null, new ExtendedOllamaConversationQueryImageParameters { ConfigEntry = configEntry, Model = model, Prompt = prompt, Images = images, MaxTokens = maxTokens }); - } - - ///<summary>Take in images and answer questions about them</summary> - public Task<JsonElement?> QueryImageAsync(ExtendedOllamaConversationQueryImageParameters data) - { - return _haContext.CallServiceWithResponseAsync("extended_ollama_conversation", "query_image", null, data); - } - - ///<summary>Take in images and answer questions about them</summary> - ///<param name="configEntry">The config entry to use for this service</param> - ///<param name="model">The model eg: gpt-4-vision-preview</param> - ///<param name="prompt">The text to ask about image eg: What’s in this image?</param> - ///<param name="images">A list of images that would be asked eg: {"url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"}</param> - ///<param name="maxTokens">The maximum tokens eg: 300</param> - public Task<JsonElement?> QueryImageAsync(object configEntry, string prompt, object images, string? model = null, double? maxTokens = null) - { - return _haContext.CallServiceWithResponseAsync("extended_ollama_conversation", "query_image", null, new ExtendedOllamaConversationQueryImageParameters { ConfigEntry = configEntry, Model = model, Prompt = prompt, Images = images, MaxTokens = maxTokens }); - } -} - -public partial record ExtendedOllamaConversationQueryImageParameters -{ - ///<summary>The config entry to use for this service</summary> - [JsonPropertyName("config_entry")] - public object? ConfigEntry { get; init; } - - ///<summary>The model eg: gpt-4-vision-preview</summary> - [JsonPropertyName("model")] - public string? Model { get; init; } - - ///<summary>The text to ask about image eg: What’s in this image?</summary> - [JsonPropertyName("prompt")] - public string? Prompt { get; init; } - - ///<summary>A list of images that would be asked eg: {"url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"}</summary> - [JsonPropertyName("images")] - public object? Images { get; init; } - - ///<summary>The maximum tokens eg: 300</summary> - [JsonPropertyName("max_tokens")] - public double? MaxTokens { get; init; } -} - -public partial class FfmpegServices -{ - private readonly IHaContext _haContext; - public FfmpegServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Sends a restart command to an FFmpeg-based sensor.</summary> - public void Restart(FfmpegRestartParameters data) - { - _haContext.CallService("ffmpeg", "restart", null, data); - } - - ///<summary>Sends a restart command to an FFmpeg-based sensor.</summary> - ///<param name="entityId">Name of entity that will restart. Platform dependent.</param> - public void Restart(string? entityId = null) - { - _haContext.CallService("ffmpeg", "restart", null, new FfmpegRestartParameters { EntityId = entityId }); - } - - ///<summary>Sends a start command to an FFmpeg-based sensor.</summary> - public void Start(FfmpegStartParameters data) - { - _haContext.CallService("ffmpeg", "start", null, data); - } - - ///<summary>Sends a start command to an FFmpeg-based sensor.</summary> - ///<param name="entityId">Name of entity that will start. Platform dependent.</param> - public void Start(string? entityId = null) - { - _haContext.CallService("ffmpeg", "start", null, new FfmpegStartParameters { EntityId = entityId }); - } - - ///<summary>Sends a stop command to an FFmpeg-based sensor.</summary> - public void Stop(FfmpegStopParameters data) - { - _haContext.CallService("ffmpeg", "stop", null, data); - } - - ///<summary>Sends a stop command to an FFmpeg-based sensor.</summary> - ///<param name="entityId">Name of entity that will stop. Platform dependent.</param> - public void Stop(string? entityId = null) - { - _haContext.CallService("ffmpeg", "stop", null, new FfmpegStopParameters { EntityId = entityId }); - } -} - -public partial record FfmpegRestartParameters -{ - ///<summary>Name of entity that will restart. Platform dependent.</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } -} - -public partial record FfmpegStartParameters -{ - ///<summary>Name of entity that will start. Platform dependent.</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } -} - -public partial record FfmpegStopParameters -{ - ///<summary>Name of entity that will stop. Platform dependent.</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } -} - -public partial class FrontendServices -{ - private readonly IHaContext _haContext; - public FrontendServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Reloads themes from the YAML-configuration.</summary> - public void ReloadThemes(object? data = null) - { - _haContext.CallService("frontend", "reload_themes", null, data); - } - - ///<summary>Sets the default theme Home Assistant uses. Can be overridden by a user.</summary> - public void SetTheme(FrontendSetThemeParameters data) - { - _haContext.CallService("frontend", "set_theme", null, data); - } - - ///<summary>Sets the default theme Home Assistant uses. Can be overridden by a user.</summary> - ///<param name="name">Name of a theme. eg: default</param> - ///<param name="mode">Theme mode.</param> - public void SetTheme(object name, object? mode = null) - { - _haContext.CallService("frontend", "set_theme", null, new FrontendSetThemeParameters { Name = name, Mode = mode }); - } -} - -public partial record FrontendSetThemeParameters -{ - ///<summary>Name of a theme. eg: default</summary> - [JsonPropertyName("name")] - public object? Name { get; init; } - - ///<summary>Theme mode.</summary> - [JsonPropertyName("mode")] - public object? Mode { get; init; } -} - -public partial class HomeassistantServices -{ - private readonly IHaContext _haContext; - public HomeassistantServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Checks the Home Assistant YAML-configuration files for errors. Errors will be shown in the Home Assistant logs.</summary> - public void CheckConfig(object? data = null) - { - _haContext.CallService("homeassistant", "check_config", null, data); - } - - ///<summary>Reloads all YAML configuration that can be reloaded without restarting Home Assistant.</summary> - public void ReloadAll(object? data = null) - { - _haContext.CallService("homeassistant", "reload_all", null, data); - } - - ///<summary>Reloads the specified config entry.</summary> - ///<param name="target">The target for this service call</param> - public void ReloadConfigEntry(ServiceTarget target, HomeassistantReloadConfigEntryParameters data) - { - _haContext.CallService("homeassistant", "reload_config_entry", target, data); - } - - ///<summary>Reloads the specified config entry.</summary> - ///<param name="entryId">The configuration entry ID of the entry to be reloaded. eg: 8955375327824e14ba89e4b29cc3ec9a</param> - public void ReloadConfigEntry(ServiceTarget target, string? entryId = null) - { - _haContext.CallService("homeassistant", "reload_config_entry", target, new HomeassistantReloadConfigEntryParameters { EntryId = entryId }); - } - - ///<summary>Reloads the Core configuration from the YAML-configuration.</summary> - public void ReloadCoreConfig(object? data = null) - { - _haContext.CallService("homeassistant", "reload_core_config", null, data); - } - - ///<summary>Reloads Jinja2 templates found in the `custom_templates` folder in your config. New values will be applied on the next render of the template.</summary> - public void ReloadCustomTemplates(object? data = null) - { - _haContext.CallService("homeassistant", "reload_custom_templates", null, data); - } - - ///<summary>Restarts Home Assistant.</summary> - public void Restart(object? data = null) - { - _haContext.CallService("homeassistant", "restart", null, data); - } - - ///<summary>Saves the persistent states immediately. Maintains the normal periodic saving interval.</summary> - public void SavePersistentStates(object? data = null) - { - _haContext.CallService("homeassistant", "save_persistent_states", null, data); - } - - ///<summary>Updates the Home Assistant location.</summary> - public void SetLocation(HomeassistantSetLocationParameters data) - { - _haContext.CallService("homeassistant", "set_location", null, data); - } - - ///<summary>Updates the Home Assistant location.</summary> - ///<param name="latitude">Latitude of your location. eg: 32.87336</param> - ///<param name="longitude">Longitude of your location. eg: 117.22743</param> - ///<param name="elevation">Elevation of your location above sea level. eg: 120</param> - public void SetLocation(double latitude, double longitude, double? elevation = null) - { - _haContext.CallService("homeassistant", "set_location", null, new HomeassistantSetLocationParameters { Latitude = latitude, Longitude = longitude, Elevation = elevation }); - } - - ///<summary>Stops Home Assistant.</summary> - public void Stop(object? data = null) - { - _haContext.CallService("homeassistant", "stop", null, data); - } - - ///<summary>Generic action to toggle devices on/off under any domain.</summary> - ///<param name="target">The target for this service call</param> - public void Toggle(ServiceTarget target, object? data = null) - { - _haContext.CallService("homeassistant", "toggle", target, data); - } - - ///<summary>Generic action to turn devices off under any domain.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOff(ServiceTarget target, object? data = null) - { - _haContext.CallService("homeassistant", "turn_off", target, data); - } - - ///<summary>Generic action to turn devices on under any domain.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOn(ServiceTarget target, object? data = null) - { - _haContext.CallService("homeassistant", "turn_on", target, data); - } - - ///<summary>Forces one or more entities to update their data.</summary> - public void UpdateEntity(HomeassistantUpdateEntityParameters data) - { - _haContext.CallService("homeassistant", "update_entity", null, data); - } - - ///<summary>Forces one or more entities to update their data.</summary> - ///<param name="entityId">List of entities to force update.</param> - public void UpdateEntity(IEnumerable<string> entityId) - { - _haContext.CallService("homeassistant", "update_entity", null, new HomeassistantUpdateEntityParameters { EntityId = entityId }); - } -} - -public partial record HomeassistantReloadConfigEntryParameters -{ - ///<summary>The configuration entry ID of the entry to be reloaded. eg: 8955375327824e14ba89e4b29cc3ec9a</summary> - [JsonPropertyName("entry_id")] - public string? EntryId { get; init; } -} - -public partial record HomeassistantSetLocationParameters -{ - ///<summary>Latitude of your location. eg: 32.87336</summary> - [JsonPropertyName("latitude")] - public double? Latitude { get; init; } - - ///<summary>Longitude of your location. eg: 117.22743</summary> - [JsonPropertyName("longitude")] - public double? Longitude { get; init; } - - ///<summary>Elevation of your location above sea level. eg: 120</summary> - [JsonPropertyName("elevation")] - public double? Elevation { get; init; } -} - -public partial record HomeassistantUpdateEntityParameters -{ - ///<summary>List of entities to force update.</summary> - [JsonPropertyName("entity_id")] - public IEnumerable<string>? EntityId { get; init; } -} - -public partial class InputBooleanServices -{ - private readonly IHaContext _haContext; - public InputBooleanServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Reloads helpers from the YAML-configuration.</summary> - public void Reload(object? data = null) - { - _haContext.CallService("input_boolean", "reload", null, data); - } - - ///<summary>Toggles the helper on/off.</summary> - ///<param name="target">The target for this service call</param> - public void Toggle(ServiceTarget target, object? data = null) - { - _haContext.CallService("input_boolean", "toggle", target, data); - } - - ///<summary>Turns off the helper.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOff(ServiceTarget target, object? data = null) - { - _haContext.CallService("input_boolean", "turn_off", target, data); - } - - ///<summary>Turns on the helper.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOn(ServiceTarget target, object? data = null) - { - _haContext.CallService("input_boolean", "turn_on", target, data); - } -} - -public partial class InputButtonServices -{ - private readonly IHaContext _haContext; - public InputButtonServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Mimics the physical button press on the device.</summary> - ///<param name="target">The target for this service call</param> - public void Press(ServiceTarget target, object? data = null) - { - _haContext.CallService("input_button", "press", target, data); - } - - ///<summary>Reloads helpers from the YAML-configuration.</summary> - public void Reload(object? data = null) - { - _haContext.CallService("input_button", "reload", null, data); - } -} - -public partial class InputDatetimeServices -{ - private readonly IHaContext _haContext; - public InputDatetimeServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Reloads helpers from the YAML-configuration.</summary> - public void Reload(object? data = null) - { - _haContext.CallService("input_datetime", "reload", null, data); - } - - ///<summary>Sets the date and/or time.</summary> - ///<param name="target">The target for this service call</param> - public void SetDatetime(ServiceTarget target, InputDatetimeSetDatetimeParameters data) - { - _haContext.CallService("input_datetime", "set_datetime", target, data); - } - - ///<summary>Sets the date and/or time.</summary> - ///<param name="date">The target date. eg: "2019-04-20"</param> - ///<param name="time">The target time. eg: "05:04:20"</param> - ///<param name="datetime">The target date & time. eg: "2019-04-20 05:04:20"</param> - ///<param name="timestamp">The target date & time, expressed by a UNIX timestamp.</param> - public void SetDatetime(ServiceTarget target, string? date = null, TimeOnly? time = null, string? datetime = null, double? timestamp = null) - { - _haContext.CallService("input_datetime", "set_datetime", target, new InputDatetimeSetDatetimeParameters { Date = date, Time = time, Datetime = datetime, Timestamp = timestamp }); - } -} - -public partial record InputDatetimeSetDatetimeParameters -{ - ///<summary>The target date. eg: "2019-04-20"</summary> - [JsonPropertyName("date")] - public string? Date { get; init; } - - ///<summary>The target time. eg: "05:04:20"</summary> - [JsonPropertyName("time")] - public TimeOnly? Time { get; init; } - - ///<summary>The target date & time. eg: "2019-04-20 05:04:20"</summary> - [JsonPropertyName("datetime")] - public string? Datetime { get; init; } - - ///<summary>The target date & time, expressed by a UNIX timestamp.</summary> - [JsonPropertyName("timestamp")] - public double? Timestamp { get; init; } -} - -public partial class InputNumberServices -{ - private readonly IHaContext _haContext; - public InputNumberServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Decrements the current value by 1 step.</summary> - ///<param name="target">The target for this service call</param> - public void Decrement(ServiceTarget target, object? data = null) - { - _haContext.CallService("input_number", "decrement", target, data); - } - - ///<summary>Increments the current value by 1 step.</summary> - ///<param name="target">The target for this service call</param> - public void Increment(ServiceTarget target, object? data = null) - { - _haContext.CallService("input_number", "increment", target, data); - } - - ///<summary>Reloads helpers from the YAML-configuration.</summary> - public void Reload(object? data = null) - { - _haContext.CallService("input_number", "reload", null, data); - } - - ///<summary>Sets the value.</summary> - ///<param name="target">The target for this service call</param> - public void SetValue(ServiceTarget target, InputNumberSetValueParameters data) - { - _haContext.CallService("input_number", "set_value", target, data); - } - - ///<summary>Sets the value.</summary> - ///<param name="value">The target value.</param> - public void SetValue(ServiceTarget target, double value) - { - _haContext.CallService("input_number", "set_value", target, new InputNumberSetValueParameters { Value = value }); - } -} - -public partial record InputNumberSetValueParameters -{ - ///<summary>The target value.</summary> - [JsonPropertyName("value")] - public double? Value { get; init; } -} - -public partial class InputSelectServices -{ - private readonly IHaContext _haContext; - public InputSelectServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Reloads helpers from the YAML-configuration.</summary> - public void Reload(object? data = null) - { - _haContext.CallService("input_select", "reload", null, data); - } - - ///<summary>Selects the first option.</summary> - ///<param name="target">The target for this service call</param> - public void SelectFirst(ServiceTarget target, object? data = null) - { - _haContext.CallService("input_select", "select_first", target, data); - } - - ///<summary>Selects the last option.</summary> - ///<param name="target">The target for this service call</param> - public void SelectLast(ServiceTarget target, object? data = null) - { - _haContext.CallService("input_select", "select_last", target, data); - } - - ///<summary>Selects the next option.</summary> - ///<param name="target">The target for this service call</param> - public void SelectNext(ServiceTarget target, InputSelectSelectNextParameters data) - { - _haContext.CallService("input_select", "select_next", target, data); - } - - ///<summary>Selects the next option.</summary> - ///<param name="cycle">If the option should cycle from the last to the first option on the list.</param> - public void SelectNext(ServiceTarget target, bool? cycle = null) - { - _haContext.CallService("input_select", "select_next", target, new InputSelectSelectNextParameters { Cycle = cycle }); - } - - ///<summary>Selects an option.</summary> - ///<param name="target">The target for this service call</param> - public void SelectOption(ServiceTarget target, InputSelectSelectOptionParameters data) - { - _haContext.CallService("input_select", "select_option", target, data); - } - - ///<summary>Selects an option.</summary> - ///<param name="option">Option to be selected. eg: "Item A"</param> - public void SelectOption(ServiceTarget target, string option) - { - _haContext.CallService("input_select", "select_option", target, new InputSelectSelectOptionParameters { Option = option }); - } - - ///<summary>Selects the previous option.</summary> - ///<param name="target">The target for this service call</param> - public void SelectPrevious(ServiceTarget target, InputSelectSelectPreviousParameters data) - { - _haContext.CallService("input_select", "select_previous", target, data); - } - - ///<summary>Selects the previous option.</summary> - ///<param name="cycle">If the option should cycle from the first to the last option on the list.</param> - public void SelectPrevious(ServiceTarget target, bool? cycle = null) - { - _haContext.CallService("input_select", "select_previous", target, new InputSelectSelectPreviousParameters { Cycle = cycle }); - } - - ///<summary>Sets the options.</summary> - ///<param name="target">The target for this service call</param> - public void SetOptions(ServiceTarget target, InputSelectSetOptionsParameters data) - { - _haContext.CallService("input_select", "set_options", target, data); - } - - ///<summary>Sets the options.</summary> - ///<param name="options">List of options. eg: ["Item A", "Item B", "Item C"]</param> - public void SetOptions(ServiceTarget target, IEnumerable<string> options) - { - _haContext.CallService("input_select", "set_options", target, new InputSelectSetOptionsParameters { Options = options }); - } -} - -public partial record InputSelectSelectNextParameters -{ - ///<summary>If the option should cycle from the last to the first option on the list.</summary> - [JsonPropertyName("cycle")] - public bool? Cycle { get; init; } -} - -public partial record InputSelectSelectOptionParameters -{ - ///<summary>Option to be selected. eg: "Item A"</summary> - [JsonPropertyName("option")] - public string? Option { get; init; } -} - -public partial record InputSelectSelectPreviousParameters -{ - ///<summary>If the option should cycle from the first to the last option on the list.</summary> - [JsonPropertyName("cycle")] - public bool? Cycle { get; init; } -} - -public partial record InputSelectSetOptionsParameters -{ - ///<summary>List of options. eg: ["Item A", "Item B", "Item C"]</summary> - [JsonPropertyName("options")] - public IEnumerable<string>? Options { get; init; } -} - -public partial class InputTextServices -{ - private readonly IHaContext _haContext; - public InputTextServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Reloads helpers from the YAML-configuration.</summary> - public void Reload(object? data = null) - { - _haContext.CallService("input_text", "reload", null, data); - } - - ///<summary>Sets the value.</summary> - ///<param name="target">The target for this service call</param> - public void SetValue(ServiceTarget target, InputTextSetValueParameters data) - { - _haContext.CallService("input_text", "set_value", target, data); - } - - ///<summary>Sets the value.</summary> - ///<param name="value">The target value. eg: This is an example text</param> - public void SetValue(ServiceTarget target, string value) - { - _haContext.CallService("input_text", "set_value", target, new InputTextSetValueParameters { Value = value }); - } -} - -public partial record InputTextSetValueParameters -{ - ///<summary>The target value. eg: This is an example text</summary> - [JsonPropertyName("value")] - public string? Value { get; init; } -} - -public partial class IntentScriptServices -{ - private readonly IHaContext _haContext; - public IntentScriptServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Reloads the intent script from the YAML-configuration.</summary> - public void Reload(object? data = null) - { - _haContext.CallService("intent_script", "reload", null, data); - } -} - -public partial class LightServices -{ - private readonly IHaContext _haContext; - public LightServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Toggles one or more lights, from on to off, or off to on, based on their current state.</summary> - ///<param name="target">The target for this service call</param> - public void Toggle(ServiceTarget target, LightToggleParameters data) - { - _haContext.CallService("light", "toggle", target, data); - } - - ///<summary>Toggles one or more lights, from on to off, or off to on, based on their current state.</summary> - ///<param name="transition">Duration it takes to get to next state.</param> - ///<param name="rgbColor">The color in RGB format. A list of three integers between 0 and 255 representing the values of red, green, and blue. eg: [255, 100, 100]</param> - ///<param name="kelvin">Color temperature in Kelvin.</param> - ///<param name="brightnessPct">Number indicating the percentage of full brightness, where 0 turns the light off, 1 is the minimum brightness, and 100 is the maximum brightness.</param> - ///<param name="effect">Light effect.</param> - ///<param name="rgbwColor"> eg: [255, 100, 100, 50]</param> - ///<param name="rgbwwColor"> eg: [255, 100, 100, 50, 70]</param> - ///<param name="colorName"></param> - ///<param name="hsColor"> eg: [300, 70]</param> - ///<param name="xyColor"> eg: [0.52, 0.43]</param> - ///<param name="colorTemp"></param> - ///<param name="brightness"></param> - ///<param name="white"></param> - ///<param name="profile"> eg: relax</param> - ///<param name="flash"></param> - public void Toggle(ServiceTarget target, double? transition = null, IReadOnlyCollection<int>? rgbColor = null, object? kelvin = null, double? brightnessPct = null, string? effect = null, object? rgbwColor = null, object? rgbwwColor = null, object? colorName = null, object? hsColor = null, object? xyColor = null, object? colorTemp = null, double? brightness = null, object? white = null, string? profile = null, object? flash = null) - { - _haContext.CallService("light", "toggle", target, new LightToggleParameters { Transition = transition, RgbColor = rgbColor, Kelvin = kelvin, BrightnessPct = brightnessPct, Effect = effect, RgbwColor = rgbwColor, RgbwwColor = rgbwwColor, ColorName = colorName, HsColor = hsColor, XyColor = xyColor, ColorTemp = colorTemp, Brightness = brightness, White = white, Profile = profile, Flash = flash }); - } - - ///<summary>Turns off one or more lights.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOff(ServiceTarget target, LightTurnOffParameters data) - { - _haContext.CallService("light", "turn_off", target, data); - } - - ///<summary>Turns off one or more lights.</summary> - ///<param name="transition">Duration it takes to get to next state.</param> - ///<param name="flash"></param> - public void TurnOff(ServiceTarget target, double? transition = null, object? flash = null) - { - _haContext.CallService("light", "turn_off", target, new LightTurnOffParameters { Transition = transition, Flash = flash }); - } - - ///<summary>Turns on one or more lights and adjusts their properties, even when they are turned on already.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOn(ServiceTarget target, LightTurnOnParameters data) - { - _haContext.CallService("light", "turn_on", target, data); - } - - ///<summary>Turns on one or more lights and adjusts their properties, even when they are turned on already.</summary> - ///<param name="transition">Duration it takes to get to next state.</param> - ///<param name="rgbColor">The color in RGB format. A list of three integers between 0 and 255 representing the values of red, green, and blue. eg: [255, 100, 100]</param> - ///<param name="kelvin">Color temperature in Kelvin.</param> - ///<param name="brightnessPct">Number indicating the percentage of full brightness, where 0 turns the light off, 1 is the minimum brightness, and 100 is the maximum brightness.</param> - ///<param name="brightnessStepPct">Change brightness by a percentage.</param> - ///<param name="effect">Light effect.</param> - ///<param name="rgbwColor"> eg: [255, 100, 100, 50]</param> - ///<param name="rgbwwColor"> eg: [255, 100, 100, 50, 70]</param> - ///<param name="colorName"></param> - ///<param name="hsColor"> eg: [300, 70]</param> - ///<param name="xyColor"> eg: [0.52, 0.43]</param> - ///<param name="colorTemp"></param> - ///<param name="brightness"></param> - ///<param name="brightnessStep"></param> - ///<param name="white"></param> - ///<param name="profile"> eg: relax</param> - ///<param name="flash"></param> - public void TurnOn(ServiceTarget target, double? transition = null, IReadOnlyCollection<int>? rgbColor = null, object? kelvin = null, double? brightnessPct = null, double? brightnessStepPct = null, string? effect = null, object? rgbwColor = null, object? rgbwwColor = null, object? colorName = null, object? hsColor = null, object? xyColor = null, object? colorTemp = null, double? brightness = null, double? brightnessStep = null, object? white = null, string? profile = null, object? flash = null) - { - _haContext.CallService("light", "turn_on", target, new LightTurnOnParameters { Transition = transition, RgbColor = rgbColor, Kelvin = kelvin, BrightnessPct = brightnessPct, BrightnessStepPct = brightnessStepPct, Effect = effect, RgbwColor = rgbwColor, RgbwwColor = rgbwwColor, ColorName = colorName, HsColor = hsColor, XyColor = xyColor, ColorTemp = colorTemp, Brightness = brightness, BrightnessStep = brightnessStep, White = white, Profile = profile, Flash = flash }); - } -} - -public partial record LightToggleParameters -{ - ///<summary>Duration it takes to get to next state.</summary> - [JsonPropertyName("transition")] - public double? Transition { get; init; } - - ///<summary>The color in RGB format. A list of three integers between 0 and 255 representing the values of red, green, and blue. eg: [255, 100, 100]</summary> - [JsonPropertyName("rgb_color")] - public IReadOnlyCollection<int>? RgbColor { get; init; } - - ///<summary>Color temperature in Kelvin.</summary> - [JsonPropertyName("kelvin")] - public object? Kelvin { get; init; } - - ///<summary>Number indicating the percentage of full brightness, where 0 turns the light off, 1 is the minimum brightness, and 100 is the maximum brightness.</summary> - [JsonPropertyName("brightness_pct")] - public double? BrightnessPct { get; init; } - - ///<summary>Light effect.</summary> - [JsonPropertyName("effect")] - public string? Effect { get; init; } - - ///<summary> eg: [255, 100, 100, 50]</summary> - [JsonPropertyName("rgbw_color")] - public object? RgbwColor { get; init; } - - ///<summary> eg: [255, 100, 100, 50, 70]</summary> - [JsonPropertyName("rgbww_color")] - public object? RgbwwColor { get; init; } - - [JsonPropertyName("color_name")] - public object? ColorName { get; init; } - - ///<summary> eg: [300, 70]</summary> - [JsonPropertyName("hs_color")] - public object? HsColor { get; init; } - - ///<summary> eg: [0.52, 0.43]</summary> - [JsonPropertyName("xy_color")] - public object? XyColor { get; init; } - - [JsonPropertyName("color_temp")] - public object? ColorTemp { get; init; } - - [JsonPropertyName("brightness")] - public double? Brightness { get; init; } - - [JsonPropertyName("white")] - public object? White { get; init; } - - ///<summary> eg: relax</summary> - [JsonPropertyName("profile")] - public string? Profile { get; init; } - - [JsonPropertyName("flash")] - public object? Flash { get; init; } -} - -public partial record LightTurnOffParameters -{ - ///<summary>Duration it takes to get to next state.</summary> - [JsonPropertyName("transition")] - public double? Transition { get; init; } - - [JsonPropertyName("flash")] - public object? Flash { get; init; } -} - -public partial record LightTurnOnParameters -{ - ///<summary>Duration it takes to get to next state.</summary> - [JsonPropertyName("transition")] - public double? Transition { get; init; } - - ///<summary>The color in RGB format. A list of three integers between 0 and 255 representing the values of red, green, and blue. eg: [255, 100, 100]</summary> - [JsonPropertyName("rgb_color")] - public IReadOnlyCollection<int>? RgbColor { get; init; } - - ///<summary>Color temperature in Kelvin.</summary> - [JsonPropertyName("kelvin")] - public object? Kelvin { get; init; } - - ///<summary>Number indicating the percentage of full brightness, where 0 turns the light off, 1 is the minimum brightness, and 100 is the maximum brightness.</summary> - [JsonPropertyName("brightness_pct")] - public double? BrightnessPct { get; init; } - - ///<summary>Change brightness by a percentage.</summary> - [JsonPropertyName("brightness_step_pct")] - public double? BrightnessStepPct { get; init; } - - ///<summary>Light effect.</summary> - [JsonPropertyName("effect")] - public string? Effect { get; init; } - - ///<summary> eg: [255, 100, 100, 50]</summary> - [JsonPropertyName("rgbw_color")] - public object? RgbwColor { get; init; } - - ///<summary> eg: [255, 100, 100, 50, 70]</summary> - [JsonPropertyName("rgbww_color")] - public object? RgbwwColor { get; init; } - - [JsonPropertyName("color_name")] - public object? ColorName { get; init; } - - ///<summary> eg: [300, 70]</summary> - [JsonPropertyName("hs_color")] - public object? HsColor { get; init; } - - ///<summary> eg: [0.52, 0.43]</summary> - [JsonPropertyName("xy_color")] - public object? XyColor { get; init; } - - [JsonPropertyName("color_temp")] - public object? ColorTemp { get; init; } - - [JsonPropertyName("brightness")] - public double? Brightness { get; init; } - - [JsonPropertyName("brightness_step")] - public double? BrightnessStep { get; init; } - - [JsonPropertyName("white")] - public object? White { get; init; } - - ///<summary> eg: relax</summary> - [JsonPropertyName("profile")] - public string? Profile { get; init; } - - [JsonPropertyName("flash")] - public object? Flash { get; init; } -} - -public partial class LockServices -{ - private readonly IHaContext _haContext; - public LockServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Locks a lock.</summary> - ///<param name="target">The target for this service call</param> - public void Lock(ServiceTarget target, LockLockParameters data) - { - _haContext.CallService("lock", "lock", target, data); - } - - ///<summary>Locks a lock.</summary> - ///<param name="code">Code used to lock the lock. eg: 1234</param> - public void Lock(ServiceTarget target, string? code = null) - { - _haContext.CallService("lock", "lock", target, new LockLockParameters { Code = code }); - } - - ///<summary>Opens a lock.</summary> - ///<param name="target">The target for this service call</param> - public void Open(ServiceTarget target, LockOpenParameters data) - { - _haContext.CallService("lock", "open", target, data); - } - - ///<summary>Opens a lock.</summary> - ///<param name="code">Code used to open the lock. eg: 1234</param> - public void Open(ServiceTarget target, string? code = null) - { - _haContext.CallService("lock", "open", target, new LockOpenParameters { Code = code }); - } - - ///<summary>Unlocks a lock.</summary> - ///<param name="target">The target for this service call</param> - public void Unlock(ServiceTarget target, LockUnlockParameters data) - { - _haContext.CallService("lock", "unlock", target, data); - } - - ///<summary>Unlocks a lock.</summary> - ///<param name="code">Code used to unlock the lock. eg: 1234</param> - public void Unlock(ServiceTarget target, string? code = null) - { - _haContext.CallService("lock", "unlock", target, new LockUnlockParameters { Code = code }); - } -} - -public partial record LockLockParameters -{ - ///<summary>Code used to lock the lock. eg: 1234</summary> - [JsonPropertyName("code")] - public string? Code { get; init; } -} - -public partial record LockOpenParameters -{ - ///<summary>Code used to open the lock. eg: 1234</summary> - [JsonPropertyName("code")] - public string? Code { get; init; } -} - -public partial record LockUnlockParameters -{ - ///<summary>Code used to unlock the lock. eg: 1234</summary> - [JsonPropertyName("code")] - public string? Code { get; init; } -} - -public partial class LogbookServices -{ - private readonly IHaContext _haContext; - public LogbookServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Creates a custom entry in the logbook.</summary> - public void Log(LogbookLogParameters data) - { - _haContext.CallService("logbook", "log", null, data); - } - - ///<summary>Creates a custom entry in the logbook.</summary> - ///<param name="name">Custom name for an entity, can be referenced using the 'Entity ID' field. eg: Kitchen</param> - ///<param name="message">Message of the logbook entry. eg: is being used</param> - ///<param name="entityId">Entity to reference in the logbook entry.</param> - ///<param name="domain">Determines which icon is used in the logbook entry. The icon illustrates the integration domain related to this logbook entry. eg: light</param> - public void Log(string name, string message, string? entityId = null, string? domain = null) - { - _haContext.CallService("logbook", "log", null, new LogbookLogParameters { Name = name, Message = message, EntityId = entityId, Domain = domain }); - } -} - -public partial record LogbookLogParameters -{ - ///<summary>Custom name for an entity, can be referenced using the 'Entity ID' field. eg: Kitchen</summary> - [JsonPropertyName("name")] - public string? Name { get; init; } - - ///<summary>Message of the logbook entry. eg: is being used</summary> - [JsonPropertyName("message")] - public string? Message { get; init; } - - ///<summary>Entity to reference in the logbook entry.</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>Determines which icon is used in the logbook entry. The icon illustrates the integration domain related to this logbook entry. eg: light</summary> - [JsonPropertyName("domain")] - public string? Domain { get; init; } -} - -public partial class LoggerServices -{ - private readonly IHaContext _haContext; - public LoggerServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Sets the default log level for integrations.</summary> - public void SetDefaultLevel(LoggerSetDefaultLevelParameters data) - { - _haContext.CallService("logger", "set_default_level", null, data); - } - - ///<summary>Sets the default log level for integrations.</summary> - ///<param name="level">Default severity level for all integrations.</param> - public void SetDefaultLevel(object? level = null) - { - _haContext.CallService("logger", "set_default_level", null, new LoggerSetDefaultLevelParameters { Level = level }); - } - - ///<summary>Sets the log level for one or more integrations.</summary> - public void SetLevel(object? data = null) - { - _haContext.CallService("logger", "set_level", null, data); - } -} - -public partial record LoggerSetDefaultLevelParameters -{ - ///<summary>Default severity level for all integrations.</summary> - [JsonPropertyName("level")] - public object? Level { get; init; } -} - -public partial class LovelaceServices -{ - private readonly IHaContext _haContext; - public LovelaceServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Reloads dashboard resources from the YAML-configuration.</summary> - public void ReloadResources(object? data = null) - { - _haContext.CallService("lovelace", "reload_resources", null, data); - } -} - -public partial class MediaPlayerServices -{ - private readonly IHaContext _haContext; - public MediaPlayerServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Browses the available media.</summary> - ///<param name="target">The target for this service call</param> - public void BrowseMedia(ServiceTarget target, MediaPlayerBrowseMediaParameters data) - { - _haContext.CallService("media_player", "browse_media", target, data); - } - - ///<summary>Browses the available media.</summary> - ///<param name="mediaContentType">The type of the content to browse, such as image, music, tv show, video, episode, channel, or playlist. eg: music</param> - ///<param name="mediaContentId">The ID of the content to browse. Integration dependent. eg: A:ALBUMARTIST/Beatles</param> - public void BrowseMedia(ServiceTarget target, string? mediaContentType = null, string? mediaContentId = null) - { - _haContext.CallService("media_player", "browse_media", target, new MediaPlayerBrowseMediaParameters { MediaContentType = mediaContentType, MediaContentId = mediaContentId }); - } - - ///<summary>Browses the available media.</summary> - ///<param name="target">The target for this service call</param> - public Task<JsonElement?> BrowseMediaAsync(ServiceTarget target, MediaPlayerBrowseMediaParameters data) - { - return _haContext.CallServiceWithResponseAsync("media_player", "browse_media", target, data); - } - - ///<summary>Browses the available media.</summary> - ///<param name="target">The target for this service call</param> - ///<param name="mediaContentType">The type of the content to browse, such as image, music, tv show, video, episode, channel, or playlist. eg: music</param> - ///<param name="mediaContentId">The ID of the content to browse. Integration dependent. eg: A:ALBUMARTIST/Beatles</param> - public Task<JsonElement?> BrowseMediaAsync(ServiceTarget target, string? mediaContentType = null, string? mediaContentId = null) - { - return _haContext.CallServiceWithResponseAsync("media_player", "browse_media", target, new MediaPlayerBrowseMediaParameters { MediaContentType = mediaContentType, MediaContentId = mediaContentId }); - } - - ///<summary>Removes all items from the playlist.</summary> - ///<param name="target">The target for this service call</param> - public void ClearPlaylist(ServiceTarget target, object? data = null) - { - _haContext.CallService("media_player", "clear_playlist", target, data); - } - - ///<summary>Groups media players together for synchronous playback. Only works on supported multiroom audio systems.</summary> - ///<param name="target">The target for this service call</param> - public void Join(ServiceTarget target, MediaPlayerJoinParameters data) - { - _haContext.CallService("media_player", "join", target, data); - } - - ///<summary>Groups media players together for synchronous playback. Only works on supported multiroom audio systems.</summary> - ///<param name="groupMembers">The players which will be synced with the playback specified in 'Targets'. eg: - media_player.multiroom_player2 - media_player.multiroom_player3 </param> - public void Join(ServiceTarget target, IEnumerable<string> groupMembers) - { - _haContext.CallService("media_player", "join", target, new MediaPlayerJoinParameters { GroupMembers = groupMembers }); - } - - ///<summary>Selects the next track.</summary> - ///<param name="target">The target for this service call</param> - public void MediaNextTrack(ServiceTarget target, object? data = null) - { - _haContext.CallService("media_player", "media_next_track", target, data); - } - - ///<summary>Pauses.</summary> - ///<param name="target">The target for this service call</param> - public void MediaPause(ServiceTarget target, object? data = null) - { - _haContext.CallService("media_player", "media_pause", target, data); - } - - ///<summary>Starts playing.</summary> - ///<param name="target">The target for this service call</param> - public void MediaPlay(ServiceTarget target, object? data = null) - { - _haContext.CallService("media_player", "media_play", target, data); - } - - ///<summary>Toggles play/pause.</summary> - ///<param name="target">The target for this service call</param> - public void MediaPlayPause(ServiceTarget target, object? data = null) - { - _haContext.CallService("media_player", "media_play_pause", target, data); - } - - ///<summary>Selects the previous track.</summary> - ///<param name="target">The target for this service call</param> - public void MediaPreviousTrack(ServiceTarget target, object? data = null) - { - _haContext.CallService("media_player", "media_previous_track", target, data); - } - - ///<summary>Allows you to go to a different part of the media that is currently playing.</summary> - ///<param name="target">The target for this service call</param> - public void MediaSeek(ServiceTarget target, MediaPlayerMediaSeekParameters data) - { - _haContext.CallService("media_player", "media_seek", target, data); - } - - ///<summary>Allows you to go to a different part of the media that is currently playing.</summary> - ///<param name="seekPosition">Target position in the currently playing media. The format is platform dependent.</param> - public void MediaSeek(ServiceTarget target, double seekPosition) - { - _haContext.CallService("media_player", "media_seek", target, new MediaPlayerMediaSeekParameters { SeekPosition = seekPosition }); - } - - ///<summary>Stops playing.</summary> - ///<param name="target">The target for this service call</param> - public void MediaStop(ServiceTarget target, object? data = null) - { - _haContext.CallService("media_player", "media_stop", target, data); - } - - ///<summary>Starts playing specified media.</summary> - ///<param name="target">The target for this service call</param> - public void PlayMedia(ServiceTarget target, MediaPlayerPlayMediaParameters data) - { - _haContext.CallService("media_player", "play_media", target, data); - } - - ///<summary>Starts playing specified media.</summary> - ///<param name="mediaContentId">The ID of the content to play. Platform dependent. eg: https://home-assistant.io/images/cast/splash.png</param> - ///<param name="mediaContentType">The type of the content to play, such as image, music, tv show, video, episode, channel, or playlist. eg: music</param> - ///<param name="enqueue">If the content should be played now or be added to the queue.</param> - ///<param name="announce">If the media should be played as an announcement. eg: true</param> - public void PlayMedia(ServiceTarget target, string mediaContentId, string mediaContentType, object? enqueue = null, bool? announce = null) - { - _haContext.CallService("media_player", "play_media", target, new MediaPlayerPlayMediaParameters { MediaContentId = mediaContentId, MediaContentType = mediaContentType, Enqueue = enqueue, Announce = announce }); - } - - ///<summary>Sets the repeat mode.</summary> - ///<param name="target">The target for this service call</param> - public void RepeatSet(ServiceTarget target, MediaPlayerRepeatSetParameters data) - { - _haContext.CallService("media_player", "repeat_set", target, data); - } - - ///<summary>Sets the repeat mode.</summary> - ///<param name="repeat">Whether the media (one or all) should be played in a loop or not.</param> - public void RepeatSet(ServiceTarget target, object repeat) - { - _haContext.CallService("media_player", "repeat_set", target, new MediaPlayerRepeatSetParameters { Repeat = repeat }); - } - - ///<summary>Selects a specific sound mode.</summary> - ///<param name="target">The target for this service call</param> - public void SelectSoundMode(ServiceTarget target, MediaPlayerSelectSoundModeParameters data) - { - _haContext.CallService("media_player", "select_sound_mode", target, data); - } - - ///<summary>Selects a specific sound mode.</summary> - ///<param name="soundMode">Name of the sound mode to switch to. eg: Music</param> - public void SelectSoundMode(ServiceTarget target, string? soundMode = null) - { - _haContext.CallService("media_player", "select_sound_mode", target, new MediaPlayerSelectSoundModeParameters { SoundMode = soundMode }); - } - - ///<summary>Sends the media player the command to change input source.</summary> - ///<param name="target">The target for this service call</param> - public void SelectSource(ServiceTarget target, MediaPlayerSelectSourceParameters data) - { - _haContext.CallService("media_player", "select_source", target, data); - } - - ///<summary>Sends the media player the command to change input source.</summary> - ///<param name="source">Name of the source to switch to. Platform dependent. eg: video1</param> - public void SelectSource(ServiceTarget target, string source) - { - _haContext.CallService("media_player", "select_source", target, new MediaPlayerSelectSourceParameters { Source = source }); - } - - ///<summary>Enables or disables the shuffle mode.</summary> - ///<param name="target">The target for this service call</param> - public void ShuffleSet(ServiceTarget target, MediaPlayerShuffleSetParameters data) - { - _haContext.CallService("media_player", "shuffle_set", target, data); - } - - ///<summary>Enables or disables the shuffle mode.</summary> - ///<param name="shuffle">Whether the media should be played in randomized order or not.</param> - public void ShuffleSet(ServiceTarget target, bool shuffle) - { - _haContext.CallService("media_player", "shuffle_set", target, new MediaPlayerShuffleSetParameters { Shuffle = shuffle }); - } - - ///<summary>Toggles a media player on/off.</summary> - ///<param name="target">The target for this service call</param> - public void Toggle(ServiceTarget target, object? data = null) - { - _haContext.CallService("media_player", "toggle", target, data); - } - - ///<summary>Turns off the power of the media player.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOff(ServiceTarget target, object? data = null) - { - _haContext.CallService("media_player", "turn_off", target, data); - } - - ///<summary>Turns on the power of the media player.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOn(ServiceTarget target, object? data = null) - { - _haContext.CallService("media_player", "turn_on", target, data); - } - - ///<summary>Removes the player from a group. Only works on platforms which support player groups.</summary> - ///<param name="target">The target for this service call</param> - public void Unjoin(ServiceTarget target, object? data = null) - { - _haContext.CallService("media_player", "unjoin", target, data); - } - - ///<summary>Turns down the volume.</summary> - ///<param name="target">The target for this service call</param> - public void VolumeDown(ServiceTarget target, object? data = null) - { - _haContext.CallService("media_player", "volume_down", target, data); - } - - ///<summary>Mutes or unmutes the media player.</summary> - ///<param name="target">The target for this service call</param> - public void VolumeMute(ServiceTarget target, MediaPlayerVolumeMuteParameters data) - { - _haContext.CallService("media_player", "volume_mute", target, data); - } - - ///<summary>Mutes or unmutes the media player.</summary> - ///<param name="isVolumeMuted">Defines whether or not it is muted.</param> - public void VolumeMute(ServiceTarget target, bool isVolumeMuted) - { - _haContext.CallService("media_player", "volume_mute", target, new MediaPlayerVolumeMuteParameters { IsVolumeMuted = isVolumeMuted }); - } - - ///<summary>Sets the volume level.</summary> - ///<param name="target">The target for this service call</param> - public void VolumeSet(ServiceTarget target, MediaPlayerVolumeSetParameters data) - { - _haContext.CallService("media_player", "volume_set", target, data); - } - - ///<summary>Sets the volume level.</summary> - ///<param name="volumeLevel">The volume. 0 is inaudible, 1 is the maximum volume.</param> - public void VolumeSet(ServiceTarget target, double volumeLevel) - { - _haContext.CallService("media_player", "volume_set", target, new MediaPlayerVolumeSetParameters { VolumeLevel = volumeLevel }); - } - - ///<summary>Turns up the volume.</summary> - ///<param name="target">The target for this service call</param> - public void VolumeUp(ServiceTarget target, object? data = null) - { - _haContext.CallService("media_player", "volume_up", target, data); - } -} - -public partial record MediaPlayerBrowseMediaParameters -{ - ///<summary>The type of the content to browse, such as image, music, tv show, video, episode, channel, or playlist. eg: music</summary> - [JsonPropertyName("media_content_type")] - public string? MediaContentType { get; init; } - - ///<summary>The ID of the content to browse. Integration dependent. eg: A:ALBUMARTIST/Beatles</summary> - [JsonPropertyName("media_content_id")] - public string? MediaContentId { get; init; } -} - -public partial record MediaPlayerJoinParameters -{ - ///<summary>The players which will be synced with the playback specified in 'Targets'. eg: - media_player.multiroom_player2 - media_player.multiroom_player3 </summary> - [JsonPropertyName("group_members")] - public IEnumerable<string>? GroupMembers { get; init; } -} - -public partial record MediaPlayerMediaSeekParameters -{ - ///<summary>Target position in the currently playing media. The format is platform dependent.</summary> - [JsonPropertyName("seek_position")] - public double? SeekPosition { get; init; } -} - -public partial record MediaPlayerPlayMediaParameters -{ - ///<summary>The ID of the content to play. Platform dependent. eg: https://home-assistant.io/images/cast/splash.png</summary> - [JsonPropertyName("media_content_id")] - public string? MediaContentId { get; init; } - - ///<summary>The type of the content to play, such as image, music, tv show, video, episode, channel, or playlist. eg: music</summary> - [JsonPropertyName("media_content_type")] - public string? MediaContentType { get; init; } - - ///<summary>If the content should be played now or be added to the queue.</summary> - [JsonPropertyName("enqueue")] - public object? Enqueue { get; init; } - - ///<summary>If the media should be played as an announcement. eg: true</summary> - [JsonPropertyName("announce")] - public bool? Announce { get; init; } -} - -public partial record MediaPlayerRepeatSetParameters -{ - ///<summary>Whether the media (one or all) should be played in a loop or not.</summary> - [JsonPropertyName("repeat")] - public object? Repeat { get; init; } -} - -public partial record MediaPlayerSelectSoundModeParameters -{ - ///<summary>Name of the sound mode to switch to. eg: Music</summary> - [JsonPropertyName("sound_mode")] - public string? SoundMode { get; init; } -} - -public partial record MediaPlayerSelectSourceParameters -{ - ///<summary>Name of the source to switch to. Platform dependent. eg: video1</summary> - [JsonPropertyName("source")] - public string? Source { get; init; } -} - -public partial record MediaPlayerShuffleSetParameters -{ - ///<summary>Whether the media should be played in randomized order or not.</summary> - [JsonPropertyName("shuffle")] - public bool? Shuffle { get; init; } -} - -public partial record MediaPlayerVolumeMuteParameters -{ - ///<summary>Defines whether or not it is muted.</summary> - [JsonPropertyName("is_volume_muted")] - public bool? IsVolumeMuted { get; init; } -} - -public partial record MediaPlayerVolumeSetParameters -{ - ///<summary>The volume. 0 is inaudible, 1 is the maximum volume.</summary> - [JsonPropertyName("volume_level")] - public double? VolumeLevel { get; init; } -} - -public partial class MqttServices -{ - private readonly IHaContext _haContext; - public MqttServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Writes all messages on a specific topic into the `mqtt_dump.txt` file in your configuration folder.</summary> - public void Dump(MqttDumpParameters data) - { - _haContext.CallService("mqtt", "dump", null, data); - } - - ///<summary>Writes all messages on a specific topic into the `mqtt_dump.txt` file in your configuration folder.</summary> - ///<param name="topic">Topic to listen to. eg: OpenZWave/#</param> - ///<param name="duration">How long we should listen for messages in seconds.</param> - public void Dump(string? topic = null, double? duration = null) - { - _haContext.CallService("mqtt", "dump", null, new MqttDumpParameters { Topic = topic, Duration = duration }); - } - - ///<summary>Publishes a message to an MQTT topic.</summary> - public void Publish(MqttPublishParameters data) - { - _haContext.CallService("mqtt", "publish", null, data); - } - - ///<summary>Publishes a message to an MQTT topic.</summary> - ///<param name="topic">Topic to publish to. eg: /homeassistant/hello</param> - ///<param name="payload">The payload to publish. Publishes an empty message if not provided. eg: The temperature is {{ states('sensor.temperature') }}</param> - ///<param name="evaluatePayload">If 'Payload' is a Python bytes literal, evaluate the bytes literal and publish the raw data.</param> - ///<param name="qos">Quality of Service to use. 0: At most once. 1: At least once. 2: Exactly once.</param> - ///<param name="retain">If the message should have the retain flag set. If set, the broker stores the most recent message on a topic.</param> - public void Publish(string topic, object? payload = null, bool? evaluatePayload = null, object? qos = null, bool? retain = null) - { - _haContext.CallService("mqtt", "publish", null, new MqttPublishParameters { Topic = topic, Payload = payload, EvaluatePayload = evaluatePayload, Qos = qos, Retain = retain }); - } - - ///<summary>Reloads MQTT entities from the YAML-configuration.</summary> - public void Reload(object? data = null) - { - _haContext.CallService("mqtt", "reload", null, data); - } -} - -public partial record MqttDumpParameters -{ - ///<summary>Topic to listen to. eg: OpenZWave/#</summary> - [JsonPropertyName("topic")] - public string? Topic { get; init; } - - ///<summary>How long we should listen for messages in seconds.</summary> - [JsonPropertyName("duration")] - public double? Duration { get; init; } -} - -public partial record MqttPublishParameters -{ - ///<summary>Topic to publish to. eg: /homeassistant/hello</summary> - [JsonPropertyName("topic")] - public string? Topic { get; init; } - - ///<summary>The payload to publish. Publishes an empty message if not provided. eg: The temperature is {{ states('sensor.temperature') }}</summary> - [JsonPropertyName("payload")] - public object? Payload { get; init; } - - ///<summary>If 'Payload' is a Python bytes literal, evaluate the bytes literal and publish the raw data.</summary> - [JsonPropertyName("evaluate_payload")] - public bool? EvaluatePayload { get; init; } - - ///<summary>Quality of Service to use. 0: At most once. 1: At least once. 2: Exactly once.</summary> - [JsonPropertyName("qos")] - public object? Qos { get; init; } - - ///<summary>If the message should have the retain flag set. If set, the broker stores the most recent message on a topic.</summary> - [JsonPropertyName("retain")] - public bool? Retain { get; init; } -} - -public partial class NetdaemonServices -{ - private readonly IHaContext _haContext; - public NetdaemonServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Create an entity</summary> - public void EntityCreate(NetdaemonEntityCreateParameters data) - { - _haContext.CallService("netdaemon", "entity_create", null, data); - } - - ///<summary>Create an entity</summary> - ///<param name="entityId">The entity ID of the entity eg: sensor.awesome</param> - ///<param name="state">The state of the entity eg: Lorem ipsum</param> - ///<param name="icon">The icon for the entity eg: mdi:rocket-launch-outline</param> - ///<param name="unit">The unit of measurement for the entity</param> - ///<param name="options">List of options for a select entity</param> - ///<param name="attributes">The attributes of the entity</param> - public void EntityCreate(object? entityId = null, object? state = null, object? icon = null, object? unit = null, object? options = null, object? attributes = null) - { - _haContext.CallService("netdaemon", "entity_create", null, new NetdaemonEntityCreateParameters { EntityId = entityId, State = state, Icon = icon, Unit = unit, Options = options, Attributes = attributes }); - } - - ///<summary>Remove an entity</summary> - public void EntityRemove(NetdaemonEntityRemoveParameters data) - { - _haContext.CallService("netdaemon", "entity_remove", null, data); - } - - ///<summary>Remove an entity</summary> - ///<param name="entityId">The entity ID of the entity eg: sensor.awesome</param> - public void EntityRemove(object? entityId = null) - { - _haContext.CallService("netdaemon", "entity_remove", null, new NetdaemonEntityRemoveParameters { EntityId = entityId }); - } - - ///<summary>Update an entity</summary> - public void EntityUpdate(NetdaemonEntityUpdateParameters data) - { - _haContext.CallService("netdaemon", "entity_update", null, data); - } - - ///<summary>Update an entity</summary> - ///<param name="entityId">The entity ID of the entity eg: sensor.awesome</param> - ///<param name="state">The state of the entity eg: Lorem ipsum</param> - ///<param name="icon">The icon for the entity eg: mdi:rocket-launch-outline</param> - ///<param name="unit">The unit of measurement for the entity</param> - ///<param name="options">List of options for a select entity</param> - ///<param name="attributes">The attributes of the entity</param> - public void EntityUpdate(object? entityId = null, object? state = null, object? icon = null, object? unit = null, object? options = null, object? attributes = null) - { - _haContext.CallService("netdaemon", "entity_update", null, new NetdaemonEntityUpdateParameters { EntityId = entityId, State = state, Icon = icon, Unit = unit, Options = options, Attributes = attributes }); - } - - ///<summary>Register a new service for netdaemon, used by the daemon and not to be used by users</summary> - public void RegisterService(NetdaemonRegisterServiceParameters data) - { - _haContext.CallService("netdaemon", "register_service", null, data); - } - - ///<summary>Register a new service for netdaemon, used by the daemon and not to be used by users</summary> - ///<param name="service">The name of the service to register</param> - ///<param name="class">The class that implements the service call</param> - ///<param name="method">The method to call</param> - public void RegisterService(object? service = null, object? @class = null, object? @method = null) - { - _haContext.CallService("netdaemon", "register_service", null, new NetdaemonRegisterServiceParameters { Service = service, Class = @class, Method = @method }); - } - - public void ReloadApps(object? data = null) - { - _haContext.CallService("netdaemon", "reload_apps", null, data); - } - - public void SpotifyPauseUnpause(object? data = null) - { - _haContext.CallService("netdaemon", "spotify_pause_unpause", null, data); - } - - public void SpotifyPlayAlbum(object? data = null) - { - _haContext.CallService("netdaemon", "spotify_play_album", null, data); - } - - public void SpotifyPlayArtist(object? data = null) - { - _haContext.CallService("netdaemon", "spotify_play_artist", null, data); - } - - public void SpotifyPlayPlaylist(object? data = null) - { - _haContext.CallService("netdaemon", "spotify_play_playlist", null, data); - } - - public void SpotifyPlaySong(object? data = null) - { - _haContext.CallService("netdaemon", "spotify_play_song", null, data); - } -} - -public partial record NetdaemonEntityCreateParameters -{ - ///<summary>The entity ID of the entity eg: sensor.awesome</summary> - [JsonPropertyName("entity_id")] - public object? EntityId { get; init; } - - ///<summary>The state of the entity eg: Lorem ipsum</summary> - [JsonPropertyName("state")] - public object? State { get; init; } - - ///<summary>The icon for the entity eg: mdi:rocket-launch-outline</summary> - [JsonPropertyName("icon")] - public object? Icon { get; init; } - - ///<summary>The unit of measurement for the entity</summary> - [JsonPropertyName("unit")] - public object? Unit { get; init; } - - ///<summary>List of options for a select entity</summary> - [JsonPropertyName("options")] - public object? Options { get; init; } - - ///<summary>The attributes of the entity</summary> - [JsonPropertyName("attributes")] - public object? Attributes { get; init; } -} - -public partial record NetdaemonEntityRemoveParameters -{ - ///<summary>The entity ID of the entity eg: sensor.awesome</summary> - [JsonPropertyName("entity_id")] - public object? EntityId { get; init; } -} - -public partial record NetdaemonEntityUpdateParameters -{ - ///<summary>The entity ID of the entity eg: sensor.awesome</summary> - [JsonPropertyName("entity_id")] - public object? EntityId { get; init; } - - ///<summary>The state of the entity eg: Lorem ipsum</summary> - [JsonPropertyName("state")] - public object? State { get; init; } - - ///<summary>The icon for the entity eg: mdi:rocket-launch-outline</summary> - [JsonPropertyName("icon")] - public object? Icon { get; init; } - - ///<summary>The unit of measurement for the entity</summary> - [JsonPropertyName("unit")] - public object? Unit { get; init; } - - ///<summary>List of options for a select entity</summary> - [JsonPropertyName("options")] - public object? Options { get; init; } - - ///<summary>The attributes of the entity</summary> - [JsonPropertyName("attributes")] - public object? Attributes { get; init; } -} - -public partial record NetdaemonRegisterServiceParameters -{ - ///<summary>The name of the service to register</summary> - [JsonPropertyName("service")] - public object? Service { get; init; } - - ///<summary>The class that implements the service call</summary> - [JsonPropertyName("class")] - public object? Class { get; init; } - - ///<summary>The method to call</summary> - [JsonPropertyName("method")] - public object? Method { get; init; } -} - -public partial class NotifyServices -{ - private readonly IHaContext _haContext; - public NotifyServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Sends a notification message using the mobile_app_pixel_8 integration.</summary> - public void MobileAppPixel8(NotifyMobileAppPixel8Parameters data) - { - _haContext.CallService("notify", "mobile_app_pixel_8", null, data); - } - - ///<summary>Sends a notification message using the mobile_app_pixel_8 integration.</summary> - ///<param name="message"> eg: The garage door has been open for 10 minutes.</param> - ///<param name="title"> eg: Your Garage Door Friend</param> - ///<param name="target"> eg: platform specific</param> - ///<param name="data"> eg: platform specific</param> - public void MobileAppPixel8(string message, string? title = null, object? target = null, object? data = null) - { - _haContext.CallService("notify", "mobile_app_pixel_8", null, new NotifyMobileAppPixel8Parameters { Message = message, Title = title, Target = target, Data = data }); - } - - ///<summary>Sends a notification message using the mobile_app_z_flip_6 integration.</summary> - public void MobileAppZFlip6(NotifyMobileAppZFlip6Parameters data) - { - _haContext.CallService("notify", "mobile_app_z_flip_6", null, data); - } - - ///<summary>Sends a notification message using the mobile_app_z_flip_6 integration.</summary> - ///<param name="message"> eg: The garage door has been open for 10 minutes.</param> - ///<param name="title"> eg: Your Garage Door Friend</param> - ///<param name="target"> eg: platform specific</param> - ///<param name="data"> eg: platform specific</param> - public void MobileAppZFlip6(string message, string? title = null, object? target = null, object? data = null) - { - _haContext.CallService("notify", "mobile_app_z_flip_6", null, new NotifyMobileAppZFlip6Parameters { Message = message, Title = title, Target = target, Data = data }); - } - - ///<summary>Sends a notification message using the notify service.</summary> - public void Notify(NotifyNotifyParameters data) - { - _haContext.CallService("notify", "notify", null, data); - } - - ///<summary>Sends a notification message using the notify service.</summary> - ///<param name="message"> eg: The garage door has been open for 10 minutes.</param> - ///<param name="title"> eg: Your Garage Door Friend</param> - ///<param name="target"> eg: platform specific</param> - ///<param name="data"> eg: platform specific</param> - public void Notify(string message, string? title = null, object? target = null, object? data = null) - { - _haContext.CallService("notify", "notify", null, new NotifyNotifyParameters { Message = message, Title = title, Target = target, Data = data }); - } - - ///<summary>Sends a notification that is visible in the notifications panel.</summary> - public void PersistentNotification(NotifyPersistentNotificationParameters data) - { - _haContext.CallService("notify", "persistent_notification", null, data); - } - - ///<summary>Sends a notification that is visible in the notifications panel.</summary> - ///<param name="message">Message body of the notification. eg: The garage door has been open for 10 minutes.</param> - ///<param name="title">Title of the notification. eg: Your Garage Door Friend</param> - ///<param name="data">Some integrations provide extended functionality via this field. For more information, refer to the integration documentation. eg: platform specific</param> - public void PersistentNotification(string message, string? title = null, object? data = null) - { - _haContext.CallService("notify", "persistent_notification", null, new NotifyPersistentNotificationParameters { Message = message, Title = title, Data = data }); - } - - ///<summary>Sends a notification message.</summary> - ///<param name="target">The target for this service call</param> - public void SendMessage(ServiceTarget target, NotifySendMessageParameters data) - { - _haContext.CallService("notify", "send_message", target, data); - } - - ///<summary>Sends a notification message.</summary> - ///<param name="message">Your notification message.</param> - ///<param name="title">Title for your notification message.</param> - public void SendMessage(ServiceTarget target, string message, string? title = null) - { - _haContext.CallService("notify", "send_message", target, new NotifySendMessageParameters { Message = message, Title = title }); - } -} - -public partial record NotifyMobileAppPixel8Parameters -{ - ///<summary> eg: The garage door has been open for 10 minutes.</summary> - [JsonPropertyName("message")] - public string? Message { get; init; } - - ///<summary> eg: Your Garage Door Friend</summary> - [JsonPropertyName("title")] - public string? Title { get; init; } - - ///<summary> eg: platform specific</summary> - [JsonPropertyName("target")] - public object? Target { get; init; } - - ///<summary> eg: platform specific</summary> - [JsonPropertyName("data")] - public object? Data { get; init; } -} - -public partial record NotifyMobileAppZFlip6Parameters -{ - ///<summary> eg: The garage door has been open for 10 minutes.</summary> - [JsonPropertyName("message")] - public string? Message { get; init; } - - ///<summary> eg: Your Garage Door Friend</summary> - [JsonPropertyName("title")] - public string? Title { get; init; } - - ///<summary> eg: platform specific</summary> - [JsonPropertyName("target")] - public object? Target { get; init; } - - ///<summary> eg: platform specific</summary> - [JsonPropertyName("data")] - public object? Data { get; init; } -} - -public partial record NotifyNotifyParameters -{ - ///<summary> eg: The garage door has been open for 10 minutes.</summary> - [JsonPropertyName("message")] - public string? Message { get; init; } - - ///<summary> eg: Your Garage Door Friend</summary> - [JsonPropertyName("title")] - public string? Title { get; init; } - - ///<summary> eg: platform specific</summary> - [JsonPropertyName("target")] - public object? Target { get; init; } - - ///<summary> eg: platform specific</summary> - [JsonPropertyName("data")] - public object? Data { get; init; } -} - -public partial record NotifyPersistentNotificationParameters -{ - ///<summary>Message body of the notification. eg: The garage door has been open for 10 minutes.</summary> - [JsonPropertyName("message")] - public string? Message { get; init; } - - ///<summary>Title of the notification. eg: Your Garage Door Friend</summary> - [JsonPropertyName("title")] - public string? Title { get; init; } - - ///<summary>Some integrations provide extended functionality via this field. For more information, refer to the integration documentation. eg: platform specific</summary> - [JsonPropertyName("data")] - public object? Data { get; init; } -} - -public partial record NotifySendMessageParameters -{ - ///<summary>Your notification message.</summary> - [JsonPropertyName("message")] - public string? Message { get; init; } - - ///<summary>Title for your notification message.</summary> - [JsonPropertyName("title")] - public string? Title { get; init; } -} - -public partial class NumberServices -{ - private readonly IHaContext _haContext; - public NumberServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Sets the value of a number.</summary> - ///<param name="target">The target for this service call</param> - public void SetValue(ServiceTarget target, NumberSetValueParameters data) - { - _haContext.CallService("number", "set_value", target, data); - } - - ///<summary>Sets the value of a number.</summary> - ///<param name="value">The target value to set. eg: 42</param> - public void SetValue(ServiceTarget target, string value) - { - _haContext.CallService("number", "set_value", target, new NumberSetValueParameters { Value = value }); - } -} - -public partial record NumberSetValueParameters -{ - ///<summary>The target value to set. eg: 42</summary> - [JsonPropertyName("value")] - public string? Value { get; init; } -} - -public partial class PersistentNotificationServices -{ - private readonly IHaContext _haContext; - public PersistentNotificationServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Shows a notification on the notifications panel.</summary> - public void Create(PersistentNotificationCreateParameters data) - { - _haContext.CallService("persistent_notification", "create", null, data); - } - - ///<summary>Shows a notification on the notifications panel.</summary> - ///<param name="message">Message body of the notification. eg: Please check your configuration.yaml.</param> - ///<param name="title">Optional title of the notification. eg: Test notification</param> - ///<param name="notificationId">ID of the notification. This new notification will overwrite an existing notification with the same ID. eg: 1234</param> - public void Create(string message, string? title = null, string? notificationId = null) - { - _haContext.CallService("persistent_notification", "create", null, new PersistentNotificationCreateParameters { Message = message, Title = title, NotificationId = notificationId }); - } - - ///<summary>Deletes a notification from the notifications panel.</summary> - public void Dismiss(PersistentNotificationDismissParameters data) - { - _haContext.CallService("persistent_notification", "dismiss", null, data); - } - - ///<summary>Deletes a notification from the notifications panel.</summary> - ///<param name="notificationId">ID of the notification to be deleted. eg: 1234</param> - public void Dismiss(string notificationId) - { - _haContext.CallService("persistent_notification", "dismiss", null, new PersistentNotificationDismissParameters { NotificationId = notificationId }); - } - - ///<summary>Deletes all notifications from the notifications panel.</summary> - public void DismissAll(object? data = null) - { - _haContext.CallService("persistent_notification", "dismiss_all", null, data); - } -} - -public partial record PersistentNotificationCreateParameters -{ - ///<summary>Message body of the notification. eg: Please check your configuration.yaml.</summary> - [JsonPropertyName("message")] - public string? Message { get; init; } - - ///<summary>Optional title of the notification. eg: Test notification</summary> - [JsonPropertyName("title")] - public string? Title { get; init; } - - ///<summary>ID of the notification. This new notification will overwrite an existing notification with the same ID. eg: 1234</summary> - [JsonPropertyName("notification_id")] - public string? NotificationId { get; init; } -} - -public partial record PersistentNotificationDismissParameters -{ - ///<summary>ID of the notification to be deleted. eg: 1234</summary> - [JsonPropertyName("notification_id")] - public string? NotificationId { get; init; } -} - -public partial class PersonServices -{ - private readonly IHaContext _haContext; - public PersonServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Reloads persons from the YAML-configuration.</summary> - public void Reload(object? data = null) - { - _haContext.CallService("person", "reload", null, data); - } -} - -public partial class RecorderServices -{ - private readonly IHaContext _haContext; - public RecorderServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Stops the recording of events and state changes.</summary> - public void Disable(object? data = null) - { - _haContext.CallService("recorder", "disable", null, data); - } - - ///<summary>Starts the recording of events and state changes.</summary> - public void Enable(object? data = null) - { - _haContext.CallService("recorder", "enable", null, data); - } - - ///<summary>Starts purge task - to clean up old data from your database.</summary> - public void Purge(RecorderPurgeParameters data) - { - _haContext.CallService("recorder", "purge", null, data); - } - - ///<summary>Starts purge task - to clean up old data from your database.</summary> - ///<param name="keepDays">Number of days to keep the data in the database. Starting today, counting backward. A value of `7` means that everything older than a week will be purged.</param> - ///<param name="repack">Attempt to save disk space by rewriting the entire database file.</param> - ///<param name="applyFilter">Apply `entity_id` and `event_type` filters in addition to time-based purge.</param> - public void Purge(double? keepDays = null, bool? repack = null, bool? applyFilter = null) - { - _haContext.CallService("recorder", "purge", null, new RecorderPurgeParameters { KeepDays = keepDays, Repack = repack, ApplyFilter = applyFilter }); - } - - ///<summary>Starts a purge task to remove the data related to specific entities from your database.</summary> - public void PurgeEntities(RecorderPurgeEntitiesParameters data) - { - _haContext.CallService("recorder", "purge_entities", null, data); - } - - ///<summary>Starts a purge task to remove the data related to specific entities from your database.</summary> - ///<param name="entityId">List of entities for which the data is to be removed from the recorder database.</param> - ///<param name="domains">List of domains for which the data needs to be removed from the recorder database. eg: sun</param> - ///<param name="entityGlobs">List of glob patterns used to select the entities for which the data is to be removed from the recorder database. eg: domain*.object_id*</param> - ///<param name="keepDays">Number of days to keep the data for rows matching the filter. Starting today, counting backward. A value of `7` means that everything older than a week will be purged. The default of 0 days will remove all matching rows immediately.</param> - public void PurgeEntities(IEnumerable<string>? entityId = null, object? domains = null, object? entityGlobs = null, double? keepDays = null) - { - _haContext.CallService("recorder", "purge_entities", null, new RecorderPurgeEntitiesParameters { EntityId = entityId, Domains = domains, EntityGlobs = entityGlobs, KeepDays = keepDays }); - } -} - -public partial record RecorderPurgeParameters -{ - ///<summary>Number of days to keep the data in the database. Starting today, counting backward. A value of `7` means that everything older than a week will be purged.</summary> - [JsonPropertyName("keep_days")] - public double? KeepDays { get; init; } - - ///<summary>Attempt to save disk space by rewriting the entire database file.</summary> - [JsonPropertyName("repack")] - public bool? Repack { get; init; } - - ///<summary>Apply `entity_id` and `event_type` filters in addition to time-based purge.</summary> - [JsonPropertyName("apply_filter")] - public bool? ApplyFilter { get; init; } -} - -public partial record RecorderPurgeEntitiesParameters -{ - ///<summary>List of entities for which the data is to be removed from the recorder database.</summary> - [JsonPropertyName("entity_id")] - public IEnumerable<string>? EntityId { get; init; } - - ///<summary>List of domains for which the data needs to be removed from the recorder database. eg: sun</summary> - [JsonPropertyName("domains")] - public object? Domains { get; init; } - - ///<summary>List of glob patterns used to select the entities for which the data is to be removed from the recorder database. eg: domain*.object_id*</summary> - [JsonPropertyName("entity_globs")] - public object? EntityGlobs { get; init; } - - ///<summary>Number of days to keep the data for rows matching the filter. Starting today, counting backward. A value of `7` means that everything older than a week will be purged. The default of 0 days will remove all matching rows immediately.</summary> - [JsonPropertyName("keep_days")] - public double? KeepDays { get; init; } -} - -public partial class RemoteServices -{ - private readonly IHaContext _haContext; - public RemoteServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Deletes a command or a list of commands from the database.</summary> - ///<param name="target">The target for this service call</param> - public void DeleteCommand(ServiceTarget target, RemoteDeleteCommandParameters data) - { - _haContext.CallService("remote", "delete_command", target, data); - } - - ///<summary>Deletes a command or a list of commands from the database.</summary> - ///<param name="device">Device from which commands will be deleted. eg: television</param> - ///<param name="command">The single command or the list of commands to be deleted. eg: Mute</param> - public void DeleteCommand(ServiceTarget target, object command, string? device = null) - { - _haContext.CallService("remote", "delete_command", target, new RemoteDeleteCommandParameters { Device = device, Command = command }); - } - - ///<summary>Learns a command or a list of commands from a device.</summary> - ///<param name="target">The target for this service call</param> - public void LearnCommand(ServiceTarget target, RemoteLearnCommandParameters data) - { - _haContext.CallService("remote", "learn_command", target, data); - } - - ///<summary>Learns a command or a list of commands from a device.</summary> - ///<param name="device">Device ID to learn command from. eg: television</param> - ///<param name="command">A single command or a list of commands to learn. eg: Turn on</param> - ///<param name="commandType">The type of command to be learned.</param> - ///<param name="alternative">If code must be stored as an alternative. This is useful for discrete codes. Discrete codes are used for toggles that only perform one function. For example, a code to only turn a device on. If it is on already, sending the code won't change the state.</param> - ///<param name="timeout">Timeout for the command to be learned.</param> - public void LearnCommand(ServiceTarget target, string? device = null, object? command = null, object? commandType = null, bool? alternative = null, long? timeout = null) - { - _haContext.CallService("remote", "learn_command", target, new RemoteLearnCommandParameters { Device = device, Command = command, CommandType = commandType, Alternative = alternative, Timeout = timeout }); - } - - ///<summary>Sends a command or a list of commands to a device.</summary> - ///<param name="target">The target for this service call</param> - public void SendCommand(ServiceTarget target, RemoteSendCommandParameters data) - { - _haContext.CallService("remote", "send_command", target, data); - } - - ///<summary>Sends a command or a list of commands to a device.</summary> - ///<param name="device">Device ID to send command to. eg: 32756745</param> - ///<param name="command">A single command or a list of commands to send. eg: Play</param> - ///<param name="numRepeats">The number of times you want to repeat the commands.</param> - ///<param name="delaySecs">The time you want to wait in between repeated commands.</param> - ///<param name="holdSecs">The time you want to have it held before the release is send.</param> - public void SendCommand(ServiceTarget target, object command, string? device = null, double? numRepeats = null, double? delaySecs = null, double? holdSecs = null) - { - _haContext.CallService("remote", "send_command", target, new RemoteSendCommandParameters { Device = device, Command = command, NumRepeats = numRepeats, DelaySecs = delaySecs, HoldSecs = holdSecs }); - } - - ///<summary>Sends the toggle command.</summary> - ///<param name="target">The target for this service call</param> - public void Toggle(ServiceTarget target, object? data = null) - { - _haContext.CallService("remote", "toggle", target, data); - } - - ///<summary>Sends the turn off command.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOff(ServiceTarget target, object? data = null) - { - _haContext.CallService("remote", "turn_off", target, data); - } - - ///<summary>Sends the turn on command.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOn(ServiceTarget target, RemoteTurnOnParameters data) - { - _haContext.CallService("remote", "turn_on", target, data); - } - - ///<summary>Sends the turn on command.</summary> - ///<param name="activity">Activity ID or activity name to be started. eg: BedroomTV</param> - public void TurnOn(ServiceTarget target, string? activity = null) - { - _haContext.CallService("remote", "turn_on", target, new RemoteTurnOnParameters { Activity = activity }); - } -} - -public partial record RemoteDeleteCommandParameters -{ - ///<summary>Device from which commands will be deleted. eg: television</summary> - [JsonPropertyName("device")] - public string? Device { get; init; } - - ///<summary>The single command or the list of commands to be deleted. eg: Mute</summary> - [JsonPropertyName("command")] - public object? Command { get; init; } -} - -public partial record RemoteLearnCommandParameters -{ - ///<summary>Device ID to learn command from. eg: television</summary> - [JsonPropertyName("device")] - public string? Device { get; init; } - - ///<summary>A single command or a list of commands to learn. eg: Turn on</summary> - [JsonPropertyName("command")] - public object? Command { get; init; } - - ///<summary>The type of command to be learned.</summary> - [JsonPropertyName("command_type")] - public object? CommandType { get; init; } - - ///<summary>If code must be stored as an alternative. This is useful for discrete codes. Discrete codes are used for toggles that only perform one function. For example, a code to only turn a device on. If it is on already, sending the code won't change the state.</summary> - [JsonPropertyName("alternative")] - public bool? Alternative { get; init; } - - ///<summary>Timeout for the command to be learned.</summary> - [JsonPropertyName("timeout")] - public long? Timeout { get; init; } -} - -public partial record RemoteSendCommandParameters -{ - ///<summary>Device ID to send command to. eg: 32756745</summary> - [JsonPropertyName("device")] - public string? Device { get; init; } - - ///<summary>A single command or a list of commands to send. eg: Play</summary> - [JsonPropertyName("command")] - public object? Command { get; init; } - - ///<summary>The number of times you want to repeat the commands.</summary> - [JsonPropertyName("num_repeats")] - public double? NumRepeats { get; init; } - - ///<summary>The time you want to wait in between repeated commands.</summary> - [JsonPropertyName("delay_secs")] - public double? DelaySecs { get; init; } - - ///<summary>The time you want to have it held before the release is send.</summary> - [JsonPropertyName("hold_secs")] - public double? HoldSecs { get; init; } -} - -public partial record RemoteTurnOnParameters -{ - ///<summary>Activity ID or activity name to be started. eg: BedroomTV</summary> - [JsonPropertyName("activity")] - public string? Activity { get; init; } -} - -public partial class RestServices -{ - private readonly IHaContext _haContext; - public RestServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Reloads REST entities from the YAML-configuration.</summary> - public void Reload(object? data = null) - { - _haContext.CallService("rest", "reload", null, data); - } -} - -public partial class SceneServices -{ - private readonly IHaContext _haContext; - public SceneServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Activates a scene with configuration.</summary> - public void Apply(SceneApplyParameters data) - { - _haContext.CallService("scene", "apply", null, data); - } - - ///<summary>Activates a scene with configuration.</summary> - ///<param name="entities">List of entities and their target state. eg: light.kitchen: "on" light.ceiling: state: "on" brightness: 80 </param> - ///<param name="transition">Time it takes the devices to transition into the states defined in the scene.</param> - public void Apply(object entities, double? transition = null) - { - _haContext.CallService("scene", "apply", null, new SceneApplyParameters { Entities = entities, Transition = transition }); - } - - ///<summary>Creates a new scene.</summary> - public void Create(SceneCreateParameters data) - { - _haContext.CallService("scene", "create", null, data); - } - - ///<summary>Creates a new scene.</summary> - ///<param name="sceneId">The entity ID of the new scene. eg: all_lights</param> - ///<param name="entities">List of entities and their target state. If your entities are already in the target state right now, use 'Entities snapshot' instead. eg: light.tv_back_light: "on" light.ceiling: state: "on" brightness: 200 </param> - ///<param name="snapshotEntities">List of entities to be included in the snapshot. By taking a snapshot, you record the current state of those entities. If you do not want to use the current state of all your entities for this scene, you can combine 'Entities snapshot' with 'Entity states'. eg: - light.ceiling - light.kitchen </param> - public void Create(string sceneId, object? entities = null, IEnumerable<string>? snapshotEntities = null) - { - _haContext.CallService("scene", "create", null, new SceneCreateParameters { SceneId = sceneId, Entities = entities, SnapshotEntities = snapshotEntities }); - } - - ///<summary>Deletes a dynamically created scene.</summary> - ///<param name="target">The target for this service call</param> - public void Delete(ServiceTarget target, object? data = null) - { - _haContext.CallService("scene", "delete", target, data); - } - - ///<summary>Reloads the scenes from the YAML-configuration.</summary> - public void Reload(object? data = null) - { - _haContext.CallService("scene", "reload", null, data); - } - - ///<summary>Activates a scene.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOn(ServiceTarget target, SceneTurnOnParameters data) - { - _haContext.CallService("scene", "turn_on", target, data); - } - - ///<summary>Activates a scene.</summary> - ///<param name="transition">Time it takes the devices to transition into the states defined in the scene.</param> - public void TurnOn(ServiceTarget target, double? transition = null) - { - _haContext.CallService("scene", "turn_on", target, new SceneTurnOnParameters { Transition = transition }); - } -} - -public partial record SceneApplyParameters -{ - ///<summary>List of entities and their target state. eg: light.kitchen: "on" light.ceiling: state: "on" brightness: 80 </summary> - [JsonPropertyName("entities")] - public object? Entities { get; init; } - - ///<summary>Time it takes the devices to transition into the states defined in the scene.</summary> - [JsonPropertyName("transition")] - public double? Transition { get; init; } -} - -public partial record SceneCreateParameters -{ - ///<summary>The entity ID of the new scene. eg: all_lights</summary> - [JsonPropertyName("scene_id")] - public string? SceneId { get; init; } - - ///<summary>List of entities and their target state. If your entities are already in the target state right now, use 'Entities snapshot' instead. eg: light.tv_back_light: "on" light.ceiling: state: "on" brightness: 200 </summary> - [JsonPropertyName("entities")] - public object? Entities { get; init; } - - ///<summary>List of entities to be included in the snapshot. By taking a snapshot, you record the current state of those entities. If you do not want to use the current state of all your entities for this scene, you can combine 'Entities snapshot' with 'Entity states'. eg: - light.ceiling - light.kitchen </summary> - [JsonPropertyName("snapshot_entities")] - public IEnumerable<string>? SnapshotEntities { get; init; } -} - -public partial record SceneTurnOnParameters -{ - ///<summary>Time it takes the devices to transition into the states defined in the scene.</summary> - [JsonPropertyName("transition")] - public double? Transition { get; init; } -} - -public partial class ScheduleServices -{ - private readonly IHaContext _haContext; - public ScheduleServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Retrieves the configured time ranges of one or multiple schedules.</summary> - ///<param name="target">The target for this service call</param> - public void GetSchedule(ServiceTarget target, object? data = null) - { - _haContext.CallService("schedule", "get_schedule", target, data); - } - - ///<summary>Retrieves the configured time ranges of one or multiple schedules.</summary> - ///<param name="target">The target for this service call</param> - public Task<JsonElement?> GetScheduleAsync(ServiceTarget target, object? data = null) - { - return _haContext.CallServiceWithResponseAsync("schedule", "get_schedule", target, data); - } - - ///<summary>Reloads schedules from the YAML-configuration.</summary> - public void Reload(object? data = null) - { - _haContext.CallService("schedule", "reload", null, data); - } -} - -public partial class ScriptServices -{ - private readonly IHaContext _haContext; - public ScriptServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Script for pausing a timer using HA Assist.</summary> - public void AssistTimerpause(object? data = null) - { - _haContext.CallService("script", "assist_timerpause", null, data); - } - - ///<summary>Script for pausing a timer using HA Assist.</summary> - public Task<JsonElement?> AssistTimerpauseAsync(object? data = null) - { - return _haContext.CallServiceWithResponseAsync("script", "assist_timerpause", null, data); - } - - ///<summary>Script for starting a timer using HA Assist.</summary> - public void AssistTimerstart(object? data = null) - { - _haContext.CallService("script", "assist_timerstart", null, data); - } - - ///<summary>Script for starting a timer using HA Assist.</summary> - public Task<JsonElement?> AssistTimerstartAsync(object? data = null) - { - return _haContext.CallServiceWithResponseAsync("script", "assist_timerstart", null, data); - } - - ///<summary>Script for stopping a timer using HA Assist.</summary> - public void AssistTimerstop(object? data = null) - { - _haContext.CallService("script", "assist_timerstop", null, data); - } - - ///<summary>Script for stopping a timer using HA Assist.</summary> - public Task<JsonElement?> AssistTimerstopAsync(object? data = null) - { - return _haContext.CallServiceWithResponseAsync("script", "assist_timerstop", null, data); - } - - ///<summary>Reloads all the available scripts.</summary> - public void Reload(object? data = null) - { - _haContext.CallService("script", "reload", null, data); - } - - ///<summary>Starts a script if it isn't running, stops it otherwise.</summary> - ///<param name="target">The target for this service call</param> - public void Toggle(ServiceTarget target, object? data = null) - { - _haContext.CallService("script", "toggle", target, data); - } - - ///<summary>Stops a running script.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOff(ServiceTarget target, object? data = null) - { - _haContext.CallService("script", "turn_off", target, data); - } - - ///<summary>Runs the sequence of actions defined in a script.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOn(ServiceTarget target, object? data = null) - { - _haContext.CallService("script", "turn_on", target, data); - } - - ///<summary>Script for turning on the UE Boom 2 speaker.</summary> - public void TurnOnUe(object? data = null) - { - _haContext.CallService("script", "turn_on_ue", null, data); - } - - ///<summary>Script for turning on the UE Boom 2 speaker.</summary> - public Task<JsonElement?> TurnOnUeAsync(object? data = null) - { - return _haContext.CallServiceWithResponseAsync("script", "turn_on_ue", null, data); - } -} - -public partial class SelectServices -{ - private readonly IHaContext _haContext; - public SelectServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Selects the first option.</summary> - ///<param name="target">The target for this service call</param> - public void SelectFirst(ServiceTarget target, object? data = null) - { - _haContext.CallService("select", "select_first", target, data); - } - - ///<summary>Selects the last option.</summary> - ///<param name="target">The target for this service call</param> - public void SelectLast(ServiceTarget target, object? data = null) - { - _haContext.CallService("select", "select_last", target, data); - } - - ///<summary>Selects the next option.</summary> - ///<param name="target">The target for this service call</param> - public void SelectNext(ServiceTarget target, SelectSelectNextParameters data) - { - _haContext.CallService("select", "select_next", target, data); - } - - ///<summary>Selects the next option.</summary> - ///<param name="cycle">If the option should cycle from the last to the first.</param> - public void SelectNext(ServiceTarget target, bool? cycle = null) - { - _haContext.CallService("select", "select_next", target, new SelectSelectNextParameters { Cycle = cycle }); - } - - ///<summary>Selects an option.</summary> - ///<param name="target">The target for this service call</param> - public void SelectOption(ServiceTarget target, SelectSelectOptionParameters data) - { - _haContext.CallService("select", "select_option", target, data); - } - - ///<summary>Selects an option.</summary> - ///<param name="option">Option to be selected. eg: "Item A"</param> - public void SelectOption(ServiceTarget target, string option) - { - _haContext.CallService("select", "select_option", target, new SelectSelectOptionParameters { Option = option }); - } - - ///<summary>Selects the previous option.</summary> - ///<param name="target">The target for this service call</param> - public void SelectPrevious(ServiceTarget target, SelectSelectPreviousParameters data) - { - _haContext.CallService("select", "select_previous", target, data); - } - - ///<summary>Selects the previous option.</summary> - ///<param name="cycle">If the option should cycle from the first to the last.</param> - public void SelectPrevious(ServiceTarget target, bool? cycle = null) - { - _haContext.CallService("select", "select_previous", target, new SelectSelectPreviousParameters { Cycle = cycle }); - } -} - -public partial record SelectSelectNextParameters -{ - ///<summary>If the option should cycle from the last to the first.</summary> - [JsonPropertyName("cycle")] - public bool? Cycle { get; init; } -} - -public partial record SelectSelectOptionParameters -{ - ///<summary>Option to be selected. eg: "Item A"</summary> - [JsonPropertyName("option")] - public string? Option { get; init; } -} - -public partial record SelectSelectPreviousParameters -{ - ///<summary>If the option should cycle from the first to the last.</summary> - [JsonPropertyName("cycle")] - public bool? Cycle { get; init; } -} - -public partial class ShellCommandServices -{ - private readonly IHaContext _haContext; - public ShellCommandServices(IHaContext haContext) - { - _haContext = haContext; - } - - public void TurnOnUe(object? data = null) - { - _haContext.CallService("shell_command", "turn_on_ue", null, data); - } - - public Task<JsonElement?> TurnOnUeAsync(object? data = null) - { - return _haContext.CallServiceWithResponseAsync("shell_command", "turn_on_ue", null, data); - } -} - -public partial class ShoppingListServices -{ - private readonly IHaContext _haContext; - public ShoppingListServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Adds an item to the shopping list.</summary> - public void AddItem(ShoppingListAddItemParameters data) - { - _haContext.CallService("shopping_list", "add_item", null, data); - } - - ///<summary>Adds an item to the shopping list.</summary> - ///<param name="name">The name of the item to add. eg: Beer</param> - public void AddItem(string name) - { - _haContext.CallService("shopping_list", "add_item", null, new ShoppingListAddItemParameters { Name = name }); - } - - ///<summary>Removes completed items from the shopping list.</summary> - public void ClearCompletedItems(object? data = null) - { - _haContext.CallService("shopping_list", "clear_completed_items", null, data); - } - - ///<summary>Marks all items as completed in the shopping list (without removing them from the list).</summary> - public void CompleteAll(object? data = null) - { - _haContext.CallService("shopping_list", "complete_all", null, data); - } - - ///<summary>Marks the first item with matching name as completed in the shopping list.</summary> - public void CompleteItem(ShoppingListCompleteItemParameters data) - { - _haContext.CallService("shopping_list", "complete_item", null, data); - } - - ///<summary>Marks the first item with matching name as completed in the shopping list.</summary> - ///<param name="name">The name of the item to mark as completed (without removing). eg: Beer</param> - public void CompleteItem(string name) - { - _haContext.CallService("shopping_list", "complete_item", null, new ShoppingListCompleteItemParameters { Name = name }); - } - - ///<summary>Marks all items as incomplete in the shopping list.</summary> - public void IncompleteAll(object? data = null) - { - _haContext.CallService("shopping_list", "incomplete_all", null, data); - } - - ///<summary>Marks the first item with matching name as incomplete in the shopping list.</summary> - public void IncompleteItem(ShoppingListIncompleteItemParameters data) - { - _haContext.CallService("shopping_list", "incomplete_item", null, data); - } - - ///<summary>Marks the first item with matching name as incomplete in the shopping list.</summary> - ///<param name="name">The name of the item to mark as incomplete. eg: Beer</param> - public void IncompleteItem(string name) - { - _haContext.CallService("shopping_list", "incomplete_item", null, new ShoppingListIncompleteItemParameters { Name = name }); - } - - ///<summary>Removes the first item with matching name from the shopping list.</summary> - public void RemoveItem(ShoppingListRemoveItemParameters data) - { - _haContext.CallService("shopping_list", "remove_item", null, data); - } - - ///<summary>Removes the first item with matching name from the shopping list.</summary> - ///<param name="name">The name of the item to remove. eg: Beer</param> - public void RemoveItem(string name) - { - _haContext.CallService("shopping_list", "remove_item", null, new ShoppingListRemoveItemParameters { Name = name }); - } - - ///<summary>Sorts all items by name in the shopping list.</summary> - public void Sort(ShoppingListSortParameters data) - { - _haContext.CallService("shopping_list", "sort", null, data); - } - - ///<summary>Sorts all items by name in the shopping list.</summary> - ///<param name="reverse">Whether to sort in reverse (descending) order.</param> - public void Sort(bool? reverse = null) - { - _haContext.CallService("shopping_list", "sort", null, new ShoppingListSortParameters { Reverse = reverse }); - } -} - -public partial record ShoppingListAddItemParameters -{ - ///<summary>The name of the item to add. eg: Beer</summary> - [JsonPropertyName("name")] - public string? Name { get; init; } -} - -public partial record ShoppingListCompleteItemParameters -{ - ///<summary>The name of the item to mark as completed (without removing). eg: Beer</summary> - [JsonPropertyName("name")] - public string? Name { get; init; } -} - -public partial record ShoppingListIncompleteItemParameters -{ - ///<summary>The name of the item to mark as incomplete. eg: Beer</summary> - [JsonPropertyName("name")] - public string? Name { get; init; } -} - -public partial record ShoppingListRemoveItemParameters -{ - ///<summary>The name of the item to remove. eg: Beer</summary> - [JsonPropertyName("name")] - public string? Name { get; init; } -} - -public partial record ShoppingListSortParameters -{ - ///<summary>Whether to sort in reverse (descending) order.</summary> - [JsonPropertyName("reverse")] - public bool? Reverse { get; init; } -} - -public partial class SpotifyplusServices -{ - private readonly IHaContext _haContext; - public SpotifyplusServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Add one or more items to the end of the user's current Spotify Player playback queue.</summary> - public void AddPlayerQueueItems(SpotifyplusAddPlayerQueueItemsParameters data) - { - _haContext.CallService("spotifyplus", "add_player_queue_items", null, data); - } - - ///<summary>Add one or more items to the end of the user's current Spotify Player playback queue.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="uris">A list of Spotify track or episode URIs to add to the queue (spotify:track:6zd8T1PBe9JFHmuVnurdRp, spotify:track:1kWUud3vY5ij5r62zxpTRy); values can be track or episode URIs. All URIs must be of the same type - you cannot mix and match tracks and episodes. An unlimited number of items can be added in one request, but the more items the longer it will take. eg: spotify:track:6zd8T1PBe9JFHmuVnurdRp</param> - ///<param name="deviceId">The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</param> - ///<param name="verifyDeviceId">DEPRECATED - no longer used, but left here to maintain compatibility.</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing the add request (if necessary). This delay will give the spotify web api time to process the change before another command is issued. Default is 0.15; value range is 0 - 10. eg: 0.15</param> - public void AddPlayerQueueItems(string entityId, string uris, string? deviceId = null, bool? verifyDeviceId = null, double? delay = null) - { - _haContext.CallService("spotifyplus", "add_player_queue_items", null, new SpotifyplusAddPlayerQueueItemsParameters { EntityId = entityId, Uris = uris, DeviceId = deviceId, VerifyDeviceId = verifyDeviceId, Delay = delay }); - } - - ///<summary>Check if one or more albums (or the currently playing album) exists in the current user's 'Your Library' favorites.</summary> - public void CheckAlbumFavorites(SpotifyplusCheckAlbumFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "check_album_favorites", null, data); - } - - ///<summary>Check if one or more albums (or the currently playing album) exists in the current user's 'Your Library' favorites.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify album id's (e.g. `6vc9OTcyd3hyzabCmsdnwE,382ObEPsp2rxGrnsizN5TX`). A maximum of 50 id's may be specified. If omitted, the currently playing track album uri id value is used. eg: 6vc9OTcyd3hyzabCmsdnwE,382ObEPsp2rxGrnsizN5TX</param> - public void CheckAlbumFavorites(string entityId, string? ids = null) - { - _haContext.CallService("spotifyplus", "check_album_favorites", null, new SpotifyplusCheckAlbumFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Check if one or more albums (or the currently playing album) exists in the current user's 'Your Library' favorites.</summary> - public Task<JsonElement?> CheckAlbumFavoritesAsync(SpotifyplusCheckAlbumFavoritesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "check_album_favorites", null, data); - } - - ///<summary>Check if one or more albums (or the currently playing album) exists in the current user's 'Your Library' favorites.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify album id's (e.g. `6vc9OTcyd3hyzabCmsdnwE,382ObEPsp2rxGrnsizN5TX`). A maximum of 50 id's may be specified. If omitted, the currently playing track album uri id value is used. eg: 6vc9OTcyd3hyzabCmsdnwE,382ObEPsp2rxGrnsizN5TX</param> - public Task<JsonElement?> CheckAlbumFavoritesAsync(string entityId, string? ids = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "check_album_favorites", null, new SpotifyplusCheckAlbumFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Check if one or more artists (or the currently playing artists) is followed in the current user's 'Your Library' favorites.</summary> - public void CheckArtistsFollowing(SpotifyplusCheckArtistsFollowingParameters data) - { - _haContext.CallService("spotifyplus", "check_artists_following", null, data); - } - - ///<summary>Check if one or more artists (or the currently playing artists) is followed in the current user's 'Your Library' favorites.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify artist id's (e.g. `2CIMQHirSU0MQqyYHq0eOx,1IQ2e1buppatiN1bxUVkrk`). A maximum of 50 id's may be specified. If omitted, the currently playing track artist uri id value is used. eg: 2CIMQHirSU0MQqyYHq0eOx,1IQ2e1buppatiN1bxUVkrk</param> - public void CheckArtistsFollowing(string entityId, string? ids = null) - { - _haContext.CallService("spotifyplus", "check_artists_following", null, new SpotifyplusCheckArtistsFollowingParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Check if one or more artists (or the currently playing artists) is followed in the current user's 'Your Library' favorites.</summary> - public Task<JsonElement?> CheckArtistsFollowingAsync(SpotifyplusCheckArtistsFollowingParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "check_artists_following", null, data); - } - - ///<summary>Check if one or more artists (or the currently playing artists) is followed in the current user's 'Your Library' favorites.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify artist id's (e.g. `2CIMQHirSU0MQqyYHq0eOx,1IQ2e1buppatiN1bxUVkrk`). A maximum of 50 id's may be specified. If omitted, the currently playing track artist uri id value is used. eg: 2CIMQHirSU0MQqyYHq0eOx,1IQ2e1buppatiN1bxUVkrk</param> - public Task<JsonElement?> CheckArtistsFollowingAsync(string entityId, string? ids = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "check_artists_following", null, new SpotifyplusCheckArtistsFollowingParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Check if one or more audiobooks (or the currently playing audiobook) exists in the current user's 'Your Library' favorites.</summary> - public void CheckAudiobookFavorites(SpotifyplusCheckAudiobookFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "check_audiobook_favorites", null, data); - } - - ///<summary>Check if one or more audiobooks (or the currently playing audiobook) exists in the current user's 'Your Library' favorites.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify audiobook id's (e.g. `3PFyizE2tGCSRLusl2Qizf,7iHfbu1YPACw6oZPAFJtqe`). A maximum of 50 id's may be specified. If omitted, the currently playing audiobook uri id value is used. eg: 3PFyizE2tGCSRLusl2Qizf,7iHfbu1YPACw6oZPAFJtqe</param> - public void CheckAudiobookFavorites(string entityId, string? ids = null) - { - _haContext.CallService("spotifyplus", "check_audiobook_favorites", null, new SpotifyplusCheckAudiobookFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Check if one or more audiobooks (or the currently playing audiobook) exists in the current user's 'Your Library' favorites.</summary> - public Task<JsonElement?> CheckAudiobookFavoritesAsync(SpotifyplusCheckAudiobookFavoritesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "check_audiobook_favorites", null, data); - } - - ///<summary>Check if one or more audiobooks (or the currently playing audiobook) exists in the current user's 'Your Library' favorites.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify audiobook id's (e.g. `3PFyizE2tGCSRLusl2Qizf,7iHfbu1YPACw6oZPAFJtqe`). A maximum of 50 id's may be specified. If omitted, the currently playing audiobook uri id value is used. eg: 3PFyizE2tGCSRLusl2Qizf,7iHfbu1YPACw6oZPAFJtqe</param> - public Task<JsonElement?> CheckAudiobookFavoritesAsync(string entityId, string? ids = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "check_audiobook_favorites", null, new SpotifyplusCheckAudiobookFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Check if one or more episodes (or the currently playing episode) exists in the current user's 'Your Library' favorites.</summary> - public void CheckEpisodeFavorites(SpotifyplusCheckEpisodeFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "check_episode_favorites", null, data); - } - - ///<summary>Check if one or more episodes (or the currently playing episode) exists in the current user's 'Your Library' favorites.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify episode id's (e.g. `3F97boSWlXi8OzuhWClZHQ,1hPX5WJY6ja6yopgVPBqm4`). A maximum of 50 id's may be specified. If omitted, the currently playing episode uri id value is used. eg: 3F97boSWlXi8OzuhWClZHQ,1hPX5WJY6ja6yopgVPBqm4</param> - public void CheckEpisodeFavorites(string entityId, string? ids = null) - { - _haContext.CallService("spotifyplus", "check_episode_favorites", null, new SpotifyplusCheckEpisodeFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Check if one or more episodes (or the currently playing episode) exists in the current user's 'Your Library' favorites.</summary> - public Task<JsonElement?> CheckEpisodeFavoritesAsync(SpotifyplusCheckEpisodeFavoritesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "check_episode_favorites", null, data); - } - - ///<summary>Check if one or more episodes (or the currently playing episode) exists in the current user's 'Your Library' favorites.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify episode id's (e.g. `3F97boSWlXi8OzuhWClZHQ,1hPX5WJY6ja6yopgVPBqm4`). A maximum of 50 id's may be specified. If omitted, the currently playing episode uri id value is used. eg: 3F97boSWlXi8OzuhWClZHQ,1hPX5WJY6ja6yopgVPBqm4</param> - public Task<JsonElement?> CheckEpisodeFavoritesAsync(string entityId, string? ids = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "check_episode_favorites", null, new SpotifyplusCheckEpisodeFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Check to see if the current user is following a specified playlist.</summary> - public void CheckPlaylistFollowers(SpotifyplusCheckPlaylistFollowersParameters data) - { - _haContext.CallService("spotifyplus", "check_playlist_followers", null, data); - } - - ///<summary>Check to see if the current user is following a specified playlist.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. `3cEYpjA9oz9GiPac4AsH4n`). eg: 3cEYpjA9oz9GiPac4AsH4n</param> - ///<param name="userIds">Deprecated - must contain the current user's Spotify Username; Maximum of 1 id. Omit to default to current user name.</param> - public void CheckPlaylistFollowers(string entityId, string playlistId, string? userIds = null) - { - _haContext.CallService("spotifyplus", "check_playlist_followers", null, new SpotifyplusCheckPlaylistFollowersParameters { EntityId = entityId, PlaylistId = playlistId, UserIds = userIds }); - } - - ///<summary>Check to see if the current user is following a specified playlist.</summary> - public Task<JsonElement?> CheckPlaylistFollowersAsync(SpotifyplusCheckPlaylistFollowersParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "check_playlist_followers", null, data); - } - - ///<summary>Check to see if the current user is following a specified playlist.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. `3cEYpjA9oz9GiPac4AsH4n`). eg: 3cEYpjA9oz9GiPac4AsH4n</param> - ///<param name="userIds">Deprecated - must contain the current user's Spotify Username; Maximum of 1 id. Omit to default to current user name.</param> - public Task<JsonElement?> CheckPlaylistFollowersAsync(string entityId, string playlistId, string? userIds = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "check_playlist_followers", null, new SpotifyplusCheckPlaylistFollowersParameters { EntityId = entityId, PlaylistId = playlistId, UserIds = userIds }); - } - - ///<summary>Check if one or more shows (or the currently playing show) exists in the current user's 'Your Library' favorites.</summary> - public void CheckShowFavorites(SpotifyplusCheckShowFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "check_show_favorites", null, data); - } - - ///<summary>Check if one or more shows (or the currently playing show) exists in the current user's 'Your Library' favorites.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify show id's (e.g. `6kAsbP8pxwaU2kPibKTuHE,4rOoJ6Egrf8K2IrywzwOMk`). A maximum of 50 id's may be specified. If omitted, the currently playing show uri id value is used. eg: 6kAsbP8pxwaU2kPibKTuHE,4rOoJ6Egrf8K2IrywzwOMk</param> - public void CheckShowFavorites(string entityId, string? ids = null) - { - _haContext.CallService("spotifyplus", "check_show_favorites", null, new SpotifyplusCheckShowFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Check if one or more shows (or the currently playing show) exists in the current user's 'Your Library' favorites.</summary> - public Task<JsonElement?> CheckShowFavoritesAsync(SpotifyplusCheckShowFavoritesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "check_show_favorites", null, data); - } - - ///<summary>Check if one or more shows (or the currently playing show) exists in the current user's 'Your Library' favorites.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify show id's (e.g. `6kAsbP8pxwaU2kPibKTuHE,4rOoJ6Egrf8K2IrywzwOMk`). A maximum of 50 id's may be specified. If omitted, the currently playing show uri id value is used. eg: 6kAsbP8pxwaU2kPibKTuHE,4rOoJ6Egrf8K2IrywzwOMk</param> - public Task<JsonElement?> CheckShowFavoritesAsync(string entityId, string? ids = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "check_show_favorites", null, new SpotifyplusCheckShowFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Check if one or more tracks (or the currently playing track) exists in the current user's 'Your Library' favorites.</summary> - public void CheckTrackFavorites(SpotifyplusCheckTrackFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "check_track_favorites", null, data); - } - - ///<summary>Check if one or more tracks (or the currently playing track) exists in the current user's 'Your Library' favorites.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify track id's (e.g. `1kWUud3vY5ij5r62zxpTRy,4eoYKv2kDwJS7gRGh5q6SK`). A maximum of 50 id's may be specified. If omitted, the currently playing context uri id value is used. eg: 1kWUud3vY5ij5r62zxpTRy,4eoYKv2kDwJS7gRGh5q6SK</param> - public void CheckTrackFavorites(string entityId, string? ids = null) - { - _haContext.CallService("spotifyplus", "check_track_favorites", null, new SpotifyplusCheckTrackFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Check if one or more tracks (or the currently playing track) exists in the current user's 'Your Library' favorites.</summary> - public Task<JsonElement?> CheckTrackFavoritesAsync(SpotifyplusCheckTrackFavoritesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "check_track_favorites", null, data); - } - - ///<summary>Check if one or more tracks (or the currently playing track) exists in the current user's 'Your Library' favorites.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify track id's (e.g. `1kWUud3vY5ij5r62zxpTRy,4eoYKv2kDwJS7gRGh5q6SK`). A maximum of 50 id's may be specified. If omitted, the currently playing context uri id value is used. eg: 1kWUud3vY5ij5r62zxpTRy,4eoYKv2kDwJS7gRGh5q6SK</param> - public Task<JsonElement?> CheckTrackFavoritesAsync(string entityId, string? ids = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "check_track_favorites", null, new SpotifyplusCheckTrackFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Check to see if the current user is following one or more users.</summary> - public void CheckUsersFollowing(SpotifyplusCheckUsersFollowingParameters data) - { - _haContext.CallService("spotifyplus", "check_users_following", null, data); - } - - ///<summary>Check to see if the current user is following one or more users.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify user ID's to check (e.g. `smedjan, 7piUznRWxNyKpaPvmOSdiZ`). A maximum of 50 ID's can be specified. eg: smedjan, 7piUznRWxNyKpaPvmOSdiZ</param> - public void CheckUsersFollowing(string entityId, string ids) - { - _haContext.CallService("spotifyplus", "check_users_following", null, new SpotifyplusCheckUsersFollowingParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Check to see if the current user is following one or more users.</summary> - public Task<JsonElement?> CheckUsersFollowingAsync(SpotifyplusCheckUsersFollowingParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "check_users_following", null, data); - } - - ///<summary>Check to see if the current user is following one or more users.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify user ID's to check (e.g. `smedjan, 7piUznRWxNyKpaPvmOSdiZ`). A maximum of 50 ID's can be specified. eg: smedjan, 7piUznRWxNyKpaPvmOSdiZ</param> - public Task<JsonElement?> CheckUsersFollowingAsync(string entityId, string ids) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "check_users_following", null, new SpotifyplusCheckUsersFollowingParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Add the current user as a follower of one or more artists.</summary> - public void FollowArtists(SpotifyplusFollowArtistsParameters data) - { - _haContext.CallService("spotifyplus", "follow_artists", null, data); - } - - ///<summary>Add the current user as a follower of one or more artists.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify artist id's (e.g. `2CIMQHirSU0MQqyYHq0eOx,1IQ2e1buppatiN1bxUVkrk`). A maximum of 50 id's may be specified. If omitted, the currently playing track artist uri id value is used. eg: 2CIMQHirSU0MQqyYHq0eOx,1IQ2e1buppatiN1bxUVkrk</param> - public void FollowArtists(string entityId, string? ids = null) - { - _haContext.CallService("spotifyplus", "follow_artists", null, new SpotifyplusFollowArtistsParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Add the current user as a follower of a playlist.</summary> - public void FollowPlaylist(SpotifyplusFollowPlaylistParameters data) - { - _haContext.CallService("spotifyplus", "follow_playlist", null, data); - } - - ///<summary>Add the current user as a follower of a playlist.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. `3cEYpjA9oz9GiPac4AsH4n`). If omitted, the currently playing playlist uri id value is used. eg: 3cEYpjA9oz9GiPac4AsH4n</param> - ///<param name="public">If true the playlist will be included in user's public playlists, if false it will remain private. eg: True</param> - public void FollowPlaylist(string entityId, string? playlistId = null, bool? @public = null) - { - _haContext.CallService("spotifyplus", "follow_playlist", null, new SpotifyplusFollowPlaylistParameters { EntityId = entityId, PlaylistId = playlistId, Public = @public }); - } - - ///<summary>Add the current user as a follower of one or more users.</summary> - public void FollowUsers(SpotifyplusFollowUsersParameters data) - { - _haContext.CallService("spotifyplus", "follow_users", null, data); - } - - ///<summary>Add the current user as a follower of one or more users.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of the Spotify user IDs (e.g. 'smedjan,3758dfdsfjk435hjk6k79lm0n3c4'). A maximum of 50 IDs can be sent in one request. eg: smedjan,3758dfdsfjk435hjk6k79lm0n3c4</param> - public void FollowUsers(string entityId, string ids) - { - _haContext.CallService("spotifyplus", "follow_users", null, new SpotifyplusFollowUsersParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Get Spotify catalog information for a single album.</summary> - public void GetAlbum(SpotifyplusGetAlbumParameters data) - { - _haContext.CallService("spotifyplus", "get_album", null, data); - } - - ///<summary>Get Spotify catalog information for a single album.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="albumId">The Spotify ID of the album. If omitted, the currently playing album uri id value is used. eg: 6vc9OTcyd3hyzabCmsdnwE</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - public void GetAlbum(string entityId, string? albumId = null, string? market = null) - { - _haContext.CallService("spotifyplus", "get_album", null, new SpotifyplusGetAlbumParameters { EntityId = entityId, AlbumId = albumId, Market = market }); - } - - ///<summary>Get Spotify catalog information for a single album.</summary> - public Task<JsonElement?> GetAlbumAsync(SpotifyplusGetAlbumParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_album", null, data); - } - - ///<summary>Get Spotify catalog information for a single album.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="albumId">The Spotify ID of the album. If omitted, the currently playing album uri id value is used. eg: 6vc9OTcyd3hyzabCmsdnwE</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - public Task<JsonElement?> GetAlbumAsync(string entityId, string? albumId = null, string? market = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_album", null, new SpotifyplusGetAlbumParameters { EntityId = entityId, AlbumId = albumId, Market = market }); - } - - ///<summary>Get a list of the albums saved in the current Spotify user's 'Your Library'.</summary> - public void GetAlbumFavorites(SpotifyplusGetAlbumFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "get_album_favorites", null, data); - } - - ///<summary>Get a list of the albums saved in the current Spotify user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public void GetAlbumFavorites(string entityId, double? limit = null, double? offset = null, string? market = null, double? limitTotal = null, bool? sortResult = null) - { - _haContext.CallService("spotifyplus", "get_album_favorites", null, new SpotifyplusGetAlbumFavoritesParameters { EntityId = entityId, Limit = limit, Offset = offset, Market = market, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get a list of the albums saved in the current Spotify user's 'Your Library'.</summary> - public Task<JsonElement?> GetAlbumFavoritesAsync(SpotifyplusGetAlbumFavoritesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_album_favorites", null, data); - } - - ///<summary>Get a list of the albums saved in the current Spotify user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public Task<JsonElement?> GetAlbumFavoritesAsync(string entityId, double? limit = null, double? offset = null, string? market = null, double? limitTotal = null, bool? sortResult = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_album_favorites", null, new SpotifyplusGetAlbumFavoritesParameters { EntityId = entityId, Limit = limit, Offset = offset, Market = market, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get a list of new album releases featured in Spotify.</summary> - public void GetAlbumNewReleases(SpotifyplusGetAlbumNewReleasesParameters data) - { - _haContext.CallService("spotifyplus", "get_album_new_releases", null, data); - } - - ///<summary>Get a list of new album releases featured in Spotify.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="country">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public void GetAlbumNewReleases(string entityId, double? limit = null, double? offset = null, string? country = null, double? limitTotal = null, bool? sortResult = null) - { - _haContext.CallService("spotifyplus", "get_album_new_releases", null, new SpotifyplusGetAlbumNewReleasesParameters { EntityId = entityId, Limit = limit, Offset = offset, Country = country, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get a list of new album releases featured in Spotify.</summary> - public Task<JsonElement?> GetAlbumNewReleasesAsync(SpotifyplusGetAlbumNewReleasesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_album_new_releases", null, data); - } - - ///<summary>Get a list of new album releases featured in Spotify.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="country">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public Task<JsonElement?> GetAlbumNewReleasesAsync(string entityId, double? limit = null, double? offset = null, string? country = null, double? limitTotal = null, bool? sortResult = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_album_new_releases", null, new SpotifyplusGetAlbumNewReleasesParameters { EntityId = entityId, Limit = limit, Offset = offset, Country = country, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get Spotify catalog information about an album's tracks.</summary> - public void GetAlbumTracks(SpotifyplusGetAlbumTracksParameters data) - { - _haContext.CallService("spotifyplus", "get_album_tracks", null, data); - } - - ///<summary>Get Spotify catalog information about an album's tracks.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="albumId">The Spotify ID of the album (e.g. `6vc9OTcyd3hyzabCmsdnwE`). If null, the currently playing album uri id value is used; a Spotify Free or Premium account is required to correctly read the currently playing context. eg: 6vc9OTcyd3hyzabCmsdnwE</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public void GetAlbumTracks(string entityId, string? albumId = null, double? limit = null, double? offset = null, string? market = null, double? limitTotal = null) - { - _haContext.CallService("spotifyplus", "get_album_tracks", null, new SpotifyplusGetAlbumTracksParameters { EntityId = entityId, AlbumId = albumId, Limit = limit, Offset = offset, Market = market, LimitTotal = limitTotal }); - } - - ///<summary>Get Spotify catalog information about an album's tracks.</summary> - public Task<JsonElement?> GetAlbumTracksAsync(SpotifyplusGetAlbumTracksParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_album_tracks", null, data); - } - - ///<summary>Get Spotify catalog information about an album's tracks.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="albumId">The Spotify ID of the album (e.g. `6vc9OTcyd3hyzabCmsdnwE`). If null, the currently playing album uri id value is used; a Spotify Free or Premium account is required to correctly read the currently playing context. eg: 6vc9OTcyd3hyzabCmsdnwE</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public Task<JsonElement?> GetAlbumTracksAsync(string entityId, string? albumId = null, double? limit = null, double? offset = null, string? market = null, double? limitTotal = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_album_tracks", null, new SpotifyplusGetAlbumTracksParameters { EntityId = entityId, AlbumId = albumId, Limit = limit, Offset = offset, Market = market, LimitTotal = limitTotal }); - } - - ///<summary>Get Spotify catalog information for a single artist.</summary> - public void GetArtist(SpotifyplusGetArtistParameters data) - { - _haContext.CallService("spotifyplus", "get_artist", null, data); - } - - ///<summary>Get Spotify catalog information for a single artist.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="artistId">The Spotify ID of the artist. If omitted, the currently playing artist uri id value is used. eg: 6APm8EjxOHSYM5B4i3vT3q</param> - public void GetArtist(string entityId, string? artistId = null) - { - _haContext.CallService("spotifyplus", "get_artist", null, new SpotifyplusGetArtistParameters { EntityId = entityId, ArtistId = artistId }); - } - - ///<summary>Get Spotify catalog information for a single artist.</summary> - public Task<JsonElement?> GetArtistAsync(SpotifyplusGetArtistParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_artist", null, data); - } - - ///<summary>Get Spotify catalog information for a single artist.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="artistId">The Spotify ID of the artist. If omitted, the currently playing artist uri id value is used. eg: 6APm8EjxOHSYM5B4i3vT3q</param> - public Task<JsonElement?> GetArtistAsync(string entityId, string? artistId = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_artist", null, new SpotifyplusGetArtistParameters { EntityId = entityId, ArtistId = artistId }); - } - - ///<summary>Get Spotify catalog information about an artist's albums.</summary> - public void GetArtistAlbums(SpotifyplusGetArtistAlbumsParameters data) - { - _haContext.CallService("spotifyplus", "get_artist_albums", null, data); - } - - ///<summary>Get Spotify catalog information about an artist's albums.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="artistId">The Spotify ID of the artist. If omitted, the currently playing artist uri id value is used. eg: 6APm8EjxOHSYM5B4i3vT3q</param> - ///<param name="includeGroups">A comma-separated list of keywords that will be used to filter the response. If not supplied, only `album` types will be returned. Valid values are `album`, `single`, `appears_on`, `compilation`. eg: album</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public void GetArtistAlbums(string entityId, string? artistId = null, string? includeGroups = null, double? limit = null, double? offset = null, string? market = null, double? limitTotal = null, bool? sortResult = null) - { - _haContext.CallService("spotifyplus", "get_artist_albums", null, new SpotifyplusGetArtistAlbumsParameters { EntityId = entityId, ArtistId = artistId, IncludeGroups = includeGroups, Limit = limit, Offset = offset, Market = market, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get Spotify catalog information about an artist's albums.</summary> - public Task<JsonElement?> GetArtistAlbumsAsync(SpotifyplusGetArtistAlbumsParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_artist_albums", null, data); - } - - ///<summary>Get Spotify catalog information about an artist's albums.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="artistId">The Spotify ID of the artist. If omitted, the currently playing artist uri id value is used. eg: 6APm8EjxOHSYM5B4i3vT3q</param> - ///<param name="includeGroups">A comma-separated list of keywords that will be used to filter the response. If not supplied, only `album` types will be returned. Valid values are `album`, `single`, `appears_on`, `compilation`. eg: album</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public Task<JsonElement?> GetArtistAlbumsAsync(string entityId, string? artistId = null, string? includeGroups = null, double? limit = null, double? offset = null, string? market = null, double? limitTotal = null, bool? sortResult = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_artist_albums", null, new SpotifyplusGetArtistAlbumsParameters { EntityId = entityId, ArtistId = artistId, IncludeGroups = includeGroups, Limit = limit, Offset = offset, Market = market, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get artist about information from the Spotify Artist Biography page for the specified Spotify artist ID.</summary> - public void GetArtistInfo(SpotifyplusGetArtistInfoParameters data) - { - _haContext.CallService("spotifyplus", "get_artist_info", null, data); - } - - ///<summary>Get artist about information from the Spotify Artist Biography page for the specified Spotify artist ID.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="artistId">The Spotify ID of the artist. If omitted, the currently playing artist uri id value is used. eg: 6APm8EjxOHSYM5B4i3vT3q</param> - public void GetArtistInfo(string entityId, string? artistId = null) - { - _haContext.CallService("spotifyplus", "get_artist_info", null, new SpotifyplusGetArtistInfoParameters { EntityId = entityId, ArtistId = artistId }); - } - - ///<summary>Get artist about information from the Spotify Artist Biography page for the specified Spotify artist ID.</summary> - public Task<JsonElement?> GetArtistInfoAsync(SpotifyplusGetArtistInfoParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_artist_info", null, data); - } - - ///<summary>Get artist about information from the Spotify Artist Biography page for the specified Spotify artist ID.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="artistId">The Spotify ID of the artist. If omitted, the currently playing artist uri id value is used. eg: 6APm8EjxOHSYM5B4i3vT3q</param> - public Task<JsonElement?> GetArtistInfoAsync(string entityId, string? artistId = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_artist_info", null, new SpotifyplusGetArtistInfoParameters { EntityId = entityId, ArtistId = artistId }); - } - - ///<summary>Get Spotify catalog information about artists similar to a given artist. Similarity is based on analysis of the Spotify community's listening history.</summary> - public void GetArtistRelatedArtists(SpotifyplusGetArtistRelatedArtistsParameters data) - { - _haContext.CallService("spotifyplus", "get_artist_related_artists", null, data); - } - - ///<summary>Get Spotify catalog information about artists similar to a given artist. Similarity is based on analysis of the Spotify community's listening history.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="artistId">The Spotify ID of the artist. If omitted, the currently playing artist uri id value is used. eg: 6APm8EjxOHSYM5B4i3vT3q</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public void GetArtistRelatedArtists(string entityId, string? artistId = null, bool? sortResult = null) - { - _haContext.CallService("spotifyplus", "get_artist_related_artists", null, new SpotifyplusGetArtistRelatedArtistsParameters { EntityId = entityId, ArtistId = artistId, SortResult = sortResult }); - } - - ///<summary>Get Spotify catalog information about artists similar to a given artist. Similarity is based on analysis of the Spotify community's listening history.</summary> - public Task<JsonElement?> GetArtistRelatedArtistsAsync(SpotifyplusGetArtistRelatedArtistsParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_artist_related_artists", null, data); - } - - ///<summary>Get Spotify catalog information about artists similar to a given artist. Similarity is based on analysis of the Spotify community's listening history.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="artistId">The Spotify ID of the artist. If omitted, the currently playing artist uri id value is used. eg: 6APm8EjxOHSYM5B4i3vT3q</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public Task<JsonElement?> GetArtistRelatedArtistsAsync(string entityId, string? artistId = null, bool? sortResult = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_artist_related_artists", null, new SpotifyplusGetArtistRelatedArtistsParameters { EntityId = entityId, ArtistId = artistId, SortResult = sortResult }); - } - - ///<summary>Get Spotify catalog information about an artist's top tracks by country.</summary> - public void GetArtistTopTracks(SpotifyplusGetArtistTopTracksParameters data) - { - _haContext.CallService("spotifyplus", "get_artist_top_tracks", null, data); - } - - ///<summary>Get Spotify catalog information about an artist's top tracks by country.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="artistId">The Spotify ID of the artist. If omitted, the currently playing artist uri id value is used. eg: 6APm8EjxOHSYM5B4i3vT3q</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public void GetArtistTopTracks(string entityId, string? artistId = null, string? market = null, bool? sortResult = null) - { - _haContext.CallService("spotifyplus", "get_artist_top_tracks", null, new SpotifyplusGetArtistTopTracksParameters { EntityId = entityId, ArtistId = artistId, Market = market, SortResult = sortResult }); - } - - ///<summary>Get Spotify catalog information about an artist's top tracks by country.</summary> - public Task<JsonElement?> GetArtistTopTracksAsync(SpotifyplusGetArtistTopTracksParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_artist_top_tracks", null, data); - } - - ///<summary>Get Spotify catalog information about an artist's top tracks by country.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="artistId">The Spotify ID of the artist. If omitted, the currently playing artist uri id value is used. eg: 6APm8EjxOHSYM5B4i3vT3q</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public Task<JsonElement?> GetArtistTopTracksAsync(string entityId, string? artistId = null, string? market = null, bool? sortResult = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_artist_top_tracks", null, new SpotifyplusGetArtistTopTracksParameters { EntityId = entityId, ArtistId = artistId, Market = market, SortResult = sortResult }); - } - - ///<summary>Get the current user's followed artists.</summary> - public void GetArtistsFollowed(SpotifyplusGetArtistsFollowedParameters data) - { - _haContext.CallService("spotifyplus", "get_artists_followed", null, data); - } - - ///<summary>Get the current user's followed artists.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="after">The last artist ID retrieved from the previous request, or null for the first request. eg: 6APm8EjxOHSYM5B4i3vT3q</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public void GetArtistsFollowed(string entityId, string? after = null, double? limit = null, double? limitTotal = null, bool? sortResult = null) - { - _haContext.CallService("spotifyplus", "get_artists_followed", null, new SpotifyplusGetArtistsFollowedParameters { EntityId = entityId, After = after, Limit = limit, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get the current user's followed artists.</summary> - public Task<JsonElement?> GetArtistsFollowedAsync(SpotifyplusGetArtistsFollowedParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_artists_followed", null, data); - } - - ///<summary>Get the current user's followed artists.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="after">The last artist ID retrieved from the previous request, or null for the first request. eg: 6APm8EjxOHSYM5B4i3vT3q</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public Task<JsonElement?> GetArtistsFollowedAsync(string entityId, string? after = null, double? limit = null, double? limitTotal = null, bool? sortResult = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_artists_followed", null, new SpotifyplusGetArtistsFollowedParameters { EntityId = entityId, After = after, Limit = limit, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get Spotify catalog information for a single audiobook.</summary> - public void GetAudiobook(SpotifyplusGetAudiobookParameters data) - { - _haContext.CallService("spotifyplus", "get_audiobook", null, data); - } - - ///<summary>Get Spotify catalog information for a single audiobook.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="audiobookId">The Spotify ID for the audiobook (e.g. `74aydHJKgYz3AIq3jjBSv1`). If null, the currently playing audiobook uri id value is used. eg: 74aydHJKgYz3AIq3jjBSv1</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - public void GetAudiobook(string entityId, string? audiobookId = null, string? market = null) - { - _haContext.CallService("spotifyplus", "get_audiobook", null, new SpotifyplusGetAudiobookParameters { EntityId = entityId, AudiobookId = audiobookId, Market = market }); - } - - ///<summary>Get Spotify catalog information for a single audiobook.</summary> - public Task<JsonElement?> GetAudiobookAsync(SpotifyplusGetAudiobookParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_audiobook", null, data); - } - - ///<summary>Get Spotify catalog information for a single audiobook.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="audiobookId">The Spotify ID for the audiobook (e.g. `74aydHJKgYz3AIq3jjBSv1`). If null, the currently playing audiobook uri id value is used. eg: 74aydHJKgYz3AIq3jjBSv1</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - public Task<JsonElement?> GetAudiobookAsync(string entityId, string? audiobookId = null, string? market = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_audiobook", null, new SpotifyplusGetAudiobookParameters { EntityId = entityId, AudiobookId = audiobookId, Market = market }); - } - - ///<summary>Get Spotify catalog information about an audiobook's chapters.</summary> - public void GetAudiobookChapters(SpotifyplusGetAudiobookChaptersParameters data) - { - _haContext.CallService("spotifyplus", "get_audiobook_chapters", null, data); - } - - ///<summary>Get Spotify catalog information about an audiobook's chapters.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="audiobookId">The Spotify ID for the audiobook (e.g. `74aydHJKgYz3AIq3jjBSv1`). If null, the currently playing audiobook uri id value is used. eg: 74aydHJKgYz3AIq3jjBSv1</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public void GetAudiobookChapters(string entityId, string? audiobookId = null, double? limit = null, double? offset = null, string? market = null, double? limitTotal = null) - { - _haContext.CallService("spotifyplus", "get_audiobook_chapters", null, new SpotifyplusGetAudiobookChaptersParameters { EntityId = entityId, AudiobookId = audiobookId, Limit = limit, Offset = offset, Market = market, LimitTotal = limitTotal }); - } - - ///<summary>Get Spotify catalog information about an audiobook's chapters.</summary> - public Task<JsonElement?> GetAudiobookChaptersAsync(SpotifyplusGetAudiobookChaptersParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_audiobook_chapters", null, data); - } - - ///<summary>Get Spotify catalog information about an audiobook's chapters.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="audiobookId">The Spotify ID for the audiobook (e.g. `74aydHJKgYz3AIq3jjBSv1`). If null, the currently playing audiobook uri id value is used. eg: 74aydHJKgYz3AIq3jjBSv1</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public Task<JsonElement?> GetAudiobookChaptersAsync(string entityId, string? audiobookId = null, double? limit = null, double? offset = null, string? market = null, double? limitTotal = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_audiobook_chapters", null, new SpotifyplusGetAudiobookChaptersParameters { EntityId = entityId, AudiobookId = audiobookId, Limit = limit, Offset = offset, Market = market, LimitTotal = limitTotal }); - } - - ///<summary>Get a list of the audiobooks saved in the current Spotify user's 'Your Library'.</summary> - public void GetAudiobookFavorites(SpotifyplusGetAudiobookFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "get_audiobook_favorites", null, data); - } - - ///<summary>Get a list of the audiobooks saved in the current Spotify user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public void GetAudiobookFavorites(string entityId, double? limit = null, double? offset = null, double? limitTotal = null, bool? sortResult = null) - { - _haContext.CallService("spotifyplus", "get_audiobook_favorites", null, new SpotifyplusGetAudiobookFavoritesParameters { EntityId = entityId, Limit = limit, Offset = offset, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get a list of the audiobooks saved in the current Spotify user's 'Your Library'.</summary> - public Task<JsonElement?> GetAudiobookFavoritesAsync(SpotifyplusGetAudiobookFavoritesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_audiobook_favorites", null, data); - } - - ///<summary>Get a list of the audiobooks saved in the current Spotify user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public Task<JsonElement?> GetAudiobookFavoritesAsync(string entityId, double? limit = null, double? offset = null, double? limitTotal = null, bool? sortResult = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_audiobook_favorites", null, new SpotifyplusGetAudiobookFavoritesParameters { EntityId = entityId, Limit = limit, Offset = offset, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get a sorted list of ALL categories used to tag items in Spotify.</summary> - public void GetBrowseCategorysList(SpotifyplusGetBrowseCategorysListParameters data) - { - _haContext.CallService("spotifyplus", "get_browse_categorys_list", null, data); - } - - ///<summary>Get a sorted list of ALL categories used to tag items in Spotify.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="country">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="locale">The desired language, consisting of a lowercase ISO 639-1 language code and an uppercase ISO 3166-1 alpha-2 country code, joined by an underscore. For example `es_MX`, meaning `Spanish (Mexico)`. Provide this parameter if you want the results returned in a particular language (where available). Note that if locale is not supplied, or if the specified language is not available, all strings will be returned in the Spotify default language (American English). eg: es_MX</param> - ///<param name="refresh">True to return real-time information from the spotify web api and update the cache; otherwise, False to just return the cached value. eg: False</param> - public void GetBrowseCategorysList(string entityId, string? country = null, string? locale = null, bool? refresh = null) - { - _haContext.CallService("spotifyplus", "get_browse_categorys_list", null, new SpotifyplusGetBrowseCategorysListParameters { EntityId = entityId, Country = country, Locale = locale, Refresh = refresh }); - } - - ///<summary>Get a sorted list of ALL categories used to tag items in Spotify.</summary> - public Task<JsonElement?> GetBrowseCategorysListAsync(SpotifyplusGetBrowseCategorysListParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_browse_categorys_list", null, data); - } - - ///<summary>Get a sorted list of ALL categories used to tag items in Spotify.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="country">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="locale">The desired language, consisting of a lowercase ISO 639-1 language code and an uppercase ISO 3166-1 alpha-2 country code, joined by an underscore. For example `es_MX`, meaning `Spanish (Mexico)`. Provide this parameter if you want the results returned in a particular language (where available). Note that if locale is not supplied, or if the specified language is not available, all strings will be returned in the Spotify default language (American English). eg: es_MX</param> - ///<param name="refresh">True to return real-time information from the spotify web api and update the cache; otherwise, False to just return the cached value. eg: False</param> - public Task<JsonElement?> GetBrowseCategorysListAsync(string entityId, string? country = null, string? locale = null, bool? refresh = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_browse_categorys_list", null, new SpotifyplusGetBrowseCategorysListParameters { EntityId = entityId, Country = country, Locale = locale, Refresh = refresh }); - } - - ///<summary>Get a list of Spotify playlists tagged with a particular category.</summary> - public void GetCategoryPlaylists(SpotifyplusGetCategoryPlaylistsParameters data) - { - _haContext.CallService("spotifyplus", "get_category_playlists", null, data); - } - - ///<summary>Get a list of Spotify playlists tagged with a particular category.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="categoryId">The Spotify category ID (not name) for the category. eg: dinner</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="country">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public void GetCategoryPlaylists(string entityId, string categoryId, double? limit = null, double? offset = null, string? country = null, double? limitTotal = null, bool? sortResult = null) - { - _haContext.CallService("spotifyplus", "get_category_playlists", null, new SpotifyplusGetCategoryPlaylistsParameters { EntityId = entityId, CategoryId = categoryId, Limit = limit, Offset = offset, Country = country, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get a list of Spotify playlists tagged with a particular category.</summary> - public Task<JsonElement?> GetCategoryPlaylistsAsync(SpotifyplusGetCategoryPlaylistsParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_category_playlists", null, data); - } - - ///<summary>Get a list of Spotify playlists tagged with a particular category.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="categoryId">The Spotify category ID (not name) for the category. eg: dinner</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="country">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public Task<JsonElement?> GetCategoryPlaylistsAsync(string entityId, string categoryId, double? limit = null, double? offset = null, string? country = null, double? limitTotal = null, bool? sortResult = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_category_playlists", null, new SpotifyplusGetCategoryPlaylistsParameters { EntityId = entityId, CategoryId = categoryId, Limit = limit, Offset = offset, Country = country, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get Spotify catalog information for a single chapter.</summary> - public void GetChapter(SpotifyplusGetChapterParameters data) - { - _haContext.CallService("spotifyplus", "get_chapter", null, data); - } - - ///<summary>Get Spotify catalog information for a single chapter.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="chapterId">The Spotify ID of the chapter. If omitted, the currently playing chapter uri id value is used. eg: 3V0yw9UDrYAfkhAvTrvt9Y</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - public void GetChapter(string entityId, string? chapterId = null, string? market = null) - { - _haContext.CallService("spotifyplus", "get_chapter", null, new SpotifyplusGetChapterParameters { EntityId = entityId, ChapterId = chapterId, Market = market }); - } - - ///<summary>Get Spotify catalog information for a single chapter.</summary> - public Task<JsonElement?> GetChapterAsync(SpotifyplusGetChapterParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_chapter", null, data); - } - - ///<summary>Get Spotify catalog information for a single chapter.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="chapterId">The Spotify ID of the chapter. If omitted, the currently playing chapter uri id value is used. eg: 3V0yw9UDrYAfkhAvTrvt9Y</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - public Task<JsonElement?> GetChapterAsync(string entityId, string? chapterId = null, string? market = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_chapter", null, new SpotifyplusGetChapterParameters { EntityId = entityId, ChapterId = chapterId, Market = market }); - } - - ///<summary>Gets the contents of an image url and transfers the contents to the local file system.</summary> - public void GetCoverImageFile(SpotifyplusGetCoverImageFileParameters data) - { - _haContext.CallService("spotifyplus", "get_cover_image_file", null, data); - } - - ///<summary>Gets the contents of an image url and transfers the contents to the local file system.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="imageUrl">The cover image url whose contents are to be retrieved. eg: https://i.scdn.co/image/ab67616d0000b27316c019c87a927829804caf0b</param> - ///<param name="outputPath">Fully-qualified path to store the downloaded image to. eg: /config/www/images/cover_file_image.jpg</param> - public void GetCoverImageFile(string entityId, string imageUrl, string outputPath) - { - _haContext.CallService("spotifyplus", "get_cover_image_file", null, new SpotifyplusGetCoverImageFileParameters { EntityId = entityId, ImageUrl = imageUrl, OutputPath = outputPath }); - } - - ///<summary>Get Spotify catalog information for a single episode.</summary> - public void GetEpisode(SpotifyplusGetEpisodeParameters data) - { - _haContext.CallService("spotifyplus", "get_episode", null, data); - } - - ///<summary>Get Spotify catalog information for a single episode.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="episodeId">The Spotify ID of the episode. If omitted, the currently playing episode uri id value is used. eg: 26c0zVyOv1lzfYpBXdh1zC</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - public void GetEpisode(string entityId, string? episodeId = null, string? market = null) - { - _haContext.CallService("spotifyplus", "get_episode", null, new SpotifyplusGetEpisodeParameters { EntityId = entityId, EpisodeId = episodeId, Market = market }); - } - - ///<summary>Get Spotify catalog information for a single episode.</summary> - public Task<JsonElement?> GetEpisodeAsync(SpotifyplusGetEpisodeParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_episode", null, data); - } - - ///<summary>Get Spotify catalog information for a single episode.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="episodeId">The Spotify ID of the episode. If omitted, the currently playing episode uri id value is used. eg: 26c0zVyOv1lzfYpBXdh1zC</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - public Task<JsonElement?> GetEpisodeAsync(string entityId, string? episodeId = null, string? market = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_episode", null, new SpotifyplusGetEpisodeParameters { EntityId = entityId, EpisodeId = episodeId, Market = market }); - } - - ///<summary>Get a list of the episodes saved in the current Spotify user's 'Your Library'.</summary> - public void GetEpisodeFavorites(SpotifyplusGetEpisodeFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "get_episode_favorites", null, data); - } - - ///<summary>Get a list of the episodes saved in the current Spotify user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public void GetEpisodeFavorites(string entityId, double? limit = null, double? offset = null, double? limitTotal = null, bool? sortResult = null) - { - _haContext.CallService("spotifyplus", "get_episode_favorites", null, new SpotifyplusGetEpisodeFavoritesParameters { EntityId = entityId, Limit = limit, Offset = offset, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get a list of the episodes saved in the current Spotify user's 'Your Library'.</summary> - public Task<JsonElement?> GetEpisodeFavoritesAsync(SpotifyplusGetEpisodeFavoritesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_episode_favorites", null, data); - } - - ///<summary>Get a list of the episodes saved in the current Spotify user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public Task<JsonElement?> GetEpisodeFavoritesAsync(string entityId, double? limit = null, double? offset = null, double? limitTotal = null, bool? sortResult = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_episode_favorites", null, new SpotifyplusGetEpisodeFavoritesParameters { EntityId = entityId, Limit = limit, Offset = offset, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get a list of Spotify featured playlists.</summary> - public void GetFeaturedPlaylists(SpotifyplusGetFeaturedPlaylistsParameters data) - { - _haContext.CallService("spotifyplus", "get_featured_playlists", null, data); - } - - ///<summary>Get a list of Spotify featured playlists.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="country">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="locale">The desired language, consisting of a lowercase ISO 639-1 language code and an uppercase ISO 3166-1 alpha-2 country code, joined by an underscore. For example `es_MX`, meaning `Spanish (Mexico)`. Provide this parameter if you want the results returned in a particular language (where available). Note that if locale is not supplied, or if the specified language is not available, all strings will be returned in the Spotify default language (American English). eg: es_MX</param> - ///<param name="timestamp">A timestamp in ISO 8601 format (yyyy-MM-ddTHH:mm:ss). Use this parameter to specify the user's local time to get results tailored for that specific date and time in the day. If not provided, the response defaults to the current UTC time. eg: 2023-10-23T09:00:00</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public void GetFeaturedPlaylists(string entityId, double? limit = null, double? offset = null, string? country = null, string? locale = null, string? timestamp = null, double? limitTotal = null, bool? sortResult = null) - { - _haContext.CallService("spotifyplus", "get_featured_playlists", null, new SpotifyplusGetFeaturedPlaylistsParameters { EntityId = entityId, Limit = limit, Offset = offset, Country = country, Locale = locale, Timestamp = timestamp, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get a list of Spotify featured playlists.</summary> - public Task<JsonElement?> GetFeaturedPlaylistsAsync(SpotifyplusGetFeaturedPlaylistsParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_featured_playlists", null, data); - } - - ///<summary>Get a list of Spotify featured playlists.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="country">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="locale">The desired language, consisting of a lowercase ISO 639-1 language code and an uppercase ISO 3166-1 alpha-2 country code, joined by an underscore. For example `es_MX`, meaning `Spanish (Mexico)`. Provide this parameter if you want the results returned in a particular language (where available). Note that if locale is not supplied, or if the specified language is not available, all strings will be returned in the Spotify default language (American English). eg: es_MX</param> - ///<param name="timestamp">A timestamp in ISO 8601 format (yyyy-MM-ddTHH:mm:ss). Use this parameter to specify the user's local time to get results tailored for that specific date and time in the day. If not provided, the response defaults to the current UTC time. eg: 2023-10-23T09:00:00</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public Task<JsonElement?> GetFeaturedPlaylistsAsync(string entityId, double? limit = null, double? offset = null, string? country = null, string? locale = null, string? timestamp = null, double? limitTotal = null, bool? sortResult = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_featured_playlists", null, new SpotifyplusGetFeaturedPlaylistsParameters { EntityId = entityId, Limit = limit, Offset = offset, Country = country, Locale = locale, Timestamp = timestamp, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get vibrant color palette values from the specified image source.</summary> - public void GetImageVibrantColors(SpotifyplusGetImageVibrantColorsParameters data) - { - _haContext.CallService("spotifyplus", "get_image_vibrant_colors", null, data); - } - - ///<summary>Get vibrant color palette values from the specified image source.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="imageSource">The image source to extract color palette information from. If the prefix of the value is `http:` or `https:`, then the image is downloaded from the url. This can also point to a filename on the local file system. If null, the currently playing Spotify track image url is used. Example = `https://i.scdn.co/image/ab67616d0000b2733deaee5f76ab2da15dd8db86`, `c:/image1.jpg` eg: https://i.scdn.co/image/ab67616d0000b2733deaee5f76ab2da15dd8db86</param> - ///<param name="colorCount">The number of colors in the initial palette from which swatches will be generated. Default is 64; Range is 1 to 256. eg: 64</param> - ///<param name="colorQuality">Controls the processing time and quality of the palette generation. A lower value (e.g. 1) results in higher quality but takes more processing time, while a higher value (e.g. 5) is faster but may result in a lower-quality palette. Default is 5; Range is 1 to 10. eg: 5</param> - public void GetImageVibrantColors(string entityId, string? imageSource = null, double? colorCount = null, double? colorQuality = null) - { - _haContext.CallService("spotifyplus", "get_image_vibrant_colors", null, new SpotifyplusGetImageVibrantColorsParameters { EntityId = entityId, ImageSource = imageSource, ColorCount = colorCount, ColorQuality = colorQuality }); - } - - ///<summary>Get vibrant color palette values from the specified image source.</summary> - public Task<JsonElement?> GetImageVibrantColorsAsync(SpotifyplusGetImageVibrantColorsParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_image_vibrant_colors", null, data); - } - - ///<summary>Get vibrant color palette values from the specified image source.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="imageSource">The image source to extract color palette information from. If the prefix of the value is `http:` or `https:`, then the image is downloaded from the url. This can also point to a filename on the local file system. If null, the currently playing Spotify track image url is used. Example = `https://i.scdn.co/image/ab67616d0000b2733deaee5f76ab2da15dd8db86`, `c:/image1.jpg` eg: https://i.scdn.co/image/ab67616d0000b2733deaee5f76ab2da15dd8db86</param> - ///<param name="colorCount">The number of colors in the initial palette from which swatches will be generated. Default is 64; Range is 1 to 256. eg: 64</param> - ///<param name="colorQuality">Controls the processing time and quality of the palette generation. A lower value (e.g. 1) results in higher quality but takes more processing time, while a higher value (e.g. 5) is faster but may result in a lower-quality palette. Default is 5; Range is 1 to 10. eg: 5</param> - public Task<JsonElement?> GetImageVibrantColorsAsync(string entityId, string? imageSource = null, double? colorCount = null, double? colorQuality = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_image_vibrant_colors", null, new SpotifyplusGetImageVibrantColorsParameters { EntityId = entityId, ImageSource = imageSource, ColorCount = colorCount, ColorQuality = colorQuality }); - } - - ///<summary>Get information about a user's available Spotify Connect player devices. Some device models are not supported and will not be listed in the API response.</summary> - public void GetPlayerDevices(SpotifyplusGetPlayerDevicesParameters data) - { - _haContext.CallService("spotifyplus", "get_player_devices", null, data); - } - - ///<summary>Get information about a user's available Spotify Connect player devices. Some device models are not supported and will not be listed in the API response.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="refresh">True to return real-time information from the spotify web api and update the cache; otherwise, False to just return the cached value. eg: True</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public void GetPlayerDevices(string entityId, bool? refresh = null, bool? sortResult = null) - { - _haContext.CallService("spotifyplus", "get_player_devices", null, new SpotifyplusGetPlayerDevicesParameters { EntityId = entityId, Refresh = refresh, SortResult = sortResult }); - } - - ///<summary>Get information about a user's available Spotify Connect player devices. Some device models are not supported and will not be listed in the API response.</summary> - public Task<JsonElement?> GetPlayerDevicesAsync(SpotifyplusGetPlayerDevicesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_player_devices", null, data); - } - - ///<summary>Get information about a user's available Spotify Connect player devices. Some device models are not supported and will not be listed in the API response.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="refresh">True to return real-time information from the spotify web api and update the cache; otherwise, False to just return the cached value. eg: True</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public Task<JsonElement?> GetPlayerDevicesAsync(string entityId, bool? refresh = null, bool? sortResult = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_player_devices", null, new SpotifyplusGetPlayerDevicesParameters { EntityId = entityId, Refresh = refresh, SortResult = sortResult }); - } - - ///<summary>Get the object currently being played on the user's Spotify account.</summary> - public void GetPlayerNowPlaying(SpotifyplusGetPlayerNowPlayingParameters data) - { - _haContext.CallService("spotifyplus", "get_player_now_playing", null, data); - } - - ///<summary>Get the object currently being played on the user's Spotify account.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="additionalTypes">A comma-separated list of item types that your client supports besides the default track type. Valid types are 'track' and 'episode'. eg: episode</param> - public void GetPlayerNowPlaying(string entityId, string? market = null, string? additionalTypes = null) - { - _haContext.CallService("spotifyplus", "get_player_now_playing", null, new SpotifyplusGetPlayerNowPlayingParameters { EntityId = entityId, Market = market, AdditionalTypes = additionalTypes }); - } - - ///<summary>Get the object currently being played on the user's Spotify account.</summary> - public Task<JsonElement?> GetPlayerNowPlayingAsync(SpotifyplusGetPlayerNowPlayingParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_player_now_playing", null, data); - } - - ///<summary>Get the object currently being played on the user's Spotify account.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="additionalTypes">A comma-separated list of item types that your client supports besides the default track type. Valid types are 'track' and 'episode'. eg: episode</param> - public Task<JsonElement?> GetPlayerNowPlayingAsync(string entityId, string? market = null, string? additionalTypes = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_player_now_playing", null, new SpotifyplusGetPlayerNowPlayingParameters { EntityId = entityId, Market = market, AdditionalTypes = additionalTypes }); - } - - ///<summary>Get information about the user's current playback state, including track or episode, progress, and active device.</summary> - public void GetPlayerPlaybackState(SpotifyplusGetPlayerPlaybackStateParameters data) - { - _haContext.CallService("spotifyplus", "get_player_playback_state", null, data); - } - - ///<summary>Get information about the user's current playback state, including track or episode, progress, and active device.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="additionalTypes">A comma-separated list of item types that your client supports besides the default track type. Valid types are 'track' and 'episode'. eg: episode</param> - public void GetPlayerPlaybackState(string entityId, string? market = null, string? additionalTypes = null) - { - _haContext.CallService("spotifyplus", "get_player_playback_state", null, new SpotifyplusGetPlayerPlaybackStateParameters { EntityId = entityId, Market = market, AdditionalTypes = additionalTypes }); - } - - ///<summary>Get information about the user's current playback state, including track or episode, progress, and active device.</summary> - public Task<JsonElement?> GetPlayerPlaybackStateAsync(SpotifyplusGetPlayerPlaybackStateParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_player_playback_state", null, data); - } - - ///<summary>Get information about the user's current playback state, including track or episode, progress, and active device.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="additionalTypes">A comma-separated list of item types that your client supports besides the default track type. Valid types are 'track' and 'episode'. eg: episode</param> - public Task<JsonElement?> GetPlayerPlaybackStateAsync(string entityId, string? market = null, string? additionalTypes = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_player_playback_state", null, new SpotifyplusGetPlayerPlaybackStateParameters { EntityId = entityId, Market = market, AdditionalTypes = additionalTypes }); - } - - ///<summary>Get the list of objects that make up the user's playback queue.</summary> - public void GetPlayerQueueInfo(SpotifyplusGetPlayerQueueInfoParameters data) - { - _haContext.CallService("spotifyplus", "get_player_queue_info", null, data); - } - - ///<summary>Get the list of objects that make up the user's playback queue.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - public void GetPlayerQueueInfo(string entityId) - { - _haContext.CallService("spotifyplus", "get_player_queue_info", null, new SpotifyplusGetPlayerQueueInfoParameters { EntityId = entityId }); - } - - ///<summary>Get the list of objects that make up the user's playback queue.</summary> - public Task<JsonElement?> GetPlayerQueueInfoAsync(SpotifyplusGetPlayerQueueInfoParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_player_queue_info", null, data); - } - - ///<summary>Get the list of objects that make up the user's playback queue.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - public Task<JsonElement?> GetPlayerQueueInfoAsync(string entityId) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_player_queue_info", null, new SpotifyplusGetPlayerQueueInfoParameters { EntityId = entityId }); - } - - ///<summary>Get tracks from the current user's recently played tracks; currently doesn't support podcast episodes, and only 50 items may be returned due to spotify limits.</summary> - public void GetPlayerRecentTracks(SpotifyplusGetPlayerRecentTracksParameters data) - { - _haContext.CallService("spotifyplus", "get_player_recent_tracks", null, data); - } - - ///<summary>Get tracks from the current user's recently played tracks; currently doesn't support podcast episodes, and only 50 items may be returned due to spotify limits.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="after">Returns all items after (but not including) this cursor position, which is a Unix timestamp in milliseconds. If `after` is specified, `before` must not be specified. Use with limit to get the next set of items. Default is `0` (the first item). eg: 1706218456821</param> - ///<param name="before">Returns all items before (but not including) this cursor position, which is a Unix timestamp in milliseconds. If `before` is specified, `after` must not be specified. Use with limit to get the next set of items. Default is `0` (the first item). eg: 1706218467821</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public void GetPlayerRecentTracks(string entityId, double? limit = null, double? after = null, double? before = null, double? limitTotal = null) - { - _haContext.CallService("spotifyplus", "get_player_recent_tracks", null, new SpotifyplusGetPlayerRecentTracksParameters { EntityId = entityId, Limit = limit, After = after, Before = before, LimitTotal = limitTotal }); - } - - ///<summary>Get tracks from the current user's recently played tracks; currently doesn't support podcast episodes, and only 50 items may be returned due to spotify limits.</summary> - public Task<JsonElement?> GetPlayerRecentTracksAsync(SpotifyplusGetPlayerRecentTracksParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_player_recent_tracks", null, data); - } - - ///<summary>Get tracks from the current user's recently played tracks; currently doesn't support podcast episodes, and only 50 items may be returned due to spotify limits.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="after">Returns all items after (but not including) this cursor position, which is a Unix timestamp in milliseconds. If `after` is specified, `before` must not be specified. Use with limit to get the next set of items. Default is `0` (the first item). eg: 1706218456821</param> - ///<param name="before">Returns all items before (but not including) this cursor position, which is a Unix timestamp in milliseconds. If `before` is specified, `after` must not be specified. Use with limit to get the next set of items. Default is `0` (the first item). eg: 1706218467821</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public Task<JsonElement?> GetPlayerRecentTracksAsync(string entityId, double? limit = null, double? after = null, double? before = null, double? limitTotal = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_player_recent_tracks", null, new SpotifyplusGetPlayerRecentTracksParameters { EntityId = entityId, Limit = limit, After = after, Before = before, LimitTotal = limitTotal }); - } - - ///<summary>Get a playlist owned by a Spotify user.</summary> - public void GetPlaylist(SpotifyplusGetPlaylistParameters data) - { - _haContext.CallService("spotifyplus", "get_playlist", null, data); - } - - ///<summary>Get a playlist owned by a Spotify user.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist. If omitted, the currently playing playlist uri id value is used. eg: 5v5ETK9WFXAnGQ3MRubKuE</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="fields">A comma-separated list of fields to return from the Spotify Web API. All fields are returned if omitted. eg: description,id,name,public,snapshot_id,type,uri,tracks(limit,next,offset,previous,total,items(track(id,name,track_number,type,uri,album(id,images,name,total_tracks,type,uri,artists(id,name,type,uri)))))</param> - ///<param name="additionalTypes">A comma-separated list of item types that your client supports besides the default track type. Valid types are 'track' and 'episode'. eg: episode</param> - public void GetPlaylist(string entityId, string? playlistId = null, string? market = null, string? fields = null, string? additionalTypes = null) - { - _haContext.CallService("spotifyplus", "get_playlist", null, new SpotifyplusGetPlaylistParameters { EntityId = entityId, PlaylistId = playlistId, Market = market, Fields = fields, AdditionalTypes = additionalTypes }); - } - - ///<summary>Get a playlist owned by a Spotify user.</summary> - public Task<JsonElement?> GetPlaylistAsync(SpotifyplusGetPlaylistParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_playlist", null, data); - } - - ///<summary>Get a playlist owned by a Spotify user.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist. If omitted, the currently playing playlist uri id value is used. eg: 5v5ETK9WFXAnGQ3MRubKuE</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="fields">A comma-separated list of fields to return from the Spotify Web API. All fields are returned if omitted. eg: description,id,name,public,snapshot_id,type,uri,tracks(limit,next,offset,previous,total,items(track(id,name,track_number,type,uri,album(id,images,name,total_tracks,type,uri,artists(id,name,type,uri)))))</param> - ///<param name="additionalTypes">A comma-separated list of item types that your client supports besides the default track type. Valid types are 'track' and 'episode'. eg: episode</param> - public Task<JsonElement?> GetPlaylistAsync(string entityId, string? playlistId = null, string? market = null, string? fields = null, string? additionalTypes = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_playlist", null, new SpotifyplusGetPlaylistParameters { EntityId = entityId, PlaylistId = playlistId, Market = market, Fields = fields, AdditionalTypes = additionalTypes }); - } - - ///<summary>Get the current image associated with a specific playlist.</summary> - public void GetPlaylistCoverImage(SpotifyplusGetPlaylistCoverImageParameters data) - { - _haContext.CallService("spotifyplus", "get_playlist_cover_image", null, data); - } - - ///<summary>Get the current image associated with a specific playlist.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. 5v5ETK9WFXAnGQ3MRubKuE). If omitted, the currently playing playlist uri id value is used. eg: 5v5ETK9WFXAnGQ3MRubKuE</param> - public void GetPlaylistCoverImage(string entityId, string? playlistId = null) - { - _haContext.CallService("spotifyplus", "get_playlist_cover_image", null, new SpotifyplusGetPlaylistCoverImageParameters { EntityId = entityId, PlaylistId = playlistId }); - } - - ///<summary>Get the current image associated with a specific playlist.</summary> - public Task<JsonElement?> GetPlaylistCoverImageAsync(SpotifyplusGetPlaylistCoverImageParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_playlist_cover_image", null, data); - } - - ///<summary>Get the current image associated with a specific playlist.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. 5v5ETK9WFXAnGQ3MRubKuE). If omitted, the currently playing playlist uri id value is used. eg: 5v5ETK9WFXAnGQ3MRubKuE</param> - public Task<JsonElement?> GetPlaylistCoverImageAsync(string entityId, string? playlistId = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_playlist_cover_image", null, new SpotifyplusGetPlaylistCoverImageParameters { EntityId = entityId, PlaylistId = playlistId }); - } - - ///<summary>Get a list of the playlists owned or followed by the current Spotify user.</summary> - public void GetPlaylistFavorites(SpotifyplusGetPlaylistFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "get_playlist_favorites", null, data); - } - - ///<summary>Get a list of the playlists owned or followed by the current Spotify user.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public void GetPlaylistFavorites(string entityId, double? limit = null, double? offset = null, double? limitTotal = null, bool? sortResult = null) - { - _haContext.CallService("spotifyplus", "get_playlist_favorites", null, new SpotifyplusGetPlaylistFavoritesParameters { EntityId = entityId, Limit = limit, Offset = offset, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get a list of the playlists owned or followed by the current Spotify user.</summary> - public Task<JsonElement?> GetPlaylistFavoritesAsync(SpotifyplusGetPlaylistFavoritesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_playlist_favorites", null, data); - } - - ///<summary>Get a list of the playlists owned or followed by the current Spotify user.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public Task<JsonElement?> GetPlaylistFavoritesAsync(string entityId, double? limit = null, double? offset = null, double? limitTotal = null, bool? sortResult = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_playlist_favorites", null, new SpotifyplusGetPlaylistFavoritesParameters { EntityId = entityId, Limit = limit, Offset = offset, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get full details of the items of a playlist owned by a Spotify user.</summary> - public void GetPlaylistItems(SpotifyplusGetPlaylistItemsParameters data) - { - _haContext.CallService("spotifyplus", "get_playlist_items", null, data); - } - - ///<summary>Get full details of the items of a playlist owned by a Spotify user.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. 5v5ETK9WFXAnGQ3MRubKuE). If null, the currently playing playlist uri id value is used. eg: 5v5ETK9WFXAnGQ3MRubKuE</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="fields">Filters for the query; a comma-separated list of the fields to return. If omitted, all fields are returned. For example, specify 'fields=description,uri' to get just the playlist's description and URI. eg: items(track(name,uri,album(name,uri)))</param> - ///<param name="additionalTypes">A comma-separated list of item types that your client supports besides the default track type. Valid types are 'track' and 'episode'. eg: track</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public void GetPlaylistItems(string entityId, string playlistId, double? limit = null, double? offset = null, string? market = null, string? fields = null, string? additionalTypes = null, double? limitTotal = null) - { - _haContext.CallService("spotifyplus", "get_playlist_items", null, new SpotifyplusGetPlaylistItemsParameters { EntityId = entityId, PlaylistId = playlistId, Limit = limit, Offset = offset, Market = market, Fields = fields, AdditionalTypes = additionalTypes, LimitTotal = limitTotal }); - } - - ///<summary>Get full details of the items of a playlist owned by a Spotify user.</summary> - public Task<JsonElement?> GetPlaylistItemsAsync(SpotifyplusGetPlaylistItemsParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_playlist_items", null, data); - } - - ///<summary>Get full details of the items of a playlist owned by a Spotify user.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. 5v5ETK9WFXAnGQ3MRubKuE). If null, the currently playing playlist uri id value is used. eg: 5v5ETK9WFXAnGQ3MRubKuE</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="fields">Filters for the query; a comma-separated list of the fields to return. If omitted, all fields are returned. For example, specify 'fields=description,uri' to get just the playlist's description and URI. eg: items(track(name,uri,album(name,uri)))</param> - ///<param name="additionalTypes">A comma-separated list of item types that your client supports besides the default track type. Valid types are 'track' and 'episode'. eg: track</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public Task<JsonElement?> GetPlaylistItemsAsync(string entityId, string playlistId, double? limit = null, double? offset = null, string? market = null, string? fields = null, string? additionalTypes = null, double? limitTotal = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_playlist_items", null, new SpotifyplusGetPlaylistItemsParameters { EntityId = entityId, PlaylistId = playlistId, Limit = limit, Offset = offset, Market = market, Fields = fields, AdditionalTypes = additionalTypes, LimitTotal = limitTotal }); - } - - ///<summary>Get a list of the playlists owned or followed by the current Spotify user.</summary> - public void GetPlaylistsForUser(SpotifyplusGetPlaylistsForUserParameters data) - { - _haContext.CallService("spotifyplus", "get_playlists_for_user", null, data); - } - - ///<summary>Get a list of the playlists owned or followed by the current Spotify user.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="userId">The user's Spotify user ID (e.g. `smedjan`). eg: smedjan</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public void GetPlaylistsForUser(string entityId, string userId, double? limit = null, double? offset = null, double? limitTotal = null, bool? sortResult = null) - { - _haContext.CallService("spotifyplus", "get_playlists_for_user", null, new SpotifyplusGetPlaylistsForUserParameters { EntityId = entityId, UserId = userId, Limit = limit, Offset = offset, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get a list of the playlists owned or followed by the current Spotify user.</summary> - public Task<JsonElement?> GetPlaylistsForUserAsync(SpotifyplusGetPlaylistsForUserParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_playlists_for_user", null, data); - } - - ///<summary>Get a list of the playlists owned or followed by the current Spotify user.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="userId">The user's Spotify user ID (e.g. `smedjan`). eg: smedjan</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public Task<JsonElement?> GetPlaylistsForUserAsync(string entityId, string userId, double? limit = null, double? offset = null, double? limitTotal = null, bool? sortResult = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_playlists_for_user", null, new SpotifyplusGetPlaylistsForUserParameters { EntityId = entityId, UserId = userId, Limit = limit, Offset = offset, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get Spotify catalog information for a single show.</summary> - public void GetShow(SpotifyplusGetShowParameters data) - { - _haContext.CallService("spotifyplus", "get_show", null, data); - } - - ///<summary>Get Spotify catalog information for a single show.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="showId">The Spotify ID of the show. If omitted, the currently playing show uri id value is used. eg: 5CfCWKI5pZ28U0uOzXkDHe</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - public void GetShow(string entityId, string? showId = null, string? market = null) - { - _haContext.CallService("spotifyplus", "get_show", null, new SpotifyplusGetShowParameters { EntityId = entityId, ShowId = showId, Market = market }); - } - - ///<summary>Get Spotify catalog information for a single show.</summary> - public Task<JsonElement?> GetShowAsync(SpotifyplusGetShowParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_show", null, data); - } - - ///<summary>Get Spotify catalog information for a single show.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="showId">The Spotify ID of the show. If omitted, the currently playing show uri id value is used. eg: 5CfCWKI5pZ28U0uOzXkDHe</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - public Task<JsonElement?> GetShowAsync(string entityId, string? showId = null, string? market = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_show", null, new SpotifyplusGetShowParameters { EntityId = entityId, ShowId = showId, Market = market }); - } - - ///<summary>Get Spotify catalog information about a show's episodes.</summary> - public void GetShowEpisodes(SpotifyplusGetShowEpisodesParameters data) - { - _haContext.CallService("spotifyplus", "get_show_episodes", null, data); - } - - ///<summary>Get Spotify catalog information about a show's episodes.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="showId">The Spotify ID for the show. If omitted, the currently playing show uri id value is used. eg: 6kAsbP8pxwaU2kPibKTuHE</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public void GetShowEpisodes(string entityId, string? showId = null, double? limit = null, double? offset = null, string? market = null, double? limitTotal = null) - { - _haContext.CallService("spotifyplus", "get_show_episodes", null, new SpotifyplusGetShowEpisodesParameters { EntityId = entityId, ShowId = showId, Limit = limit, Offset = offset, Market = market, LimitTotal = limitTotal }); - } - - ///<summary>Get Spotify catalog information about a show's episodes.</summary> - public Task<JsonElement?> GetShowEpisodesAsync(SpotifyplusGetShowEpisodesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_show_episodes", null, data); - } - - ///<summary>Get Spotify catalog information about a show's episodes.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="showId">The Spotify ID for the show. If omitted, the currently playing show uri id value is used. eg: 6kAsbP8pxwaU2kPibKTuHE</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public Task<JsonElement?> GetShowEpisodesAsync(string entityId, string? showId = null, double? limit = null, double? offset = null, string? market = null, double? limitTotal = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_show_episodes", null, new SpotifyplusGetShowEpisodesParameters { EntityId = entityId, ShowId = showId, Limit = limit, Offset = offset, Market = market, LimitTotal = limitTotal }); - } - - ///<summary>Get a list of the shows saved in the current Spotify user's 'Your Library'.</summary> - public void GetShowFavorites(SpotifyplusGetShowFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "get_show_favorites", null, data); - } - - ///<summary>Get a list of the shows saved in the current Spotify user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - ///<param name="excludeAudiobooks">True (default) to exclude audiobook shows from the returned list, leaving only podcast shows; otherwise, False to include all results returned by the Spotify Web API. eg: True</param> - public void GetShowFavorites(string entityId, double? limit = null, double? offset = null, double? limitTotal = null, bool? sortResult = null, bool? excludeAudiobooks = null) - { - _haContext.CallService("spotifyplus", "get_show_favorites", null, new SpotifyplusGetShowFavoritesParameters { EntityId = entityId, Limit = limit, Offset = offset, LimitTotal = limitTotal, SortResult = sortResult, ExcludeAudiobooks = excludeAudiobooks }); - } - - ///<summary>Get a list of the shows saved in the current Spotify user's 'Your Library'.</summary> - public Task<JsonElement?> GetShowFavoritesAsync(SpotifyplusGetShowFavoritesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_show_favorites", null, data); - } - - ///<summary>Get a list of the shows saved in the current Spotify user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - ///<param name="excludeAudiobooks">True (default) to exclude audiobook shows from the returned list, leaving only podcast shows; otherwise, False to include all results returned by the Spotify Web API. eg: True</param> - public Task<JsonElement?> GetShowFavoritesAsync(string entityId, double? limit = null, double? offset = null, double? limitTotal = null, bool? sortResult = null, bool? excludeAudiobooks = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_show_favorites", null, new SpotifyplusGetShowFavoritesParameters { EntityId = entityId, Limit = limit, Offset = offset, LimitTotal = limitTotal, SortResult = sortResult, ExcludeAudiobooks = excludeAudiobooks }); - } - - ///<summary>Get information about a specific Spotify Connect player device, and (optionally) activate the device if it requires it.</summary> - public void GetSpotifyConnectDevice(SpotifyplusGetSpotifyConnectDeviceParameters data) - { - _haContext.CallService("spotifyplus", "get_spotify_connect_device", null, data); - } - - ///<summary>Get information about a specific Spotify Connect player device, and (optionally) activate the device if it requires it.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="deviceValue">The id (e.g. '30fbc80e35598f3c242f2120413c943dfd9715fe') or name (e.g. 'Office') of the Spotify Connect Player device this command is targeting. If an '*' is specified, then the SpotifyPlus default device is used. eg: Bose-ST10-1</param> - ///<param name="verifyUserContext">DEPRECATED - no longer used, but left here to maintain compatibility.</param> - ///<param name="verifyTimeout">Maximum time to wait (in seconds) for the device to become active in the Spotify Connect device list. This value is only used if a Connect command has to be issued to activate the device. Default is 5; value range is 0 - 10. eg: 0.50</param> - ///<param name="refreshDeviceList">DEPRECATED - no longer used, but left here to maintain compatibility.</param> - ///<param name="activateDevice">True to activate the device if necessary; otherwise, False. eg: True</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing any command to the device. This delay will give the spotify zeroconf api time to process the change before another command is issued. Default is 0.25; value range is 0 - 10. eg: 0.25</param> - public void GetSpotifyConnectDevice(string entityId, string deviceValue, bool? verifyUserContext = null, double? verifyTimeout = null, bool? refreshDeviceList = null, bool? activateDevice = null, double? delay = null) - { - _haContext.CallService("spotifyplus", "get_spotify_connect_device", null, new SpotifyplusGetSpotifyConnectDeviceParameters { EntityId = entityId, DeviceValue = deviceValue, VerifyUserContext = verifyUserContext, VerifyTimeout = verifyTimeout, RefreshDeviceList = refreshDeviceList, ActivateDevice = activateDevice, Delay = delay }); - } - - ///<summary>Get information about a specific Spotify Connect player device, and (optionally) activate the device if it requires it.</summary> - public Task<JsonElement?> GetSpotifyConnectDeviceAsync(SpotifyplusGetSpotifyConnectDeviceParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_spotify_connect_device", null, data); - } - - ///<summary>Get information about a specific Spotify Connect player device, and (optionally) activate the device if it requires it.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="deviceValue">The id (e.g. '30fbc80e35598f3c242f2120413c943dfd9715fe') or name (e.g. 'Office') of the Spotify Connect Player device this command is targeting. If an '*' is specified, then the SpotifyPlus default device is used. eg: Bose-ST10-1</param> - ///<param name="verifyUserContext">DEPRECATED - no longer used, but left here to maintain compatibility.</param> - ///<param name="verifyTimeout">Maximum time to wait (in seconds) for the device to become active in the Spotify Connect device list. This value is only used if a Connect command has to be issued to activate the device. Default is 5; value range is 0 - 10. eg: 0.50</param> - ///<param name="refreshDeviceList">DEPRECATED - no longer used, but left here to maintain compatibility.</param> - ///<param name="activateDevice">True to activate the device if necessary; otherwise, False. eg: True</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing any command to the device. This delay will give the spotify zeroconf api time to process the change before another command is issued. Default is 0.25; value range is 0 - 10. eg: 0.25</param> - public Task<JsonElement?> GetSpotifyConnectDeviceAsync(string entityId, string deviceValue, bool? verifyUserContext = null, double? verifyTimeout = null, bool? refreshDeviceList = null, bool? activateDevice = null, double? delay = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_spotify_connect_device", null, new SpotifyplusGetSpotifyConnectDeviceParameters { EntityId = entityId, DeviceValue = deviceValue, VerifyUserContext = verifyUserContext, VerifyTimeout = verifyTimeout, RefreshDeviceList = refreshDeviceList, ActivateDevice = activateDevice, Delay = delay }); - } - - ///<summary>Get information about all available Spotify Connect player (both static and dynamic) devices.</summary> - public void GetSpotifyConnectDevices(SpotifyplusGetSpotifyConnectDevicesParameters data) - { - _haContext.CallService("spotifyplus", "get_spotify_connect_devices", null, data); - } - - ///<summary>Get information about all available Spotify Connect player (both static and dynamic) devices.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="refresh">True (default) to return real-time information from the spotify zeroconf api and update the cache; otherwise, False to just return the cached value. eg: True</param> - ///<param name="sortResult">DEPRECATED - no longer used, but left here to maintain compatibility.</param> - public void GetSpotifyConnectDevices(string entityId, bool? refresh = null, bool? sortResult = null) - { - _haContext.CallService("spotifyplus", "get_spotify_connect_devices", null, new SpotifyplusGetSpotifyConnectDevicesParameters { EntityId = entityId, Refresh = refresh, SortResult = sortResult }); - } - - ///<summary>Get information about all available Spotify Connect player (both static and dynamic) devices.</summary> - public Task<JsonElement?> GetSpotifyConnectDevicesAsync(SpotifyplusGetSpotifyConnectDevicesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_spotify_connect_devices", null, data); - } - - ///<summary>Get information about all available Spotify Connect player (both static and dynamic) devices.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="refresh">True (default) to return real-time information from the spotify zeroconf api and update the cache; otherwise, False to just return the cached value. eg: True</param> - ///<param name="sortResult">DEPRECATED - no longer used, but left here to maintain compatibility.</param> - public Task<JsonElement?> GetSpotifyConnectDevicesAsync(string entityId, bool? refresh = null, bool? sortResult = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_spotify_connect_devices", null, new SpotifyplusGetSpotifyConnectDevicesParameters { EntityId = entityId, Refresh = refresh, SortResult = sortResult }); - } - - ///<summary>Get Spotify catalog information for a single track.</summary> - public void GetTrack(SpotifyplusGetTrackParameters data) - { - _haContext.CallService("spotifyplus", "get_track", null, data); - } - - ///<summary>Get Spotify catalog information for a single track.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="trackId">The Spotify ID of the track. If omitted, the currently playing track uri id value is used. eg: 1kWUud3vY5ij5r62zxpTRy</param> - public void GetTrack(string entityId, string? trackId = null) - { - _haContext.CallService("spotifyplus", "get_track", null, new SpotifyplusGetTrackParameters { EntityId = entityId, TrackId = trackId }); - } - - ///<summary>Get Spotify catalog information for a single track.</summary> - public Task<JsonElement?> GetTrackAsync(SpotifyplusGetTrackParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_track", null, data); - } - - ///<summary>Get Spotify catalog information for a single track.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="trackId">The Spotify ID of the track. If omitted, the currently playing track uri id value is used. eg: 1kWUud3vY5ij5r62zxpTRy</param> - public Task<JsonElement?> GetTrackAsync(string entityId, string? trackId = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_track", null, new SpotifyplusGetTrackParameters { EntityId = entityId, TrackId = trackId }); - } - - ///<summary>Get audio feature information for a single track identified by its unique Spotify ID.</summary> - public void GetTrackAudioFeatures(SpotifyplusGetTrackAudioFeaturesParameters data) - { - _haContext.CallService("spotifyplus", "get_track_audio_features", null, data); - } - - ///<summary>Get audio feature information for a single track identified by its unique Spotify ID.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="trackId">The Spotify ID of the track. Example = `1kWUud3vY5ij5r62zxpTRy`. If null, the currently playing track uri id value is used. eg: 7ouMYWpwJ422jRcDASZB7P</param> - public void GetTrackAudioFeatures(string entityId, string? trackId = null) - { - _haContext.CallService("spotifyplus", "get_track_audio_features", null, new SpotifyplusGetTrackAudioFeaturesParameters { EntityId = entityId, TrackId = trackId }); - } - - ///<summary>Get audio feature information for a single track identified by its unique Spotify ID.</summary> - public Task<JsonElement?> GetTrackAudioFeaturesAsync(SpotifyplusGetTrackAudioFeaturesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_track_audio_features", null, data); - } - - ///<summary>Get audio feature information for a single track identified by its unique Spotify ID.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="trackId">The Spotify ID of the track. Example = `1kWUud3vY5ij5r62zxpTRy`. If null, the currently playing track uri id value is used. eg: 7ouMYWpwJ422jRcDASZB7P</param> - public Task<JsonElement?> GetTrackAudioFeaturesAsync(string entityId, string? trackId = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_track_audio_features", null, new SpotifyplusGetTrackAudioFeaturesParameters { EntityId = entityId, TrackId = trackId }); - } - - ///<summary>Get a list of the tracks saved in the current Spotify user's 'Your Library'.</summary> - public void GetTrackFavorites(SpotifyplusGetTrackFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "get_track_favorites", null, data); - } - - ///<summary>Get a list of the tracks saved in the current Spotify user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public void GetTrackFavorites(string entityId, double? limit = null, double? offset = null, string? market = null, double? limitTotal = null, bool? sortResult = null) - { - _haContext.CallService("spotifyplus", "get_track_favorites", null, new SpotifyplusGetTrackFavoritesParameters { EntityId = entityId, Limit = limit, Offset = offset, Market = market, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get a list of the tracks saved in the current Spotify user's 'Your Library'.</summary> - public Task<JsonElement?> GetTrackFavoritesAsync(SpotifyplusGetTrackFavoritesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_track_favorites", null, data); - } - - ///<summary>Get a list of the tracks saved in the current Spotify user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public Task<JsonElement?> GetTrackFavoritesAsync(string entityId, double? limit = null, double? offset = null, string? market = null, double? limitTotal = null, bool? sortResult = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_track_favorites", null, new SpotifyplusGetTrackFavoritesParameters { EntityId = entityId, Limit = limit, Offset = offset, Market = market, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get track recommendations for specified criteria.</summary> - public void GetTrackRecommendations(SpotifyplusGetTrackRecommendationsParameters data) - { - _haContext.CallService("spotifyplus", "get_track_recommendations", null, data); - } - - ///<summary>Get track recommendations for specified criteria.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="seedArtists">A comma separated list of Spotify IDs for seed artists (e.g. 4NHQUGzhtTLFvgF5SZesLK). Up to 5 seed values may be provided in any combination of seedArtists, seedTracks and seedGenres; only required if seedGenres and seedTracks are not set.</param> - ///<param name="seedGenres">A comma separated list of any genres in the set of available genre seeds (e.g. classical,country). Up to 5 seed values may be provided in any combination of seedArtists, seedTracks and seedGenres; only required if seedArtists and seedTracks are not set. eg: rock,hard-rock,rock-n-roll</param> - ///<param name="seedTracks">A comma separated list of Spotify IDs for a seed track (e.g. 0c6xIDDpzE81m2q797ordA). Up to 5 seed values may be provided in any combination of seedArtists, seedTracks and seedGenres; only required if seedArtists and seedGenres are not set.</param> - ///<param name="minAcousticness">Restrict results to only those tracks whose acousticness level is greater than the specified value. Range is `0` - `1`.</param> - ///<param name="maxAcousticness">Restrict results to only those tracks whose acousticness level is less than the specified value. Range is `0` - `1`.</param> - ///<param name="targetAcousticness">Restrict results to only those tracks whose acousticness level is equal to the specified value. Range is `0` - `1`.</param> - ///<param name="minDanceability">Restrict results to only those tracks whose danceability level is greater than the specified value. Range is `0` - `1`.</param> - ///<param name="maxDanceability">Restrict results to only those tracks whose danceability level is less than the specified value. Range is `0` - `1`.</param> - ///<param name="targetDanceability">Restrict results to only those tracks whose acousticness is equal to the specified value. Range is `0` - `1`.</param> - ///<param name="minDurationMs">Restrict results to only those tracks whose duration is greater than the specified value in milliseconds.</param> - ///<param name="maxDurationMs">Restrict results to only those tracks whose duration is less than the specified value in milliseconds.</param> - ///<param name="targetDurationMs">Restrict results to only those tracks whose duration is equal to the specified value in milliseconds.</param> - ///<param name="minEnergy">Restrict results to only those tracks whose energy level is greater than the specified value. Range is `0` - `1`. eg: 0.975</param> - ///<param name="maxEnergy">Restrict results to only those tracks whose energy level is less than the specified value. Range is `0` - `1`.</param> - ///<param name="targetEnergy">Restrict results to only those tracks whose energy level is equal to the specified value. Range is `0` - `1`.</param> - ///<param name="minInstrumentalness">Restrict results to only those tracks whose instrumentalness level is greater than the specified value. Range is `0` - `1`.</param> - ///<param name="maxInstrumentalness">Restrict results to only those tracks whose instrumentalness level is less than the specified value. Range is `0` - `1`.</param> - ///<param name="targetInstrumentalness">Restrict results to only those tracks whose instrumentalness level is equal to the specified value. Range is `0` - `1`.</param> - ///<param name="minKey">Restrict results to only those tracks whose key level is greater than the specified value. Range is `0` - `11`.</param> - ///<param name="maxKey">Restrict results to only those tracks whose key level is less than the specified value. Range is `0` - `11`.</param> - ///<param name="targetKey">Restrict results to only those tracks whose key level is equal to the specified value. Range is `0` - `11`.</param> - ///<param name="minLiveness">Restrict results to only those tracks whose liveness level is greater than the specified value. Range is `0` - `1`.</param> - ///<param name="maxLiveness">Restrict results to only those tracks whose liveness level is less than the specified value. Range is `0` - `1`.</param> - ///<param name="targetLiveness">Restrict results to only those tracks whose liveness level is equal to the specified value. Range is `0` - `1`.</param> - ///<param name="minLoudness">Restrict results to only those tracks whose loudness level is greater than the specified value. eg: -9.201</param> - ///<param name="maxLoudness">Restrict results to only those tracks whose loudness level is less than the specified value.</param> - ///<param name="targetLoudness">Restrict results to only those tracks whose loudness level is equal to the specified value.</param> - ///<param name="minMode">Restrict results to only those tracks whose mode level is greater than the specified value. Range is `0` - `1`.</param> - ///<param name="maxMode">Restrict results to only those tracks whose mode level is less than the specified value. Range is `0` - `1`.</param> - ///<param name="targetMode">Restrict results to only those tracks whose mode level is equal to the specified value. Range is `0` - `1`.</param> - ///<param name="minPopularity">Restrict results to only those tracks whose popularity level is greater than the specified value. Range is `0` - `100`.</param> - ///<param name="maxPopularity">Restrict results to only those tracks whose popularity level is less than the specified value. Range is `0` - `100`.</param> - ///<param name="targetPopularity">Restrict results to only those tracks whose popularity level is equal to the specified value. Range is `0` - `100`.</param> - ///<param name="minSpeechiness">Restrict results to only those tracks whose speechiness level is greater than the specified value. Range is `0` - `1`.</param> - ///<param name="maxSpeechiness">Restrict results to only those tracks whose speechiness level is less than the specified value. Range is `0` - `1`.</param> - ///<param name="targetSpeechiness">Restrict results to only those tracks whose speechiness level is equal to the specified value. Range is `0` - `1`.</param> - ///<param name="minTempo">Restrict results to only those tracks with a tempo greater than the specified number of beats per minute.</param> - ///<param name="maxTempo">Restrict results to only those tracks with a tempo less than the specified number of beats per minute.</param> - ///<param name="targetTempo">Restrict results to only those tracks with a tempo equal to the specified number of beats per minute.</param> - ///<param name="minTimeSignature">Restrict results to only those tracks whose time signature is greater than the specified value. Range is `0` - `11`. eg: 4</param> - ///<param name="maxTimeSignature">Restrict results to only those tracks whose time signature is less than the specified value. Range is `0` - `11`.</param> - ///<param name="targetTimeSignature">Restrict results to only those tracks whose time signature is equal to the specified value. Range is `0` - `11`.</param> - ///<param name="minValence">Restrict results to only those tracks whose valence level is greater than the specified value. Range is `0` - `1`.</param> - ///<param name="maxValence">Restrict results to only those tracks whose valence level is less than the specified value. Range is `0` - `1`.</param> - ///<param name="targetValence">Restrict results to only those tracks whose valence level is equal to the specified value. Range is `0` - `1`.</param> - public void GetTrackRecommendations(string entityId, double? limit = null, string? market = null, string? seedArtists = null, string? seedGenres = null, string? seedTracks = null, double? minAcousticness = null, double? maxAcousticness = null, double? targetAcousticness = null, double? minDanceability = null, double? maxDanceability = null, double? targetDanceability = null, double? minDurationMs = null, double? maxDurationMs = null, double? targetDurationMs = null, double? minEnergy = null, double? maxEnergy = null, double? targetEnergy = null, double? minInstrumentalness = null, double? maxInstrumentalness = null, double? targetInstrumentalness = null, double? minKey = null, double? maxKey = null, double? targetKey = null, double? minLiveness = null, double? maxLiveness = null, double? targetLiveness = null, double? minLoudness = null, double? maxLoudness = null, double? targetLoudness = null, double? minMode = null, double? maxMode = null, double? targetMode = null, double? minPopularity = null, double? maxPopularity = null, double? targetPopularity = null, double? minSpeechiness = null, double? maxSpeechiness = null, double? targetSpeechiness = null, double? minTempo = null, double? maxTempo = null, double? targetTempo = null, double? minTimeSignature = null, double? maxTimeSignature = null, double? targetTimeSignature = null, double? minValence = null, double? maxValence = null, double? targetValence = null) - { - _haContext.CallService("spotifyplus", "get_track_recommendations", null, new SpotifyplusGetTrackRecommendationsParameters { EntityId = entityId, Limit = limit, Market = market, SeedArtists = seedArtists, SeedGenres = seedGenres, SeedTracks = seedTracks, MinAcousticness = minAcousticness, MaxAcousticness = maxAcousticness, TargetAcousticness = targetAcousticness, MinDanceability = minDanceability, MaxDanceability = maxDanceability, TargetDanceability = targetDanceability, MinDurationMs = minDurationMs, MaxDurationMs = maxDurationMs, TargetDurationMs = targetDurationMs, MinEnergy = minEnergy, MaxEnergy = maxEnergy, TargetEnergy = targetEnergy, MinInstrumentalness = minInstrumentalness, MaxInstrumentalness = maxInstrumentalness, TargetInstrumentalness = targetInstrumentalness, MinKey = minKey, MaxKey = maxKey, TargetKey = targetKey, MinLiveness = minLiveness, MaxLiveness = maxLiveness, TargetLiveness = targetLiveness, MinLoudness = minLoudness, MaxLoudness = maxLoudness, TargetLoudness = targetLoudness, MinMode = minMode, MaxMode = maxMode, TargetMode = targetMode, MinPopularity = minPopularity, MaxPopularity = maxPopularity, TargetPopularity = targetPopularity, MinSpeechiness = minSpeechiness, MaxSpeechiness = maxSpeechiness, TargetSpeechiness = targetSpeechiness, MinTempo = minTempo, MaxTempo = maxTempo, TargetTempo = targetTempo, MinTimeSignature = minTimeSignature, MaxTimeSignature = maxTimeSignature, TargetTimeSignature = targetTimeSignature, MinValence = minValence, MaxValence = maxValence, TargetValence = targetValence }); - } - - ///<summary>Get track recommendations for specified criteria.</summary> - public Task<JsonElement?> GetTrackRecommendationsAsync(SpotifyplusGetTrackRecommendationsParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_track_recommendations", null, data); - } - - ///<summary>Get track recommendations for specified criteria.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</param> - ///<param name="seedArtists">A comma separated list of Spotify IDs for seed artists (e.g. 4NHQUGzhtTLFvgF5SZesLK). Up to 5 seed values may be provided in any combination of seedArtists, seedTracks and seedGenres; only required if seedGenres and seedTracks are not set.</param> - ///<param name="seedGenres">A comma separated list of any genres in the set of available genre seeds (e.g. classical,country). Up to 5 seed values may be provided in any combination of seedArtists, seedTracks and seedGenres; only required if seedArtists and seedTracks are not set. eg: rock,hard-rock,rock-n-roll</param> - ///<param name="seedTracks">A comma separated list of Spotify IDs for a seed track (e.g. 0c6xIDDpzE81m2q797ordA). Up to 5 seed values may be provided in any combination of seedArtists, seedTracks and seedGenres; only required if seedArtists and seedGenres are not set.</param> - ///<param name="minAcousticness">Restrict results to only those tracks whose acousticness level is greater than the specified value. Range is `0` - `1`.</param> - ///<param name="maxAcousticness">Restrict results to only those tracks whose acousticness level is less than the specified value. Range is `0` - `1`.</param> - ///<param name="targetAcousticness">Restrict results to only those tracks whose acousticness level is equal to the specified value. Range is `0` - `1`.</param> - ///<param name="minDanceability">Restrict results to only those tracks whose danceability level is greater than the specified value. Range is `0` - `1`.</param> - ///<param name="maxDanceability">Restrict results to only those tracks whose danceability level is less than the specified value. Range is `0` - `1`.</param> - ///<param name="targetDanceability">Restrict results to only those tracks whose acousticness is equal to the specified value. Range is `0` - `1`.</param> - ///<param name="minDurationMs">Restrict results to only those tracks whose duration is greater than the specified value in milliseconds.</param> - ///<param name="maxDurationMs">Restrict results to only those tracks whose duration is less than the specified value in milliseconds.</param> - ///<param name="targetDurationMs">Restrict results to only those tracks whose duration is equal to the specified value in milliseconds.</param> - ///<param name="minEnergy">Restrict results to only those tracks whose energy level is greater than the specified value. Range is `0` - `1`. eg: 0.975</param> - ///<param name="maxEnergy">Restrict results to only those tracks whose energy level is less than the specified value. Range is `0` - `1`.</param> - ///<param name="targetEnergy">Restrict results to only those tracks whose energy level is equal to the specified value. Range is `0` - `1`.</param> - ///<param name="minInstrumentalness">Restrict results to only those tracks whose instrumentalness level is greater than the specified value. Range is `0` - `1`.</param> - ///<param name="maxInstrumentalness">Restrict results to only those tracks whose instrumentalness level is less than the specified value. Range is `0` - `1`.</param> - ///<param name="targetInstrumentalness">Restrict results to only those tracks whose instrumentalness level is equal to the specified value. Range is `0` - `1`.</param> - ///<param name="minKey">Restrict results to only those tracks whose key level is greater than the specified value. Range is `0` - `11`.</param> - ///<param name="maxKey">Restrict results to only those tracks whose key level is less than the specified value. Range is `0` - `11`.</param> - ///<param name="targetKey">Restrict results to only those tracks whose key level is equal to the specified value. Range is `0` - `11`.</param> - ///<param name="minLiveness">Restrict results to only those tracks whose liveness level is greater than the specified value. Range is `0` - `1`.</param> - ///<param name="maxLiveness">Restrict results to only those tracks whose liveness level is less than the specified value. Range is `0` - `1`.</param> - ///<param name="targetLiveness">Restrict results to only those tracks whose liveness level is equal to the specified value. Range is `0` - `1`.</param> - ///<param name="minLoudness">Restrict results to only those tracks whose loudness level is greater than the specified value. eg: -9.201</param> - ///<param name="maxLoudness">Restrict results to only those tracks whose loudness level is less than the specified value.</param> - ///<param name="targetLoudness">Restrict results to only those tracks whose loudness level is equal to the specified value.</param> - ///<param name="minMode">Restrict results to only those tracks whose mode level is greater than the specified value. Range is `0` - `1`.</param> - ///<param name="maxMode">Restrict results to only those tracks whose mode level is less than the specified value. Range is `0` - `1`.</param> - ///<param name="targetMode">Restrict results to only those tracks whose mode level is equal to the specified value. Range is `0` - `1`.</param> - ///<param name="minPopularity">Restrict results to only those tracks whose popularity level is greater than the specified value. Range is `0` - `100`.</param> - ///<param name="maxPopularity">Restrict results to only those tracks whose popularity level is less than the specified value. Range is `0` - `100`.</param> - ///<param name="targetPopularity">Restrict results to only those tracks whose popularity level is equal to the specified value. Range is `0` - `100`.</param> - ///<param name="minSpeechiness">Restrict results to only those tracks whose speechiness level is greater than the specified value. Range is `0` - `1`.</param> - ///<param name="maxSpeechiness">Restrict results to only those tracks whose speechiness level is less than the specified value. Range is `0` - `1`.</param> - ///<param name="targetSpeechiness">Restrict results to only those tracks whose speechiness level is equal to the specified value. Range is `0` - `1`.</param> - ///<param name="minTempo">Restrict results to only those tracks with a tempo greater than the specified number of beats per minute.</param> - ///<param name="maxTempo">Restrict results to only those tracks with a tempo less than the specified number of beats per minute.</param> - ///<param name="targetTempo">Restrict results to only those tracks with a tempo equal to the specified number of beats per minute.</param> - ///<param name="minTimeSignature">Restrict results to only those tracks whose time signature is greater than the specified value. Range is `0` - `11`. eg: 4</param> - ///<param name="maxTimeSignature">Restrict results to only those tracks whose time signature is less than the specified value. Range is `0` - `11`.</param> - ///<param name="targetTimeSignature">Restrict results to only those tracks whose time signature is equal to the specified value. Range is `0` - `11`.</param> - ///<param name="minValence">Restrict results to only those tracks whose valence level is greater than the specified value. Range is `0` - `1`.</param> - ///<param name="maxValence">Restrict results to only those tracks whose valence level is less than the specified value. Range is `0` - `1`.</param> - ///<param name="targetValence">Restrict results to only those tracks whose valence level is equal to the specified value. Range is `0` - `1`.</param> - public Task<JsonElement?> GetTrackRecommendationsAsync(string entityId, double? limit = null, string? market = null, string? seedArtists = null, string? seedGenres = null, string? seedTracks = null, double? minAcousticness = null, double? maxAcousticness = null, double? targetAcousticness = null, double? minDanceability = null, double? maxDanceability = null, double? targetDanceability = null, double? minDurationMs = null, double? maxDurationMs = null, double? targetDurationMs = null, double? minEnergy = null, double? maxEnergy = null, double? targetEnergy = null, double? minInstrumentalness = null, double? maxInstrumentalness = null, double? targetInstrumentalness = null, double? minKey = null, double? maxKey = null, double? targetKey = null, double? minLiveness = null, double? maxLiveness = null, double? targetLiveness = null, double? minLoudness = null, double? maxLoudness = null, double? targetLoudness = null, double? minMode = null, double? maxMode = null, double? targetMode = null, double? minPopularity = null, double? maxPopularity = null, double? targetPopularity = null, double? minSpeechiness = null, double? maxSpeechiness = null, double? targetSpeechiness = null, double? minTempo = null, double? maxTempo = null, double? targetTempo = null, double? minTimeSignature = null, double? maxTimeSignature = null, double? targetTimeSignature = null, double? minValence = null, double? maxValence = null, double? targetValence = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_track_recommendations", null, new SpotifyplusGetTrackRecommendationsParameters { EntityId = entityId, Limit = limit, Market = market, SeedArtists = seedArtists, SeedGenres = seedGenres, SeedTracks = seedTracks, MinAcousticness = minAcousticness, MaxAcousticness = maxAcousticness, TargetAcousticness = targetAcousticness, MinDanceability = minDanceability, MaxDanceability = maxDanceability, TargetDanceability = targetDanceability, MinDurationMs = minDurationMs, MaxDurationMs = maxDurationMs, TargetDurationMs = targetDurationMs, MinEnergy = minEnergy, MaxEnergy = maxEnergy, TargetEnergy = targetEnergy, MinInstrumentalness = minInstrumentalness, MaxInstrumentalness = maxInstrumentalness, TargetInstrumentalness = targetInstrumentalness, MinKey = minKey, MaxKey = maxKey, TargetKey = targetKey, MinLiveness = minLiveness, MaxLiveness = maxLiveness, TargetLiveness = targetLiveness, MinLoudness = minLoudness, MaxLoudness = maxLoudness, TargetLoudness = targetLoudness, MinMode = minMode, MaxMode = maxMode, TargetMode = targetMode, MinPopularity = minPopularity, MaxPopularity = maxPopularity, TargetPopularity = targetPopularity, MinSpeechiness = minSpeechiness, MaxSpeechiness = maxSpeechiness, TargetSpeechiness = targetSpeechiness, MinTempo = minTempo, MaxTempo = maxTempo, TargetTempo = targetTempo, MinTimeSignature = minTimeSignature, MaxTimeSignature = maxTimeSignature, TargetTimeSignature = targetTimeSignature, MinValence = minValence, MaxValence = maxValence, TargetValence = targetValence }); - } - - ///<summary>Get audio features for multiple tracks based on their Spotify IDs.</summary> - public void GetTracksAudioFeatures(SpotifyplusGetTracksAudioFeaturesParameters data) - { - _haContext.CallService("spotifyplus", "get_tracks_audio_features", null, data); - } - - ///<summary>Get audio features for multiple tracks based on their Spotify IDs.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of the Spotify track IDs. Maximum of 100 IDs. Example `7ouMYWpwJ422jRcDASZB7P,4VqPOruhp5EdPBeR92t6lQ,2takcwOaAZWiXQijPHIx7B`. eg: 7ouMYWpwJ422jRcDASZB7P,4VqPOruhp5EdPBeR92t6lQ,2takcwOaAZWiXQijPHIx7B</param> - public void GetTracksAudioFeatures(string entityId, string ids) - { - _haContext.CallService("spotifyplus", "get_tracks_audio_features", null, new SpotifyplusGetTracksAudioFeaturesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Get audio features for multiple tracks based on their Spotify IDs.</summary> - public Task<JsonElement?> GetTracksAudioFeaturesAsync(SpotifyplusGetTracksAudioFeaturesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_tracks_audio_features", null, data); - } - - ///<summary>Get audio features for multiple tracks based on their Spotify IDs.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of the Spotify track IDs. Maximum of 100 IDs. Example `7ouMYWpwJ422jRcDASZB7P,4VqPOruhp5EdPBeR92t6lQ,2takcwOaAZWiXQijPHIx7B`. eg: 7ouMYWpwJ422jRcDASZB7P,4VqPOruhp5EdPBeR92t6lQ,2takcwOaAZWiXQijPHIx7B</param> - public Task<JsonElement?> GetTracksAudioFeaturesAsync(string entityId, string ids) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_tracks_audio_features", null, new SpotifyplusGetTracksAudioFeaturesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Get the current user's top artists based on calculated affinity.</summary> - public void GetUsersTopArtists(SpotifyplusGetUsersTopArtistsParameters data) - { - _haContext.CallService("spotifyplus", "get_users_top_artists", null, data); - } - - ///<summary>Get the current user's top artists based on calculated affinity.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="timeRange">Over what time frame the affinities are computed. Valid values are `long_term` (calculated from several years of data and including all new data as it becomes available), `medium_term` (approximately last 6 months), and `short_term` (approximately last 4 weeks). eg: long_term</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public void GetUsersTopArtists(string entityId, string? timeRange = null, double? limit = null, double? offset = null, double? limitTotal = null, bool? sortResult = null) - { - _haContext.CallService("spotifyplus", "get_users_top_artists", null, new SpotifyplusGetUsersTopArtistsParameters { EntityId = entityId, TimeRange = timeRange, Limit = limit, Offset = offset, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get the current user's top artists based on calculated affinity.</summary> - public Task<JsonElement?> GetUsersTopArtistsAsync(SpotifyplusGetUsersTopArtistsParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_users_top_artists", null, data); - } - - ///<summary>Get the current user's top artists based on calculated affinity.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="timeRange">Over what time frame the affinities are computed. Valid values are `long_term` (calculated from several years of data and including all new data as it becomes available), `medium_term` (approximately last 6 months), and `short_term` (approximately last 4 weeks). eg: long_term</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public Task<JsonElement?> GetUsersTopArtistsAsync(string entityId, string? timeRange = null, double? limit = null, double? offset = null, double? limitTotal = null, bool? sortResult = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_users_top_artists", null, new SpotifyplusGetUsersTopArtistsParameters { EntityId = entityId, TimeRange = timeRange, Limit = limit, Offset = offset, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get the current user's top tracks based on calculated affinity.</summary> - public void GetUsersTopTracks(SpotifyplusGetUsersTopTracksParameters data) - { - _haContext.CallService("spotifyplus", "get_users_top_tracks", null, data); - } - - ///<summary>Get the current user's top tracks based on calculated affinity.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="timeRange">Over what time frame the affinities are computed. Valid values are `long_term` (calculated from several years of data and including all new data as it becomes available), `medium_term` (approximately last 6 months), and `short_term` (approximately last 4 weeks). eg: long_term</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public void GetUsersTopTracks(string entityId, string? timeRange = null, double? limit = null, double? offset = null, double? limitTotal = null, bool? sortResult = null) - { - _haContext.CallService("spotifyplus", "get_users_top_tracks", null, new SpotifyplusGetUsersTopTracksParameters { EntityId = entityId, TimeRange = timeRange, Limit = limit, Offset = offset, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Get the current user's top tracks based on calculated affinity.</summary> - public Task<JsonElement?> GetUsersTopTracksAsync(SpotifyplusGetUsersTopTracksParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_users_top_tracks", null, data); - } - - ///<summary>Get the current user's top tracks based on calculated affinity.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="timeRange">Over what time frame the affinities are computed. Valid values are `long_term` (calculated from several years of data and including all new data as it becomes available), `medium_term` (approximately last 6 months), and `short_term` (approximately last 4 weeks). eg: long_term</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - ///<param name="sortResult">True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</param> - public Task<JsonElement?> GetUsersTopTracksAsync(string entityId, string? timeRange = null, double? limit = null, double? offset = null, double? limitTotal = null, bool? sortResult = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "get_users_top_tracks", null, new SpotifyplusGetUsersTopTracksParameters { EntityId = entityId, TimeRange = timeRange, Limit = limit, Offset = offset, LimitTotal = limitTotal, SortResult = sortResult }); - } - - ///<summary>Pause media play for the specified Spotify Connect device.</summary> - public void PlayerMediaPause(SpotifyplusPlayerMediaPauseParameters data) - { - _haContext.CallService("spotifyplus", "player_media_pause", null, data); - } - - ///<summary>Pause media play for the specified Spotify Connect device.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="deviceId">The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing the final Connect command (if necessary). This delay will give the spotify web api time to process the device list change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</param> - public void PlayerMediaPause(string entityId, string? deviceId = null, double? delay = null) - { - _haContext.CallService("spotifyplus", "player_media_pause", null, new SpotifyplusPlayerMediaPauseParameters { EntityId = entityId, DeviceId = deviceId, Delay = delay }); - } - - ///<summary>Start playing one or more tracks of the specified context on a Spotify Connect device.</summary> - public void PlayerMediaPlayContext(SpotifyplusPlayerMediaPlayContextParameters data) - { - _haContext.CallService("spotifyplus", "player_media_play_context", null, data); - } - - ///<summary>Start playing one or more tracks of the specified context on a Spotify Connect device.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="contextUri">Spotify URI of the context to play (e.g. `spotify:album:6vc9OTcyd3hyzabCmsdnwE`). Valid contexts are albums, artists & playlists. eg: spotify:album:6vc9OTcyd3hyzabCmsdnwE</param> - ///<param name="offsetUri">Indicates from what Uri in the context playback should start (e.g. `1kWUud3vY5ij5r62zxpTRy`. Only available when contextUri corresponds to an artist, album or playlist. The offsetPosition argument will be used if this value is null. eg: spotify:track:1kWUud3vY5ij5r62zxpTRy</param> - ///<param name="offsetPosition">Indicates from what position in the context playback should start. The value is zero-based, and can't be negative. Only available when contextUri corresponds to an album or playlist. eg: 3</param> - ///<param name="positionMs">The position (in milliseconds) to seek to; must be a positive number. Passing in a position that is greater than the length of the track will cause the player to start playing the next track. eg: 0</param> - ///<param name="deviceId">The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing the final Connect command (if necessary). This delay will give the spotify web api time to process the device list change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</param> - public void PlayerMediaPlayContext(string entityId, string contextUri, string? offsetUri = null, double? offsetPosition = null, double? positionMs = null, string? deviceId = null, double? delay = null) - { - _haContext.CallService("spotifyplus", "player_media_play_context", null, new SpotifyplusPlayerMediaPlayContextParameters { EntityId = entityId, ContextUri = contextUri, OffsetUri = offsetUri, OffsetPosition = offsetPosition, PositionMs = positionMs, DeviceId = deviceId, Delay = delay }); - } - - ///<summary>Start playing track favorites on the specified Spotify Connect device.</summary> - public void PlayerMediaPlayTrackFavorites(SpotifyplusPlayerMediaPlayTrackFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "player_media_play_track_favorites", null, data); - } - - ///<summary>Start playing track favorites on the specified Spotify Connect device.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="deviceId">The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</param> - ///<param name="shuffle">True to set player shuffle mode to on; otherwise, False for no shuffle. eg: True</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing the command to the player. This delay will give the spotify web api time to process the change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</param> - ///<param name="resolveDeviceId">DEPRECATED - no longer used, but left here to maintain compatibility.</param> - ///<param name="limitTotal">The maximum number of items to retrieve from favorites. Default is 200; Range is 1 - 750. eg: 200</param> - public void PlayerMediaPlayTrackFavorites(string entityId, string? deviceId = null, bool? shuffle = null, double? delay = null, bool? resolveDeviceId = null, double? limitTotal = null) - { - _haContext.CallService("spotifyplus", "player_media_play_track_favorites", null, new SpotifyplusPlayerMediaPlayTrackFavoritesParameters { EntityId = entityId, DeviceId = deviceId, Shuffle = shuffle, Delay = delay, ResolveDeviceId = resolveDeviceId, LimitTotal = limitTotal }); - } - - ///<summary>Start playing one or more tracks on the specified Spotify Connect device.</summary> - public void PlayerMediaPlayTracks(SpotifyplusPlayerMediaPlayTracksParameters data) - { - _haContext.CallService("spotifyplus", "player_media_play_tracks", null, data); - } - - ///<summary>Start playing one or more tracks on the specified Spotify Connect device.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="uris">A list of Spotify track URIs to play; can be track or episode URIs. A maximum of 50 items can be added in one request. eg: spotify:track:6zd8T1PBe9JFHmuVnurdRp,spotify:track:1kWUud3vY5ij5r62zxpTRy</param> - ///<param name="positionMs">The position (in milliseconds) to seek to; must be a positive number. Passing in a position that is greater than the length of the track will cause the player to start playing the next track. eg: 0</param> - ///<param name="deviceId">The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing the final Connect command (if necessary). This delay will give the spotify web api time to process the device list change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</param> - public void PlayerMediaPlayTracks(string entityId, string uris, double? positionMs = null, string? deviceId = null, double? delay = null) - { - _haContext.CallService("spotifyplus", "player_media_play_tracks", null, new SpotifyplusPlayerMediaPlayTracksParameters { EntityId = entityId, Uris = uris, PositionMs = positionMs, DeviceId = deviceId, Delay = delay }); - } - - ///<summary>Resume media play for the specified Spotify Connect device.</summary> - public void PlayerMediaResume(SpotifyplusPlayerMediaResumeParameters data) - { - _haContext.CallService("spotifyplus", "player_media_resume", null, data); - } - - ///<summary>Resume media play for the specified Spotify Connect device.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="deviceId">The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing the final Connect command (if necessary). This delay will give the spotify web api time to process the device list change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</param> - public void PlayerMediaResume(string entityId, string? deviceId = null, double? delay = null) - { - _haContext.CallService("spotifyplus", "player_media_resume", null, new SpotifyplusPlayerMediaResumeParameters { EntityId = entityId, DeviceId = deviceId, Delay = delay }); - } - - ///<summary>Seeks to the given absolute or relative position in the user's currently playing track for the specified Spotify Connect device.</summary> - public void PlayerMediaSeek(SpotifyplusPlayerMediaSeekParameters data) - { - _haContext.CallService("spotifyplus", "player_media_seek", null, data); - } - - ///<summary>Seeks to the given absolute or relative position in the user's currently playing track for the specified Spotify Connect device.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="positionMs">The absolute position in milliseconds to seek to; must be a positive number or zero if the `relativePositionMS` argument is specified. Passing in a position that is greater than the length of the track will cause the player to start playing the next song. Example = `25000` to start playing at the 25 second mark. eg: 25000</param> - ///<param name="deviceId">The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing the final Connect command (if necessary). This delay will give the spotify web api time to process the device list change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</param> - ///<param name="relativePositionMs">The relative position in milliseconds to seek to; can be a positive or negative number, or zero if the `positionMS` argument is specified. Example = `-10000` to seek behind by 10 seconds; `10000` to seek ahead by 10 seconds. eg: 10000</param> - public void PlayerMediaSeek(string entityId, double? positionMs = null, string? deviceId = null, double? delay = null, double? relativePositionMs = null) - { - _haContext.CallService("spotifyplus", "player_media_seek", null, new SpotifyplusPlayerMediaSeekParameters { EntityId = entityId, PositionMs = positionMs, DeviceId = deviceId, Delay = delay, RelativePositionMs = relativePositionMs }); - } - - ///<summary>Skips to next track in the user's queue for the specified Spotify Connect device.</summary> - public void PlayerMediaSkipNext(SpotifyplusPlayerMediaSkipNextParameters data) - { - _haContext.CallService("spotifyplus", "player_media_skip_next", null, data); - } - - ///<summary>Skips to next track in the user's queue for the specified Spotify Connect device.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="deviceId">The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing the final Connect command (if necessary). This delay will give the spotify web api time to process the device list change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</param> - public void PlayerMediaSkipNext(string entityId, string? deviceId = null, double? delay = null) - { - _haContext.CallService("spotifyplus", "player_media_skip_next", null, new SpotifyplusPlayerMediaSkipNextParameters { EntityId = entityId, DeviceId = deviceId, Delay = delay }); - } - - ///<summary>Skips to previous track in the user's queue for the specified Spotify Connect device.</summary> - public void PlayerMediaSkipPrevious(SpotifyplusPlayerMediaSkipPreviousParameters data) - { - _haContext.CallService("spotifyplus", "player_media_skip_previous", null, data); - } - - ///<summary>Skips to previous track in the user's queue for the specified Spotify Connect device.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="deviceId">The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing the final Connect command (if necessary). This delay will give the spotify web api time to process the device list change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</param> - public void PlayerMediaSkipPrevious(string entityId, string? deviceId = null, double? delay = null) - { - _haContext.CallService("spotifyplus", "player_media_skip_previous", null, new SpotifyplusPlayerMediaSkipPreviousParameters { EntityId = entityId, DeviceId = deviceId, Delay = delay }); - } - - ///<summary>Set repeat mode for the specified Spotify Connect device.</summary> - public void PlayerSetRepeatMode(SpotifyplusPlayerSetRepeatModeParameters data) - { - _haContext.CallService("spotifyplus", "player_set_repeat_mode", null, data); - } - - ///<summary>Set repeat mode for the specified Spotify Connect device.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="state">The repeat mode state to set; `track` will repeat the current track; `context` will repeat the current context; `off` will turn repeat off. Default is 'off'. eg: off</param> - ///<param name="deviceId">The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing the command to the player. This delay will give the spotify web api time to process the change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</param> - public void PlayerSetRepeatMode(string entityId, object state, string? deviceId = null, double? delay = null) - { - _haContext.CallService("spotifyplus", "player_set_repeat_mode", null, new SpotifyplusPlayerSetRepeatModeParameters { EntityId = entityId, State = state, DeviceId = deviceId, Delay = delay }); - } - - ///<summary>Set shuffle mode for the specified Spotify Connect device.</summary> - public void PlayerSetShuffleMode(SpotifyplusPlayerSetShuffleModeParameters data) - { - _haContext.CallService("spotifyplus", "player_set_shuffle_mode", null, data); - } - - ///<summary>Set shuffle mode for the specified Spotify Connect device.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="state">True to set player shuffle mode to on; otherwise, False for no shuffle. eg: True</param> - ///<param name="deviceId">The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing the command to the player. This delay will give the spotify web api time to process the change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</param> - public void PlayerSetShuffleMode(string entityId, bool state, string? deviceId = null, double? delay = null) - { - _haContext.CallService("spotifyplus", "player_set_shuffle_mode", null, new SpotifyplusPlayerSetShuffleModeParameters { EntityId = entityId, State = state, DeviceId = deviceId, Delay = delay }); - } - - ///<summary>Set volume level for the specified Spotify Connect device.</summary> - public void PlayerSetVolumeLevel(SpotifyplusPlayerSetVolumeLevelParameters data) - { - _haContext.CallService("spotifyplus", "player_set_volume_level", null, data); - } - - ///<summary>Set volume level for the specified Spotify Connect device.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="volumeLevel">The volume level to set, expressed as a percentage value (e.g. 25). Must be a value from 0 (muted) to 100 (max volume) inclusive. eg: 25</param> - ///<param name="deviceId">The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing the command to the player. This delay will give the spotify web api time to process the change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</param> - public void PlayerSetVolumeLevel(string entityId, double volumeLevel, string? deviceId = null, double? delay = null) - { - _haContext.CallService("spotifyplus", "player_set_volume_level", null, new SpotifyplusPlayerSetVolumeLevelParameters { EntityId = entityId, VolumeLevel = volumeLevel, DeviceId = deviceId, Delay = delay }); - } - - ///<summary>Transfer playback to a new Spotify Connect device and optionally begin playback.</summary> - public void PlayerTransferPlayback(SpotifyplusPlayerTransferPlaybackParameters data) - { - _haContext.CallService("spotifyplus", "player_transfer_playback", null, data); - } - - ///<summary>Transfer playback to a new Spotify Connect device and optionally begin playback.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="deviceId">The id or name of the Spotify Connect Player device on which playback should be started/transferred. If no device is specified, then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</param> - ///<param name="play">True (default) to start playback on the new device; otherise, False to keep the current playback state on the existing device. eg: True</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing the final Connect command (if necessary). This delay will give the spotify web api time to process the device list change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</param> - ///<param name="refreshDeviceList">DEPRECATED - no longer used, but left here to maintain compatibility.</param> - ///<param name="forceActivateDevice">True to issue a Spotify Connect Disconnect call prior to transfer, which will force the device to reconnect to Spotify Connect; otherwise, False to not disconnect. Default is True. eg: True</param> - ///<param name="deviceIdFrom">The player device identifier where play is being transferred from; only used to stop play on restricted devices prior to transferring playback. eg: Office</param> - public void PlayerTransferPlayback(string entityId, string? deviceId = null, bool? play = null, double? delay = null, bool? refreshDeviceList = null, bool? forceActivateDevice = null, string? deviceIdFrom = null) - { - _haContext.CallService("spotifyplus", "player_transfer_playback", null, new SpotifyplusPlayerTransferPlaybackParameters { EntityId = entityId, DeviceId = deviceId, Play = play, Delay = delay, RefreshDeviceList = refreshDeviceList, ForceActivateDevice = forceActivateDevice, DeviceIdFrom = deviceIdFrom }); - } - - ///<summary>Change a playlist's details (name, description, and public / private state).</summary> - public void PlaylistChange(SpotifyplusPlaylistChangeParameters data) - { - _haContext.CallService("spotifyplus", "playlist_change", null, data); - } - - ///<summary>Change a playlist's details (name, description, and public / private state).</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. `5AC9ZXA7nJ7oGWO911FuDG`). eg: 5AC9ZXA7nJ7oGWO911FuDG</param> - ///<param name="name">The updated name of the playlist (e.g. `My Updated Playlist`). This name does not need to be unique; a user may have several playlists with the same name. eg: My Updated Playlist</param> - ///<param name="description">The playlist description, as displayed in Spotify Clients and in the Web API. eg: A Playlist updated by the SpotifyPlus integration</param> - ///<param name="public">If true, the playlist will be public; if false, it will be private. eg: False</param> - ///<param name="collaborative">If true, the playlist will be collaborative (other users can modify it). To create a collaborative playlist you must also set the public argument to false. eg: False</param> - ///<param name="imagePath">The fully-qualified path of the image to be uploaded (e.g. `www/images/spotify_playlist_default_image.png`). The image must be in PNG or JPEG format, and cannot exceed 256KB in Base64 encoded size. Omit this parameter if you do not wish to update the existing playlist image. eg: www/images/spotify_playlist_default_image.png</param> - public void PlaylistChange(string entityId, string playlistId, string name, string description, bool @public, bool collaborative, string? imagePath = null) - { - _haContext.CallService("spotifyplus", "playlist_change", null, new SpotifyplusPlaylistChangeParameters { EntityId = entityId, PlaylistId = playlistId, Name = name, Description = description, Public = @public, Collaborative = collaborative, ImagePath = imagePath }); - } - - ///<summary>Replace the image used to represent a specific playlist.</summary> - public void PlaylistCoverImageAdd(SpotifyplusPlaylistCoverImageAddParameters data) - { - _haContext.CallService("spotifyplus", "playlist_cover_image_add", null, data); - } - - ///<summary>Replace the image used to represent a specific playlist.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. 5AC9ZXA7nJ7oGWO911FuDG). eg: 5v5ETK9WFXAnGQ3MRubKuE</param> - ///<param name="imagePath">The fully-qualified path of the image to be uploaded (e.g. `www/images/spotify_playlist_default_image.png`). The image must be in PNG or JPEG format, and cannot exceed 256KB in Base64 encoded size. eg: www/images/spotify_playlist_default_image.png</param> - public void PlaylistCoverImageAdd(string entityId, string playlistId, string imagePath) - { - _haContext.CallService("spotifyplus", "playlist_cover_image_add", null, new SpotifyplusPlaylistCoverImageAddParameters { EntityId = entityId, PlaylistId = playlistId, ImagePath = imagePath }); - } - - ///<summary>Create an empty playlist for a Spotify user. The playlist will remain empty until you add tracks.</summary> - public void PlaylistCreate(SpotifyplusPlaylistCreateParameters data) - { - _haContext.CallService("spotifyplus", "playlist_create", null, data); - } - - ///<summary>Create an empty playlist for a Spotify user. The playlist will remain empty until you add tracks.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="userId">The user's Spotify user ID (e.g. 32k99y2kg5lnn3mxhtmd2bpdkjfu). Omit this argument to use the Spotify User ID of the player entity_id. eg: 32k99y2kg5lnn3mxhtmd2bpdkjfu</param> - ///<param name="name">The name for the new playlist (e.g. `My New Playlist`). This name does not need to be unique; a user may have several playlists with the same name. eg: My New Playlist</param> - ///<param name="description">The playlist description, as displayed in Spotify Clients and in the Web API. eg: A Playlist created by the SpotifyPlus integration</param> - ///<param name="public">If true, the playlist will be public; if false, it will be private. eg: False</param> - ///<param name="collaborative">If true, the playlist will be collaborative (other users can modify it). To create a collaborative playlist you must also set the public argument to false. eg: False</param> - ///<param name="imagePath">The fully-qualified path of the image to be uploaded (e.g. `www/images/spotify_playlist_default_image.png`). The image must be in PNG or JPEG format, and cannot exceed 256KB in Base64 encoded size. Omit this parameter if you do not wish to add a playlist image. eg: www/images/spotify_playlist_default_image.png</param> - public void PlaylistCreate(string entityId, string name, string description, bool @public, bool collaborative, string? userId = null, string? imagePath = null) - { - _haContext.CallService("spotifyplus", "playlist_create", null, new SpotifyplusPlaylistCreateParameters { EntityId = entityId, UserId = userId, Name = name, Description = description, Public = @public, Collaborative = collaborative, ImagePath = imagePath }); - } - - ///<summary>Create an empty playlist for a Spotify user. The playlist will remain empty until you add tracks.</summary> - public Task<JsonElement?> PlaylistCreateAsync(SpotifyplusPlaylistCreateParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "playlist_create", null, data); - } - - ///<summary>Create an empty playlist for a Spotify user. The playlist will remain empty until you add tracks.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="userId">The user's Spotify user ID (e.g. 32k99y2kg5lnn3mxhtmd2bpdkjfu). Omit this argument to use the Spotify User ID of the player entity_id. eg: 32k99y2kg5lnn3mxhtmd2bpdkjfu</param> - ///<param name="name">The name for the new playlist (e.g. `My New Playlist`). This name does not need to be unique; a user may have several playlists with the same name. eg: My New Playlist</param> - ///<param name="description">The playlist description, as displayed in Spotify Clients and in the Web API. eg: A Playlist created by the SpotifyPlus integration</param> - ///<param name="public">If true, the playlist will be public; if false, it will be private. eg: False</param> - ///<param name="collaborative">If true, the playlist will be collaborative (other users can modify it). To create a collaborative playlist you must also set the public argument to false. eg: False</param> - ///<param name="imagePath">The fully-qualified path of the image to be uploaded (e.g. `www/images/spotify_playlist_default_image.png`). The image must be in PNG or JPEG format, and cannot exceed 256KB in Base64 encoded size. Omit this parameter if you do not wish to add a playlist image. eg: www/images/spotify_playlist_default_image.png</param> - public Task<JsonElement?> PlaylistCreateAsync(string entityId, string name, string description, bool @public, bool collaborative, string? userId = null, string? imagePath = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "playlist_create", null, new SpotifyplusPlaylistCreateParameters { EntityId = entityId, UserId = userId, Name = name, Description = description, Public = @public, Collaborative = collaborative, ImagePath = imagePath }); - } - - ///<summary>Add one or more items to a user's playlist. Items are added in the order they are listed in the `uris` argument.</summary> - public void PlaylistItemsAdd(SpotifyplusPlaylistItemsAddParameters data) - { - _haContext.CallService("spotifyplus", "playlist_items_add", null, data); - } - - ///<summary>Add one or more items to a user's playlist. Items are added in the order they are listed in the `uris` argument.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. 5AC9ZXA7nJ7oGWO911FuDG). eg: 5AC9ZXA7nJ7oGWO911FuDG</param> - ///<param name="uris">A comma-separated list of Spotify URIs to add; can be track or episode URIs (e.g. spotify:track:4iV5W9uYEdYUVa79Axb7Rh). A maximum of 100 items can be specified in one request. If nothing is specified, then the track (or episode) uri currently playing is used. eg: spotify:track:4iV5W9uYEdYUVa79Axb7Rh,spotify:episode:512ojhOuo1ktJprKbVcKyQ</param> - ///<param name="position">The position to insert the items, a zero-based index. For example, to insert the items in the first position use a value of 0; to insert the items in the third position use a value of 2. Omit the parameter to append the items to the end of the playlist. eg: 0</param> - public void PlaylistItemsAdd(string entityId, string playlistId, string? uris = null, double? position = null) - { - _haContext.CallService("spotifyplus", "playlist_items_add", null, new SpotifyplusPlaylistItemsAddParameters { EntityId = entityId, PlaylistId = playlistId, Uris = uris, Position = position }); - } - - ///<summary>Add one or more items to a user's playlist. Items are added in the order they are listed in the `uris` argument.</summary> - public Task<JsonElement?> PlaylistItemsAddAsync(SpotifyplusPlaylistItemsAddParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "playlist_items_add", null, data); - } - - ///<summary>Add one or more items to a user's playlist. Items are added in the order they are listed in the `uris` argument.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. 5AC9ZXA7nJ7oGWO911FuDG). eg: 5AC9ZXA7nJ7oGWO911FuDG</param> - ///<param name="uris">A comma-separated list of Spotify URIs to add; can be track or episode URIs (e.g. spotify:track:4iV5W9uYEdYUVa79Axb7Rh). A maximum of 100 items can be specified in one request. If nothing is specified, then the track (or episode) uri currently playing is used. eg: spotify:track:4iV5W9uYEdYUVa79Axb7Rh,spotify:episode:512ojhOuo1ktJprKbVcKyQ</param> - ///<param name="position">The position to insert the items, a zero-based index. For example, to insert the items in the first position use a value of 0; to insert the items in the third position use a value of 2. Omit the parameter to append the items to the end of the playlist. eg: 0</param> - public Task<JsonElement?> PlaylistItemsAddAsync(string entityId, string playlistId, string? uris = null, double? position = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "playlist_items_add", null, new SpotifyplusPlaylistItemsAddParameters { EntityId = entityId, PlaylistId = playlistId, Uris = uris, Position = position }); - } - - ///<summary>Removes (clears) all items from a user's playlist.</summary> - public void PlaylistItemsClear(SpotifyplusPlaylistItemsClearParameters data) - { - _haContext.CallService("spotifyplus", "playlist_items_clear", null, data); - } - - ///<summary>Removes (clears) all items from a user's playlist.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. 5AC9ZXA7nJ7oGWO911FuDG). eg: 5AC9ZXA7nJ7oGWO911FuDG</param> - public void PlaylistItemsClear(string entityId, string playlistId) - { - _haContext.CallService("spotifyplus", "playlist_items_clear", null, new SpotifyplusPlaylistItemsClearParameters { EntityId = entityId, PlaylistId = playlistId }); - } - - ///<summary>Removes (clears) all items from a user's playlist.</summary> - public Task<JsonElement?> PlaylistItemsClearAsync(SpotifyplusPlaylistItemsClearParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "playlist_items_clear", null, data); - } - - ///<summary>Removes (clears) all items from a user's playlist.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. 5AC9ZXA7nJ7oGWO911FuDG). eg: 5AC9ZXA7nJ7oGWO911FuDG</param> - public Task<JsonElement?> PlaylistItemsClearAsync(string entityId, string playlistId) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "playlist_items_clear", null, new SpotifyplusPlaylistItemsClearParameters { EntityId = entityId, PlaylistId = playlistId }); - } - - ///<summary>Remove one or more items from a user's playlist.</summary> - public void PlaylistItemsRemove(SpotifyplusPlaylistItemsRemoveParameters data) - { - _haContext.CallService("spotifyplus", "playlist_items_remove", null, data); - } - - ///<summary>Remove one or more items from a user's playlist.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. 5AC9ZXA7nJ7oGWO911FuDG). eg: 5AC9ZXA7nJ7oGWO911FuDG</param> - ///<param name="uris">A comma-separated list of Spotify URIs to remove; can be track or episode URIs (e.g. spotify:track:4iV5W9uYEdYUVa79Axb7Rh). A maximum of 100 items can be specified in one request. If nothing is specified, then the track (or episode) uri currently playing is used. eg: spotify:track:4iV5W9uYEdYUVa79Axb7Rh,spotify:episode:512ojhOuo1ktJprKbVcKyQ</param> - ///<param name="snapshotId">The playlist's snapshot ID against which you want to make the changes (e.g. `MzgsMWVkNDY3MTQ5YjVjYWE0MzAyNjkyZWMyOThjNjE3YWMwOTY0ZmJjYg==`). The API will validate that the specified items exist and make the changes, even if more recent changes have been made to the playlist. If omitted, the current playlist is updated.</param> - public void PlaylistItemsRemove(string entityId, string playlistId, string? uris = null, string? snapshotId = null) - { - _haContext.CallService("spotifyplus", "playlist_items_remove", null, new SpotifyplusPlaylistItemsRemoveParameters { EntityId = entityId, PlaylistId = playlistId, Uris = uris, SnapshotId = snapshotId }); - } - - ///<summary>Remove one or more items from a user's playlist.</summary> - public Task<JsonElement?> PlaylistItemsRemoveAsync(SpotifyplusPlaylistItemsRemoveParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "playlist_items_remove", null, data); - } - - ///<summary>Remove one or more items from a user's playlist.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. 5AC9ZXA7nJ7oGWO911FuDG). eg: 5AC9ZXA7nJ7oGWO911FuDG</param> - ///<param name="uris">A comma-separated list of Spotify URIs to remove; can be track or episode URIs (e.g. spotify:track:4iV5W9uYEdYUVa79Axb7Rh). A maximum of 100 items can be specified in one request. If nothing is specified, then the track (or episode) uri currently playing is used. eg: spotify:track:4iV5W9uYEdYUVa79Axb7Rh,spotify:episode:512ojhOuo1ktJprKbVcKyQ</param> - ///<param name="snapshotId">The playlist's snapshot ID against which you want to make the changes (e.g. `MzgsMWVkNDY3MTQ5YjVjYWE0MzAyNjkyZWMyOThjNjE3YWMwOTY0ZmJjYg==`). The API will validate that the specified items exist and make the changes, even if more recent changes have been made to the playlist. If omitted, the current playlist is updated.</param> - public Task<JsonElement?> PlaylistItemsRemoveAsync(string entityId, string playlistId, string? uris = null, string? snapshotId = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "playlist_items_remove", null, new SpotifyplusPlaylistItemsRemoveParameters { EntityId = entityId, PlaylistId = playlistId, Uris = uris, SnapshotId = snapshotId }); - } - - ///<summary>Reorder items in a user's playlist.</summary> - public void PlaylistItemsReorder(SpotifyplusPlaylistItemsReorderParameters data) - { - _haContext.CallService("spotifyplus", "playlist_items_reorder", null, data); - } - - ///<summary>Reorder items in a user's playlist.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. 5AC9ZXA7nJ7oGWO911FuDG). eg: 4yptcTKnXjCu3V92tVVafS</param> - ///<param name="rangeStart">The position of the first item to be reordered. This is a one-offset integer (NOT zero-offset). eg: 2</param> - ///<param name="insertBefore">The position where the items should be inserted. To reorder the items to the end of the playlist, simply set `insertBefore` to the position after the last item. This is a one-offset integer (NOT zero-offset). eg: 1</param> - ///<param name="rangeLength">The amount of items to be reordered; defaults to 1 if not set. The range of items to be reordered begins from the `rangeStart` position, and includes the `rangeLength` subsequent items. eg: 1</param> - ///<param name="snapshotId">The playlist's snapshot ID against which you want to make the changes (e.g. `MzgsMWVkNDY3MTQ5YjVjYWE0MzAyNjkyZWMyOThjNjE3YWMwOTY0ZmJjYg==`). The API will validate that the specified items exist and make the changes, even if more recent changes have been made to the playlist. If omitted, the current playlist is updated.</param> - public void PlaylistItemsReorder(string entityId, string playlistId, double rangeStart, double insertBefore, double? rangeLength = null, string? snapshotId = null) - { - _haContext.CallService("spotifyplus", "playlist_items_reorder", null, new SpotifyplusPlaylistItemsReorderParameters { EntityId = entityId, PlaylistId = playlistId, RangeStart = rangeStart, InsertBefore = insertBefore, RangeLength = rangeLength, SnapshotId = snapshotId }); - } - - ///<summary>Reorder items in a user's playlist.</summary> - public Task<JsonElement?> PlaylistItemsReorderAsync(SpotifyplusPlaylistItemsReorderParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "playlist_items_reorder", null, data); - } - - ///<summary>Reorder items in a user's playlist.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. 5AC9ZXA7nJ7oGWO911FuDG). eg: 4yptcTKnXjCu3V92tVVafS</param> - ///<param name="rangeStart">The position of the first item to be reordered. This is a one-offset integer (NOT zero-offset). eg: 2</param> - ///<param name="insertBefore">The position where the items should be inserted. To reorder the items to the end of the playlist, simply set `insertBefore` to the position after the last item. This is a one-offset integer (NOT zero-offset). eg: 1</param> - ///<param name="rangeLength">The amount of items to be reordered; defaults to 1 if not set. The range of items to be reordered begins from the `rangeStart` position, and includes the `rangeLength` subsequent items. eg: 1</param> - ///<param name="snapshotId">The playlist's snapshot ID against which you want to make the changes (e.g. `MzgsMWVkNDY3MTQ5YjVjYWE0MzAyNjkyZWMyOThjNjE3YWMwOTY0ZmJjYg==`). The API will validate that the specified items exist and make the changes, even if more recent changes have been made to the playlist. If omitted, the current playlist is updated.</param> - public Task<JsonElement?> PlaylistItemsReorderAsync(string entityId, string playlistId, double rangeStart, double insertBefore, double? rangeLength = null, string? snapshotId = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "playlist_items_reorder", null, new SpotifyplusPlaylistItemsReorderParameters { EntityId = entityId, PlaylistId = playlistId, RangeStart = rangeStart, InsertBefore = insertBefore, RangeLength = rangeLength, SnapshotId = snapshotId }); - } - - ///<summary>Replace one or more items in a user's playlist. Replacing items in a playlist will overwrite its existing items. This service can also be used to clear a playlist.</summary> - public void PlaylistItemsReplace(SpotifyplusPlaylistItemsReplaceParameters data) - { - _haContext.CallService("spotifyplus", "playlist_items_replace", null, data); - } - - ///<summary>Replace one or more items in a user's playlist. Replacing items in a playlist will overwrite its existing items. This service can also be used to clear a playlist.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. `3cEYpjA9oz9GiPac4AsH4n`). eg: 3cEYpjA9oz9GiPac4AsH4n</param> - ///<param name="uris">A comma-separated list of Spotify URIs to replace; can be track or episode URIs (e.g. `spotify:track:4iV5W9uYEdYUVa79Axb7Rh, spotify:episode:26c0zVyOv1lzfYpBXdh1zC`). A maximum of 100 items can be specified in one request.</param> - public void PlaylistItemsReplace(string entityId, string playlistId, string? uris = null) - { - _haContext.CallService("spotifyplus", "playlist_items_replace", null, new SpotifyplusPlaylistItemsReplaceParameters { EntityId = entityId, PlaylistId = playlistId, Uris = uris }); - } - - ///<summary>Replace one or more items in a user's playlist. Replacing items in a playlist will overwrite its existing items. This service can also be used to clear a playlist.</summary> - public Task<JsonElement?> PlaylistItemsReplaceAsync(SpotifyplusPlaylistItemsReplaceParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "playlist_items_replace", null, data); - } - - ///<summary>Replace one or more items in a user's playlist. Replacing items in a playlist will overwrite its existing items. This service can also be used to clear a playlist.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. `3cEYpjA9oz9GiPac4AsH4n`). eg: 3cEYpjA9oz9GiPac4AsH4n</param> - ///<param name="uris">A comma-separated list of Spotify URIs to replace; can be track or episode URIs (e.g. `spotify:track:4iV5W9uYEdYUVa79Axb7Rh, spotify:episode:26c0zVyOv1lzfYpBXdh1zC`). A maximum of 100 items can be specified in one request.</param> - public Task<JsonElement?> PlaylistItemsReplaceAsync(string entityId, string playlistId, string? uris = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "playlist_items_replace", null, new SpotifyplusPlaylistItemsReplaceParameters { EntityId = entityId, PlaylistId = playlistId, Uris = uris }); - } - - ///<summary>Remove one or more albums from the current user's 'Your Library'.</summary> - public void RemoveAlbumFavorites(SpotifyplusRemoveAlbumFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "remove_album_favorites", null, data); - } - - ///<summary>Remove one or more albums from the current user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify album id's (e.g. `6vc9OTcyd3hyzabCmsdnwE,382ObEPsp2rxGrnsizN5TX`). A maximum of 50 id's may be specified. If omitted, the currently playing track album uri id value is used. eg: 6vc9OTcyd3hyzabCmsdnwE,382ObEPsp2rxGrnsizN5TX</param> - public void RemoveAlbumFavorites(string entityId, string? ids = null) - { - _haContext.CallService("spotifyplus", "remove_album_favorites", null, new SpotifyplusRemoveAlbumFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Remove one or more audiobooks from the current user's 'Your Library'.</summary> - public void RemoveAudiobookFavorites(SpotifyplusRemoveAudiobookFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "remove_audiobook_favorites", null, data); - } - - ///<summary>Remove one or more audiobooks from the current user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify audiobook id's (e.g. `3PFyizE2tGCSRLusl2Qizf,7iHfbu1YPACw6oZPAFJtqe`). A maximum of 50 id's may be specified. If omitted, the currently playing audiobook uri id value is used. eg: 3PFyizE2tGCSRLusl2Qizf,7iHfbu1YPACw6oZPAFJtqe</param> - public void RemoveAudiobookFavorites(string entityId, string? ids = null) - { - _haContext.CallService("spotifyplus", "remove_audiobook_favorites", null, new SpotifyplusRemoveAudiobookFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Remove one or more episodes from the current user's 'Your Library'.</summary> - public void RemoveEpisodeFavorites(SpotifyplusRemoveEpisodeFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "remove_episode_favorites", null, data); - } - - ///<summary>Remove one or more episodes from the current user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify episode id's (e.g. `3F97boSWlXi8OzuhWClZHQ,1hPX5WJY6ja6yopgVPBqm4`). A maximum of 50 id's may be specified. If omitted, the currently playing episode uri id value is used. eg: 3F97boSWlXi8OzuhWClZHQ,1hPX5WJY6ja6yopgVPBqm4</param> - public void RemoveEpisodeFavorites(string entityId, string? ids = null) - { - _haContext.CallService("spotifyplus", "remove_episode_favorites", null, new SpotifyplusRemoveEpisodeFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Remove one or more albums from the current user's 'Your Library'.</summary> - public void RemoveShowFavorites(SpotifyplusRemoveShowFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "remove_show_favorites", null, data); - } - - ///<summary>Remove one or more albums from the current user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify show id's (e.g. `6kAsbP8pxwaU2kPibKTuHE,4rOoJ6Egrf8K2IrywzwOMk`). A maximum of 50 id's may be specified. If omitted, the currently playing show uri id value is used. eg: 6kAsbP8pxwaU2kPibKTuHE,4rOoJ6Egrf8K2IrywzwOMk</param> - public void RemoveShowFavorites(string entityId, string? ids = null) - { - _haContext.CallService("spotifyplus", "remove_show_favorites", null, new SpotifyplusRemoveShowFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Remove one or more tracks from the current user's 'Your Library'.</summary> - public void RemoveTrackFavorites(SpotifyplusRemoveTrackFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "remove_track_favorites", null, data); - } - - ///<summary>Remove one or more tracks from the current user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify track id's (e.g. `1kWUud3vY5ij5r62zxpTRy,4eoYKv2kDwJS7gRGh5q6SK`). A maximum of 50 id's may be specified. If omitted, the currently playing context uri id value is used. eg: 1kWUud3vY5ij5r62zxpTRy,4eoYKv2kDwJS7gRGh5q6SK</param> - public void RemoveTrackFavorites(string entityId, string? ids = null) - { - _haContext.CallService("spotifyplus", "remove_track_favorites", null, new SpotifyplusRemoveTrackFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Save one or more albums to the current user's 'Your Library'.</summary> - public void SaveAlbumFavorites(SpotifyplusSaveAlbumFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "save_album_favorites", null, data); - } - - ///<summary>Save one or more albums to the current user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify album id's (e.g. `6vc9OTcyd3hyzabCmsdnwE,382ObEPsp2rxGrnsizN5TX`). A maximum of 50 id's may be specified. If omitted, the currently playing track album uri id value is used. eg: 6vc9OTcyd3hyzabCmsdnwE,382ObEPsp2rxGrnsizN5TX</param> - public void SaveAlbumFavorites(string entityId, string? ids = null) - { - _haContext.CallService("spotifyplus", "save_album_favorites", null, new SpotifyplusSaveAlbumFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Save one or more audiobook to the current user's 'Your Library'.</summary> - public void SaveAudiobookFavorites(SpotifyplusSaveAudiobookFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "save_audiobook_favorites", null, data); - } - - ///<summary>Save one or more audiobook to the current user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify audiobook id's (e.g. `3PFyizE2tGCSRLusl2Qizf,7iHfbu1YPACw6oZPAFJtqe`). A maximum of 50 id's may be specified. If omitted, the currently playing audiobook uri id value is used. eg: 3PFyizE2tGCSRLusl2Qizf,7iHfbu1YPACw6oZPAFJtqe</param> - public void SaveAudiobookFavorites(string entityId, string? ids = null) - { - _haContext.CallService("spotifyplus", "save_audiobook_favorites", null, new SpotifyplusSaveAudiobookFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Save one or more episodes to the current user's 'Your Library'.</summary> - public void SaveEpisodeFavorites(SpotifyplusSaveEpisodeFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "save_episode_favorites", null, data); - } - - ///<summary>Save one or more episodes to the current user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify episode id's (e.g. `3F97boSWlXi8OzuhWClZHQ,1hPX5WJY6ja6yopgVPBqm4`). A maximum of 50 id's may be specified. If omitted, the currently playing episode uri id value is used. eg: 3F97boSWlXi8OzuhWClZHQ,1hPX5WJY6ja6yopgVPBqm4</param> - public void SaveEpisodeFavorites(string entityId, string? ids = null) - { - _haContext.CallService("spotifyplus", "save_episode_favorites", null, new SpotifyplusSaveEpisodeFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Save one or more shows to the current user's 'Your Library'.</summary> - public void SaveShowFavorites(SpotifyplusSaveShowFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "save_show_favorites", null, data); - } - - ///<summary>Save one or more shows to the current user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify show id's (e.g. `6kAsbP8pxwaU2kPibKTuHE,4rOoJ6Egrf8K2IrywzwOMk`). A maximum of 50 id's may be specified. If omitted, the currently playing show uri id value is used. eg: 6kAsbP8pxwaU2kPibKTuHE,4rOoJ6Egrf8K2IrywzwOMk</param> - public void SaveShowFavorites(string entityId, string? ids = null) - { - _haContext.CallService("spotifyplus", "save_show_favorites", null, new SpotifyplusSaveShowFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Save one or more tracks to the current user's 'Your Library'.</summary> - public void SaveTrackFavorites(SpotifyplusSaveTrackFavoritesParameters data) - { - _haContext.CallService("spotifyplus", "save_track_favorites", null, data); - } - - ///<summary>Save one or more tracks to the current user's 'Your Library'.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify track id's (e.g. `1kWUud3vY5ij5r62zxpTRy,4eoYKv2kDwJS7gRGh5q6SK`). A maximum of 50 id's may be specified. If omitted, the currently playing context uri id value is used. eg: 1kWUud3vY5ij5r62zxpTRy,4eoYKv2kDwJS7gRGh5q6SK</param> - public void SaveTrackFavorites(string entityId, string? ids = null) - { - _haContext.CallService("spotifyplus", "save_track_favorites", null, new SpotifyplusSaveTrackFavoritesParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Get Spotify catalog information about Albums that match a keyword string.</summary> - public void SearchAlbums(SpotifyplusSearchAlbumsParameters data) - { - _haContext.CallService("spotifyplus", "search_albums", null, data); - } - - ///<summary>Get Spotify catalog information about Albums that match a keyword string.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="criteria">The criteria to search for. eg: Welcome to the New</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</param> - ///<param name="includeExternal">If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public void SearchAlbums(string entityId, string criteria, double? limit = null, double? offset = null, string? market = null, string? includeExternal = null, double? limitTotal = null) - { - _haContext.CallService("spotifyplus", "search_albums", null, new SpotifyplusSearchAlbumsParameters { EntityId = entityId, Criteria = criteria, Limit = limit, Offset = offset, Market = market, IncludeExternal = includeExternal, LimitTotal = limitTotal }); - } - - ///<summary>Get Spotify catalog information about Albums that match a keyword string.</summary> - public Task<JsonElement?> SearchAlbumsAsync(SpotifyplusSearchAlbumsParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "search_albums", null, data); - } - - ///<summary>Get Spotify catalog information about Albums that match a keyword string.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="criteria">The criteria to search for. eg: Welcome to the New</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</param> - ///<param name="includeExternal">If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public Task<JsonElement?> SearchAlbumsAsync(string entityId, string criteria, double? limit = null, double? offset = null, string? market = null, string? includeExternal = null, double? limitTotal = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "search_albums", null, new SpotifyplusSearchAlbumsParameters { EntityId = entityId, Criteria = criteria, Limit = limit, Offset = offset, Market = market, IncludeExternal = includeExternal, LimitTotal = limitTotal }); - } - - ///<summary>Get Spotify catalog information about Artists that match a keyword string.</summary> - public void SearchArtists(SpotifyplusSearchArtistsParameters data) - { - _haContext.CallService("spotifyplus", "search_artists", null, data); - } - - ///<summary>Get Spotify catalog information about Artists that match a keyword string.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="criteria">The criteria to search for. eg: MercyMe</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</param> - ///<param name="includeExternal">If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public void SearchArtists(string entityId, string criteria, double? limit = null, double? offset = null, string? market = null, string? includeExternal = null, double? limitTotal = null) - { - _haContext.CallService("spotifyplus", "search_artists", null, new SpotifyplusSearchArtistsParameters { EntityId = entityId, Criteria = criteria, Limit = limit, Offset = offset, Market = market, IncludeExternal = includeExternal, LimitTotal = limitTotal }); - } - - ///<summary>Get Spotify catalog information about Artists that match a keyword string.</summary> - public Task<JsonElement?> SearchArtistsAsync(SpotifyplusSearchArtistsParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "search_artists", null, data); - } - - ///<summary>Get Spotify catalog information about Artists that match a keyword string.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="criteria">The criteria to search for. eg: MercyMe</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</param> - ///<param name="includeExternal">If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public Task<JsonElement?> SearchArtistsAsync(string entityId, string criteria, double? limit = null, double? offset = null, string? market = null, string? includeExternal = null, double? limitTotal = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "search_artists", null, new SpotifyplusSearchArtistsParameters { EntityId = entityId, Criteria = criteria, Limit = limit, Offset = offset, Market = market, IncludeExternal = includeExternal, LimitTotal = limitTotal }); - } - - ///<summary>Get Spotify catalog information about Audiobooks that match a keyword string.</summary> - public void SearchAudiobooks(SpotifyplusSearchAudiobooksParameters data) - { - _haContext.CallService("spotifyplus", "search_audiobooks", null, data); - } - - ///<summary>Get Spotify catalog information about Audiobooks that match a keyword string.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="criteria">The criteria to search for. eg: The Elfstones of Shannara</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</param> - ///<param name="includeExternal">If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public void SearchAudiobooks(string entityId, string criteria, double? limit = null, double? offset = null, string? market = null, string? includeExternal = null, double? limitTotal = null) - { - _haContext.CallService("spotifyplus", "search_audiobooks", null, new SpotifyplusSearchAudiobooksParameters { EntityId = entityId, Criteria = criteria, Limit = limit, Offset = offset, Market = market, IncludeExternal = includeExternal, LimitTotal = limitTotal }); - } - - ///<summary>Get Spotify catalog information about Audiobooks that match a keyword string.</summary> - public Task<JsonElement?> SearchAudiobooksAsync(SpotifyplusSearchAudiobooksParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "search_audiobooks", null, data); - } - - ///<summary>Get Spotify catalog information about Audiobooks that match a keyword string.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="criteria">The criteria to search for. eg: The Elfstones of Shannara</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</param> - ///<param name="includeExternal">If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public Task<JsonElement?> SearchAudiobooksAsync(string entityId, string criteria, double? limit = null, double? offset = null, string? market = null, string? includeExternal = null, double? limitTotal = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "search_audiobooks", null, new SpotifyplusSearchAudiobooksParameters { EntityId = entityId, Criteria = criteria, Limit = limit, Offset = offset, Market = market, IncludeExternal = includeExternal, LimitTotal = limitTotal }); - } - - ///<summary>Get Spotify catalog information about Episodes that match a keyword string.</summary> - public void SearchEpisodes(SpotifyplusSearchEpisodesParameters data) - { - _haContext.CallService("spotifyplus", "search_episodes", null, data); - } - - ///<summary>Get Spotify catalog information about Episodes that match a keyword string.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="criteria">The criteria to search for. eg: Armchair Anonymous</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</param> - ///<param name="includeExternal">If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public void SearchEpisodes(string entityId, string criteria, double? limit = null, double? offset = null, string? market = null, string? includeExternal = null, double? limitTotal = null) - { - _haContext.CallService("spotifyplus", "search_episodes", null, new SpotifyplusSearchEpisodesParameters { EntityId = entityId, Criteria = criteria, Limit = limit, Offset = offset, Market = market, IncludeExternal = includeExternal, LimitTotal = limitTotal }); - } - - ///<summary>Get Spotify catalog information about Episodes that match a keyword string.</summary> - public Task<JsonElement?> SearchEpisodesAsync(SpotifyplusSearchEpisodesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "search_episodes", null, data); - } - - ///<summary>Get Spotify catalog information about Episodes that match a keyword string.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="criteria">The criteria to search for. eg: Armchair Anonymous</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</param> - ///<param name="includeExternal">If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public Task<JsonElement?> SearchEpisodesAsync(string entityId, string criteria, double? limit = null, double? offset = null, string? market = null, string? includeExternal = null, double? limitTotal = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "search_episodes", null, new SpotifyplusSearchEpisodesParameters { EntityId = entityId, Criteria = criteria, Limit = limit, Offset = offset, Market = market, IncludeExternal = includeExternal, LimitTotal = limitTotal }); - } - - ///<summary>Get Spotify catalog information about Playlists that match a keyword string.</summary> - public void SearchPlaylists(SpotifyplusSearchPlaylistsParameters data) - { - _haContext.CallService("spotifyplus", "search_playlists", null, data); - } - - ///<summary>Get Spotify catalog information about Playlists that match a keyword string.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="criteria">The criteria to search for. eg: Daily Mix</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</param> - ///<param name="includeExternal">If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public void SearchPlaylists(string entityId, string criteria, double? limit = null, double? offset = null, string? market = null, string? includeExternal = null, double? limitTotal = null) - { - _haContext.CallService("spotifyplus", "search_playlists", null, new SpotifyplusSearchPlaylistsParameters { EntityId = entityId, Criteria = criteria, Limit = limit, Offset = offset, Market = market, IncludeExternal = includeExternal, LimitTotal = limitTotal }); - } - - ///<summary>Get Spotify catalog information about Playlists that match a keyword string.</summary> - public Task<JsonElement?> SearchPlaylistsAsync(SpotifyplusSearchPlaylistsParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "search_playlists", null, data); - } - - ///<summary>Get Spotify catalog information about Playlists that match a keyword string.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="criteria">The criteria to search for. eg: Daily Mix</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</param> - ///<param name="includeExternal">If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public Task<JsonElement?> SearchPlaylistsAsync(string entityId, string criteria, double? limit = null, double? offset = null, string? market = null, string? includeExternal = null, double? limitTotal = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "search_playlists", null, new SpotifyplusSearchPlaylistsParameters { EntityId = entityId, Criteria = criteria, Limit = limit, Offset = offset, Market = market, IncludeExternal = includeExternal, LimitTotal = limitTotal }); - } - - ///<summary>Get Spotify catalog information about Shows that match a keyword string.</summary> - public void SearchShows(SpotifyplusSearchShowsParameters data) - { - _haContext.CallService("spotifyplus", "search_shows", null, data); - } - - ///<summary>Get Spotify catalog information about Shows that match a keyword string.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="criteria">The criteria to search for. eg: Dax Shepard</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</param> - ///<param name="includeExternal">If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public void SearchShows(string entityId, string criteria, double? limit = null, double? offset = null, string? market = null, string? includeExternal = null, double? limitTotal = null) - { - _haContext.CallService("spotifyplus", "search_shows", null, new SpotifyplusSearchShowsParameters { EntityId = entityId, Criteria = criteria, Limit = limit, Offset = offset, Market = market, IncludeExternal = includeExternal, LimitTotal = limitTotal }); - } - - ///<summary>Get Spotify catalog information about Shows that match a keyword string.</summary> - public Task<JsonElement?> SearchShowsAsync(SpotifyplusSearchShowsParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "search_shows", null, data); - } - - ///<summary>Get Spotify catalog information about Shows that match a keyword string.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="criteria">The criteria to search for. eg: Dax Shepard</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</param> - ///<param name="includeExternal">If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public Task<JsonElement?> SearchShowsAsync(string entityId, string criteria, double? limit = null, double? offset = null, string? market = null, string? includeExternal = null, double? limitTotal = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "search_shows", null, new SpotifyplusSearchShowsParameters { EntityId = entityId, Criteria = criteria, Limit = limit, Offset = offset, Market = market, IncludeExternal = includeExternal, LimitTotal = limitTotal }); - } - - ///<summary>Get Spotify catalog information about Tracks that match a keyword string.</summary> - public void SearchTracks(SpotifyplusSearchTracksParameters data) - { - _haContext.CallService("spotifyplus", "search_tracks", null, data); - } - - ///<summary>Get Spotify catalog information about Tracks that match a keyword string.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="criteria">The criteria to search for. eg: Dear Younger Me</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</param> - ///<param name="includeExternal">If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public void SearchTracks(string entityId, string criteria, double? limit = null, double? offset = null, string? market = null, string? includeExternal = null, double? limitTotal = null) - { - _haContext.CallService("spotifyplus", "search_tracks", null, new SpotifyplusSearchTracksParameters { EntityId = entityId, Criteria = criteria, Limit = limit, Offset = offset, Market = market, IncludeExternal = includeExternal, LimitTotal = limitTotal }); - } - - ///<summary>Get Spotify catalog information about Tracks that match a keyword string.</summary> - public Task<JsonElement?> SearchTracksAsync(SpotifyplusSearchTracksParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "search_tracks", null, data); - } - - ///<summary>Get Spotify catalog information about Tracks that match a keyword string.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="criteria">The criteria to search for. eg: Dear Younger Me</param> - ///<param name="limit">The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</param> - ///<param name="offset">The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</param> - ///<param name="market">An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</param> - ///<param name="includeExternal">If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</param> - ///<param name="limitTotal">The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</param> - public Task<JsonElement?> SearchTracksAsync(string entityId, string criteria, double? limit = null, double? offset = null, string? market = null, string? includeExternal = null, double? limitTotal = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "search_tracks", null, new SpotifyplusSearchTracksParameters { EntityId = entityId, Criteria = criteria, Limit = limit, Offset = offset, Market = market, IncludeExternal = includeExternal, LimitTotal = limitTotal }); - } - - ///<summary>Forces Spotify Authorization token to expire within 10 seconds; used to test token refresh processing.</summary> - public void TestTokenExpire(SpotifyplusTestTokenExpireParameters data) - { - _haContext.CallService("spotifyplus", "test_token_expire", null, data); - } - - ///<summary>Forces Spotify Authorization token to expire within 10 seconds; used to test token refresh processing.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - public void TestTokenExpire(string entityId) - { - _haContext.CallService("spotifyplus", "test_token_expire", null, new SpotifyplusTestTokenExpireParameters { EntityId = entityId }); - } - - ///<summary>Triggers a scan interval sequence, which will update HA State values from content currently being played on the user's Spotify account.</summary> - public void TriggerScanInterval(SpotifyplusTriggerScanIntervalParameters data) - { - _haContext.CallService("spotifyplus", "trigger_scan_interval", null, data); - } - - ///<summary>Triggers a scan interval sequence, which will update HA State values from content currently being played on the user's Spotify account.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - public void TriggerScanInterval(string entityId) - { - _haContext.CallService("spotifyplus", "trigger_scan_interval", null, new SpotifyplusTriggerScanIntervalParameters { EntityId = entityId }); - } - - ///<summary>Remove the current user as a follower of one or more artists.</summary> - public void UnfollowArtists(SpotifyplusUnfollowArtistsParameters data) - { - _haContext.CallService("spotifyplus", "unfollow_artists", null, data); - } - - ///<summary>Remove the current user as a follower of one or more artists.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify artist id's (e.g. `2CIMQHirSU0MQqyYHq0eOx,1IQ2e1buppatiN1bxUVkrk`). A maximum of 50 id's may be specified. If omitted, the currently playing track artist uri id value is used. eg: 2CIMQHirSU0MQqyYHq0eOx,1IQ2e1buppatiN1bxUVkrk</param> - public void UnfollowArtists(string entityId, string? ids = null) - { - _haContext.CallService("spotifyplus", "unfollow_artists", null, new SpotifyplusUnfollowArtistsParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Remove the current user as a follower of a playlist.</summary> - public void UnfollowPlaylist(SpotifyplusUnfollowPlaylistParameters data) - { - _haContext.CallService("spotifyplus", "unfollow_playlist", null, data); - } - - ///<summary>Remove the current user as a follower of a playlist.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="playlistId">The Spotify ID of the playlist (e.g. `3cEYpjA9oz9GiPac4AsH4n`). If omitted, the currently playing playlist uri id value is used. eg: 3cEYpjA9oz9GiPac4AsH4n</param> - public void UnfollowPlaylist(string entityId, string? playlistId = null) - { - _haContext.CallService("spotifyplus", "unfollow_playlist", null, new SpotifyplusUnfollowPlaylistParameters { EntityId = entityId, PlaylistId = playlistId }); - } - - ///<summary>Remove the current user as a follower of one or more users.</summary> - public void UnfollowUsers(SpotifyplusUnfollowUsersParameters data) - { - _haContext.CallService("spotifyplus", "unfollow_users", null, data); - } - - ///<summary>Remove the current user as a follower of one or more users.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="ids">A comma-separated list of Spotify user IDs (e.g. `smedjan,3758dfdsfjk435hjk6k79lm0n3c4`). A maximum of 50 IDs can be sent in one request. eg: smedjan,3758dfdsfjk435hjk6k79lm0n3c4</param> - public void UnfollowUsers(string entityId, string ids) - { - _haContext.CallService("spotifyplus", "unfollow_users", null, new SpotifyplusUnfollowUsersParameters { EntityId = entityId, Ids = ids }); - } - - ///<summary>Set level used for volume step services.</summary> - public void VolumeSetStep(SpotifyplusVolumeSetStepParameters data) - { - _haContext.CallService("spotifyplus", "volume_set_step", null, data); - } - - ///<summary>Set level used for volume step services.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</param> - ///<param name="level">Level percentage to adjust the volume by. Default is 0.10 (e.g. 10 percent), range is 0.01 to 1.00 (e.g. 1 to 100 percent). eg: 0.05</param> - public void VolumeSetStep(string entityId, double? level = null) - { - _haContext.CallService("spotifyplus", "volume_set_step", null, new SpotifyplusVolumeSetStepParameters { EntityId = entityId, Level = level }); - } - - ///<summary>Calls the `addUser` Spotify Zeroconf API endpoint to issue a call to SpConnectionLoginBlob. If successful, the associated device id is added to the Spotify Connect active device list for the specified user account. This will also issue a `resetUsers` call prior to the `addUser` call.</summary> - public void ZeroconfDeviceConnect(SpotifyplusZeroconfDeviceConnectParameters data) - { - _haContext.CallService("spotifyplus", "zeroconf_device_connect", null, data); - } - - ///<summary>Calls the `addUser` Spotify Zeroconf API endpoint to issue a call to SpConnectionLoginBlob. If successful, the associated device id is added to the Spotify Connect active device list for the specified user account. This will also issue a `resetUsers` call prior to the `addUser` call.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify ZeroConf API service. eg: media_player.spotifyplus_username</param> - ///<param name="hostIpv4Address">IPV4 address at which the Spotify Connect Zeroconf API can be reached on the Spotify Connect device (e.g. '192.168.1.81'). eg: 192.168.1.81</param> - ///<param name="hostIpPort">Port number at which the Spotify Connect Zeroconf API can be reached on the Spotify Connect device (e.g. 8200). eg: 8200</param> - ///<param name="cpath">Spotify Connect Zeroconf API CPath property value (e.g. '/zc'). eg: /zc</param> - ///<param name="version">Spotify Connect Zeroconf API version number that the device supports (e.g. '1.0'). eg: 1.0</param> - ///<param name="useSsl">True if the host device utilizes HTTPS Secure Sockets Layer (SSL) support; otherwise, False to utilize HTTP. Default is False (HTTP). eg: False</param> - ///<param name="username">Spotify user name to login with (e.g. 'yourusername@mail.com'). This MUST match the account name (or one of them) that was used to configure Spotify Connect on the manufacturer device. If not specified, the integration options Spotify Connect username value will be used. eg: yourusername@mail.com</param> - ///<param name="password">Spotify Connect user password to login with. If not specified, the integration options Spotify Connect password value will be used. eg: yourpassword</param> - ///<param name="loginid">Spotify Connect login id to login with (e.g. '31l77fd87g8h9j00k89f07jf87ge'). This is also known as the canonical user id value. This MUST be the value that relates to the `username` argument. If not specified, the integration options Spotify Connect loginId value will be used. eg: 31l77y75hfnhk79f7gk6jkk878mg</param> - ///<param name="preDisconnect">True if a Disconnect should be made prior to the Connect call. This will ensure that the active user is logged out, which must be done if switching user accounts; otherwise, False to not issue a Disconnect call. Default is False. eg: False</param> - ///<param name="verifyDeviceListEntry">True to ensure that the device id is present in the Spotify Connect device list before issuing a call to Connect; Connect will not be called if the device id is already in the list; otherwise, False to always call Connect to add the device. Default is False. eg: False</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing a command to the device. This delay will give the spotify zeroconf api time to process the change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</param> - public void ZeroconfDeviceConnect(string entityId, string hostIpv4Address, double hostIpPort, string cpath, string? version = null, bool? useSsl = null, string? username = null, string? password = null, string? loginid = null, bool? preDisconnect = null, bool? verifyDeviceListEntry = null, double? delay = null) - { - _haContext.CallService("spotifyplus", "zeroconf_device_connect", null, new SpotifyplusZeroconfDeviceConnectParameters { EntityId = entityId, HostIpv4Address = hostIpv4Address, HostIpPort = hostIpPort, Cpath = cpath, Version = version, UseSsl = useSsl, Username = username, Password = password, Loginid = loginid, PreDisconnect = preDisconnect, VerifyDeviceListEntry = verifyDeviceListEntry, Delay = delay }); - } - - ///<summary>Calls the `addUser` Spotify Zeroconf API endpoint to issue a call to SpConnectionLoginBlob. If successful, the associated device id is added to the Spotify Connect active device list for the specified user account. This will also issue a `resetUsers` call prior to the `addUser` call.</summary> - public Task<JsonElement?> ZeroconfDeviceConnectAsync(SpotifyplusZeroconfDeviceConnectParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "zeroconf_device_connect", null, data); - } - - ///<summary>Calls the `addUser` Spotify Zeroconf API endpoint to issue a call to SpConnectionLoginBlob. If successful, the associated device id is added to the Spotify Connect active device list for the specified user account. This will also issue a `resetUsers` call prior to the `addUser` call.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify ZeroConf API service. eg: media_player.spotifyplus_username</param> - ///<param name="hostIpv4Address">IPV4 address at which the Spotify Connect Zeroconf API can be reached on the Spotify Connect device (e.g. '192.168.1.81'). eg: 192.168.1.81</param> - ///<param name="hostIpPort">Port number at which the Spotify Connect Zeroconf API can be reached on the Spotify Connect device (e.g. 8200). eg: 8200</param> - ///<param name="cpath">Spotify Connect Zeroconf API CPath property value (e.g. '/zc'). eg: /zc</param> - ///<param name="version">Spotify Connect Zeroconf API version number that the device supports (e.g. '1.0'). eg: 1.0</param> - ///<param name="useSsl">True if the host device utilizes HTTPS Secure Sockets Layer (SSL) support; otherwise, False to utilize HTTP. Default is False (HTTP). eg: False</param> - ///<param name="username">Spotify user name to login with (e.g. 'yourusername@mail.com'). This MUST match the account name (or one of them) that was used to configure Spotify Connect on the manufacturer device. If not specified, the integration options Spotify Connect username value will be used. eg: yourusername@mail.com</param> - ///<param name="password">Spotify Connect user password to login with. If not specified, the integration options Spotify Connect password value will be used. eg: yourpassword</param> - ///<param name="loginid">Spotify Connect login id to login with (e.g. '31l77fd87g8h9j00k89f07jf87ge'). This is also known as the canonical user id value. This MUST be the value that relates to the `username` argument. If not specified, the integration options Spotify Connect loginId value will be used. eg: 31l77y75hfnhk79f7gk6jkk878mg</param> - ///<param name="preDisconnect">True if a Disconnect should be made prior to the Connect call. This will ensure that the active user is logged out, which must be done if switching user accounts; otherwise, False to not issue a Disconnect call. Default is False. eg: False</param> - ///<param name="verifyDeviceListEntry">True to ensure that the device id is present in the Spotify Connect device list before issuing a call to Connect; Connect will not be called if the device id is already in the list; otherwise, False to always call Connect to add the device. Default is False. eg: False</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing a command to the device. This delay will give the spotify zeroconf api time to process the change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</param> - public Task<JsonElement?> ZeroconfDeviceConnectAsync(string entityId, string hostIpv4Address, double hostIpPort, string cpath, string? version = null, bool? useSsl = null, string? username = null, string? password = null, string? loginid = null, bool? preDisconnect = null, bool? verifyDeviceListEntry = null, double? delay = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "zeroconf_device_connect", null, new SpotifyplusZeroconfDeviceConnectParameters { EntityId = entityId, HostIpv4Address = hostIpv4Address, HostIpPort = hostIpPort, Cpath = cpath, Version = version, UseSsl = useSsl, Username = username, Password = password, Loginid = loginid, PreDisconnect = preDisconnect, VerifyDeviceListEntry = verifyDeviceListEntry, Delay = delay }); - } - - ///<summary>Calls the `resetUsers` Spotify Zeroconf API endpoint to issue a call to SpConnectionLogout. The currently logged in user (if any) will be logged out of Spotify Connect, and the device id removed from the active Spotify Connect device list.</summary> - public void ZeroconfDeviceDisconnect(SpotifyplusZeroconfDeviceDisconnectParameters data) - { - _haContext.CallService("spotifyplus", "zeroconf_device_disconnect", null, data); - } - - ///<summary>Calls the `resetUsers` Spotify Zeroconf API endpoint to issue a call to SpConnectionLogout. The currently logged in user (if any) will be logged out of Spotify Connect, and the device id removed from the active Spotify Connect device list.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify ZeroConf API service. eg: media_player.spotifyplus_username</param> - ///<param name="hostIpv4Address">IPV4 address at which the Spotify Connect Zeroconf API can be reached on the Spotify Connect device (e.g. '192.168.1.81'). eg: 192.168.1.81</param> - ///<param name="hostIpPort">Port number at which the Spotify Connect Zeroconf API can be reached on the Spotify Connect device (e.g. 8200). eg: 8200</param> - ///<param name="cpath">Spotify Connect Zeroconf API CPath property value (e.g. '/zc'). eg: /zc</param> - ///<param name="version">Spotify Connect Zeroconf API version number that the device supports (e.g. '1.0'). eg: 1.0</param> - ///<param name="useSsl">True if the host device utilizes HTTPS Secure Sockets Layer (SSL) support; otherwise, False to utilize HTTP. Default is False (HTTP). eg: False</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing a command to the device. This delay will give the spotify zeroconf api time to process the change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</param> - public void ZeroconfDeviceDisconnect(string entityId, string hostIpv4Address, double hostIpPort, string cpath, string? version = null, bool? useSsl = null, double? delay = null) - { - _haContext.CallService("spotifyplus", "zeroconf_device_disconnect", null, new SpotifyplusZeroconfDeviceDisconnectParameters { EntityId = entityId, HostIpv4Address = hostIpv4Address, HostIpPort = hostIpPort, Cpath = cpath, Version = version, UseSsl = useSsl, Delay = delay }); - } - - ///<summary>Calls the `resetUsers` Spotify Zeroconf API endpoint to issue a call to SpConnectionLogout. The currently logged in user (if any) will be logged out of Spotify Connect, and the device id removed from the active Spotify Connect device list.</summary> - public Task<JsonElement?> ZeroconfDeviceDisconnectAsync(SpotifyplusZeroconfDeviceDisconnectParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "zeroconf_device_disconnect", null, data); - } - - ///<summary>Calls the `resetUsers` Spotify Zeroconf API endpoint to issue a call to SpConnectionLogout. The currently logged in user (if any) will be logged out of Spotify Connect, and the device id removed from the active Spotify Connect device list.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify ZeroConf API service. eg: media_player.spotifyplus_username</param> - ///<param name="hostIpv4Address">IPV4 address at which the Spotify Connect Zeroconf API can be reached on the Spotify Connect device (e.g. '192.168.1.81'). eg: 192.168.1.81</param> - ///<param name="hostIpPort">Port number at which the Spotify Connect Zeroconf API can be reached on the Spotify Connect device (e.g. 8200). eg: 8200</param> - ///<param name="cpath">Spotify Connect Zeroconf API CPath property value (e.g. '/zc'). eg: /zc</param> - ///<param name="version">Spotify Connect Zeroconf API version number that the device supports (e.g. '1.0'). eg: 1.0</param> - ///<param name="useSsl">True if the host device utilizes HTTPS Secure Sockets Layer (SSL) support; otherwise, False to utilize HTTP. Default is False (HTTP). eg: False</param> - ///<param name="delay">Time delay (in seconds) to wait AFTER issuing a command to the device. This delay will give the spotify zeroconf api time to process the change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</param> - public Task<JsonElement?> ZeroconfDeviceDisconnectAsync(string entityId, string hostIpv4Address, double hostIpPort, string cpath, string? version = null, bool? useSsl = null, double? delay = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "zeroconf_device_disconnect", null, new SpotifyplusZeroconfDeviceDisconnectParameters { EntityId = entityId, HostIpv4Address = hostIpv4Address, HostIpPort = hostIpPort, Cpath = cpath, Version = version, UseSsl = useSsl, Delay = delay }); - } - - ///<summary>Calls the `getInfo` Spotify Zeroconf API endpoint to return information about the device.</summary> - public void ZeroconfDeviceGetinfo(SpotifyplusZeroconfDeviceGetinfoParameters data) - { - _haContext.CallService("spotifyplus", "zeroconf_device_getinfo", null, data); - } - - ///<summary>Calls the `getInfo` Spotify Zeroconf API endpoint to return information about the device.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify ZeroConf API service. eg: media_player.spotifyplus_username</param> - ///<param name="hostIpv4Address">IPV4 address at which the Spotify Connect Zeroconf API can be reached on the Spotify Connect device (e.g. '192.168.1.81'). eg: 192.168.1.81</param> - ///<param name="hostIpPort">Port number at which the Spotify Connect Zeroconf API can be reached on the Spotify Connect device (e.g. 8200). eg: 8200</param> - ///<param name="cpath">Spotify Connect Zeroconf API CPath property value (e.g. '/zc'). eg: /zc</param> - ///<param name="version">Spotify Connect Zeroconf API version number that the device supports (e.g. '1.0'). eg: 1.0</param> - ///<param name="useSsl">True if the host device utilizes HTTPS Secure Sockets Layer (SSL) support; otherwise, False to utilize HTTP. Default is False (HTTP). eg: False</param> - public void ZeroconfDeviceGetinfo(string entityId, string hostIpv4Address, double hostIpPort, string cpath, string? version = null, bool? useSsl = null) - { - _haContext.CallService("spotifyplus", "zeroconf_device_getinfo", null, new SpotifyplusZeroconfDeviceGetinfoParameters { EntityId = entityId, HostIpv4Address = hostIpv4Address, HostIpPort = hostIpPort, Cpath = cpath, Version = version, UseSsl = useSsl }); - } - - ///<summary>Calls the `getInfo` Spotify Zeroconf API endpoint to return information about the device.</summary> - public Task<JsonElement?> ZeroconfDeviceGetinfoAsync(SpotifyplusZeroconfDeviceGetinfoParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "zeroconf_device_getinfo", null, data); - } - - ///<summary>Calls the `getInfo` Spotify Zeroconf API endpoint to return information about the device.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the Spotify ZeroConf API service. eg: media_player.spotifyplus_username</param> - ///<param name="hostIpv4Address">IPV4 address at which the Spotify Connect Zeroconf API can be reached on the Spotify Connect device (e.g. '192.168.1.81'). eg: 192.168.1.81</param> - ///<param name="hostIpPort">Port number at which the Spotify Connect Zeroconf API can be reached on the Spotify Connect device (e.g. 8200). eg: 8200</param> - ///<param name="cpath">Spotify Connect Zeroconf API CPath property value (e.g. '/zc'). eg: /zc</param> - ///<param name="version">Spotify Connect Zeroconf API version number that the device supports (e.g. '1.0'). eg: 1.0</param> - ///<param name="useSsl">True if the host device utilizes HTTPS Secure Sockets Layer (SSL) support; otherwise, False to utilize HTTP. Default is False (HTTP). eg: False</param> - public Task<JsonElement?> ZeroconfDeviceGetinfoAsync(string entityId, string hostIpv4Address, double hostIpPort, string cpath, string? version = null, bool? useSsl = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "zeroconf_device_getinfo", null, new SpotifyplusZeroconfDeviceGetinfoParameters { EntityId = entityId, HostIpv4Address = hostIpv4Address, HostIpPort = hostIpPort, Cpath = cpath, Version = version, UseSsl = useSsl }); - } - - ///<summary>Discover Spotify Connect devices on the local network via the ZeroConf (aka MDNS) service, and return details about each device.</summary> - public void ZeroconfDiscoverDevices(SpotifyplusZeroconfDiscoverDevicesParameters data) - { - _haContext.CallService("spotifyplus", "zeroconf_discover_devices", null, data); - } - - ///<summary>Discover Spotify Connect devices on the local network via the ZeroConf (aka MDNS) service, and return details about each device.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the ZeroConf service. eg: media_player.spotifyplus_username</param> - ///<param name="timeout">Maximum amount of time to wait (in seconds) for the discovery to complete. Default is 5, range is 1 thru 10. eg: 5.0</param> - public void ZeroconfDiscoverDevices(string entityId, double? timeout = null) - { - _haContext.CallService("spotifyplus", "zeroconf_discover_devices", null, new SpotifyplusZeroconfDiscoverDevicesParameters { EntityId = entityId, Timeout = timeout }); - } - - ///<summary>Discover Spotify Connect devices on the local network via the ZeroConf (aka MDNS) service, and return details about each device.</summary> - public Task<JsonElement?> ZeroconfDiscoverDevicesAsync(SpotifyplusZeroconfDiscoverDevicesParameters data) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "zeroconf_discover_devices", null, data); - } - - ///<summary>Discover Spotify Connect devices on the local network via the ZeroConf (aka MDNS) service, and return details about each device.</summary> - ///<param name="entityId">Entity ID of the SpotifyPlus device that will make the request to the ZeroConf service. eg: media_player.spotifyplus_username</param> - ///<param name="timeout">Maximum amount of time to wait (in seconds) for the discovery to complete. Default is 5, range is 1 thru 10. eg: 5.0</param> - public Task<JsonElement?> ZeroconfDiscoverDevicesAsync(string entityId, double? timeout = null) - { - return _haContext.CallServiceWithResponseAsync("spotifyplus", "zeroconf_discover_devices", null, new SpotifyplusZeroconfDiscoverDevicesParameters { EntityId = entityId, Timeout = timeout }); - } -} - -public partial record SpotifyplusAddPlayerQueueItemsParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A list of Spotify track or episode URIs to add to the queue (spotify:track:6zd8T1PBe9JFHmuVnurdRp, spotify:track:1kWUud3vY5ij5r62zxpTRy); values can be track or episode URIs. All URIs must be of the same type - you cannot mix and match tracks and episodes. An unlimited number of items can be added in one request, but the more items the longer it will take. eg: spotify:track:6zd8T1PBe9JFHmuVnurdRp</summary> - [JsonPropertyName("uris")] - public string? Uris { get; init; } - - ///<summary>The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</summary> - [JsonPropertyName("device_id")] - public string? DeviceId { get; init; } - - ///<summary>DEPRECATED - no longer used, but left here to maintain compatibility.</summary> - [JsonPropertyName("verify_device_id")] - public bool? VerifyDeviceId { get; init; } - - ///<summary>Time delay (in seconds) to wait AFTER issuing the add request (if necessary). This delay will give the spotify web api time to process the change before another command is issued. Default is 0.15; value range is 0 - 10. eg: 0.15</summary> - [JsonPropertyName("delay")] - public double? Delay { get; init; } -} - -public partial record SpotifyplusCheckAlbumFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify album id's (e.g. `6vc9OTcyd3hyzabCmsdnwE,382ObEPsp2rxGrnsizN5TX`). A maximum of 50 id's may be specified. If omitted, the currently playing track album uri id value is used. eg: 6vc9OTcyd3hyzabCmsdnwE,382ObEPsp2rxGrnsizN5TX</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusCheckArtistsFollowingParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify artist id's (e.g. `2CIMQHirSU0MQqyYHq0eOx,1IQ2e1buppatiN1bxUVkrk`). A maximum of 50 id's may be specified. If omitted, the currently playing track artist uri id value is used. eg: 2CIMQHirSU0MQqyYHq0eOx,1IQ2e1buppatiN1bxUVkrk</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusCheckAudiobookFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify audiobook id's (e.g. `3PFyizE2tGCSRLusl2Qizf,7iHfbu1YPACw6oZPAFJtqe`). A maximum of 50 id's may be specified. If omitted, the currently playing audiobook uri id value is used. eg: 3PFyizE2tGCSRLusl2Qizf,7iHfbu1YPACw6oZPAFJtqe</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusCheckEpisodeFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify episode id's (e.g. `3F97boSWlXi8OzuhWClZHQ,1hPX5WJY6ja6yopgVPBqm4`). A maximum of 50 id's may be specified. If omitted, the currently playing episode uri id value is used. eg: 3F97boSWlXi8OzuhWClZHQ,1hPX5WJY6ja6yopgVPBqm4</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusCheckPlaylistFollowersParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the playlist (e.g. `3cEYpjA9oz9GiPac4AsH4n`). eg: 3cEYpjA9oz9GiPac4AsH4n</summary> - [JsonPropertyName("playlist_id")] - public string? PlaylistId { get; init; } - - ///<summary>Deprecated - must contain the current user's Spotify Username; Maximum of 1 id. Omit to default to current user name.</summary> - [JsonPropertyName("user_ids")] - public string? UserIds { get; init; } -} - -public partial record SpotifyplusCheckShowFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify show id's (e.g. `6kAsbP8pxwaU2kPibKTuHE,4rOoJ6Egrf8K2IrywzwOMk`). A maximum of 50 id's may be specified. If omitted, the currently playing show uri id value is used. eg: 6kAsbP8pxwaU2kPibKTuHE,4rOoJ6Egrf8K2IrywzwOMk</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusCheckTrackFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify track id's (e.g. `1kWUud3vY5ij5r62zxpTRy,4eoYKv2kDwJS7gRGh5q6SK`). A maximum of 50 id's may be specified. If omitted, the currently playing context uri id value is used. eg: 1kWUud3vY5ij5r62zxpTRy,4eoYKv2kDwJS7gRGh5q6SK</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusCheckUsersFollowingParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify user ID's to check (e.g. `smedjan, 7piUznRWxNyKpaPvmOSdiZ`). A maximum of 50 ID's can be specified. eg: smedjan, 7piUznRWxNyKpaPvmOSdiZ</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusFollowArtistsParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify artist id's (e.g. `2CIMQHirSU0MQqyYHq0eOx,1IQ2e1buppatiN1bxUVkrk`). A maximum of 50 id's may be specified. If omitted, the currently playing track artist uri id value is used. eg: 2CIMQHirSU0MQqyYHq0eOx,1IQ2e1buppatiN1bxUVkrk</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusFollowPlaylistParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the playlist (e.g. `3cEYpjA9oz9GiPac4AsH4n`). If omitted, the currently playing playlist uri id value is used. eg: 3cEYpjA9oz9GiPac4AsH4n</summary> - [JsonPropertyName("playlist_id")] - public string? PlaylistId { get; init; } - - ///<summary>If true the playlist will be included in user's public playlists, if false it will remain private. eg: True</summary> - [JsonPropertyName("public")] - public bool? Public { get; init; } -} - -public partial record SpotifyplusFollowUsersParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of the Spotify user IDs (e.g. 'smedjan,3758dfdsfjk435hjk6k79lm0n3c4'). A maximum of 50 IDs can be sent in one request. eg: smedjan,3758dfdsfjk435hjk6k79lm0n3c4</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusGetAlbumParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the album. If omitted, the currently playing album uri id value is used. eg: 6vc9OTcyd3hyzabCmsdnwE</summary> - [JsonPropertyName("album_id")] - public string? AlbumId { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } -} - -public partial record SpotifyplusGetAlbumFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } - - ///<summary>True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</summary> - [JsonPropertyName("sort_result")] - public bool? SortResult { get; init; } -} - -public partial record SpotifyplusGetAlbumNewReleasesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("country")] - public string? Country { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } - - ///<summary>True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</summary> - [JsonPropertyName("sort_result")] - public bool? SortResult { get; init; } -} - -public partial record SpotifyplusGetAlbumTracksParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the album (e.g. `6vc9OTcyd3hyzabCmsdnwE`). If null, the currently playing album uri id value is used; a Spotify Free or Premium account is required to correctly read the currently playing context. eg: 6vc9OTcyd3hyzabCmsdnwE</summary> - [JsonPropertyName("album_id")] - public string? AlbumId { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } -} - -public partial record SpotifyplusGetArtistParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the artist. If omitted, the currently playing artist uri id value is used. eg: 6APm8EjxOHSYM5B4i3vT3q</summary> - [JsonPropertyName("artist_id")] - public string? ArtistId { get; init; } -} - -public partial record SpotifyplusGetArtistAlbumsParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the artist. If omitted, the currently playing artist uri id value is used. eg: 6APm8EjxOHSYM5B4i3vT3q</summary> - [JsonPropertyName("artist_id")] - public string? ArtistId { get; init; } - - ///<summary>A comma-separated list of keywords that will be used to filter the response. If not supplied, only `album` types will be returned. Valid values are `album`, `single`, `appears_on`, `compilation`. eg: album</summary> - [JsonPropertyName("include_groups")] - public string? IncludeGroups { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } - - ///<summary>True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</summary> - [JsonPropertyName("sort_result")] - public bool? SortResult { get; init; } -} - -public partial record SpotifyplusGetArtistInfoParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the artist. If omitted, the currently playing artist uri id value is used. eg: 6APm8EjxOHSYM5B4i3vT3q</summary> - [JsonPropertyName("artist_id")] - public string? ArtistId { get; init; } -} - -public partial record SpotifyplusGetArtistRelatedArtistsParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the artist. If omitted, the currently playing artist uri id value is used. eg: 6APm8EjxOHSYM5B4i3vT3q</summary> - [JsonPropertyName("artist_id")] - public string? ArtistId { get; init; } - - ///<summary>True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</summary> - [JsonPropertyName("sort_result")] - public bool? SortResult { get; init; } -} - -public partial record SpotifyplusGetArtistTopTracksParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the artist. If omitted, the currently playing artist uri id value is used. eg: 6APm8EjxOHSYM5B4i3vT3q</summary> - [JsonPropertyName("artist_id")] - public string? ArtistId { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</summary> - [JsonPropertyName("sort_result")] - public bool? SortResult { get; init; } -} - -public partial record SpotifyplusGetArtistsFollowedParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The last artist ID retrieved from the previous request, or null for the first request. eg: 6APm8EjxOHSYM5B4i3vT3q</summary> - [JsonPropertyName("after")] - public string? After { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } - - ///<summary>True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</summary> - [JsonPropertyName("sort_result")] - public bool? SortResult { get; init; } -} - -public partial record SpotifyplusGetAudiobookParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID for the audiobook (e.g. `74aydHJKgYz3AIq3jjBSv1`). If null, the currently playing audiobook uri id value is used. eg: 74aydHJKgYz3AIq3jjBSv1</summary> - [JsonPropertyName("audiobook_id")] - public string? AudiobookId { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } -} - -public partial record SpotifyplusGetAudiobookChaptersParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID for the audiobook (e.g. `74aydHJKgYz3AIq3jjBSv1`). If null, the currently playing audiobook uri id value is used. eg: 74aydHJKgYz3AIq3jjBSv1</summary> - [JsonPropertyName("audiobook_id")] - public string? AudiobookId { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } -} - -public partial record SpotifyplusGetAudiobookFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } - - ///<summary>True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</summary> - [JsonPropertyName("sort_result")] - public bool? SortResult { get; init; } -} - -public partial record SpotifyplusGetBrowseCategorysListParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("country")] - public string? Country { get; init; } - - ///<summary>The desired language, consisting of a lowercase ISO 639-1 language code and an uppercase ISO 3166-1 alpha-2 country code, joined by an underscore. For example `es_MX`, meaning `Spanish (Mexico)`. Provide this parameter if you want the results returned in a particular language (where available). Note that if locale is not supplied, or if the specified language is not available, all strings will be returned in the Spotify default language (American English). eg: es_MX</summary> - [JsonPropertyName("locale")] - public string? Locale { get; init; } - - ///<summary>True to return real-time information from the spotify web api and update the cache; otherwise, False to just return the cached value. eg: False</summary> - [JsonPropertyName("refresh")] - public bool? Refresh { get; init; } -} - -public partial record SpotifyplusGetCategoryPlaylistsParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify category ID (not name) for the category. eg: dinner</summary> - [JsonPropertyName("category_id")] - public string? CategoryId { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("country")] - public string? Country { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } - - ///<summary>True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</summary> - [JsonPropertyName("sort_result")] - public bool? SortResult { get; init; } -} - -public partial record SpotifyplusGetChapterParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the chapter. If omitted, the currently playing chapter uri id value is used. eg: 3V0yw9UDrYAfkhAvTrvt9Y</summary> - [JsonPropertyName("chapter_id")] - public string? ChapterId { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } -} - -public partial record SpotifyplusGetCoverImageFileParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The cover image url whose contents are to be retrieved. eg: https://i.scdn.co/image/ab67616d0000b27316c019c87a927829804caf0b</summary> - [JsonPropertyName("image_url")] - public string? ImageUrl { get; init; } - - ///<summary>Fully-qualified path to store the downloaded image to. eg: /config/www/images/cover_file_image.jpg</summary> - [JsonPropertyName("output_path")] - public string? OutputPath { get; init; } -} - -public partial record SpotifyplusGetEpisodeParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the episode. If omitted, the currently playing episode uri id value is used. eg: 26c0zVyOv1lzfYpBXdh1zC</summary> - [JsonPropertyName("episode_id")] - public string? EpisodeId { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } -} - -public partial record SpotifyplusGetEpisodeFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } - - ///<summary>True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</summary> - [JsonPropertyName("sort_result")] - public bool? SortResult { get; init; } -} - -public partial record SpotifyplusGetFeaturedPlaylistsParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("country")] - public string? Country { get; init; } - - ///<summary>The desired language, consisting of a lowercase ISO 639-1 language code and an uppercase ISO 3166-1 alpha-2 country code, joined by an underscore. For example `es_MX`, meaning `Spanish (Mexico)`. Provide this parameter if you want the results returned in a particular language (where available). Note that if locale is not supplied, or if the specified language is not available, all strings will be returned in the Spotify default language (American English). eg: es_MX</summary> - [JsonPropertyName("locale")] - public string? Locale { get; init; } - - ///<summary>A timestamp in ISO 8601 format (yyyy-MM-ddTHH:mm:ss). Use this parameter to specify the user's local time to get results tailored for that specific date and time in the day. If not provided, the response defaults to the current UTC time. eg: 2023-10-23T09:00:00</summary> - [JsonPropertyName("timestamp")] - public string? Timestamp { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } - - ///<summary>True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</summary> - [JsonPropertyName("sort_result")] - public bool? SortResult { get; init; } -} - -public partial record SpotifyplusGetImageVibrantColorsParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The image source to extract color palette information from. If the prefix of the value is `http:` or `https:`, then the image is downloaded from the url. This can also point to a filename on the local file system. If null, the currently playing Spotify track image url is used. Example = `https://i.scdn.co/image/ab67616d0000b2733deaee5f76ab2da15dd8db86`, `c:/image1.jpg` eg: https://i.scdn.co/image/ab67616d0000b2733deaee5f76ab2da15dd8db86</summary> - [JsonPropertyName("image_source")] - public string? ImageSource { get; init; } - - ///<summary>The number of colors in the initial palette from which swatches will be generated. Default is 64; Range is 1 to 256. eg: 64</summary> - [JsonPropertyName("color_count")] - public double? ColorCount { get; init; } - - ///<summary>Controls the processing time and quality of the palette generation. A lower value (e.g. 1) results in higher quality but takes more processing time, while a higher value (e.g. 5) is faster but may result in a lower-quality palette. Default is 5; Range is 1 to 10. eg: 5</summary> - [JsonPropertyName("color_quality")] - public double? ColorQuality { get; init; } -} - -public partial record SpotifyplusGetPlayerDevicesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>True to return real-time information from the spotify web api and update the cache; otherwise, False to just return the cached value. eg: True</summary> - [JsonPropertyName("refresh")] - public bool? Refresh { get; init; } - - ///<summary>True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</summary> - [JsonPropertyName("sort_result")] - public bool? SortResult { get; init; } -} - -public partial record SpotifyplusGetPlayerNowPlayingParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>A comma-separated list of item types that your client supports besides the default track type. Valid types are 'track' and 'episode'. eg: episode</summary> - [JsonPropertyName("additional_types")] - public string? AdditionalTypes { get; init; } -} - -public partial record SpotifyplusGetPlayerPlaybackStateParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>A comma-separated list of item types that your client supports besides the default track type. Valid types are 'track' and 'episode'. eg: episode</summary> - [JsonPropertyName("additional_types")] - public string? AdditionalTypes { get; init; } -} - -public partial record SpotifyplusGetPlayerQueueInfoParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } -} - -public partial record SpotifyplusGetPlayerRecentTracksParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>Returns all items after (but not including) this cursor position, which is a Unix timestamp in milliseconds. If `after` is specified, `before` must not be specified. Use with limit to get the next set of items. Default is `0` (the first item). eg: 1706218456821</summary> - [JsonPropertyName("after")] - public double? After { get; init; } - - ///<summary>Returns all items before (but not including) this cursor position, which is a Unix timestamp in milliseconds. If `before` is specified, `after` must not be specified. Use with limit to get the next set of items. Default is `0` (the first item). eg: 1706218467821</summary> - [JsonPropertyName("before")] - public double? Before { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } -} - -public partial record SpotifyplusGetPlaylistParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the playlist. If omitted, the currently playing playlist uri id value is used. eg: 5v5ETK9WFXAnGQ3MRubKuE</summary> - [JsonPropertyName("playlist_id")] - public string? PlaylistId { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>A comma-separated list of fields to return from the Spotify Web API. All fields are returned if omitted. eg: description,id,name,public,snapshot_id,type,uri,tracks(limit,next,offset,previous,total,items(track(id,name,track_number,type,uri,album(id,images,name,total_tracks,type,uri,artists(id,name,type,uri)))))</summary> - [JsonPropertyName("fields")] - public string? Fields { get; init; } - - ///<summary>A comma-separated list of item types that your client supports besides the default track type. Valid types are 'track' and 'episode'. eg: episode</summary> - [JsonPropertyName("additional_types")] - public string? AdditionalTypes { get; init; } -} - -public partial record SpotifyplusGetPlaylistCoverImageParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the playlist (e.g. 5v5ETK9WFXAnGQ3MRubKuE). If omitted, the currently playing playlist uri id value is used. eg: 5v5ETK9WFXAnGQ3MRubKuE</summary> - [JsonPropertyName("playlist_id")] - public string? PlaylistId { get; init; } -} - -public partial record SpotifyplusGetPlaylistFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } - - ///<summary>True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</summary> - [JsonPropertyName("sort_result")] - public bool? SortResult { get; init; } -} - -public partial record SpotifyplusGetPlaylistItemsParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the playlist (e.g. 5v5ETK9WFXAnGQ3MRubKuE). If null, the currently playing playlist uri id value is used. eg: 5v5ETK9WFXAnGQ3MRubKuE</summary> - [JsonPropertyName("playlist_id")] - public string? PlaylistId { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>Filters for the query; a comma-separated list of the fields to return. If omitted, all fields are returned. For example, specify 'fields=description,uri' to get just the playlist's description and URI. eg: items(track(name,uri,album(name,uri)))</summary> - [JsonPropertyName("fields")] - public string? Fields { get; init; } - - ///<summary>A comma-separated list of item types that your client supports besides the default track type. Valid types are 'track' and 'episode'. eg: track</summary> - [JsonPropertyName("additional_types")] - public string? AdditionalTypes { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } -} - -public partial record SpotifyplusGetPlaylistsForUserParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The user's Spotify user ID (e.g. `smedjan`). eg: smedjan</summary> - [JsonPropertyName("user_id")] - public string? UserId { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } - - ///<summary>True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</summary> - [JsonPropertyName("sort_result")] - public bool? SortResult { get; init; } -} - -public partial record SpotifyplusGetShowParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the show. If omitted, the currently playing show uri id value is used. eg: 5CfCWKI5pZ28U0uOzXkDHe</summary> - [JsonPropertyName("show_id")] - public string? ShowId { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } -} - -public partial record SpotifyplusGetShowEpisodesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID for the show. If omitted, the currently playing show uri id value is used. eg: 6kAsbP8pxwaU2kPibKTuHE</summary> - [JsonPropertyName("show_id")] - public string? ShowId { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } -} - -public partial record SpotifyplusGetShowFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } - - ///<summary>True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</summary> - [JsonPropertyName("sort_result")] - public bool? SortResult { get; init; } - - ///<summary>True (default) to exclude audiobook shows from the returned list, leaving only podcast shows; otherwise, False to include all results returned by the Spotify Web API. eg: True</summary> - [JsonPropertyName("exclude_audiobooks")] - public bool? ExcludeAudiobooks { get; init; } -} - -public partial record SpotifyplusGetSpotifyConnectDeviceParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The id (e.g. '30fbc80e35598f3c242f2120413c943dfd9715fe') or name (e.g. 'Office') of the Spotify Connect Player device this command is targeting. If an '*' is specified, then the SpotifyPlus default device is used. eg: Bose-ST10-1</summary> - [JsonPropertyName("device_value")] - public string? DeviceValue { get; init; } - - ///<summary>DEPRECATED - no longer used, but left here to maintain compatibility.</summary> - [JsonPropertyName("verify_user_context")] - public bool? VerifyUserContext { get; init; } - - ///<summary>Maximum time to wait (in seconds) for the device to become active in the Spotify Connect device list. This value is only used if a Connect command has to be issued to activate the device. Default is 5; value range is 0 - 10. eg: 0.50</summary> - [JsonPropertyName("verify_timeout")] - public double? VerifyTimeout { get; init; } - - ///<summary>DEPRECATED - no longer used, but left here to maintain compatibility.</summary> - [JsonPropertyName("refresh_device_list")] - public bool? RefreshDeviceList { get; init; } - - ///<summary>True to activate the device if necessary; otherwise, False. eg: True</summary> - [JsonPropertyName("activate_device")] - public bool? ActivateDevice { get; init; } - - ///<summary>Time delay (in seconds) to wait AFTER issuing any command to the device. This delay will give the spotify zeroconf api time to process the change before another command is issued. Default is 0.25; value range is 0 - 10. eg: 0.25</summary> - [JsonPropertyName("delay")] - public double? Delay { get; init; } -} - -public partial record SpotifyplusGetSpotifyConnectDevicesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>True (default) to return real-time information from the spotify zeroconf api and update the cache; otherwise, False to just return the cached value. eg: True</summary> - [JsonPropertyName("refresh")] - public bool? Refresh { get; init; } - - ///<summary>DEPRECATED - no longer used, but left here to maintain compatibility.</summary> - [JsonPropertyName("sort_result")] - public bool? SortResult { get; init; } -} - -public partial record SpotifyplusGetTrackParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the track. If omitted, the currently playing track uri id value is used. eg: 1kWUud3vY5ij5r62zxpTRy</summary> - [JsonPropertyName("track_id")] - public string? TrackId { get; init; } -} - -public partial record SpotifyplusGetTrackAudioFeaturesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the track. Example = `1kWUud3vY5ij5r62zxpTRy`. If null, the currently playing track uri id value is used. eg: 7ouMYWpwJ422jRcDASZB7P</summary> - [JsonPropertyName("track_id")] - public string? TrackId { get; init; } -} - -public partial record SpotifyplusGetTrackFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } - - ///<summary>True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</summary> - [JsonPropertyName("sort_result")] - public bool? SortResult { get; init; } -} - -public partial record SpotifyplusGetTrackRecommendationsParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>A comma separated list of Spotify IDs for seed artists (e.g. 4NHQUGzhtTLFvgF5SZesLK). Up to 5 seed values may be provided in any combination of seedArtists, seedTracks and seedGenres; only required if seedGenres and seedTracks are not set.</summary> - [JsonPropertyName("seed_artists")] - public string? SeedArtists { get; init; } - - ///<summary>A comma separated list of any genres in the set of available genre seeds (e.g. classical,country). Up to 5 seed values may be provided in any combination of seedArtists, seedTracks and seedGenres; only required if seedArtists and seedTracks are not set. eg: rock,hard-rock,rock-n-roll</summary> - [JsonPropertyName("seed_genres")] - public string? SeedGenres { get; init; } - - ///<summary>A comma separated list of Spotify IDs for a seed track (e.g. 0c6xIDDpzE81m2q797ordA). Up to 5 seed values may be provided in any combination of seedArtists, seedTracks and seedGenres; only required if seedArtists and seedGenres are not set.</summary> - [JsonPropertyName("seed_tracks")] - public string? SeedTracks { get; init; } - - ///<summary>Restrict results to only those tracks whose acousticness level is greater than the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("min_acousticness")] - public double? MinAcousticness { get; init; } - - ///<summary>Restrict results to only those tracks whose acousticness level is less than the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("max_acousticness")] - public double? MaxAcousticness { get; init; } - - ///<summary>Restrict results to only those tracks whose acousticness level is equal to the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("target_acousticness")] - public double? TargetAcousticness { get; init; } - - ///<summary>Restrict results to only those tracks whose danceability level is greater than the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("min_danceability")] - public double? MinDanceability { get; init; } - - ///<summary>Restrict results to only those tracks whose danceability level is less than the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("max_danceability")] - public double? MaxDanceability { get; init; } - - ///<summary>Restrict results to only those tracks whose acousticness is equal to the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("target_danceability")] - public double? TargetDanceability { get; init; } - - ///<summary>Restrict results to only those tracks whose duration is greater than the specified value in milliseconds.</summary> - [JsonPropertyName("min_duration_ms")] - public double? MinDurationMs { get; init; } - - ///<summary>Restrict results to only those tracks whose duration is less than the specified value in milliseconds.</summary> - [JsonPropertyName("max_duration_ms")] - public double? MaxDurationMs { get; init; } - - ///<summary>Restrict results to only those tracks whose duration is equal to the specified value in milliseconds.</summary> - [JsonPropertyName("target_duration_ms")] - public double? TargetDurationMs { get; init; } - - ///<summary>Restrict results to only those tracks whose energy level is greater than the specified value. Range is `0` - `1`. eg: 0.975</summary> - [JsonPropertyName("min_energy")] - public double? MinEnergy { get; init; } - - ///<summary>Restrict results to only those tracks whose energy level is less than the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("max_energy")] - public double? MaxEnergy { get; init; } - - ///<summary>Restrict results to only those tracks whose energy level is equal to the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("target_energy")] - public double? TargetEnergy { get; init; } - - ///<summary>Restrict results to only those tracks whose instrumentalness level is greater than the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("min_instrumentalness")] - public double? MinInstrumentalness { get; init; } - - ///<summary>Restrict results to only those tracks whose instrumentalness level is less than the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("max_instrumentalness")] - public double? MaxInstrumentalness { get; init; } - - ///<summary>Restrict results to only those tracks whose instrumentalness level is equal to the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("target_instrumentalness")] - public double? TargetInstrumentalness { get; init; } - - ///<summary>Restrict results to only those tracks whose key level is greater than the specified value. Range is `0` - `11`.</summary> - [JsonPropertyName("min_key")] - public double? MinKey { get; init; } - - ///<summary>Restrict results to only those tracks whose key level is less than the specified value. Range is `0` - `11`.</summary> - [JsonPropertyName("max_key")] - public double? MaxKey { get; init; } - - ///<summary>Restrict results to only those tracks whose key level is equal to the specified value. Range is `0` - `11`.</summary> - [JsonPropertyName("target_key")] - public double? TargetKey { get; init; } - - ///<summary>Restrict results to only those tracks whose liveness level is greater than the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("min_liveness")] - public double? MinLiveness { get; init; } - - ///<summary>Restrict results to only those tracks whose liveness level is less than the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("max_liveness")] - public double? MaxLiveness { get; init; } - - ///<summary>Restrict results to only those tracks whose liveness level is equal to the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("target_liveness")] - public double? TargetLiveness { get; init; } - - ///<summary>Restrict results to only those tracks whose loudness level is greater than the specified value. eg: -9.201</summary> - [JsonPropertyName("min_loudness")] - public double? MinLoudness { get; init; } - - ///<summary>Restrict results to only those tracks whose loudness level is less than the specified value.</summary> - [JsonPropertyName("max_loudness")] - public double? MaxLoudness { get; init; } - - ///<summary>Restrict results to only those tracks whose loudness level is equal to the specified value.</summary> - [JsonPropertyName("target_loudness")] - public double? TargetLoudness { get; init; } - - ///<summary>Restrict results to only those tracks whose mode level is greater than the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("min_mode")] - public double? MinMode { get; init; } - - ///<summary>Restrict results to only those tracks whose mode level is less than the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("max_mode")] - public double? MaxMode { get; init; } - - ///<summary>Restrict results to only those tracks whose mode level is equal to the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("target_mode")] - public double? TargetMode { get; init; } - - ///<summary>Restrict results to only those tracks whose popularity level is greater than the specified value. Range is `0` - `100`.</summary> - [JsonPropertyName("min_popularity")] - public double? MinPopularity { get; init; } - - ///<summary>Restrict results to only those tracks whose popularity level is less than the specified value. Range is `0` - `100`.</summary> - [JsonPropertyName("max_popularity")] - public double? MaxPopularity { get; init; } - - ///<summary>Restrict results to only those tracks whose popularity level is equal to the specified value. Range is `0` - `100`.</summary> - [JsonPropertyName("target_popularity")] - public double? TargetPopularity { get; init; } - - ///<summary>Restrict results to only those tracks whose speechiness level is greater than the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("min_speechiness")] - public double? MinSpeechiness { get; init; } - - ///<summary>Restrict results to only those tracks whose speechiness level is less than the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("max_speechiness")] - public double? MaxSpeechiness { get; init; } - - ///<summary>Restrict results to only those tracks whose speechiness level is equal to the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("target_speechiness")] - public double? TargetSpeechiness { get; init; } - - ///<summary>Restrict results to only those tracks with a tempo greater than the specified number of beats per minute.</summary> - [JsonPropertyName("min_tempo")] - public double? MinTempo { get; init; } - - ///<summary>Restrict results to only those tracks with a tempo less than the specified number of beats per minute.</summary> - [JsonPropertyName("max_tempo")] - public double? MaxTempo { get; init; } - - ///<summary>Restrict results to only those tracks with a tempo equal to the specified number of beats per minute.</summary> - [JsonPropertyName("target_tempo")] - public double? TargetTempo { get; init; } - - ///<summary>Restrict results to only those tracks whose time signature is greater than the specified value. Range is `0` - `11`. eg: 4</summary> - [JsonPropertyName("min_time_signature")] - public double? MinTimeSignature { get; init; } - - ///<summary>Restrict results to only those tracks whose time signature is less than the specified value. Range is `0` - `11`.</summary> - [JsonPropertyName("max_time_signature")] - public double? MaxTimeSignature { get; init; } - - ///<summary>Restrict results to only those tracks whose time signature is equal to the specified value. Range is `0` - `11`.</summary> - [JsonPropertyName("target_time_signature")] - public double? TargetTimeSignature { get; init; } - - ///<summary>Restrict results to only those tracks whose valence level is greater than the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("min_valence")] - public double? MinValence { get; init; } - - ///<summary>Restrict results to only those tracks whose valence level is less than the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("max_valence")] - public double? MaxValence { get; init; } - - ///<summary>Restrict results to only those tracks whose valence level is equal to the specified value. Range is `0` - `1`.</summary> - [JsonPropertyName("target_valence")] - public double? TargetValence { get; init; } -} - -public partial record SpotifyplusGetTracksAudioFeaturesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of the Spotify track IDs. Maximum of 100 IDs. Example `7ouMYWpwJ422jRcDASZB7P,4VqPOruhp5EdPBeR92t6lQ,2takcwOaAZWiXQijPHIx7B`. eg: 7ouMYWpwJ422jRcDASZB7P,4VqPOruhp5EdPBeR92t6lQ,2takcwOaAZWiXQijPHIx7B</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusGetUsersTopArtistsParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>Over what time frame the affinities are computed. Valid values are `long_term` (calculated from several years of data and including all new data as it becomes available), `medium_term` (approximately last 6 months), and `short_term` (approximately last 4 weeks). eg: long_term</summary> - [JsonPropertyName("time_range")] - public string? TimeRange { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } - - ///<summary>True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</summary> - [JsonPropertyName("sort_result")] - public bool? SortResult { get; init; } -} - -public partial record SpotifyplusGetUsersTopTracksParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>Over what time frame the affinities are computed. Valid values are `long_term` (calculated from several years of data and including all new data as it becomes available), `medium_term` (approximately last 6 months), and `short_term` (approximately last 4 weeks). eg: long_term</summary> - [JsonPropertyName("time_range")] - public string? TimeRange { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } - - ///<summary>True to sort result items by name prior to returning to the caller; otherwise, False to return results in the order that the Spotify Web API returned them. eg: True</summary> - [JsonPropertyName("sort_result")] - public bool? SortResult { get; init; } -} - -public partial record SpotifyplusPlayerMediaPauseParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</summary> - [JsonPropertyName("device_id")] - public string? DeviceId { get; init; } - - ///<summary>Time delay (in seconds) to wait AFTER issuing the final Connect command (if necessary). This delay will give the spotify web api time to process the device list change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</summary> - [JsonPropertyName("delay")] - public double? Delay { get; init; } -} - -public partial record SpotifyplusPlayerMediaPlayContextParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>Spotify URI of the context to play (e.g. `spotify:album:6vc9OTcyd3hyzabCmsdnwE`). Valid contexts are albums, artists & playlists. eg: spotify:album:6vc9OTcyd3hyzabCmsdnwE</summary> - [JsonPropertyName("context_uri")] - public string? ContextUri { get; init; } - - ///<summary>Indicates from what Uri in the context playback should start (e.g. `1kWUud3vY5ij5r62zxpTRy`. Only available when contextUri corresponds to an artist, album or playlist. The offsetPosition argument will be used if this value is null. eg: spotify:track:1kWUud3vY5ij5r62zxpTRy</summary> - [JsonPropertyName("offset_uri")] - public string? OffsetUri { get; init; } - - ///<summary>Indicates from what position in the context playback should start. The value is zero-based, and can't be negative. Only available when contextUri corresponds to an album or playlist. eg: 3</summary> - [JsonPropertyName("offset_position")] - public double? OffsetPosition { get; init; } - - ///<summary>The position (in milliseconds) to seek to; must be a positive number. Passing in a position that is greater than the length of the track will cause the player to start playing the next track. eg: 0</summary> - [JsonPropertyName("position_ms")] - public double? PositionMs { get; init; } - - ///<summary>The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</summary> - [JsonPropertyName("device_id")] - public string? DeviceId { get; init; } - - ///<summary>Time delay (in seconds) to wait AFTER issuing the final Connect command (if necessary). This delay will give the spotify web api time to process the device list change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</summary> - [JsonPropertyName("delay")] - public double? Delay { get; init; } -} - -public partial record SpotifyplusPlayerMediaPlayTrackFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</summary> - [JsonPropertyName("device_id")] - public string? DeviceId { get; init; } - - ///<summary>True to set player shuffle mode to on; otherwise, False for no shuffle. eg: True</summary> - [JsonPropertyName("shuffle")] - public bool? Shuffle { get; init; } - - ///<summary>Time delay (in seconds) to wait AFTER issuing the command to the player. This delay will give the spotify web api time to process the change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</summary> - [JsonPropertyName("delay")] - public double? Delay { get; init; } - - ///<summary>DEPRECATED - no longer used, but left here to maintain compatibility.</summary> - [JsonPropertyName("resolve_device_id")] - public bool? ResolveDeviceId { get; init; } - - ///<summary>The maximum number of items to retrieve from favorites. Default is 200; Range is 1 - 750. eg: 200</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } -} - -public partial record SpotifyplusPlayerMediaPlayTracksParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A list of Spotify track URIs to play; can be track or episode URIs. A maximum of 50 items can be added in one request. eg: spotify:track:6zd8T1PBe9JFHmuVnurdRp,spotify:track:1kWUud3vY5ij5r62zxpTRy</summary> - [JsonPropertyName("uris")] - public string? Uris { get; init; } - - ///<summary>The position (in milliseconds) to seek to; must be a positive number. Passing in a position that is greater than the length of the track will cause the player to start playing the next track. eg: 0</summary> - [JsonPropertyName("position_ms")] - public double? PositionMs { get; init; } - - ///<summary>The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</summary> - [JsonPropertyName("device_id")] - public string? DeviceId { get; init; } - - ///<summary>Time delay (in seconds) to wait AFTER issuing the final Connect command (if necessary). This delay will give the spotify web api time to process the device list change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</summary> - [JsonPropertyName("delay")] - public double? Delay { get; init; } -} - -public partial record SpotifyplusPlayerMediaResumeParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</summary> - [JsonPropertyName("device_id")] - public string? DeviceId { get; init; } - - ///<summary>Time delay (in seconds) to wait AFTER issuing the final Connect command (if necessary). This delay will give the spotify web api time to process the device list change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</summary> - [JsonPropertyName("delay")] - public double? Delay { get; init; } -} - -public partial record SpotifyplusPlayerMediaSeekParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The absolute position in milliseconds to seek to; must be a positive number or zero if the `relativePositionMS` argument is specified. Passing in a position that is greater than the length of the track will cause the player to start playing the next song. Example = `25000` to start playing at the 25 second mark. eg: 25000</summary> - [JsonPropertyName("position_ms")] - public double? PositionMs { get; init; } - - ///<summary>The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</summary> - [JsonPropertyName("device_id")] - public string? DeviceId { get; init; } - - ///<summary>Time delay (in seconds) to wait AFTER issuing the final Connect command (if necessary). This delay will give the spotify web api time to process the device list change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</summary> - [JsonPropertyName("delay")] - public double? Delay { get; init; } - - ///<summary>The relative position in milliseconds to seek to; can be a positive or negative number, or zero if the `positionMS` argument is specified. Example = `-10000` to seek behind by 10 seconds; `10000` to seek ahead by 10 seconds. eg: 10000</summary> - [JsonPropertyName("relative_position_ms")] - public double? RelativePositionMs { get; init; } -} - -public partial record SpotifyplusPlayerMediaSkipNextParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</summary> - [JsonPropertyName("device_id")] - public string? DeviceId { get; init; } - - ///<summary>Time delay (in seconds) to wait AFTER issuing the final Connect command (if necessary). This delay will give the spotify web api time to process the device list change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</summary> - [JsonPropertyName("delay")] - public double? Delay { get; init; } -} - -public partial record SpotifyplusPlayerMediaSkipPreviousParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</summary> - [JsonPropertyName("device_id")] - public string? DeviceId { get; init; } - - ///<summary>Time delay (in seconds) to wait AFTER issuing the final Connect command (if necessary). This delay will give the spotify web api time to process the device list change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</summary> - [JsonPropertyName("delay")] - public double? Delay { get; init; } -} - -public partial record SpotifyplusPlayerSetRepeatModeParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The repeat mode state to set; `track` will repeat the current track; `context` will repeat the current context; `off` will turn repeat off. Default is 'off'. eg: off</summary> - [JsonPropertyName("state")] - public object? State { get; init; } - - ///<summary>The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</summary> - [JsonPropertyName("device_id")] - public string? DeviceId { get; init; } - - ///<summary>Time delay (in seconds) to wait AFTER issuing the command to the player. This delay will give the spotify web api time to process the change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</summary> - [JsonPropertyName("delay")] - public double? Delay { get; init; } -} - -public partial record SpotifyplusPlayerSetShuffleModeParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>True to set player shuffle mode to on; otherwise, False for no shuffle. eg: True</summary> - [JsonPropertyName("state")] - public bool? State { get; init; } - - ///<summary>The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</summary> - [JsonPropertyName("device_id")] - public string? DeviceId { get; init; } - - ///<summary>Time delay (in seconds) to wait AFTER issuing the command to the player. This delay will give the spotify web api time to process the change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</summary> - [JsonPropertyName("delay")] - public double? Delay { get; init; } -} - -public partial record SpotifyplusPlayerSetVolumeLevelParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The volume level to set, expressed as a percentage value (e.g. 25). Must be a value from 0 (muted) to 100 (max volume) inclusive. eg: 25</summary> - [JsonPropertyName("volume_level")] - public double? VolumeLevel { get; init; } - - ///<summary>The id or name of the Spotify Connect Player device this command is targeting. If not supplied, the user's currently active device is the target. If no device is active (or an '*' is specified), then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</summary> - [JsonPropertyName("device_id")] - public string? DeviceId { get; init; } - - ///<summary>Time delay (in seconds) to wait AFTER issuing the command to the player. This delay will give the spotify web api time to process the change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</summary> - [JsonPropertyName("delay")] - public double? Delay { get; init; } -} - -public partial record SpotifyplusPlayerTransferPlaybackParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The id or name of the Spotify Connect Player device on which playback should be started/transferred. If no device is specified, then the SpotifyPlus default device is activated. eg: 0d1841b0976bae2a3a310dd74c0f337465899bc8</summary> - [JsonPropertyName("device_id")] - public string? DeviceId { get; init; } - - ///<summary>True (default) to start playback on the new device; otherise, False to keep the current playback state on the existing device. eg: True</summary> - [JsonPropertyName("play")] - public bool? Play { get; init; } - - ///<summary>Time delay (in seconds) to wait AFTER issuing the final Connect command (if necessary). This delay will give the spotify web api time to process the device list change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</summary> - [JsonPropertyName("delay")] - public double? Delay { get; init; } - - ///<summary>DEPRECATED - no longer used, but left here to maintain compatibility.</summary> - [JsonPropertyName("refresh_device_list")] - public bool? RefreshDeviceList { get; init; } - - ///<summary>True to issue a Spotify Connect Disconnect call prior to transfer, which will force the device to reconnect to Spotify Connect; otherwise, False to not disconnect. Default is True. eg: True</summary> - [JsonPropertyName("force_activate_device")] - public bool? ForceActivateDevice { get; init; } - - ///<summary>The player device identifier where play is being transferred from; only used to stop play on restricted devices prior to transferring playback. eg: Office</summary> - [JsonPropertyName("device_id_from")] - public string? DeviceIdFrom { get; init; } -} - -public partial record SpotifyplusPlaylistChangeParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the playlist (e.g. `5AC9ZXA7nJ7oGWO911FuDG`). eg: 5AC9ZXA7nJ7oGWO911FuDG</summary> - [JsonPropertyName("playlist_id")] - public string? PlaylistId { get; init; } - - ///<summary>The updated name of the playlist (e.g. `My Updated Playlist`). This name does not need to be unique; a user may have several playlists with the same name. eg: My Updated Playlist</summary> - [JsonPropertyName("name")] - public string? Name { get; init; } - - ///<summary>The playlist description, as displayed in Spotify Clients and in the Web API. eg: A Playlist updated by the SpotifyPlus integration</summary> - [JsonPropertyName("description")] - public string? Description { get; init; } - - ///<summary>If true, the playlist will be public; if false, it will be private. eg: False</summary> - [JsonPropertyName("public")] - public bool? Public { get; init; } - - ///<summary>If true, the playlist will be collaborative (other users can modify it). To create a collaborative playlist you must also set the public argument to false. eg: False</summary> - [JsonPropertyName("collaborative")] - public bool? Collaborative { get; init; } - - ///<summary>The fully-qualified path of the image to be uploaded (e.g. `www/images/spotify_playlist_default_image.png`). The image must be in PNG or JPEG format, and cannot exceed 256KB in Base64 encoded size. Omit this parameter if you do not wish to update the existing playlist image. eg: www/images/spotify_playlist_default_image.png</summary> - [JsonPropertyName("image_path")] - public string? ImagePath { get; init; } -} - -public partial record SpotifyplusPlaylistCoverImageAddParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the playlist (e.g. 5AC9ZXA7nJ7oGWO911FuDG). eg: 5v5ETK9WFXAnGQ3MRubKuE</summary> - [JsonPropertyName("playlist_id")] - public string? PlaylistId { get; init; } - - ///<summary>The fully-qualified path of the image to be uploaded (e.g. `www/images/spotify_playlist_default_image.png`). The image must be in PNG or JPEG format, and cannot exceed 256KB in Base64 encoded size. eg: www/images/spotify_playlist_default_image.png</summary> - [JsonPropertyName("image_path")] - public string? ImagePath { get; init; } -} - -public partial record SpotifyplusPlaylistCreateParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The user's Spotify user ID (e.g. 32k99y2kg5lnn3mxhtmd2bpdkjfu). Omit this argument to use the Spotify User ID of the player entity_id. eg: 32k99y2kg5lnn3mxhtmd2bpdkjfu</summary> - [JsonPropertyName("user_id")] - public string? UserId { get; init; } - - ///<summary>The name for the new playlist (e.g. `My New Playlist`). This name does not need to be unique; a user may have several playlists with the same name. eg: My New Playlist</summary> - [JsonPropertyName("name")] - public string? Name { get; init; } - - ///<summary>The playlist description, as displayed in Spotify Clients and in the Web API. eg: A Playlist created by the SpotifyPlus integration</summary> - [JsonPropertyName("description")] - public string? Description { get; init; } - - ///<summary>If true, the playlist will be public; if false, it will be private. eg: False</summary> - [JsonPropertyName("public")] - public bool? Public { get; init; } - - ///<summary>If true, the playlist will be collaborative (other users can modify it). To create a collaborative playlist you must also set the public argument to false. eg: False</summary> - [JsonPropertyName("collaborative")] - public bool? Collaborative { get; init; } - - ///<summary>The fully-qualified path of the image to be uploaded (e.g. `www/images/spotify_playlist_default_image.png`). The image must be in PNG or JPEG format, and cannot exceed 256KB in Base64 encoded size. Omit this parameter if you do not wish to add a playlist image. eg: www/images/spotify_playlist_default_image.png</summary> - [JsonPropertyName("image_path")] - public string? ImagePath { get; init; } -} - -public partial record SpotifyplusPlaylistItemsAddParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the playlist (e.g. 5AC9ZXA7nJ7oGWO911FuDG). eg: 5AC9ZXA7nJ7oGWO911FuDG</summary> - [JsonPropertyName("playlist_id")] - public string? PlaylistId { get; init; } - - ///<summary>A comma-separated list of Spotify URIs to add; can be track or episode URIs (e.g. spotify:track:4iV5W9uYEdYUVa79Axb7Rh). A maximum of 100 items can be specified in one request. If nothing is specified, then the track (or episode) uri currently playing is used. eg: spotify:track:4iV5W9uYEdYUVa79Axb7Rh,spotify:episode:512ojhOuo1ktJprKbVcKyQ</summary> - [JsonPropertyName("uris")] - public string? Uris { get; init; } - - ///<summary>The position to insert the items, a zero-based index. For example, to insert the items in the first position use a value of 0; to insert the items in the third position use a value of 2. Omit the parameter to append the items to the end of the playlist. eg: 0</summary> - [JsonPropertyName("position")] - public double? Position { get; init; } -} - -public partial record SpotifyplusPlaylistItemsClearParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the playlist (e.g. 5AC9ZXA7nJ7oGWO911FuDG). eg: 5AC9ZXA7nJ7oGWO911FuDG</summary> - [JsonPropertyName("playlist_id")] - public string? PlaylistId { get; init; } -} - -public partial record SpotifyplusPlaylistItemsRemoveParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the playlist (e.g. 5AC9ZXA7nJ7oGWO911FuDG). eg: 5AC9ZXA7nJ7oGWO911FuDG</summary> - [JsonPropertyName("playlist_id")] - public string? PlaylistId { get; init; } - - ///<summary>A comma-separated list of Spotify URIs to remove; can be track or episode URIs (e.g. spotify:track:4iV5W9uYEdYUVa79Axb7Rh). A maximum of 100 items can be specified in one request. If nothing is specified, then the track (or episode) uri currently playing is used. eg: spotify:track:4iV5W9uYEdYUVa79Axb7Rh,spotify:episode:512ojhOuo1ktJprKbVcKyQ</summary> - [JsonPropertyName("uris")] - public string? Uris { get; init; } - - ///<summary>The playlist's snapshot ID against which you want to make the changes (e.g. `MzgsMWVkNDY3MTQ5YjVjYWE0MzAyNjkyZWMyOThjNjE3YWMwOTY0ZmJjYg==`). The API will validate that the specified items exist and make the changes, even if more recent changes have been made to the playlist. If omitted, the current playlist is updated.</summary> - [JsonPropertyName("snapshot_id")] - public string? SnapshotId { get; init; } -} - -public partial record SpotifyplusPlaylistItemsReorderParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the playlist (e.g. 5AC9ZXA7nJ7oGWO911FuDG). eg: 4yptcTKnXjCu3V92tVVafS</summary> - [JsonPropertyName("playlist_id")] - public string? PlaylistId { get; init; } - - ///<summary>The position of the first item to be reordered. This is a one-offset integer (NOT zero-offset). eg: 2</summary> - [JsonPropertyName("range_start")] - public double? RangeStart { get; init; } - - ///<summary>The position where the items should be inserted. To reorder the items to the end of the playlist, simply set `insertBefore` to the position after the last item. This is a one-offset integer (NOT zero-offset). eg: 1</summary> - [JsonPropertyName("insert_before")] - public double? InsertBefore { get; init; } - - ///<summary>The amount of items to be reordered; defaults to 1 if not set. The range of items to be reordered begins from the `rangeStart` position, and includes the `rangeLength` subsequent items. eg: 1</summary> - [JsonPropertyName("range_length")] - public double? RangeLength { get; init; } - - ///<summary>The playlist's snapshot ID against which you want to make the changes (e.g. `MzgsMWVkNDY3MTQ5YjVjYWE0MzAyNjkyZWMyOThjNjE3YWMwOTY0ZmJjYg==`). The API will validate that the specified items exist and make the changes, even if more recent changes have been made to the playlist. If omitted, the current playlist is updated.</summary> - [JsonPropertyName("snapshot_id")] - public string? SnapshotId { get; init; } -} - -public partial record SpotifyplusPlaylistItemsReplaceParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the playlist (e.g. `3cEYpjA9oz9GiPac4AsH4n`). eg: 3cEYpjA9oz9GiPac4AsH4n</summary> - [JsonPropertyName("playlist_id")] - public string? PlaylistId { get; init; } - - ///<summary>A comma-separated list of Spotify URIs to replace; can be track or episode URIs (e.g. `spotify:track:4iV5W9uYEdYUVa79Axb7Rh, spotify:episode:26c0zVyOv1lzfYpBXdh1zC`). A maximum of 100 items can be specified in one request.</summary> - [JsonPropertyName("uris")] - public string? Uris { get; init; } -} - -public partial record SpotifyplusRemoveAlbumFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify album id's (e.g. `6vc9OTcyd3hyzabCmsdnwE,382ObEPsp2rxGrnsizN5TX`). A maximum of 50 id's may be specified. If omitted, the currently playing track album uri id value is used. eg: 6vc9OTcyd3hyzabCmsdnwE,382ObEPsp2rxGrnsizN5TX</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusRemoveAudiobookFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify audiobook id's (e.g. `3PFyizE2tGCSRLusl2Qizf,7iHfbu1YPACw6oZPAFJtqe`). A maximum of 50 id's may be specified. If omitted, the currently playing audiobook uri id value is used. eg: 3PFyizE2tGCSRLusl2Qizf,7iHfbu1YPACw6oZPAFJtqe</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusRemoveEpisodeFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify episode id's (e.g. `3F97boSWlXi8OzuhWClZHQ,1hPX5WJY6ja6yopgVPBqm4`). A maximum of 50 id's may be specified. If omitted, the currently playing episode uri id value is used. eg: 3F97boSWlXi8OzuhWClZHQ,1hPX5WJY6ja6yopgVPBqm4</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusRemoveShowFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify show id's (e.g. `6kAsbP8pxwaU2kPibKTuHE,4rOoJ6Egrf8K2IrywzwOMk`). A maximum of 50 id's may be specified. If omitted, the currently playing show uri id value is used. eg: 6kAsbP8pxwaU2kPibKTuHE,4rOoJ6Egrf8K2IrywzwOMk</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusRemoveTrackFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify track id's (e.g. `1kWUud3vY5ij5r62zxpTRy,4eoYKv2kDwJS7gRGh5q6SK`). A maximum of 50 id's may be specified. If omitted, the currently playing context uri id value is used. eg: 1kWUud3vY5ij5r62zxpTRy,4eoYKv2kDwJS7gRGh5q6SK</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusSaveAlbumFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify album id's (e.g. `6vc9OTcyd3hyzabCmsdnwE,382ObEPsp2rxGrnsizN5TX`). A maximum of 50 id's may be specified. If omitted, the currently playing track album uri id value is used. eg: 6vc9OTcyd3hyzabCmsdnwE,382ObEPsp2rxGrnsizN5TX</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusSaveAudiobookFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify audiobook id's (e.g. `3PFyizE2tGCSRLusl2Qizf,7iHfbu1YPACw6oZPAFJtqe`). A maximum of 50 id's may be specified. If omitted, the currently playing audiobook uri id value is used. eg: 3PFyizE2tGCSRLusl2Qizf,7iHfbu1YPACw6oZPAFJtqe</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusSaveEpisodeFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify episode id's (e.g. `3F97boSWlXi8OzuhWClZHQ,1hPX5WJY6ja6yopgVPBqm4`). A maximum of 50 id's may be specified. If omitted, the currently playing episode uri id value is used. eg: 3F97boSWlXi8OzuhWClZHQ,1hPX5WJY6ja6yopgVPBqm4</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusSaveShowFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify show id's (e.g. `6kAsbP8pxwaU2kPibKTuHE,4rOoJ6Egrf8K2IrywzwOMk`). A maximum of 50 id's may be specified. If omitted, the currently playing show uri id value is used. eg: 6kAsbP8pxwaU2kPibKTuHE,4rOoJ6Egrf8K2IrywzwOMk</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusSaveTrackFavoritesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify track id's (e.g. `1kWUud3vY5ij5r62zxpTRy,4eoYKv2kDwJS7gRGh5q6SK`). A maximum of 50 id's may be specified. If omitted, the currently playing context uri id value is used. eg: 1kWUud3vY5ij5r62zxpTRy,4eoYKv2kDwJS7gRGh5q6SK</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusSearchAlbumsParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The criteria to search for. eg: Welcome to the New</summary> - [JsonPropertyName("criteria")] - public string? Criteria { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</summary> - [JsonPropertyName("include_external")] - public string? IncludeExternal { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } -} - -public partial record SpotifyplusSearchArtistsParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The criteria to search for. eg: MercyMe</summary> - [JsonPropertyName("criteria")] - public string? Criteria { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</summary> - [JsonPropertyName("include_external")] - public string? IncludeExternal { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } -} - -public partial record SpotifyplusSearchAudiobooksParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The criteria to search for. eg: The Elfstones of Shannara</summary> - [JsonPropertyName("criteria")] - public string? Criteria { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</summary> - [JsonPropertyName("include_external")] - public string? IncludeExternal { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } -} - -public partial record SpotifyplusSearchEpisodesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The criteria to search for. eg: Armchair Anonymous</summary> - [JsonPropertyName("criteria")] - public string? Criteria { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</summary> - [JsonPropertyName("include_external")] - public string? IncludeExternal { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } -} - -public partial record SpotifyplusSearchPlaylistsParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The criteria to search for. eg: Daily Mix</summary> - [JsonPropertyName("criteria")] - public string? Criteria { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</summary> - [JsonPropertyName("include_external")] - public string? IncludeExternal { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } -} - -public partial record SpotifyplusSearchShowsParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The criteria to search for. eg: Dax Shepard</summary> - [JsonPropertyName("criteria")] - public string? Criteria { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</summary> - [JsonPropertyName("include_external")] - public string? IncludeExternal { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } -} - -public partial record SpotifyplusSearchTracksParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The criteria to search for. eg: Dear Younger Me</summary> - [JsonPropertyName("criteria")] - public string? Criteria { get; init; } - - ///<summary>The maximum number of items to return in a page of items when manual paging is used. Default is 20, Range is 1 to 50. See the limit_total argument for automatic paging option. eg: 20</summary> - [JsonPropertyName("limit")] - public double? Limit { get; init; } - - ///<summary>The page index offset of the first item to return. Use with limit to get the next set of items. Default is 0 (the first item). eg: 0</summary> - [JsonPropertyName("offset")] - public double? Offset { get; init; } - - ///<summary>An ISO 3166-1 alpha-2 country code. If a country code is specified, only content that is available in that market will be returned. The country associated with the Spotify user account will take priority over this parameter. eg: ES</summary> - [JsonPropertyName("market")] - public string? Market { get; init; } - - ///<summary>If 'audio' is specified it signals that the client can play externally hosted audio content, and marks the content as playable in the response. By default externally hosted audio content is marked as unplayable in the response. Allowed values are 'audio'. eg: audio</summary> - [JsonPropertyName("include_external")] - public string? IncludeExternal { get; init; } - - ///<summary>The maximum number of items to return for the request. If specified, this argument overrides the limit and offset argument values and paging is automatically used to retrieve all available items up to the specified limit total. eg: 20</summary> - [JsonPropertyName("limit_total")] - public double? LimitTotal { get; init; } -} - -public partial record SpotifyplusTestTokenExpireParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } -} - -public partial record SpotifyplusTriggerScanIntervalParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } -} - -public partial record SpotifyplusUnfollowArtistsParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify artist id's (e.g. `2CIMQHirSU0MQqyYHq0eOx,1IQ2e1buppatiN1bxUVkrk`). A maximum of 50 id's may be specified. If omitted, the currently playing track artist uri id value is used. eg: 2CIMQHirSU0MQqyYHq0eOx,1IQ2e1buppatiN1bxUVkrk</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusUnfollowPlaylistParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>The Spotify ID of the playlist (e.g. `3cEYpjA9oz9GiPac4AsH4n`). If omitted, the currently playing playlist uri id value is used. eg: 3cEYpjA9oz9GiPac4AsH4n</summary> - [JsonPropertyName("playlist_id")] - public string? PlaylistId { get; init; } -} - -public partial record SpotifyplusUnfollowUsersParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>A comma-separated list of Spotify user IDs (e.g. `smedjan,3758dfdsfjk435hjk6k79lm0n3c4`). A maximum of 50 IDs can be sent in one request. eg: smedjan,3758dfdsfjk435hjk6k79lm0n3c4</summary> - [JsonPropertyName("ids")] - public string? Ids { get; init; } -} - -public partial record SpotifyplusVolumeSetStepParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify Web API. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>Level percentage to adjust the volume by. Default is 0.10 (e.g. 10 percent), range is 0.01 to 1.00 (e.g. 1 to 100 percent). eg: 0.05</summary> - [JsonPropertyName("level")] - public double? Level { get; init; } -} - -public partial record SpotifyplusZeroconfDeviceConnectParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify ZeroConf API service. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>IPV4 address at which the Spotify Connect Zeroconf API can be reached on the Spotify Connect device (e.g. '192.168.1.81'). eg: 192.168.1.81</summary> - [JsonPropertyName("host_ipv4_address")] - public string? HostIpv4Address { get; init; } - - ///<summary>Port number at which the Spotify Connect Zeroconf API can be reached on the Spotify Connect device (e.g. 8200). eg: 8200</summary> - [JsonPropertyName("host_ip_port")] - public double? HostIpPort { get; init; } - - ///<summary>Spotify Connect Zeroconf API CPath property value (e.g. '/zc'). eg: /zc</summary> - [JsonPropertyName("cpath")] - public string? Cpath { get; init; } - - ///<summary>Spotify Connect Zeroconf API version number that the device supports (e.g. '1.0'). eg: 1.0</summary> - [JsonPropertyName("version")] - public string? Version { get; init; } - - ///<summary>True if the host device utilizes HTTPS Secure Sockets Layer (SSL) support; otherwise, False to utilize HTTP. Default is False (HTTP). eg: False</summary> - [JsonPropertyName("use_ssl")] - public bool? UseSsl { get; init; } - - ///<summary>Spotify user name to login with (e.g. 'yourusername@mail.com'). This MUST match the account name (or one of them) that was used to configure Spotify Connect on the manufacturer device. If not specified, the integration options Spotify Connect username value will be used. eg: yourusername@mail.com</summary> - [JsonPropertyName("username")] - public string? Username { get; init; } - - ///<summary>Spotify Connect user password to login with. If not specified, the integration options Spotify Connect password value will be used. eg: yourpassword</summary> - [JsonPropertyName("password")] - public string? Password { get; init; } - - ///<summary>Spotify Connect login id to login with (e.g. '31l77fd87g8h9j00k89f07jf87ge'). This is also known as the canonical user id value. This MUST be the value that relates to the `username` argument. If not specified, the integration options Spotify Connect loginId value will be used. eg: 31l77y75hfnhk79f7gk6jkk878mg</summary> - [JsonPropertyName("loginid")] - public string? Loginid { get; init; } - - ///<summary>True if a Disconnect should be made prior to the Connect call. This will ensure that the active user is logged out, which must be done if switching user accounts; otherwise, False to not issue a Disconnect call. Default is False. eg: False</summary> - [JsonPropertyName("pre_disconnect")] - public bool? PreDisconnect { get; init; } - - ///<summary>True to ensure that the device id is present in the Spotify Connect device list before issuing a call to Connect; Connect will not be called if the device id is already in the list; otherwise, False to always call Connect to add the device. Default is False. eg: False</summary> - [JsonPropertyName("verify_device_list_entry")] - public bool? VerifyDeviceListEntry { get; init; } - - ///<summary>Time delay (in seconds) to wait AFTER issuing a command to the device. This delay will give the spotify zeroconf api time to process the change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</summary> - [JsonPropertyName("delay")] - public double? Delay { get; init; } -} - -public partial record SpotifyplusZeroconfDeviceDisconnectParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify ZeroConf API service. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>IPV4 address at which the Spotify Connect Zeroconf API can be reached on the Spotify Connect device (e.g. '192.168.1.81'). eg: 192.168.1.81</summary> - [JsonPropertyName("host_ipv4_address")] - public string? HostIpv4Address { get; init; } - - ///<summary>Port number at which the Spotify Connect Zeroconf API can be reached on the Spotify Connect device (e.g. 8200). eg: 8200</summary> - [JsonPropertyName("host_ip_port")] - public double? HostIpPort { get; init; } - - ///<summary>Spotify Connect Zeroconf API CPath property value (e.g. '/zc'). eg: /zc</summary> - [JsonPropertyName("cpath")] - public string? Cpath { get; init; } - - ///<summary>Spotify Connect Zeroconf API version number that the device supports (e.g. '1.0'). eg: 1.0</summary> - [JsonPropertyName("version")] - public string? Version { get; init; } - - ///<summary>True if the host device utilizes HTTPS Secure Sockets Layer (SSL) support; otherwise, False to utilize HTTP. Default is False (HTTP). eg: False</summary> - [JsonPropertyName("use_ssl")] - public bool? UseSsl { get; init; } - - ///<summary>Time delay (in seconds) to wait AFTER issuing a command to the device. This delay will give the spotify zeroconf api time to process the change before another command is issued. Default is 0.50; value range is 0 - 10. eg: 0.50</summary> - [JsonPropertyName("delay")] - public double? Delay { get; init; } -} - -public partial record SpotifyplusZeroconfDeviceGetinfoParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the Spotify ZeroConf API service. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>IPV4 address at which the Spotify Connect Zeroconf API can be reached on the Spotify Connect device (e.g. '192.168.1.81'). eg: 192.168.1.81</summary> - [JsonPropertyName("host_ipv4_address")] - public string? HostIpv4Address { get; init; } - - ///<summary>Port number at which the Spotify Connect Zeroconf API can be reached on the Spotify Connect device (e.g. 8200). eg: 8200</summary> - [JsonPropertyName("host_ip_port")] - public double? HostIpPort { get; init; } - - ///<summary>Spotify Connect Zeroconf API CPath property value (e.g. '/zc'). eg: /zc</summary> - [JsonPropertyName("cpath")] - public string? Cpath { get; init; } - - ///<summary>Spotify Connect Zeroconf API version number that the device supports (e.g. '1.0'). eg: 1.0</summary> - [JsonPropertyName("version")] - public string? Version { get; init; } - - ///<summary>True if the host device utilizes HTTPS Secure Sockets Layer (SSL) support; otherwise, False to utilize HTTP. Default is False (HTTP). eg: False</summary> - [JsonPropertyName("use_ssl")] - public bool? UseSsl { get; init; } -} - -public partial record SpotifyplusZeroconfDiscoverDevicesParameters -{ - ///<summary>Entity ID of the SpotifyPlus device that will make the request to the ZeroConf service. eg: media_player.spotifyplus_username</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>Maximum amount of time to wait (in seconds) for the discovery to complete. Default is 5, range is 1 thru 10. eg: 5.0</summary> - [JsonPropertyName("timeout")] - public double? Timeout { get; init; } -} - -public partial class SwitchServices -{ - private readonly IHaContext _haContext; - public SwitchServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Toggles a switch on/off.</summary> - ///<param name="target">The target for this service call</param> - public void Toggle(ServiceTarget target, object? data = null) - { - _haContext.CallService("switch", "toggle", target, data); - } - - ///<summary>Turns a switch off.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOff(ServiceTarget target, object? data = null) - { - _haContext.CallService("switch", "turn_off", target, data); - } - - ///<summary>Turns a switch on.</summary> - ///<param name="target">The target for this service call</param> - public void TurnOn(ServiceTarget target, object? data = null) - { - _haContext.CallService("switch", "turn_on", target, data); - } -} - -public partial class SystemLogServices -{ - private readonly IHaContext _haContext; - public SystemLogServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Deletes all log entries.</summary> - public void Clear(object? data = null) - { - _haContext.CallService("system_log", "clear", null, data); - } - - ///<summary>Write log entry.</summary> - public void Write(SystemLogWriteParameters data) - { - _haContext.CallService("system_log", "write", null, data); - } - - ///<summary>Write log entry.</summary> - ///<param name="message">Message to log. eg: Something went wrong</param> - ///<param name="level">Log level.</param> - ///<param name="logger">Logger name under which to log the message. Defaults to `system_log.external`. eg: mycomponent.myplatform</param> - public void Write(string message, object? level = null, string? logger = null) - { - _haContext.CallService("system_log", "write", null, new SystemLogWriteParameters { Message = message, Level = level, Logger = logger }); - } -} - -public partial record SystemLogWriteParameters -{ - ///<summary>Message to log. eg: Something went wrong</summary> - [JsonPropertyName("message")] - public string? Message { get; init; } - - ///<summary>Log level.</summary> - [JsonPropertyName("level")] - public object? Level { get; init; } - - ///<summary>Logger name under which to log the message. Defaults to `system_log.external`. eg: mycomponent.myplatform</summary> - [JsonPropertyName("logger")] - public string? Logger { get; init; } -} - -public partial class TemplateServices -{ - private readonly IHaContext _haContext; - public TemplateServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Reloads template entities from the YAML-configuration.</summary> - public void Reload(object? data = null) - { - _haContext.CallService("template", "reload", null, data); - } -} - -public partial class TimerServices -{ - private readonly IHaContext _haContext; - public TimerServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Resets a timer's duration to the last known initial value without firing the timer finished event.</summary> - ///<param name="target">The target for this service call</param> - public void Cancel(ServiceTarget target, object? data = null) - { - _haContext.CallService("timer", "cancel", target, data); - } - - ///<summary>Changes a timer by adding or subtracting a given duration.</summary> - ///<param name="target">The target for this service call</param> - public void Change(ServiceTarget target, TimerChangeParameters data) - { - _haContext.CallService("timer", "change", target, data); - } - - ///<summary>Changes a timer by adding or subtracting a given duration.</summary> - ///<param name="duration">Duration to add to or subtract from the running timer. eg: 00:01:00, 60 or -60</param> - public void Change(ServiceTarget target, string duration) - { - _haContext.CallService("timer", "change", target, new TimerChangeParameters { Duration = duration }); - } - - ///<summary>Finishes a running timer earlier than scheduled.</summary> - ///<param name="target">The target for this service call</param> - public void Finish(ServiceTarget target, object? data = null) - { - _haContext.CallService("timer", "finish", target, data); - } - - ///<summary>Pauses a running timer, retaining the remaining duration for later continuation.</summary> - ///<param name="target">The target for this service call</param> - public void Pause(ServiceTarget target, object? data = null) - { - _haContext.CallService("timer", "pause", target, data); - } - - ///<summary>Reloads timers from the YAML-configuration.</summary> - public void Reload(object? data = null) - { - _haContext.CallService("timer", "reload", null, data); - } - - ///<summary>Starts a timer or restarts it with a provided duration.</summary> - ///<param name="target">The target for this service call</param> - public void Start(ServiceTarget target, TimerStartParameters data) - { - _haContext.CallService("timer", "start", target, data); - } - - ///<summary>Starts a timer or restarts it with a provided duration.</summary> - ///<param name="duration">Custom duration to restart the timer with. eg: 00:01:00 or 60</param> - public void Start(ServiceTarget target, string? duration = null) - { - _haContext.CallService("timer", "start", target, new TimerStartParameters { Duration = duration }); - } -} - -public partial record TimerChangeParameters -{ - ///<summary>Duration to add to or subtract from the running timer. eg: 00:01:00, 60 or -60</summary> - [JsonPropertyName("duration")] - public string? Duration { get; init; } -} - -public partial record TimerStartParameters -{ - ///<summary>Custom duration to restart the timer with. eg: 00:01:00 or 60</summary> - [JsonPropertyName("duration")] - public string? Duration { get; init; } -} - -public partial class TodoServices -{ - private readonly IHaContext _haContext; - public TodoServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Adds a new to-do list item.</summary> - ///<param name="target">The target for this service call</param> - public void AddItem(ServiceTarget target, TodoAddItemParameters data) - { - _haContext.CallService("todo", "add_item", target, data); - } - - ///<summary>Adds a new to-do list item.</summary> - ///<param name="item">The name that represents the to-do item. eg: Submit income tax return</param> - ///<param name="dueDate">The date the to-do item is expected to be completed. eg: 2023-11-17</param> - ///<param name="dueDatetime">The date and time the to-do item is expected to be completed. eg: 2023-11-17 13:30:00</param> - ///<param name="description">A more complete description of the to-do item than provided by the item name. eg: A more complete description of the to-do item than that provided by the summary.</param> - public void AddItem(ServiceTarget target, string item, DateOnly? dueDate = null, DateTime? dueDatetime = null, string? description = null) - { - _haContext.CallService("todo", "add_item", target, new TodoAddItemParameters { Item = item, DueDate = dueDate, DueDatetime = dueDatetime, Description = description }); - } - - ///<summary>Gets items on a to-do list.</summary> - ///<param name="target">The target for this service call</param> - public void GetItems(ServiceTarget target, TodoGetItemsParameters data) - { - _haContext.CallService("todo", "get_items", target, data); - } - - ///<summary>Gets items on a to-do list.</summary> - ///<param name="status">Only return to-do items with the specified statuses. Returns not completed actions by default. eg: needs_action</param> - public void GetItems(ServiceTarget target, IEnumerable<object>? status = null) - { - _haContext.CallService("todo", "get_items", target, new TodoGetItemsParameters { Status = status }); - } - - ///<summary>Gets items on a to-do list.</summary> - ///<param name="target">The target for this service call</param> - public Task<JsonElement?> GetItemsAsync(ServiceTarget target, TodoGetItemsParameters data) - { - return _haContext.CallServiceWithResponseAsync("todo", "get_items", target, data); - } - - ///<summary>Gets items on a to-do list.</summary> - ///<param name="target">The target for this service call</param> - ///<param name="status">Only return to-do items with the specified statuses. Returns not completed actions by default. eg: needs_action</param> - public Task<JsonElement?> GetItemsAsync(ServiceTarget target, IEnumerable<object>? status = null) - { - return _haContext.CallServiceWithResponseAsync("todo", "get_items", target, new TodoGetItemsParameters { Status = status }); - } - - ///<summary>Removes all to-do list items that have been completed.</summary> - ///<param name="target">The target for this service call</param> - public void RemoveCompletedItems(ServiceTarget target, object? data = null) - { - _haContext.CallService("todo", "remove_completed_items", target, data); - } - - ///<summary>Removes an existing to-do list item by its name.</summary> - ///<param name="target">The target for this service call</param> - public void RemoveItem(ServiceTarget target, TodoRemoveItemParameters data) - { - _haContext.CallService("todo", "remove_item", target, data); - } - - ///<summary>Removes an existing to-do list item by its name.</summary> - ///<param name="item">The name for the to-do list item.</param> - public void RemoveItem(ServiceTarget target, string item) - { - _haContext.CallService("todo", "remove_item", target, new TodoRemoveItemParameters { Item = item }); - } - - ///<summary>Updates an existing to-do list item based on its name.</summary> - ///<param name="target">The target for this service call</param> - public void UpdateItem(ServiceTarget target, TodoUpdateItemParameters data) - { - _haContext.CallService("todo", "update_item", target, data); - } - - ///<summary>Updates an existing to-do list item based on its name.</summary> - ///<param name="item">The current name of the to-do item. eg: Submit income tax return</param> - ///<param name="rename">The new name for the to-do item eg: Something else</param> - ///<param name="status">A status or confirmation of the to-do item. eg: needs_action</param> - ///<param name="dueDate">The date the to-do item is expected to be completed. eg: 2023-11-17</param> - ///<param name="dueDatetime">The date and time the to-do item is expected to be completed. eg: 2023-11-17 13:30:00</param> - ///<param name="description">A more complete description of the to-do item than provided by the item name. eg: A more complete description of the to-do item than that provided by the summary.</param> - public void UpdateItem(ServiceTarget target, string item, string? rename = null, object? status = null, DateOnly? dueDate = null, DateTime? dueDatetime = null, string? description = null) - { - _haContext.CallService("todo", "update_item", target, new TodoUpdateItemParameters { Item = item, Rename = rename, Status = status, DueDate = dueDate, DueDatetime = dueDatetime, Description = description }); - } -} - -public partial record TodoAddItemParameters -{ - ///<summary>The name that represents the to-do item. eg: Submit income tax return</summary> - [JsonPropertyName("item")] - public string? Item { get; init; } - - ///<summary>The date the to-do item is expected to be completed. eg: 2023-11-17</summary> - [JsonPropertyName("due_date")] - public DateOnly? DueDate { get; init; } - - ///<summary>The date and time the to-do item is expected to be completed. eg: 2023-11-17 13:30:00</summary> - [JsonPropertyName("due_datetime")] - public DateTime? DueDatetime { get; init; } - - ///<summary>A more complete description of the to-do item than provided by the item name. eg: A more complete description of the to-do item than that provided by the summary.</summary> - [JsonPropertyName("description")] - public string? Description { get; init; } -} - -public partial record TodoGetItemsParameters -{ - ///<summary>Only return to-do items with the specified statuses. Returns not completed actions by default. eg: needs_action</summary> - [JsonPropertyName("status")] - public IEnumerable<object>? Status { get; init; } -} - -public partial record TodoRemoveItemParameters -{ - ///<summary>The name for the to-do list item.</summary> - [JsonPropertyName("item")] - public string? Item { get; init; } -} - -public partial record TodoUpdateItemParameters -{ - ///<summary>The current name of the to-do item. eg: Submit income tax return</summary> - [JsonPropertyName("item")] - public string? Item { get; init; } - - ///<summary>The new name for the to-do item eg: Something else</summary> - [JsonPropertyName("rename")] - public string? Rename { get; init; } - - ///<summary>A status or confirmation of the to-do item. eg: needs_action</summary> - [JsonPropertyName("status")] - public object? Status { get; init; } - - ///<summary>The date the to-do item is expected to be completed. eg: 2023-11-17</summary> - [JsonPropertyName("due_date")] - public DateOnly? DueDate { get; init; } - - ///<summary>The date and time the to-do item is expected to be completed. eg: 2023-11-17 13:30:00</summary> - [JsonPropertyName("due_datetime")] - public DateTime? DueDatetime { get; init; } - - ///<summary>A more complete description of the to-do item than provided by the item name. eg: A more complete description of the to-do item than that provided by the summary.</summary> - [JsonPropertyName("description")] - public string? Description { get; init; } -} - -public partial class TtsServices -{ - private readonly IHaContext _haContext; - public TtsServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Removes all cached text-to-speech files and purges the memory.</summary> - public void ClearCache(object? data = null) - { - _haContext.CallService("tts", "clear_cache", null, data); - } - - ///<summary>Speaks something using text-to-speech on a media player.</summary> - ///<param name="target">The target for this service call</param> - public void Speak(ServiceTarget target, TtsSpeakParameters data) - { - _haContext.CallService("tts", "speak", target, data); - } - - ///<summary>Speaks something using text-to-speech on a media player.</summary> - ///<param name="mediaPlayerEntityId">Media players to play the message.</param> - ///<param name="message">The text you want to convert into speech so that you can listen to it on your device. eg: My name is hanna</param> - ///<param name="cache">Stores this message locally so that when the text is requested again, the output can be produced more quickly.</param> - ///<param name="language">Language to use for speech generation. eg: ru</param> - ///<param name="options">A dictionary containing integration-specific options. eg: platform specific</param> - public void Speak(ServiceTarget target, string mediaPlayerEntityId, string message, bool? cache = null, string? language = null, object? options = null) - { - _haContext.CallService("tts", "speak", target, new TtsSpeakParameters { MediaPlayerEntityId = mediaPlayerEntityId, Message = message, Cache = cache, Language = language, Options = options }); - } -} - -public partial record TtsSpeakParameters -{ - ///<summary>Media players to play the message.</summary> - [JsonPropertyName("media_player_entity_id")] - public string? MediaPlayerEntityId { get; init; } - - ///<summary>The text you want to convert into speech so that you can listen to it on your device. eg: My name is hanna</summary> - [JsonPropertyName("message")] - public string? Message { get; init; } - - ///<summary>Stores this message locally so that when the text is requested again, the output can be produced more quickly.</summary> - [JsonPropertyName("cache")] - public bool? Cache { get; init; } - - ///<summary>Language to use for speech generation. eg: ru</summary> - [JsonPropertyName("language")] - public string? Language { get; init; } - - ///<summary>A dictionary containing integration-specific options. eg: platform specific</summary> - [JsonPropertyName("options")] - public object? Options { get; init; } -} - -public partial class UpdateServices -{ - private readonly IHaContext _haContext; - public UpdateServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Removes the skipped version marker from an update.</summary> - ///<param name="target">The target for this service call</param> - public void ClearSkipped(ServiceTarget target, object? data = null) - { - _haContext.CallService("update", "clear_skipped", target, data); - } - - ///<summary>Installs an update for a device or service.</summary> - ///<param name="target">The target for this service call</param> - public void Install(ServiceTarget target, UpdateInstallParameters data) - { - _haContext.CallService("update", "install", target, data); - } - - ///<summary>Installs an update for a device or service.</summary> - ///<param name="version">The version to install. If omitted, the latest version will be installed. eg: 1.0.0</param> - ///<param name="backup">If supported by the integration, this creates a backup before starting the update.</param> - public void Install(ServiceTarget target, string? version = null, bool? backup = null) - { - _haContext.CallService("update", "install", target, new UpdateInstallParameters { Version = version, Backup = backup }); - } - - ///<summary>Marks currently available update as skipped.</summary> - ///<param name="target">The target for this service call</param> - public void Skip(ServiceTarget target, object? data = null) - { - _haContext.CallService("update", "skip", target, data); - } -} - -public partial record UpdateInstallParameters -{ - ///<summary>The version to install. If omitted, the latest version will be installed. eg: 1.0.0</summary> - [JsonPropertyName("version")] - public string? Version { get; init; } - - ///<summary>If supported by the integration, this creates a backup before starting the update.</summary> - [JsonPropertyName("backup")] - public bool? Backup { get; init; } -} - -public partial class WeatherServices -{ - private readonly IHaContext _haContext; - public WeatherServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Retrieves the forecast from selected weather services.</summary> - ///<param name="target">The target for this service call</param> - public void GetForecasts(ServiceTarget target, WeatherGetForecastsParameters data) - { - _haContext.CallService("weather", "get_forecasts", target, data); - } - - ///<summary>Retrieves the forecast from selected weather services.</summary> - ///<param name="type">The scope of the weather forecast.</param> - public void GetForecasts(ServiceTarget target, object @type) - { - _haContext.CallService("weather", "get_forecasts", target, new WeatherGetForecastsParameters { Type = @type }); - } - - ///<summary>Retrieves the forecast from selected weather services.</summary> - ///<param name="target">The target for this service call</param> - public Task<JsonElement?> GetForecastsAsync(ServiceTarget target, WeatherGetForecastsParameters data) - { - return _haContext.CallServiceWithResponseAsync("weather", "get_forecasts", target, data); - } - - ///<summary>Retrieves the forecast from selected weather services.</summary> - ///<param name="target">The target for this service call</param> - ///<param name="type">The scope of the weather forecast.</param> - public Task<JsonElement?> GetForecastsAsync(ServiceTarget target, object @type) - { - return _haContext.CallServiceWithResponseAsync("weather", "get_forecasts", target, new WeatherGetForecastsParameters { Type = @type }); - } -} - -public partial record WeatherGetForecastsParameters -{ - ///<summary>The scope of the weather forecast.</summary> - [JsonPropertyName("type")] - public object? Type { get; init; } -} - -public partial class YamahaSoundbarServices -{ - private readonly IHaContext _haContext; - public YamahaSoundbarServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Execute various yamaha_soundbar-specific commands on the player.</summary> - public void Command(YamahaSoundbarCommandParameters data) - { - _haContext.CallService("yamaha_soundbar", "command", null, data); - } - - ///<summary>Execute various yamaha_soundbar-specific commands on the player.</summary> - ///<param name="entityId">Entity ID of the player against which the command wil be execuded. eg: media_player.sound_room1</param> - ///<param name="command">To set the names for WriteDeviceNameToUnit and SetApSSIDName please switch to YAML mode and enter the name there. eg: Update</param> - ///<param name="notify">Displays the result of the command as a persistent notification in Lovelace UI (optional, defaults to True). Set to False during automations to avoid seeing these. eg: False</param> - public void Command(string entityId, object command, bool? notify = null) - { - _haContext.CallService("yamaha_soundbar", "command", null, new YamahaSoundbarCommandParameters { EntityId = entityId, Command = command, Notify = notify }); - } - - ///<summary>Group players together in a multiroom setup.</summary> - public void Join(YamahaSoundbarJoinParameters data) - { - _haContext.CallService("yamaha_soundbar", "join", null, data); - } - - ///<summary>Group players together in a multiroom setup.</summary> - ///<param name="master">Entity ID of the player that should become the master of the group. eg: media_player.sound_room2</param> - ///<param name="entityId">Entity ID(s) of the player(s) that will connect to the master. Switch to YAML mode to manually add more, separated by comma. eg: media_player.sound_room1</param> - public void Join(string master, string entityId) - { - _haContext.CallService("yamaha_soundbar", "join", null, new YamahaSoundbarJoinParameters { Master = master, EntityId = entityId }); - } - - ///<summary>Play media track by name found in the tracks list.</summary> - public void PlayTrack(YamahaSoundbarPlayTrackParameters data) - { - _haContext.CallService("yamaha_soundbar", "play_track", null, data); - } - - ///<summary>Play media track by name found in the tracks list.</summary> - ///<param name="entityId">Entity ID of the player on which the playback wil be execuded. eg: media_player.sound_room1</param> - ///<param name="track">(Part of) The name of the track from the list eg: Commodores - Machine Gun Extended Mix.mp3</param> - public void PlayTrack(string entityId, string track) - { - _haContext.CallService("yamaha_soundbar", "play_track", null, new YamahaSoundbarPlayTrackParameters { EntityId = entityId, Track = track }); - } - - ///<summary>Recall content preset from the device.</summary> - public void Preset(YamahaSoundbarPresetParameters data) - { - _haContext.CallService("yamaha_soundbar", "preset", null, data); - } - - ///<summary>Recall content preset from the device.</summary> - ///<param name="entityId">Entity ID of the player for which the preset will be recalled. eg: media_player.sound_room1</param> - ///<param name="preset">Content preset number on the device eg: 1</param> - public void Preset(string entityId, double preset) - { - _haContext.CallService("yamaha_soundbar", "preset", null, new YamahaSoundbarPresetParameters { EntityId = entityId, Preset = preset }); - } - - ///<summary>Restore the state of the player after playing TTS, from a saved snapshot.</summary> - public void Restore(YamahaSoundbarRestoreParameters data) - { - _haContext.CallService("yamaha_soundbar", "restore", null, data); - } - - ///<summary>Restore the state of the player after playing TTS, from a saved snapshot.</summary> - ///<param name="entityId">Entity ID of the player of which the snapshot should be restored. eg: media_player.sound_room1</param> - public void Restore(string entityId) - { - _haContext.CallService("yamaha_soundbar", "restore", null, new YamahaSoundbarRestoreParameters { EntityId = entityId }); - } - - ///<summary>Prepare the player to play TTS and save the current state of it for restore afterwards. Current playback will stop.</summary> - public void Snapshot(YamahaSoundbarSnapshotParameters data) - { - _haContext.CallService("yamaha_soundbar", "snapshot", null, data); - } - - ///<summary>Prepare the player to play TTS and save the current state of it for restore afterwards. Current playback will stop.</summary> - ///<param name="entityId">Entity ID of the player of which the snapshot should be saved. eg: media_player.sound_room1</param> - ///<param name="switchinput">To be used with Spotify Integration. Switch player to stream input along with snapshotting, before playing TTS. Applies for players with multiple inputs like Line-in, Optical, etc. Optional - if not specified, defaults to True. eg: False</param> - public void Snapshot(string entityId, bool? switchinput = null) - { - _haContext.CallService("yamaha_soundbar", "snapshot", null, new YamahaSoundbarSnapshotParameters { EntityId = entityId, Switchinput = switchinput }); - } - - ///<summary>Set the sound options</summary> - public void SoundSettings(YamahaSoundbarSoundSettingsParameters data) - { - _haContext.CallService("yamaha_soundbar", "sound_settings", null, data); - } - - ///<summary>Set the sound options</summary> - ///<param name="entityId">Entity ID of the player on which the playback wil be execuded. eg: media_player.sound_room1</param> - ///<param name="soundProgram">Select the sound preset</param> - ///<param name="subwooferVolume">Set the subwoofer volume</param> - ///<param name="surround">Set the 3D surround option on or off</param> - ///<param name="clearVoice">Set the clear voice option on or off</param> - ///<param name="bassExtension">Set the bass extension option on or off</param> - ///<param name="mute">Set the mute on or off</param> - ///<param name="powerSaving">Set the power saving option on or off</param> - public void SoundSettings(string entityId, object? soundProgram = null, long? subwooferVolume = null, bool? surround = null, bool? clearVoice = null, bool? bassExtension = null, bool? mute = null, bool? powerSaving = null) - { - _haContext.CallService("yamaha_soundbar", "sound_settings", null, new YamahaSoundbarSoundSettingsParameters { EntityId = entityId, SoundProgram = soundProgram, SubwooferVolume = subwooferVolume, Surround = surround, ClearVoice = clearVoice, BassExtension = bassExtension, Mute = mute, PowerSaving = powerSaving }); - } - - ///<summary>Unjoin a player or all players from the multiroom setup.</summary> - public void Unjoin(YamahaSoundbarUnjoinParameters data) - { - _haContext.CallService("yamaha_soundbar", "unjoin", null, data); - } - - ///<summary>Unjoin a player or all players from the multiroom setup.</summary> - ///<param name="entityId">Entity ID(s) of the player(s) that will be unjoined from the group. If this is a master, all slaves will be unjoined. eg: media_player.sound_room2</param> - public void Unjoin(string entityId) - { - _haContext.CallService("yamaha_soundbar", "unjoin", null, new YamahaSoundbarUnjoinParameters { EntityId = entityId }); - } -} - -public partial record YamahaSoundbarCommandParameters -{ - ///<summary>Entity ID of the player against which the command wil be execuded. eg: media_player.sound_room1</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>To set the names for WriteDeviceNameToUnit and SetApSSIDName please switch to YAML mode and enter the name there. eg: Update</summary> - [JsonPropertyName("command")] - public object? Command { get; init; } - - ///<summary>Displays the result of the command as a persistent notification in Lovelace UI (optional, defaults to True). Set to False during automations to avoid seeing these. eg: False</summary> - [JsonPropertyName("notify")] - public bool? Notify { get; init; } -} - -public partial record YamahaSoundbarJoinParameters -{ - ///<summary>Entity ID of the player that should become the master of the group. eg: media_player.sound_room2</summary> - [JsonPropertyName("master")] - public string? Master { get; init; } - - ///<summary>Entity ID(s) of the player(s) that will connect to the master. Switch to YAML mode to manually add more, separated by comma. eg: media_player.sound_room1</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } -} - -public partial record YamahaSoundbarPlayTrackParameters -{ - ///<summary>Entity ID of the player on which the playback wil be execuded. eg: media_player.sound_room1</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>(Part of) The name of the track from the list eg: Commodores - Machine Gun Extended Mix.mp3</summary> - [JsonPropertyName("track")] - public string? Track { get; init; } -} - -public partial record YamahaSoundbarPresetParameters -{ - ///<summary>Entity ID of the player for which the preset will be recalled. eg: media_player.sound_room1</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>Content preset number on the device eg: 1</summary> - [JsonPropertyName("preset")] - public double? Preset { get; init; } -} - -public partial record YamahaSoundbarRestoreParameters -{ - ///<summary>Entity ID of the player of which the snapshot should be restored. eg: media_player.sound_room1</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } -} - -public partial record YamahaSoundbarSnapshotParameters -{ - ///<summary>Entity ID of the player of which the snapshot should be saved. eg: media_player.sound_room1</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>To be used with Spotify Integration. Switch player to stream input along with snapshotting, before playing TTS. Applies for players with multiple inputs like Line-in, Optical, etc. Optional - if not specified, defaults to True. eg: False</summary> - [JsonPropertyName("switchinput")] - public bool? Switchinput { get; init; } -} - -public partial record YamahaSoundbarSoundSettingsParameters -{ - ///<summary>Entity ID of the player on which the playback wil be execuded. eg: media_player.sound_room1</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } - - ///<summary>Select the sound preset</summary> - [JsonPropertyName("sound_program")] - public object? SoundProgram { get; init; } - - ///<summary>Set the subwoofer volume</summary> - [JsonPropertyName("subwoofer_volume")] - public long? SubwooferVolume { get; init; } - - ///<summary>Set the 3D surround option on or off</summary> - [JsonPropertyName("surround")] - public bool? Surround { get; init; } - - ///<summary>Set the clear voice option on or off</summary> - [JsonPropertyName("clear_voice")] - public bool? ClearVoice { get; init; } - - ///<summary>Set the bass extension option on or off</summary> - [JsonPropertyName("bass_extension")] - public bool? BassExtension { get; init; } - - ///<summary>Set the mute on or off</summary> - [JsonPropertyName("mute")] - public bool? Mute { get; init; } - - ///<summary>Set the power saving option on or off</summary> - [JsonPropertyName("power_saving")] - public bool? PowerSaving { get; init; } -} - -public partial record YamahaSoundbarUnjoinParameters -{ - ///<summary>Entity ID(s) of the player(s) that will be unjoined from the group. If this is a master, all slaves will be unjoined. eg: media_player.sound_room2</summary> - [JsonPropertyName("entity_id")] - public string? EntityId { get; init; } -} - -public partial class ZoneServices -{ - private readonly IHaContext _haContext; - public ZoneServices(IHaContext haContext) - { - _haContext = haContext; - } - - ///<summary>Reloads zones from the YAML-configuration.</summary> - public void Reload(object? data = null) - { - _haContext.CallService("zone", "reload", null, data); - } -} - -public static class AndroidtvEntityExtensionMethods -{ - ///<summary>Sends an ADB command to an Android / Fire TV device.</summary> - public static void AdbCommand(this IMediaPlayerEntityCore target, AndroidtvAdbCommandParameters data) - { - target.CallService("adb_command", data); - } - - ///<summary>Sends an ADB command to an Android / Fire TV device.</summary> - public static void AdbCommand(this IEnumerable<IMediaPlayerEntityCore> target, AndroidtvAdbCommandParameters data) - { - target.CallService("adb_command", data); - } - - ///<summary>Sends an ADB command to an Android / Fire TV device.</summary> - ///<param name="target">The IMediaPlayerEntityCore to call this service for</param> - ///<param name="command">Either a key command or an ADB shell command. eg: HOME</param> - public static void AdbCommand(this IMediaPlayerEntityCore target, string command) - { - target.CallService("adb_command", new AndroidtvAdbCommandParameters { Command = command }); - } - - ///<summary>Sends an ADB command to an Android / Fire TV device.</summary> - ///<param name="target">The IEnumerable<IMediaPlayerEntityCore> to call this service for</param> - ///<param name="command">Either a key command or an ADB shell command. eg: HOME</param> - public static void AdbCommand(this IEnumerable<IMediaPlayerEntityCore> target, string command) - { - target.CallService("adb_command", new AndroidtvAdbCommandParameters { Command = command }); - } - - ///<summary>Downloads a file from your Android / Fire TV device to your Home Assistant instance.</summary> - public static void Download(this IMediaPlayerEntityCore target, AndroidtvDownloadParameters data) - { - target.CallService("download", data); - } - - ///<summary>Downloads a file from your Android / Fire TV device to your Home Assistant instance.</summary> - public static void Download(this IEnumerable<IMediaPlayerEntityCore> target, AndroidtvDownloadParameters data) - { - target.CallService("download", data); - } - - ///<summary>Downloads a file from your Android / Fire TV device to your Home Assistant instance.</summary> - ///<param name="target">The IMediaPlayerEntityCore to call this service for</param> - ///<param name="devicePath">The filepath on the Android / Fire TV device. eg: /storage/emulated/0/Download/example.txt</param> - ///<param name="localPath">The filepath on your Home Assistant instance. eg: /config/www/example.txt</param> - public static void Download(this IMediaPlayerEntityCore target, string devicePath, string localPath) - { - target.CallService("download", new AndroidtvDownloadParameters { DevicePath = devicePath, LocalPath = localPath }); - } - - ///<summary>Downloads a file from your Android / Fire TV device to your Home Assistant instance.</summary> - ///<param name="target">The IEnumerable<IMediaPlayerEntityCore> to call this service for</param> - ///<param name="devicePath">The filepath on the Android / Fire TV device. eg: /storage/emulated/0/Download/example.txt</param> - ///<param name="localPath">The filepath on your Home Assistant instance. eg: /config/www/example.txt</param> - public static void Download(this IEnumerable<IMediaPlayerEntityCore> target, string devicePath, string localPath) - { - target.CallService("download", new AndroidtvDownloadParameters { DevicePath = devicePath, LocalPath = localPath }); - } - - ///<summary>Translates a key press on a remote into ADB 'sendevent' commands. You must press one button on the remote within 8 seconds of performing this action.</summary> - public static void LearnSendevent(this IMediaPlayerEntityCore target, object? data = null) - { - target.CallService("learn_sendevent", data); - } - - ///<summary>Translates a key press on a remote into ADB 'sendevent' commands. You must press one button on the remote within 8 seconds of performing this action.</summary> - public static void LearnSendevent(this IEnumerable<IMediaPlayerEntityCore> target, object? data = null) - { - target.CallService("learn_sendevent", data); - } - - ///<summary>Uploads a file from your Home Assistant instance to an Android / Fire TV device.</summary> - public static void Upload(this IMediaPlayerEntityCore target, AndroidtvUploadParameters data) - { - target.CallService("upload", data); - } - - ///<summary>Uploads a file from your Home Assistant instance to an Android / Fire TV device.</summary> - public static void Upload(this IEnumerable<IMediaPlayerEntityCore> target, AndroidtvUploadParameters data) - { - target.CallService("upload", data); - } - - ///<summary>Uploads a file from your Home Assistant instance to an Android / Fire TV device.</summary> - ///<param name="target">The IMediaPlayerEntityCore to call this service for</param> - ///<param name="devicePath">The filepath on the Android / Fire TV device. eg: /storage/emulated/0/Download/example.txt</param> - ///<param name="localPath">The filepath on your Home Assistant instance. eg: /config/www/example.txt</param> - public static void Upload(this IMediaPlayerEntityCore target, string devicePath, string localPath) - { - target.CallService("upload", new AndroidtvUploadParameters { DevicePath = devicePath, LocalPath = localPath }); - } - - ///<summary>Uploads a file from your Home Assistant instance to an Android / Fire TV device.</summary> - ///<param name="target">The IEnumerable<IMediaPlayerEntityCore> to call this service for</param> - ///<param name="devicePath">The filepath on the Android / Fire TV device. eg: /storage/emulated/0/Download/example.txt</param> - ///<param name="localPath">The filepath on your Home Assistant instance. eg: /config/www/example.txt</param> - public static void Upload(this IEnumerable<IMediaPlayerEntityCore> target, string devicePath, string localPath) - { - target.CallService("upload", new AndroidtvUploadParameters { DevicePath = devicePath, LocalPath = localPath }); - } -} - -public static class AssistSatelliteEntityExtensionMethods -{ - ///<summary>Lets a satellite announce a message.</summary> - public static void Announce(this AssistSatelliteEntity target, AssistSatelliteAnnounceParameters data) - { - target.CallService("announce", data); - } - - ///<summary>Lets a satellite announce a message.</summary> - public static void Announce(this IEnumerable<AssistSatelliteEntity> target, AssistSatelliteAnnounceParameters data) - { - target.CallService("announce", data); - } - - ///<summary>Lets a satellite announce a message.</summary> - ///<param name="target">The AssistSatelliteEntity to call this service for</param> - ///<param name="message">The message to announce. eg: Time to wake up!</param> - ///<param name="mediaId">The media ID to announce instead of using text-to-speech.</param> - public static void Announce(this AssistSatelliteEntity target, string? message = null, string? mediaId = null) - { - target.CallService("announce", new AssistSatelliteAnnounceParameters { Message = message, MediaId = mediaId }); - } - - ///<summary>Lets a satellite announce a message.</summary> - ///<param name="target">The IEnumerable<AssistSatelliteEntity> to call this service for</param> - ///<param name="message">The message to announce. eg: Time to wake up!</param> - ///<param name="mediaId">The media ID to announce instead of using text-to-speech.</param> - public static void Announce(this IEnumerable<AssistSatelliteEntity> target, string? message = null, string? mediaId = null) - { - target.CallService("announce", new AssistSatelliteAnnounceParameters { Message = message, MediaId = mediaId }); - } - - ///<summary>Starts a conversation from a satellite.</summary> - public static void StartConversation(this AssistSatelliteEntity target, AssistSatelliteStartConversationParameters data) - { - target.CallService("start_conversation", data); - } - - ///<summary>Starts a conversation from a satellite.</summary> - public static void StartConversation(this IEnumerable<AssistSatelliteEntity> target, AssistSatelliteStartConversationParameters data) - { - target.CallService("start_conversation", data); - } - - ///<summary>Starts a conversation from a satellite.</summary> - ///<param name="target">The AssistSatelliteEntity to call this service for</param> - ///<param name="startMessage">The message to start with. eg: You left the lights on in the living room. Turn them off?</param> - ///<param name="startMediaId">The media ID to start with instead of using text-to-speech.</param> - ///<param name="extraSystemPrompt">Provide background information to the AI about the request.</param> - public static void StartConversation(this AssistSatelliteEntity target, string? startMessage = null, string? startMediaId = null, string? extraSystemPrompt = null) - { - target.CallService("start_conversation", new AssistSatelliteStartConversationParameters { StartMessage = startMessage, StartMediaId = startMediaId, ExtraSystemPrompt = extraSystemPrompt }); - } - - ///<summary>Starts a conversation from a satellite.</summary> - ///<param name="target">The IEnumerable<AssistSatelliteEntity> to call this service for</param> - ///<param name="startMessage">The message to start with. eg: You left the lights on in the living room. Turn them off?</param> - ///<param name="startMediaId">The media ID to start with instead of using text-to-speech.</param> - ///<param name="extraSystemPrompt">Provide background information to the AI about the request.</param> - public static void StartConversation(this IEnumerable<AssistSatelliteEntity> target, string? startMessage = null, string? startMediaId = null, string? extraSystemPrompt = null) - { - target.CallService("start_conversation", new AssistSatelliteStartConversationParameters { StartMessage = startMessage, StartMediaId = startMediaId, ExtraSystemPrompt = extraSystemPrompt }); - } -} - -public static class AutomationEntityExtensionMethods -{ - ///<summary>Toggles (enable / disable) an automation.</summary> - public static void Toggle(this IAutomationEntityCore target, object? data = null) - { - target.CallService("toggle", data); - } - - ///<summary>Toggles (enable / disable) an automation.</summary> - public static void Toggle(this IEnumerable<IAutomationEntityCore> target, object? data = null) - { - target.CallService("toggle", data); - } - - ///<summary>Triggers the actions of an automation.</summary> - public static void Trigger(this IAutomationEntityCore target, AutomationTriggerParameters data) - { - target.CallService("trigger", data); - } - - ///<summary>Triggers the actions of an automation.</summary> - public static void Trigger(this IEnumerable<IAutomationEntityCore> target, AutomationTriggerParameters data) - { - target.CallService("trigger", data); - } - - ///<summary>Triggers the actions of an automation.</summary> - ///<param name="target">The IAutomationEntityCore to call this service for</param> - ///<param name="skipCondition">Defines whether or not the conditions will be skipped.</param> - public static void Trigger(this IAutomationEntityCore target, bool? skipCondition = null) - { - target.CallService("trigger", new AutomationTriggerParameters { SkipCondition = skipCondition }); - } - - ///<summary>Triggers the actions of an automation.</summary> - ///<param name="target">The IEnumerable<IAutomationEntityCore> to call this service for</param> - ///<param name="skipCondition">Defines whether or not the conditions will be skipped.</param> - public static void Trigger(this IEnumerable<IAutomationEntityCore> target, bool? skipCondition = null) - { - target.CallService("trigger", new AutomationTriggerParameters { SkipCondition = skipCondition }); - } - - ///<summary>Disables an automation.</summary> - public static void TurnOff(this IAutomationEntityCore target, AutomationTurnOffParameters data) - { - target.CallService("turn_off", data); - } - - ///<summary>Disables an automation.</summary> - public static void TurnOff(this IEnumerable<IAutomationEntityCore> target, AutomationTurnOffParameters data) - { - target.CallService("turn_off", data); - } - - ///<summary>Disables an automation.</summary> - ///<param name="target">The IAutomationEntityCore to call this service for</param> - ///<param name="stopActions">Stops currently running actions.</param> - public static void TurnOff(this IAutomationEntityCore target, bool? stopActions = null) - { - target.CallService("turn_off", new AutomationTurnOffParameters { StopActions = stopActions }); - } - - ///<summary>Disables an automation.</summary> - ///<param name="target">The IEnumerable<IAutomationEntityCore> to call this service for</param> - ///<param name="stopActions">Stops currently running actions.</param> - public static void TurnOff(this IEnumerable<IAutomationEntityCore> target, bool? stopActions = null) - { - target.CallService("turn_off", new AutomationTurnOffParameters { StopActions = stopActions }); - } - - ///<summary>Enables an automation.</summary> - public static void TurnOn(this IAutomationEntityCore target, object? data = null) - { - target.CallService("turn_on", data); - } - - ///<summary>Enables an automation.</summary> - public static void TurnOn(this IEnumerable<IAutomationEntityCore> target, object? data = null) - { - target.CallService("turn_on", data); - } -} - -public static class ButtonEntityExtensionMethods -{ - ///<summary>Press the button entity.</summary> - public static void Press(this IButtonEntityCore target, object? data = null) - { - target.CallService("press", data); - } - - ///<summary>Press the button entity.</summary> - public static void Press(this IEnumerable<IButtonEntityCore> target, object? data = null) - { - target.CallService("press", data); - } -} - -public static class CalendarEntityExtensionMethods -{ - ///<summary>Adds a new calendar event.</summary> - public static void CreateEvent(this ICalendarEntityCore target, CalendarCreateEventParameters data) - { - target.CallService("create_event", data); - } - - ///<summary>Adds a new calendar event.</summary> - public static void CreateEvent(this IEnumerable<ICalendarEntityCore> target, CalendarCreateEventParameters data) - { - target.CallService("create_event", data); - } - - ///<summary>Adds a new calendar event.</summary> - ///<param name="target">The ICalendarEntityCore to call this service for</param> - ///<param name="summary">Defines the short summary or subject for the event. eg: Department Party</param> - ///<param name="description">A more complete description of the event than the one provided by the summary. eg: Meeting to provide technical review for 'Phoenix' design.</param> - ///<param name="startDateTime">The date and time the event should start. eg: 2022-03-22 20:00:00</param> - ///<param name="endDateTime">The date and time the event should end. eg: 2022-03-22 22:00:00</param> - ///<param name="startDate">The date the all-day event should start. eg: 2022-03-22</param> - ///<param name="endDate">The date the all-day event should end (exclusive). eg: 2022-03-23</param> - ///<param name="in">Days or weeks that you want to create the event in. eg: {"days": 2} or {"weeks": 2}</param> - ///<param name="location">The location of the event. eg: Conference Room - F123, Bldg. 002</param> - public static void CreateEvent(this ICalendarEntityCore target, string summary, string? description = null, DateTime? startDateTime = null, DateTime? endDateTime = null, DateOnly? startDate = null, DateOnly? endDate = null, object? @in = null, string? location = null) - { - target.CallService("create_event", new CalendarCreateEventParameters { Summary = summary, Description = description, StartDateTime = startDateTime, EndDateTime = endDateTime, StartDate = startDate, EndDate = endDate, In = @in, Location = location }); - } - - ///<summary>Adds a new calendar event.</summary> - ///<param name="target">The IEnumerable<ICalendarEntityCore> to call this service for</param> - ///<param name="summary">Defines the short summary or subject for the event. eg: Department Party</param> - ///<param name="description">A more complete description of the event than the one provided by the summary. eg: Meeting to provide technical review for 'Phoenix' design.</param> - ///<param name="startDateTime">The date and time the event should start. eg: 2022-03-22 20:00:00</param> - ///<param name="endDateTime">The date and time the event should end. eg: 2022-03-22 22:00:00</param> - ///<param name="startDate">The date the all-day event should start. eg: 2022-03-22</param> - ///<param name="endDate">The date the all-day event should end (exclusive). eg: 2022-03-23</param> - ///<param name="in">Days or weeks that you want to create the event in. eg: {"days": 2} or {"weeks": 2}</param> - ///<param name="location">The location of the event. eg: Conference Room - F123, Bldg. 002</param> - public static void CreateEvent(this IEnumerable<ICalendarEntityCore> target, string summary, string? description = null, DateTime? startDateTime = null, DateTime? endDateTime = null, DateOnly? startDate = null, DateOnly? endDate = null, object? @in = null, string? location = null) - { - target.CallService("create_event", new CalendarCreateEventParameters { Summary = summary, Description = description, StartDateTime = startDateTime, EndDateTime = endDateTime, StartDate = startDate, EndDate = endDate, In = @in, Location = location }); - } - - ///<summary>Get events on a calendar within a time range.</summary> - public static Task<JsonElement?> GetEventsAsync(this ICalendarEntityCore target, CalendarGetEventsParameters data) - { - return target.CallServiceWithResponseAsync("get_events", data); - } - - ///<summary>Get events on a calendar within a time range.</summary> - ///<param name="target">The ICalendarEntityCore to call this service for</param> - ///<param name="startDateTime">Returns active events after this time (exclusive). When not set, defaults to now. eg: 2022-03-22 20:00:00</param> - ///<param name="endDateTime">Returns active events before this time (exclusive). Cannot be used with Duration. eg: 2022-03-22 22:00:00</param> - ///<param name="duration">Returns active events from Start time for the specified duration.</param> - public static Task<JsonElement?> GetEventsAsync(this ICalendarEntityCore target, DateTime? startDateTime = null, DateTime? endDateTime = null, object? duration = null) - { - return target.CallServiceWithResponseAsync("get_events", new CalendarGetEventsParameters { StartDateTime = startDateTime, EndDateTime = endDateTime, Duration = duration }); - } - - ///<summary>Get events on a calendar within a time range.</summary> - public static void GetEvents(this ICalendarEntityCore target, CalendarGetEventsParameters data) - { - target.CallService("get_events", data); - } - - ///<summary>Get events on a calendar within a time range.</summary> - public static void GetEvents(this IEnumerable<ICalendarEntityCore> target, CalendarGetEventsParameters data) - { - target.CallService("get_events", data); - } - - ///<summary>Get events on a calendar within a time range.</summary> - ///<param name="target">The ICalendarEntityCore to call this service for</param> - ///<param name="startDateTime">Returns active events after this time (exclusive). When not set, defaults to now. eg: 2022-03-22 20:00:00</param> - ///<param name="endDateTime">Returns active events before this time (exclusive). Cannot be used with Duration. eg: 2022-03-22 22:00:00</param> - ///<param name="duration">Returns active events from Start time for the specified duration.</param> - public static void GetEvents(this ICalendarEntityCore target, DateTime? startDateTime = null, DateTime? endDateTime = null, object? duration = null) - { - target.CallService("get_events", new CalendarGetEventsParameters { StartDateTime = startDateTime, EndDateTime = endDateTime, Duration = duration }); - } - - ///<summary>Get events on a calendar within a time range.</summary> - ///<param name="target">The IEnumerable<ICalendarEntityCore> to call this service for</param> - ///<param name="startDateTime">Returns active events after this time (exclusive). When not set, defaults to now. eg: 2022-03-22 20:00:00</param> - ///<param name="endDateTime">Returns active events before this time (exclusive). Cannot be used with Duration. eg: 2022-03-22 22:00:00</param> - ///<param name="duration">Returns active events from Start time for the specified duration.</param> - public static void GetEvents(this IEnumerable<ICalendarEntityCore> target, DateTime? startDateTime = null, DateTime? endDateTime = null, object? duration = null) - { - target.CallService("get_events", new CalendarGetEventsParameters { StartDateTime = startDateTime, EndDateTime = endDateTime, Duration = duration }); - } -} - -public static class InputBooleanEntityExtensionMethods -{ - ///<summary>Toggles the helper on/off.</summary> - public static void Toggle(this IInputBooleanEntityCore target, object? data = null) - { - target.CallService("toggle", data); - } - - ///<summary>Toggles the helper on/off.</summary> - public static void Toggle(this IEnumerable<IInputBooleanEntityCore> target, object? data = null) - { - target.CallService("toggle", data); - } - - ///<summary>Turns off the helper.</summary> - public static void TurnOff(this IInputBooleanEntityCore target, object? data = null) - { - target.CallService("turn_off", data); - } - - ///<summary>Turns off the helper.</summary> - public static void TurnOff(this IEnumerable<IInputBooleanEntityCore> target, object? data = null) - { - target.CallService("turn_off", data); - } - - ///<summary>Turns on the helper.</summary> - public static void TurnOn(this IInputBooleanEntityCore target, object? data = null) - { - target.CallService("turn_on", data); - } - - ///<summary>Turns on the helper.</summary> - public static void TurnOn(this IEnumerable<IInputBooleanEntityCore> target, object? data = null) - { - target.CallService("turn_on", data); - } -} - -public static class InputNumberEntityExtensionMethods -{ - ///<summary>Decrements the current value by 1 step.</summary> - public static void Decrement(this IInputNumberEntityCore target, object? data = null) - { - target.CallService("decrement", data); - } - - ///<summary>Decrements the current value by 1 step.</summary> - public static void Decrement(this IEnumerable<IInputNumberEntityCore> target, object? data = null) - { - target.CallService("decrement", data); - } - - ///<summary>Increments the current value by 1 step.</summary> - public static void Increment(this IInputNumberEntityCore target, object? data = null) - { - target.CallService("increment", data); - } - - ///<summary>Increments the current value by 1 step.</summary> - public static void Increment(this IEnumerable<IInputNumberEntityCore> target, object? data = null) - { - target.CallService("increment", data); - } - - ///<summary>Sets the value.</summary> - public static void SetValue(this IInputNumberEntityCore target, InputNumberSetValueParameters data) - { - target.CallService("set_value", data); - } - - ///<summary>Sets the value.</summary> - public static void SetValue(this IEnumerable<IInputNumberEntityCore> target, InputNumberSetValueParameters data) - { - target.CallService("set_value", data); - } - - ///<summary>Sets the value.</summary> - ///<param name="target">The IInputNumberEntityCore to call this service for</param> - ///<param name="value">The target value.</param> - public static void SetValue(this IInputNumberEntityCore target, double value) - { - target.CallService("set_value", new InputNumberSetValueParameters { Value = value }); - } - - ///<summary>Sets the value.</summary> - ///<param name="target">The IEnumerable<IInputNumberEntityCore> to call this service for</param> - ///<param name="value">The target value.</param> - public static void SetValue(this IEnumerable<IInputNumberEntityCore> target, double value) - { - target.CallService("set_value", new InputNumberSetValueParameters { Value = value }); - } -} - -public static class InputTextEntityExtensionMethods -{ - ///<summary>Sets the value.</summary> - public static void SetValue(this IInputTextEntityCore target, InputTextSetValueParameters data) - { - target.CallService("set_value", data); - } - - ///<summary>Sets the value.</summary> - public static void SetValue(this IEnumerable<IInputTextEntityCore> target, InputTextSetValueParameters data) - { - target.CallService("set_value", data); - } - - ///<summary>Sets the value.</summary> - ///<param name="target">The IInputTextEntityCore to call this service for</param> - ///<param name="value">The target value. eg: This is an example text</param> - public static void SetValue(this IInputTextEntityCore target, string value) - { - target.CallService("set_value", new InputTextSetValueParameters { Value = value }); - } - - ///<summary>Sets the value.</summary> - ///<param name="target">The IEnumerable<IInputTextEntityCore> to call this service for</param> - ///<param name="value">The target value. eg: This is an example text</param> - public static void SetValue(this IEnumerable<IInputTextEntityCore> target, string value) - { - target.CallService("set_value", new InputTextSetValueParameters { Value = value }); - } -} - -public static class LightEntityExtensionMethods -{ - ///<summary>Toggles one or more lights, from on to off, or off to on, based on their current state.</summary> - public static void Toggle(this ILightEntityCore target, LightToggleParameters data) - { - target.CallService("toggle", data); - } - - ///<summary>Toggles one or more lights, from on to off, or off to on, based on their current state.</summary> - public static void Toggle(this IEnumerable<ILightEntityCore> target, LightToggleParameters data) - { - target.CallService("toggle", data); - } - - ///<summary>Toggles one or more lights, from on to off, or off to on, based on their current state.</summary> - ///<param name="target">The ILightEntityCore to call this service for</param> - ///<param name="transition">Duration it takes to get to next state.</param> - ///<param name="rgbColor">The color in RGB format. A list of three integers between 0 and 255 representing the values of red, green, and blue. eg: [255, 100, 100]</param> - ///<param name="kelvin">Color temperature in Kelvin.</param> - ///<param name="brightnessPct">Number indicating the percentage of full brightness, where 0 turns the light off, 1 is the minimum brightness, and 100 is the maximum brightness.</param> - ///<param name="effect">Light effect.</param> - ///<param name="rgbwColor"> eg: [255, 100, 100, 50]</param> - ///<param name="rgbwwColor"> eg: [255, 100, 100, 50, 70]</param> - ///<param name="colorName"></param> - ///<param name="hsColor"> eg: [300, 70]</param> - ///<param name="xyColor"> eg: [0.52, 0.43]</param> - ///<param name="colorTemp"></param> - ///<param name="brightness"></param> - ///<param name="white"></param> - ///<param name="profile"> eg: relax</param> - ///<param name="flash"></param> - public static void Toggle(this ILightEntityCore target, double? transition = null, IReadOnlyCollection<int>? rgbColor = null, object? kelvin = null, double? brightnessPct = null, string? effect = null, object? rgbwColor = null, object? rgbwwColor = null, object? colorName = null, object? hsColor = null, object? xyColor = null, object? colorTemp = null, double? brightness = null, object? white = null, string? profile = null, object? flash = null) - { - target.CallService("toggle", new LightToggleParameters { Transition = transition, RgbColor = rgbColor, Kelvin = kelvin, BrightnessPct = brightnessPct, Effect = effect, RgbwColor = rgbwColor, RgbwwColor = rgbwwColor, ColorName = colorName, HsColor = hsColor, XyColor = xyColor, ColorTemp = colorTemp, Brightness = brightness, White = white, Profile = profile, Flash = flash }); - } - - ///<summary>Toggles one or more lights, from on to off, or off to on, based on their current state.</summary> - ///<param name="target">The IEnumerable<ILightEntityCore> to call this service for</param> - ///<param name="transition">Duration it takes to get to next state.</param> - ///<param name="rgbColor">The color in RGB format. A list of three integers between 0 and 255 representing the values of red, green, and blue. eg: [255, 100, 100]</param> - ///<param name="kelvin">Color temperature in Kelvin.</param> - ///<param name="brightnessPct">Number indicating the percentage of full brightness, where 0 turns the light off, 1 is the minimum brightness, and 100 is the maximum brightness.</param> - ///<param name="effect">Light effect.</param> - ///<param name="rgbwColor"> eg: [255, 100, 100, 50]</param> - ///<param name="rgbwwColor"> eg: [255, 100, 100, 50, 70]</param> - ///<param name="colorName"></param> - ///<param name="hsColor"> eg: [300, 70]</param> - ///<param name="xyColor"> eg: [0.52, 0.43]</param> - ///<param name="colorTemp"></param> - ///<param name="brightness"></param> - ///<param name="white"></param> - ///<param name="profile"> eg: relax</param> - ///<param name="flash"></param> - public static void Toggle(this IEnumerable<ILightEntityCore> target, double? transition = null, IReadOnlyCollection<int>? rgbColor = null, object? kelvin = null, double? brightnessPct = null, string? effect = null, object? rgbwColor = null, object? rgbwwColor = null, object? colorName = null, object? hsColor = null, object? xyColor = null, object? colorTemp = null, double? brightness = null, object? white = null, string? profile = null, object? flash = null) - { - target.CallService("toggle", new LightToggleParameters { Transition = transition, RgbColor = rgbColor, Kelvin = kelvin, BrightnessPct = brightnessPct, Effect = effect, RgbwColor = rgbwColor, RgbwwColor = rgbwwColor, ColorName = colorName, HsColor = hsColor, XyColor = xyColor, ColorTemp = colorTemp, Brightness = brightness, White = white, Profile = profile, Flash = flash }); - } - - ///<summary>Turns off one or more lights.</summary> - public static void TurnOff(this ILightEntityCore target, LightTurnOffParameters data) - { - target.CallService("turn_off", data); - } - - ///<summary>Turns off one or more lights.</summary> - public static void TurnOff(this IEnumerable<ILightEntityCore> target, LightTurnOffParameters data) - { - target.CallService("turn_off", data); - } - - ///<summary>Turns off one or more lights.</summary> - ///<param name="target">The ILightEntityCore to call this service for</param> - ///<param name="transition">Duration it takes to get to next state.</param> - ///<param name="flash"></param> - public static void TurnOff(this ILightEntityCore target, double? transition = null, object? flash = null) - { - target.CallService("turn_off", new LightTurnOffParameters { Transition = transition, Flash = flash }); - } - - ///<summary>Turns off one or more lights.</summary> - ///<param name="target">The IEnumerable<ILightEntityCore> to call this service for</param> - ///<param name="transition">Duration it takes to get to next state.</param> - ///<param name="flash"></param> - public static void TurnOff(this IEnumerable<ILightEntityCore> target, double? transition = null, object? flash = null) - { - target.CallService("turn_off", new LightTurnOffParameters { Transition = transition, Flash = flash }); - } - - ///<summary>Turns on one or more lights and adjusts their properties, even when they are turned on already.</summary> - public static void TurnOn(this ILightEntityCore target, LightTurnOnParameters data) - { - target.CallService("turn_on", data); - } - - ///<summary>Turns on one or more lights and adjusts their properties, even when they are turned on already.</summary> - public static void TurnOn(this IEnumerable<ILightEntityCore> target, LightTurnOnParameters data) - { - target.CallService("turn_on", data); - } - - ///<summary>Turns on one or more lights and adjusts their properties, even when they are turned on already.</summary> - ///<param name="target">The ILightEntityCore to call this service for</param> - ///<param name="transition">Duration it takes to get to next state.</param> - ///<param name="rgbColor">The color in RGB format. A list of three integers between 0 and 255 representing the values of red, green, and blue. eg: [255, 100, 100]</param> - ///<param name="kelvin">Color temperature in Kelvin.</param> - ///<param name="brightnessPct">Number indicating the percentage of full brightness, where 0 turns the light off, 1 is the minimum brightness, and 100 is the maximum brightness.</param> - ///<param name="brightnessStepPct">Change brightness by a percentage.</param> - ///<param name="effect">Light effect.</param> - ///<param name="rgbwColor"> eg: [255, 100, 100, 50]</param> - ///<param name="rgbwwColor"> eg: [255, 100, 100, 50, 70]</param> - ///<param name="colorName"></param> - ///<param name="hsColor"> eg: [300, 70]</param> - ///<param name="xyColor"> eg: [0.52, 0.43]</param> - ///<param name="colorTemp"></param> - ///<param name="brightness"></param> - ///<param name="brightnessStep"></param> - ///<param name="white"></param> - ///<param name="profile"> eg: relax</param> - ///<param name="flash"></param> - public static void TurnOn(this ILightEntityCore target, double? transition = null, IReadOnlyCollection<int>? rgbColor = null, object? kelvin = null, double? brightnessPct = null, double? brightnessStepPct = null, string? effect = null, object? rgbwColor = null, object? rgbwwColor = null, object? colorName = null, object? hsColor = null, object? xyColor = null, object? colorTemp = null, double? brightness = null, double? brightnessStep = null, object? white = null, string? profile = null, object? flash = null) - { - target.CallService("turn_on", new LightTurnOnParameters { Transition = transition, RgbColor = rgbColor, Kelvin = kelvin, BrightnessPct = brightnessPct, BrightnessStepPct = brightnessStepPct, Effect = effect, RgbwColor = rgbwColor, RgbwwColor = rgbwwColor, ColorName = colorName, HsColor = hsColor, XyColor = xyColor, ColorTemp = colorTemp, Brightness = brightness, BrightnessStep = brightnessStep, White = white, Profile = profile, Flash = flash }); - } - - ///<summary>Turns on one or more lights and adjusts their properties, even when they are turned on already.</summary> - ///<param name="target">The IEnumerable<ILightEntityCore> to call this service for</param> - ///<param name="transition">Duration it takes to get to next state.</param> - ///<param name="rgbColor">The color in RGB format. A list of three integers between 0 and 255 representing the values of red, green, and blue. eg: [255, 100, 100]</param> - ///<param name="kelvin">Color temperature in Kelvin.</param> - ///<param name="brightnessPct">Number indicating the percentage of full brightness, where 0 turns the light off, 1 is the minimum brightness, and 100 is the maximum brightness.</param> - ///<param name="brightnessStepPct">Change brightness by a percentage.</param> - ///<param name="effect">Light effect.</param> - ///<param name="rgbwColor"> eg: [255, 100, 100, 50]</param> - ///<param name="rgbwwColor"> eg: [255, 100, 100, 50, 70]</param> - ///<param name="colorName"></param> - ///<param name="hsColor"> eg: [300, 70]</param> - ///<param name="xyColor"> eg: [0.52, 0.43]</param> - ///<param name="colorTemp"></param> - ///<param name="brightness"></param> - ///<param name="brightnessStep"></param> - ///<param name="white"></param> - ///<param name="profile"> eg: relax</param> - ///<param name="flash"></param> - public static void TurnOn(this IEnumerable<ILightEntityCore> target, double? transition = null, IReadOnlyCollection<int>? rgbColor = null, object? kelvin = null, double? brightnessPct = null, double? brightnessStepPct = null, string? effect = null, object? rgbwColor = null, object? rgbwwColor = null, object? colorName = null, object? hsColor = null, object? xyColor = null, object? colorTemp = null, double? brightness = null, double? brightnessStep = null, object? white = null, string? profile = null, object? flash = null) - { - target.CallService("turn_on", new LightTurnOnParameters { Transition = transition, RgbColor = rgbColor, Kelvin = kelvin, BrightnessPct = brightnessPct, BrightnessStepPct = brightnessStepPct, Effect = effect, RgbwColor = rgbwColor, RgbwwColor = rgbwwColor, ColorName = colorName, HsColor = hsColor, XyColor = xyColor, ColorTemp = colorTemp, Brightness = brightness, BrightnessStep = brightnessStep, White = white, Profile = profile, Flash = flash }); - } -} - -public static class LockEntityExtensionMethods -{ - ///<summary>Locks a lock.</summary> - public static void Lock(this ILockEntityCore target, LockLockParameters data) - { - target.CallService("lock", data); - } - - ///<summary>Locks a lock.</summary> - public static void Lock(this IEnumerable<ILockEntityCore> target, LockLockParameters data) - { - target.CallService("lock", data); - } - - ///<summary>Locks a lock.</summary> - ///<param name="target">The ILockEntityCore to call this service for</param> - ///<param name="code">Code used to lock the lock. eg: 1234</param> - public static void Lock(this ILockEntityCore target, string? code = null) - { - target.CallService("lock", new LockLockParameters { Code = code }); - } - - ///<summary>Locks a lock.</summary> - ///<param name="target">The IEnumerable<ILockEntityCore> to call this service for</param> - ///<param name="code">Code used to lock the lock. eg: 1234</param> - public static void Lock(this IEnumerable<ILockEntityCore> target, string? code = null) - { - target.CallService("lock", new LockLockParameters { Code = code }); - } - - ///<summary>Opens a lock.</summary> - public static void Open(this ILockEntityCore target, LockOpenParameters data) - { - target.CallService("open", data); - } - - ///<summary>Opens a lock.</summary> - public static void Open(this IEnumerable<ILockEntityCore> target, LockOpenParameters data) - { - target.CallService("open", data); - } - - ///<summary>Opens a lock.</summary> - ///<param name="target">The ILockEntityCore to call this service for</param> - ///<param name="code">Code used to open the lock. eg: 1234</param> - public static void Open(this ILockEntityCore target, string? code = null) - { - target.CallService("open", new LockOpenParameters { Code = code }); - } - - ///<summary>Opens a lock.</summary> - ///<param name="target">The IEnumerable<ILockEntityCore> to call this service for</param> - ///<param name="code">Code used to open the lock. eg: 1234</param> - public static void Open(this IEnumerable<ILockEntityCore> target, string? code = null) - { - target.CallService("open", new LockOpenParameters { Code = code }); - } - - ///<summary>Unlocks a lock.</summary> - public static void Unlock(this ILockEntityCore target, LockUnlockParameters data) - { - target.CallService("unlock", data); - } - - ///<summary>Unlocks a lock.</summary> - public static void Unlock(this IEnumerable<ILockEntityCore> target, LockUnlockParameters data) - { - target.CallService("unlock", data); - } - - ///<summary>Unlocks a lock.</summary> - ///<param name="target">The ILockEntityCore to call this service for</param> - ///<param name="code">Code used to unlock the lock. eg: 1234</param> - public static void Unlock(this ILockEntityCore target, string? code = null) - { - target.CallService("unlock", new LockUnlockParameters { Code = code }); - } - - ///<summary>Unlocks a lock.</summary> - ///<param name="target">The IEnumerable<ILockEntityCore> to call this service for</param> - ///<param name="code">Code used to unlock the lock. eg: 1234</param> - public static void Unlock(this IEnumerable<ILockEntityCore> target, string? code = null) - { - target.CallService("unlock", new LockUnlockParameters { Code = code }); - } -} - -public static class MediaPlayerEntityExtensionMethods -{ - ///<summary>Browses the available media.</summary> - public static Task<JsonElement?> BrowseMediaAsync(this IMediaPlayerEntityCore target, MediaPlayerBrowseMediaParameters data) - { - return target.CallServiceWithResponseAsync("browse_media", data); - } - - ///<summary>Browses the available media.</summary> - ///<param name="target">The IMediaPlayerEntityCore to call this service for</param> - ///<param name="mediaContentType">The type of the content to browse, such as image, music, tv show, video, episode, channel, or playlist. eg: music</param> - ///<param name="mediaContentId">The ID of the content to browse. Integration dependent. eg: A:ALBUMARTIST/Beatles</param> - public static Task<JsonElement?> BrowseMediaAsync(this IMediaPlayerEntityCore target, string? mediaContentType = null, string? mediaContentId = null) - { - return target.CallServiceWithResponseAsync("browse_media", new MediaPlayerBrowseMediaParameters { MediaContentType = mediaContentType, MediaContentId = mediaContentId }); - } - - ///<summary>Browses the available media.</summary> - public static void BrowseMedia(this IMediaPlayerEntityCore target, MediaPlayerBrowseMediaParameters data) - { - target.CallService("browse_media", data); - } - - ///<summary>Browses the available media.</summary> - public static void BrowseMedia(this IEnumerable<IMediaPlayerEntityCore> target, MediaPlayerBrowseMediaParameters data) - { - target.CallService("browse_media", data); - } - - ///<summary>Browses the available media.</summary> - ///<param name="target">The IMediaPlayerEntityCore to call this service for</param> - ///<param name="mediaContentType">The type of the content to browse, such as image, music, tv show, video, episode, channel, or playlist. eg: music</param> - ///<param name="mediaContentId">The ID of the content to browse. Integration dependent. eg: A:ALBUMARTIST/Beatles</param> - public static void BrowseMedia(this IMediaPlayerEntityCore target, string? mediaContentType = null, string? mediaContentId = null) - { - target.CallService("browse_media", new MediaPlayerBrowseMediaParameters { MediaContentType = mediaContentType, MediaContentId = mediaContentId }); - } - - ///<summary>Browses the available media.</summary> - ///<param name="target">The IEnumerable<IMediaPlayerEntityCore> to call this service for</param> - ///<param name="mediaContentType">The type of the content to browse, such as image, music, tv show, video, episode, channel, or playlist. eg: music</param> - ///<param name="mediaContentId">The ID of the content to browse. Integration dependent. eg: A:ALBUMARTIST/Beatles</param> - public static void BrowseMedia(this IEnumerable<IMediaPlayerEntityCore> target, string? mediaContentType = null, string? mediaContentId = null) - { - target.CallService("browse_media", new MediaPlayerBrowseMediaParameters { MediaContentType = mediaContentType, MediaContentId = mediaContentId }); - } - - ///<summary>Removes all items from the playlist.</summary> - public static void ClearPlaylist(this IMediaPlayerEntityCore target, object? data = null) - { - target.CallService("clear_playlist", data); - } - - ///<summary>Removes all items from the playlist.</summary> - public static void ClearPlaylist(this IEnumerable<IMediaPlayerEntityCore> target, object? data = null) - { - target.CallService("clear_playlist", data); - } - - ///<summary>Groups media players together for synchronous playback. Only works on supported multiroom audio systems.</summary> - public static void Join(this IMediaPlayerEntityCore target, MediaPlayerJoinParameters data) - { - target.CallService("join", data); - } - - ///<summary>Groups media players together for synchronous playback. Only works on supported multiroom audio systems.</summary> - public static void Join(this IEnumerable<IMediaPlayerEntityCore> target, MediaPlayerJoinParameters data) - { - target.CallService("join", data); - } - - ///<summary>Groups media players together for synchronous playback. Only works on supported multiroom audio systems.</summary> - ///<param name="target">The IMediaPlayerEntityCore to call this service for</param> - ///<param name="groupMembers">The players which will be synced with the playback specified in 'Targets'. eg: - media_player.multiroom_player2 - media_player.multiroom_player3 </param> - public static void Join(this IMediaPlayerEntityCore target, IEnumerable<string> groupMembers) - { - target.CallService("join", new MediaPlayerJoinParameters { GroupMembers = groupMembers }); - } - - ///<summary>Groups media players together for synchronous playback. Only works on supported multiroom audio systems.</summary> - ///<param name="target">The IEnumerable<IMediaPlayerEntityCore> to call this service for</param> - ///<param name="groupMembers">The players which will be synced with the playback specified in 'Targets'. eg: - media_player.multiroom_player2 - media_player.multiroom_player3 </param> - public static void Join(this IEnumerable<IMediaPlayerEntityCore> target, IEnumerable<string> groupMembers) - { - target.CallService("join", new MediaPlayerJoinParameters { GroupMembers = groupMembers }); - } - - ///<summary>Selects the next track.</summary> - public static void MediaNextTrack(this IMediaPlayerEntityCore target, object? data = null) - { - target.CallService("media_next_track", data); - } - - ///<summary>Selects the next track.</summary> - public static void MediaNextTrack(this IEnumerable<IMediaPlayerEntityCore> target, object? data = null) - { - target.CallService("media_next_track", data); - } - - ///<summary>Pauses.</summary> - public static void MediaPause(this IMediaPlayerEntityCore target, object? data = null) - { - target.CallService("media_pause", data); - } - - ///<summary>Pauses.</summary> - public static void MediaPause(this IEnumerable<IMediaPlayerEntityCore> target, object? data = null) - { - target.CallService("media_pause", data); - } - - ///<summary>Starts playing.</summary> - public static void MediaPlay(this IMediaPlayerEntityCore target, object? data = null) - { - target.CallService("media_play", data); - } - - ///<summary>Starts playing.</summary> - public static void MediaPlay(this IEnumerable<IMediaPlayerEntityCore> target, object? data = null) - { - target.CallService("media_play", data); - } - - ///<summary>Toggles play/pause.</summary> - public static void MediaPlayPause(this IMediaPlayerEntityCore target, object? data = null) - { - target.CallService("media_play_pause", data); - } - - ///<summary>Toggles play/pause.</summary> - public static void MediaPlayPause(this IEnumerable<IMediaPlayerEntityCore> target, object? data = null) - { - target.CallService("media_play_pause", data); - } - - ///<summary>Selects the previous track.</summary> - public static void MediaPreviousTrack(this IMediaPlayerEntityCore target, object? data = null) - { - target.CallService("media_previous_track", data); - } - - ///<summary>Selects the previous track.</summary> - public static void MediaPreviousTrack(this IEnumerable<IMediaPlayerEntityCore> target, object? data = null) - { - target.CallService("media_previous_track", data); - } - - ///<summary>Allows you to go to a different part of the media that is currently playing.</summary> - public static void MediaSeek(this IMediaPlayerEntityCore target, MediaPlayerMediaSeekParameters data) - { - target.CallService("media_seek", data); - } - - ///<summary>Allows you to go to a different part of the media that is currently playing.</summary> - public static void MediaSeek(this IEnumerable<IMediaPlayerEntityCore> target, MediaPlayerMediaSeekParameters data) - { - target.CallService("media_seek", data); - } - - ///<summary>Allows you to go to a different part of the media that is currently playing.</summary> - ///<param name="target">The IMediaPlayerEntityCore to call this service for</param> - ///<param name="seekPosition">Target position in the currently playing media. The format is platform dependent.</param> - public static void MediaSeek(this IMediaPlayerEntityCore target, double seekPosition) - { - target.CallService("media_seek", new MediaPlayerMediaSeekParameters { SeekPosition = seekPosition }); - } - - ///<summary>Allows you to go to a different part of the media that is currently playing.</summary> - ///<param name="target">The IEnumerable<IMediaPlayerEntityCore> to call this service for</param> - ///<param name="seekPosition">Target position in the currently playing media. The format is platform dependent.</param> - public static void MediaSeek(this IEnumerable<IMediaPlayerEntityCore> target, double seekPosition) - { - target.CallService("media_seek", new MediaPlayerMediaSeekParameters { SeekPosition = seekPosition }); - } - - ///<summary>Stops playing.</summary> - public static void MediaStop(this IMediaPlayerEntityCore target, object? data = null) - { - target.CallService("media_stop", data); - } - - ///<summary>Stops playing.</summary> - public static void MediaStop(this IEnumerable<IMediaPlayerEntityCore> target, object? data = null) - { - target.CallService("media_stop", data); - } - - ///<summary>Starts playing specified media.</summary> - public static void PlayMedia(this IMediaPlayerEntityCore target, MediaPlayerPlayMediaParameters data) - { - target.CallService("play_media", data); - } - - ///<summary>Starts playing specified media.</summary> - public static void PlayMedia(this IEnumerable<IMediaPlayerEntityCore> target, MediaPlayerPlayMediaParameters data) - { - target.CallService("play_media", data); - } - - ///<summary>Starts playing specified media.</summary> - ///<param name="target">The IMediaPlayerEntityCore to call this service for</param> - ///<param name="mediaContentId">The ID of the content to play. Platform dependent. eg: https://home-assistant.io/images/cast/splash.png</param> - ///<param name="mediaContentType">The type of the content to play, such as image, music, tv show, video, episode, channel, or playlist. eg: music</param> - ///<param name="enqueue">If the content should be played now or be added to the queue.</param> - ///<param name="announce">If the media should be played as an announcement. eg: true</param> - public static void PlayMedia(this IMediaPlayerEntityCore target, string mediaContentId, string mediaContentType, object? enqueue = null, bool? announce = null) - { - target.CallService("play_media", new MediaPlayerPlayMediaParameters { MediaContentId = mediaContentId, MediaContentType = mediaContentType, Enqueue = enqueue, Announce = announce }); - } - - ///<summary>Starts playing specified media.</summary> - ///<param name="target">The IEnumerable<IMediaPlayerEntityCore> to call this service for</param> - ///<param name="mediaContentId">The ID of the content to play. Platform dependent. eg: https://home-assistant.io/images/cast/splash.png</param> - ///<param name="mediaContentType">The type of the content to play, such as image, music, tv show, video, episode, channel, or playlist. eg: music</param> - ///<param name="enqueue">If the content should be played now or be added to the queue.</param> - ///<param name="announce">If the media should be played as an announcement. eg: true</param> - public static void PlayMedia(this IEnumerable<IMediaPlayerEntityCore> target, string mediaContentId, string mediaContentType, object? enqueue = null, bool? announce = null) - { - target.CallService("play_media", new MediaPlayerPlayMediaParameters { MediaContentId = mediaContentId, MediaContentType = mediaContentType, Enqueue = enqueue, Announce = announce }); - } - - ///<summary>Sets the repeat mode.</summary> - public static void RepeatSet(this IMediaPlayerEntityCore target, MediaPlayerRepeatSetParameters data) - { - target.CallService("repeat_set", data); - } - - ///<summary>Sets the repeat mode.</summary> - public static void RepeatSet(this IEnumerable<IMediaPlayerEntityCore> target, MediaPlayerRepeatSetParameters data) - { - target.CallService("repeat_set", data); - } - - ///<summary>Sets the repeat mode.</summary> - ///<param name="target">The IMediaPlayerEntityCore to call this service for</param> - ///<param name="repeat">Whether the media (one or all) should be played in a loop or not.</param> - public static void RepeatSet(this IMediaPlayerEntityCore target, object repeat) - { - target.CallService("repeat_set", new MediaPlayerRepeatSetParameters { Repeat = repeat }); - } - - ///<summary>Sets the repeat mode.</summary> - ///<param name="target">The IEnumerable<IMediaPlayerEntityCore> to call this service for</param> - ///<param name="repeat">Whether the media (one or all) should be played in a loop or not.</param> - public static void RepeatSet(this IEnumerable<IMediaPlayerEntityCore> target, object repeat) - { - target.CallService("repeat_set", new MediaPlayerRepeatSetParameters { Repeat = repeat }); - } - - ///<summary>Selects a specific sound mode.</summary> - public static void SelectSoundMode(this IMediaPlayerEntityCore target, MediaPlayerSelectSoundModeParameters data) - { - target.CallService("select_sound_mode", data); - } - - ///<summary>Selects a specific sound mode.</summary> - public static void SelectSoundMode(this IEnumerable<IMediaPlayerEntityCore> target, MediaPlayerSelectSoundModeParameters data) - { - target.CallService("select_sound_mode", data); - } - - ///<summary>Selects a specific sound mode.</summary> - ///<param name="target">The IMediaPlayerEntityCore to call this service for</param> - ///<param name="soundMode">Name of the sound mode to switch to. eg: Music</param> - public static void SelectSoundMode(this IMediaPlayerEntityCore target, string? soundMode = null) - { - target.CallService("select_sound_mode", new MediaPlayerSelectSoundModeParameters { SoundMode = soundMode }); - } - - ///<summary>Selects a specific sound mode.</summary> - ///<param name="target">The IEnumerable<IMediaPlayerEntityCore> to call this service for</param> - ///<param name="soundMode">Name of the sound mode to switch to. eg: Music</param> - public static void SelectSoundMode(this IEnumerable<IMediaPlayerEntityCore> target, string? soundMode = null) - { - target.CallService("select_sound_mode", new MediaPlayerSelectSoundModeParameters { SoundMode = soundMode }); - } - - ///<summary>Sends the media player the command to change input source.</summary> - public static void SelectSource(this IMediaPlayerEntityCore target, MediaPlayerSelectSourceParameters data) - { - target.CallService("select_source", data); - } - - ///<summary>Sends the media player the command to change input source.</summary> - public static void SelectSource(this IEnumerable<IMediaPlayerEntityCore> target, MediaPlayerSelectSourceParameters data) - { - target.CallService("select_source", data); - } - - ///<summary>Sends the media player the command to change input source.</summary> - ///<param name="target">The IMediaPlayerEntityCore to call this service for</param> - ///<param name="source">Name of the source to switch to. Platform dependent. eg: video1</param> - public static void SelectSource(this IMediaPlayerEntityCore target, string source) - { - target.CallService("select_source", new MediaPlayerSelectSourceParameters { Source = source }); - } - - ///<summary>Sends the media player the command to change input source.</summary> - ///<param name="target">The IEnumerable<IMediaPlayerEntityCore> to call this service for</param> - ///<param name="source">Name of the source to switch to. Platform dependent. eg: video1</param> - public static void SelectSource(this IEnumerable<IMediaPlayerEntityCore> target, string source) - { - target.CallService("select_source", new MediaPlayerSelectSourceParameters { Source = source }); - } - - ///<summary>Enables or disables the shuffle mode.</summary> - public static void ShuffleSet(this IMediaPlayerEntityCore target, MediaPlayerShuffleSetParameters data) - { - target.CallService("shuffle_set", data); - } - - ///<summary>Enables or disables the shuffle mode.</summary> - public static void ShuffleSet(this IEnumerable<IMediaPlayerEntityCore> target, MediaPlayerShuffleSetParameters data) - { - target.CallService("shuffle_set", data); - } - - ///<summary>Enables or disables the shuffle mode.</summary> - ///<param name="target">The IMediaPlayerEntityCore to call this service for</param> - ///<param name="shuffle">Whether the media should be played in randomized order or not.</param> - public static void ShuffleSet(this IMediaPlayerEntityCore target, bool shuffle) - { - target.CallService("shuffle_set", new MediaPlayerShuffleSetParameters { Shuffle = shuffle }); - } - - ///<summary>Enables or disables the shuffle mode.</summary> - ///<param name="target">The IEnumerable<IMediaPlayerEntityCore> to call this service for</param> - ///<param name="shuffle">Whether the media should be played in randomized order or not.</param> - public static void ShuffleSet(this IEnumerable<IMediaPlayerEntityCore> target, bool shuffle) - { - target.CallService("shuffle_set", new MediaPlayerShuffleSetParameters { Shuffle = shuffle }); - } - - ///<summary>Toggles a media player on/off.</summary> - public static void Toggle(this IMediaPlayerEntityCore target, object? data = null) - { - target.CallService("toggle", data); - } - - ///<summary>Toggles a media player on/off.</summary> - public static void Toggle(this IEnumerable<IMediaPlayerEntityCore> target, object? data = null) - { - target.CallService("toggle", data); - } - - ///<summary>Turns off the power of the media player.</summary> - public static void TurnOff(this IMediaPlayerEntityCore target, object? data = null) - { - target.CallService("turn_off", data); - } - - ///<summary>Turns off the power of the media player.</summary> - public static void TurnOff(this IEnumerable<IMediaPlayerEntityCore> target, object? data = null) - { - target.CallService("turn_off", data); - } - - ///<summary>Turns on the power of the media player.</summary> - public static void TurnOn(this IMediaPlayerEntityCore target, object? data = null) - { - target.CallService("turn_on", data); - } - - ///<summary>Turns on the power of the media player.</summary> - public static void TurnOn(this IEnumerable<IMediaPlayerEntityCore> target, object? data = null) - { - target.CallService("turn_on", data); - } - - ///<summary>Removes the player from a group. Only works on platforms which support player groups.</summary> - public static void Unjoin(this IMediaPlayerEntityCore target, object? data = null) - { - target.CallService("unjoin", data); - } - - ///<summary>Removes the player from a group. Only works on platforms which support player groups.</summary> - public static void Unjoin(this IEnumerable<IMediaPlayerEntityCore> target, object? data = null) - { - target.CallService("unjoin", data); - } - - ///<summary>Turns down the volume.</summary> - public static void VolumeDown(this IMediaPlayerEntityCore target, object? data = null) - { - target.CallService("volume_down", data); - } - - ///<summary>Turns down the volume.</summary> - public static void VolumeDown(this IEnumerable<IMediaPlayerEntityCore> target, object? data = null) - { - target.CallService("volume_down", data); - } - - ///<summary>Mutes or unmutes the media player.</summary> - public static void VolumeMute(this IMediaPlayerEntityCore target, MediaPlayerVolumeMuteParameters data) - { - target.CallService("volume_mute", data); - } - - ///<summary>Mutes or unmutes the media player.</summary> - public static void VolumeMute(this IEnumerable<IMediaPlayerEntityCore> target, MediaPlayerVolumeMuteParameters data) - { - target.CallService("volume_mute", data); - } - - ///<summary>Mutes or unmutes the media player.</summary> - ///<param name="target">The IMediaPlayerEntityCore to call this service for</param> - ///<param name="isVolumeMuted">Defines whether or not it is muted.</param> - public static void VolumeMute(this IMediaPlayerEntityCore target, bool isVolumeMuted) - { - target.CallService("volume_mute", new MediaPlayerVolumeMuteParameters { IsVolumeMuted = isVolumeMuted }); - } - - ///<summary>Mutes or unmutes the media player.</summary> - ///<param name="target">The IEnumerable<IMediaPlayerEntityCore> to call this service for</param> - ///<param name="isVolumeMuted">Defines whether or not it is muted.</param> - public static void VolumeMute(this IEnumerable<IMediaPlayerEntityCore> target, bool isVolumeMuted) - { - target.CallService("volume_mute", new MediaPlayerVolumeMuteParameters { IsVolumeMuted = isVolumeMuted }); - } - - ///<summary>Sets the volume level.</summary> - public static void VolumeSet(this IMediaPlayerEntityCore target, MediaPlayerVolumeSetParameters data) - { - target.CallService("volume_set", data); - } - - ///<summary>Sets the volume level.</summary> - public static void VolumeSet(this IEnumerable<IMediaPlayerEntityCore> target, MediaPlayerVolumeSetParameters data) - { - target.CallService("volume_set", data); - } - - ///<summary>Sets the volume level.</summary> - ///<param name="target">The IMediaPlayerEntityCore to call this service for</param> - ///<param name="volumeLevel">The volume. 0 is inaudible, 1 is the maximum volume.</param> - public static void VolumeSet(this IMediaPlayerEntityCore target, double volumeLevel) - { - target.CallService("volume_set", new MediaPlayerVolumeSetParameters { VolumeLevel = volumeLevel }); - } - - ///<summary>Sets the volume level.</summary> - ///<param name="target">The IEnumerable<IMediaPlayerEntityCore> to call this service for</param> - ///<param name="volumeLevel">The volume. 0 is inaudible, 1 is the maximum volume.</param> - public static void VolumeSet(this IEnumerable<IMediaPlayerEntityCore> target, double volumeLevel) - { - target.CallService("volume_set", new MediaPlayerVolumeSetParameters { VolumeLevel = volumeLevel }); - } - - ///<summary>Turns up the volume.</summary> - public static void VolumeUp(this IMediaPlayerEntityCore target, object? data = null) - { - target.CallService("volume_up", data); - } - - ///<summary>Turns up the volume.</summary> - public static void VolumeUp(this IEnumerable<IMediaPlayerEntityCore> target, object? data = null) - { - target.CallService("volume_up", data); - } -} - -public static class NumberEntityExtensionMethods -{ - ///<summary>Sets the value of a number.</summary> - public static void SetValue(this INumberEntityCore target, NumberSetValueParameters data) - { - target.CallService("set_value", data); - } - - ///<summary>Sets the value of a number.</summary> - public static void SetValue(this IEnumerable<INumberEntityCore> target, NumberSetValueParameters data) - { - target.CallService("set_value", data); - } - - ///<summary>Sets the value of a number.</summary> - ///<param name="target">The INumberEntityCore to call this service for</param> - ///<param name="value">The target value to set. eg: 42</param> - public static void SetValue(this INumberEntityCore target, string value) - { - target.CallService("set_value", new NumberSetValueParameters { Value = value }); - } - - ///<summary>Sets the value of a number.</summary> - ///<param name="target">The IEnumerable<INumberEntityCore> to call this service for</param> - ///<param name="value">The target value to set. eg: 42</param> - public static void SetValue(this IEnumerable<INumberEntityCore> target, string value) - { - target.CallService("set_value", new NumberSetValueParameters { Value = value }); - } -} - -public static class RemoteEntityExtensionMethods -{ - ///<summary>Deletes a command or a list of commands from the database.</summary> - public static void DeleteCommand(this IRemoteEntityCore target, RemoteDeleteCommandParameters data) - { - target.CallService("delete_command", data); - } - - ///<summary>Deletes a command or a list of commands from the database.</summary> - public static void DeleteCommand(this IEnumerable<IRemoteEntityCore> target, RemoteDeleteCommandParameters data) - { - target.CallService("delete_command", data); - } - - ///<summary>Deletes a command or a list of commands from the database.</summary> - ///<param name="target">The IRemoteEntityCore to call this service for</param> - ///<param name="device">Device from which commands will be deleted. eg: television</param> - ///<param name="command">The single command or the list of commands to be deleted. eg: Mute</param> - public static void DeleteCommand(this IRemoteEntityCore target, object command, string? device = null) - { - target.CallService("delete_command", new RemoteDeleteCommandParameters { Device = device, Command = command }); - } - - ///<summary>Deletes a command or a list of commands from the database.</summary> - ///<param name="target">The IEnumerable<IRemoteEntityCore> to call this service for</param> - ///<param name="device">Device from which commands will be deleted. eg: television</param> - ///<param name="command">The single command or the list of commands to be deleted. eg: Mute</param> - public static void DeleteCommand(this IEnumerable<IRemoteEntityCore> target, object command, string? device = null) - { - target.CallService("delete_command", new RemoteDeleteCommandParameters { Device = device, Command = command }); - } - - ///<summary>Learns a command or a list of commands from a device.</summary> - public static void LearnCommand(this IRemoteEntityCore target, RemoteLearnCommandParameters data) - { - target.CallService("learn_command", data); - } - - ///<summary>Learns a command or a list of commands from a device.</summary> - public static void LearnCommand(this IEnumerable<IRemoteEntityCore> target, RemoteLearnCommandParameters data) - { - target.CallService("learn_command", data); - } - - ///<summary>Learns a command or a list of commands from a device.</summary> - ///<param name="target">The IRemoteEntityCore to call this service for</param> - ///<param name="device">Device ID to learn command from. eg: television</param> - ///<param name="command">A single command or a list of commands to learn. eg: Turn on</param> - ///<param name="commandType">The type of command to be learned.</param> - ///<param name="alternative">If code must be stored as an alternative. This is useful for discrete codes. Discrete codes are used for toggles that only perform one function. For example, a code to only turn a device on. If it is on already, sending the code won't change the state.</param> - ///<param name="timeout">Timeout for the command to be learned.</param> - public static void LearnCommand(this IRemoteEntityCore target, string? device = null, object? command = null, object? commandType = null, bool? alternative = null, long? timeout = null) - { - target.CallService("learn_command", new RemoteLearnCommandParameters { Device = device, Command = command, CommandType = commandType, Alternative = alternative, Timeout = timeout }); - } - - ///<summary>Learns a command or a list of commands from a device.</summary> - ///<param name="target">The IEnumerable<IRemoteEntityCore> to call this service for</param> - ///<param name="device">Device ID to learn command from. eg: television</param> - ///<param name="command">A single command or a list of commands to learn. eg: Turn on</param> - ///<param name="commandType">The type of command to be learned.</param> - ///<param name="alternative">If code must be stored as an alternative. This is useful for discrete codes. Discrete codes are used for toggles that only perform one function. For example, a code to only turn a device on. If it is on already, sending the code won't change the state.</param> - ///<param name="timeout">Timeout for the command to be learned.</param> - public static void LearnCommand(this IEnumerable<IRemoteEntityCore> target, string? device = null, object? command = null, object? commandType = null, bool? alternative = null, long? timeout = null) - { - target.CallService("learn_command", new RemoteLearnCommandParameters { Device = device, Command = command, CommandType = commandType, Alternative = alternative, Timeout = timeout }); - } - - ///<summary>Sends a command or a list of commands to a device.</summary> - public static void SendCommand(this IRemoteEntityCore target, RemoteSendCommandParameters data) - { - target.CallService("send_command", data); - } - - ///<summary>Sends a command or a list of commands to a device.</summary> - public static void SendCommand(this IEnumerable<IRemoteEntityCore> target, RemoteSendCommandParameters data) - { - target.CallService("send_command", data); - } - - ///<summary>Sends a command or a list of commands to a device.</summary> - ///<param name="target">The IRemoteEntityCore to call this service for</param> - ///<param name="device">Device ID to send command to. eg: 32756745</param> - ///<param name="command">A single command or a list of commands to send. eg: Play</param> - ///<param name="numRepeats">The number of times you want to repeat the commands.</param> - ///<param name="delaySecs">The time you want to wait in between repeated commands.</param> - ///<param name="holdSecs">The time you want to have it held before the release is send.</param> - public static void SendCommand(this IRemoteEntityCore target, object command, string? device = null, double? numRepeats = null, double? delaySecs = null, double? holdSecs = null) - { - target.CallService("send_command", new RemoteSendCommandParameters { Device = device, Command = command, NumRepeats = numRepeats, DelaySecs = delaySecs, HoldSecs = holdSecs }); - } - - ///<summary>Sends a command or a list of commands to a device.</summary> - ///<param name="target">The IEnumerable<IRemoteEntityCore> to call this service for</param> - ///<param name="device">Device ID to send command to. eg: 32756745</param> - ///<param name="command">A single command or a list of commands to send. eg: Play</param> - ///<param name="numRepeats">The number of times you want to repeat the commands.</param> - ///<param name="delaySecs">The time you want to wait in between repeated commands.</param> - ///<param name="holdSecs">The time you want to have it held before the release is send.</param> - public static void SendCommand(this IEnumerable<IRemoteEntityCore> target, object command, string? device = null, double? numRepeats = null, double? delaySecs = null, double? holdSecs = null) - { - target.CallService("send_command", new RemoteSendCommandParameters { Device = device, Command = command, NumRepeats = numRepeats, DelaySecs = delaySecs, HoldSecs = holdSecs }); - } - - ///<summary>Sends the toggle command.</summary> - public static void Toggle(this IRemoteEntityCore target, object? data = null) - { - target.CallService("toggle", data); - } - - ///<summary>Sends the toggle command.</summary> - public static void Toggle(this IEnumerable<IRemoteEntityCore> target, object? data = null) - { - target.CallService("toggle", data); - } - - ///<summary>Sends the turn off command.</summary> - public static void TurnOff(this IRemoteEntityCore target, object? data = null) - { - target.CallService("turn_off", data); - } - - ///<summary>Sends the turn off command.</summary> - public static void TurnOff(this IEnumerable<IRemoteEntityCore> target, object? data = null) - { - target.CallService("turn_off", data); - } - - ///<summary>Sends the turn on command.</summary> - public static void TurnOn(this IRemoteEntityCore target, RemoteTurnOnParameters data) - { - target.CallService("turn_on", data); - } - - ///<summary>Sends the turn on command.</summary> - public static void TurnOn(this IEnumerable<IRemoteEntityCore> target, RemoteTurnOnParameters data) - { - target.CallService("turn_on", data); - } - - ///<summary>Sends the turn on command.</summary> - ///<param name="target">The IRemoteEntityCore to call this service for</param> - ///<param name="activity">Activity ID or activity name to be started. eg: BedroomTV</param> - public static void TurnOn(this IRemoteEntityCore target, string? activity = null) - { - target.CallService("turn_on", new RemoteTurnOnParameters { Activity = activity }); - } - - ///<summary>Sends the turn on command.</summary> - ///<param name="target">The IEnumerable<IRemoteEntityCore> to call this service for</param> - ///<param name="activity">Activity ID or activity name to be started. eg: BedroomTV</param> - public static void TurnOn(this IEnumerable<IRemoteEntityCore> target, string? activity = null) - { - target.CallService("turn_on", new RemoteTurnOnParameters { Activity = activity }); - } -} - -public static class ScriptEntityExtensionMethods -{ - ///<summary>Starts a script if it isn't running, stops it otherwise.</summary> - public static void Toggle(this IScriptEntityCore target, object? data = null) - { - target.CallService("toggle", data); - } - - ///<summary>Starts a script if it isn't running, stops it otherwise.</summary> - public static void Toggle(this IEnumerable<IScriptEntityCore> target, object? data = null) - { - target.CallService("toggle", data); - } - - ///<summary>Stops a running script.</summary> - public static void TurnOff(this IScriptEntityCore target, object? data = null) - { - target.CallService("turn_off", data); - } - - ///<summary>Stops a running script.</summary> - public static void TurnOff(this IEnumerable<IScriptEntityCore> target, object? data = null) - { - target.CallService("turn_off", data); - } - - ///<summary>Runs the sequence of actions defined in a script.</summary> - public static void TurnOn(this IScriptEntityCore target, object? data = null) - { - target.CallService("turn_on", data); - } - - ///<summary>Runs the sequence of actions defined in a script.</summary> - public static void TurnOn(this IEnumerable<IScriptEntityCore> target, object? data = null) - { - target.CallService("turn_on", data); - } -} - -public static class SelectEntityExtensionMethods -{ - ///<summary>Selects the first option.</summary> - public static void SelectFirst(this ISelectEntityCore target, object? data = null) - { - target.CallService("select_first", data); - } - - ///<summary>Selects the first option.</summary> - public static void SelectFirst(this IEnumerable<ISelectEntityCore> target, object? data = null) - { - target.CallService("select_first", data); - } - - ///<summary>Selects the last option.</summary> - public static void SelectLast(this ISelectEntityCore target, object? data = null) - { - target.CallService("select_last", data); - } - - ///<summary>Selects the last option.</summary> - public static void SelectLast(this IEnumerable<ISelectEntityCore> target, object? data = null) - { - target.CallService("select_last", data); - } - - ///<summary>Selects the next option.</summary> - public static void SelectNext(this ISelectEntityCore target, SelectSelectNextParameters data) - { - target.CallService("select_next", data); - } - - ///<summary>Selects the next option.</summary> - public static void SelectNext(this IEnumerable<ISelectEntityCore> target, SelectSelectNextParameters data) - { - target.CallService("select_next", data); - } - - ///<summary>Selects the next option.</summary> - ///<param name="target">The ISelectEntityCore to call this service for</param> - ///<param name="cycle">If the option should cycle from the last to the first.</param> - public static void SelectNext(this ISelectEntityCore target, bool? cycle = null) - { - target.CallService("select_next", new SelectSelectNextParameters { Cycle = cycle }); - } - - ///<summary>Selects the next option.</summary> - ///<param name="target">The IEnumerable<ISelectEntityCore> to call this service for</param> - ///<param name="cycle">If the option should cycle from the last to the first.</param> - public static void SelectNext(this IEnumerable<ISelectEntityCore> target, bool? cycle = null) - { - target.CallService("select_next", new SelectSelectNextParameters { Cycle = cycle }); - } - - ///<summary>Selects an option.</summary> - public static void SelectOption(this ISelectEntityCore target, SelectSelectOptionParameters data) - { - target.CallService("select_option", data); - } - - ///<summary>Selects an option.</summary> - public static void SelectOption(this IEnumerable<ISelectEntityCore> target, SelectSelectOptionParameters data) - { - target.CallService("select_option", data); - } - - ///<summary>Selects an option.</summary> - ///<param name="target">The ISelectEntityCore to call this service for</param> - ///<param name="option">Option to be selected. eg: "Item A"</param> - public static void SelectOption(this ISelectEntityCore target, string option) - { - target.CallService("select_option", new SelectSelectOptionParameters { Option = option }); - } - - ///<summary>Selects an option.</summary> - ///<param name="target">The IEnumerable<ISelectEntityCore> to call this service for</param> - ///<param name="option">Option to be selected. eg: "Item A"</param> - public static void SelectOption(this IEnumerable<ISelectEntityCore> target, string option) - { - target.CallService("select_option", new SelectSelectOptionParameters { Option = option }); - } - - ///<summary>Selects the previous option.</summary> - public static void SelectPrevious(this ISelectEntityCore target, SelectSelectPreviousParameters data) - { - target.CallService("select_previous", data); - } - - ///<summary>Selects the previous option.</summary> - public static void SelectPrevious(this IEnumerable<ISelectEntityCore> target, SelectSelectPreviousParameters data) - { - target.CallService("select_previous", data); - } - - ///<summary>Selects the previous option.</summary> - ///<param name="target">The ISelectEntityCore to call this service for</param> - ///<param name="cycle">If the option should cycle from the first to the last.</param> - public static void SelectPrevious(this ISelectEntityCore target, bool? cycle = null) - { - target.CallService("select_previous", new SelectSelectPreviousParameters { Cycle = cycle }); - } - - ///<summary>Selects the previous option.</summary> - ///<param name="target">The IEnumerable<ISelectEntityCore> to call this service for</param> - ///<param name="cycle">If the option should cycle from the first to the last.</param> - public static void SelectPrevious(this IEnumerable<ISelectEntityCore> target, bool? cycle = null) - { - target.CallService("select_previous", new SelectSelectPreviousParameters { Cycle = cycle }); - } -} - -public static class SwitchEntityExtensionMethods -{ - ///<summary>Toggles a switch on/off.</summary> - public static void Toggle(this ISwitchEntityCore target, object? data = null) - { - target.CallService("toggle", data); - } - - ///<summary>Toggles a switch on/off.</summary> - public static void Toggle(this IEnumerable<ISwitchEntityCore> target, object? data = null) - { - target.CallService("toggle", data); - } - - ///<summary>Turns a switch off.</summary> - public static void TurnOff(this ISwitchEntityCore target, object? data = null) - { - target.CallService("turn_off", data); - } - - ///<summary>Turns a switch off.</summary> - public static void TurnOff(this IEnumerable<ISwitchEntityCore> target, object? data = null) - { - target.CallService("turn_off", data); - } - - ///<summary>Turns a switch on.</summary> - public static void TurnOn(this ISwitchEntityCore target, object? data = null) - { - target.CallService("turn_on", data); - } - - ///<summary>Turns a switch on.</summary> - public static void TurnOn(this IEnumerable<ISwitchEntityCore> target, object? data = null) - { - target.CallService("turn_on", data); - } -} - -public static class TimerEntityExtensionMethods -{ - ///<summary>Resets a timer's duration to the last known initial value without firing the timer finished event.</summary> - public static void Cancel(this ITimerEntityCore target, object? data = null) - { - target.CallService("cancel", data); - } - - ///<summary>Resets a timer's duration to the last known initial value without firing the timer finished event.</summary> - public static void Cancel(this IEnumerable<ITimerEntityCore> target, object? data = null) - { - target.CallService("cancel", data); - } - - ///<summary>Changes a timer by adding or subtracting a given duration.</summary> - public static void Change(this ITimerEntityCore target, TimerChangeParameters data) - { - target.CallService("change", data); - } - - ///<summary>Changes a timer by adding or subtracting a given duration.</summary> - public static void Change(this IEnumerable<ITimerEntityCore> target, TimerChangeParameters data) - { - target.CallService("change", data); - } - - ///<summary>Changes a timer by adding or subtracting a given duration.</summary> - ///<param name="target">The ITimerEntityCore to call this service for</param> - ///<param name="duration">Duration to add to or subtract from the running timer. eg: 00:01:00, 60 or -60</param> - public static void Change(this ITimerEntityCore target, string duration) - { - target.CallService("change", new TimerChangeParameters { Duration = duration }); - } - - ///<summary>Changes a timer by adding or subtracting a given duration.</summary> - ///<param name="target">The IEnumerable<ITimerEntityCore> to call this service for</param> - ///<param name="duration">Duration to add to or subtract from the running timer. eg: 00:01:00, 60 or -60</param> - public static void Change(this IEnumerable<ITimerEntityCore> target, string duration) - { - target.CallService("change", new TimerChangeParameters { Duration = duration }); - } - - ///<summary>Finishes a running timer earlier than scheduled.</summary> - public static void Finish(this ITimerEntityCore target, object? data = null) - { - target.CallService("finish", data); - } - - ///<summary>Finishes a running timer earlier than scheduled.</summary> - public static void Finish(this IEnumerable<ITimerEntityCore> target, object? data = null) - { - target.CallService("finish", data); - } - - ///<summary>Pauses a running timer, retaining the remaining duration for later continuation.</summary> - public static void Pause(this ITimerEntityCore target, object? data = null) - { - target.CallService("pause", data); - } - - ///<summary>Pauses a running timer, retaining the remaining duration for later continuation.</summary> - public static void Pause(this IEnumerable<ITimerEntityCore> target, object? data = null) - { - target.CallService("pause", data); - } - - ///<summary>Starts a timer or restarts it with a provided duration.</summary> - public static void Start(this ITimerEntityCore target, TimerStartParameters data) - { - target.CallService("start", data); - } - - ///<summary>Starts a timer or restarts it with a provided duration.</summary> - public static void Start(this IEnumerable<ITimerEntityCore> target, TimerStartParameters data) - { - target.CallService("start", data); - } - - ///<summary>Starts a timer or restarts it with a provided duration.</summary> - ///<param name="target">The ITimerEntityCore to call this service for</param> - ///<param name="duration">Custom duration to restart the timer with. eg: 00:01:00 or 60</param> - public static void Start(this ITimerEntityCore target, string? duration = null) - { - target.CallService("start", new TimerStartParameters { Duration = duration }); - } - - ///<summary>Starts a timer or restarts it with a provided duration.</summary> - ///<param name="target">The IEnumerable<ITimerEntityCore> to call this service for</param> - ///<param name="duration">Custom duration to restart the timer with. eg: 00:01:00 or 60</param> - public static void Start(this IEnumerable<ITimerEntityCore> target, string? duration = null) - { - target.CallService("start", new TimerStartParameters { Duration = duration }); - } -} - -public static class TodoEntityExtensionMethods -{ - ///<summary>Adds a new to-do list item.</summary> - public static void AddItem(this TodoEntity target, TodoAddItemParameters data) - { - target.CallService("add_item", data); - } - - ///<summary>Adds a new to-do list item.</summary> - public static void AddItem(this IEnumerable<TodoEntity> target, TodoAddItemParameters data) - { - target.CallService("add_item", data); - } - - ///<summary>Adds a new to-do list item.</summary> - ///<param name="target">The TodoEntity to call this service for</param> - ///<param name="item">The name that represents the to-do item. eg: Submit income tax return</param> - ///<param name="dueDate">The date the to-do item is expected to be completed. eg: 2023-11-17</param> - ///<param name="dueDatetime">The date and time the to-do item is expected to be completed. eg: 2023-11-17 13:30:00</param> - ///<param name="description">A more complete description of the to-do item than provided by the item name. eg: A more complete description of the to-do item than that provided by the summary.</param> - public static void AddItem(this TodoEntity target, string item, DateOnly? dueDate = null, DateTime? dueDatetime = null, string? description = null) - { - target.CallService("add_item", new TodoAddItemParameters { Item = item, DueDate = dueDate, DueDatetime = dueDatetime, Description = description }); - } - - ///<summary>Adds a new to-do list item.</summary> - ///<param name="target">The IEnumerable<TodoEntity> to call this service for</param> - ///<param name="item">The name that represents the to-do item. eg: Submit income tax return</param> - ///<param name="dueDate">The date the to-do item is expected to be completed. eg: 2023-11-17</param> - ///<param name="dueDatetime">The date and time the to-do item is expected to be completed. eg: 2023-11-17 13:30:00</param> - ///<param name="description">A more complete description of the to-do item than provided by the item name. eg: A more complete description of the to-do item than that provided by the summary.</param> - public static void AddItem(this IEnumerable<TodoEntity> target, string item, DateOnly? dueDate = null, DateTime? dueDatetime = null, string? description = null) - { - target.CallService("add_item", new TodoAddItemParameters { Item = item, DueDate = dueDate, DueDatetime = dueDatetime, Description = description }); - } - - ///<summary>Gets items on a to-do list.</summary> - public static Task<JsonElement?> GetItemsAsync(this TodoEntity target, TodoGetItemsParameters data) - { - return target.CallServiceWithResponseAsync("get_items", data); - } - - ///<summary>Gets items on a to-do list.</summary> - ///<param name="target">The TodoEntity to call this service for</param> - ///<param name="status">Only return to-do items with the specified statuses. Returns not completed actions by default. eg: needs_action</param> - public static Task<JsonElement?> GetItemsAsync(this TodoEntity target, IEnumerable<object>? status = null) - { - return target.CallServiceWithResponseAsync("get_items", new TodoGetItemsParameters { Status = status }); - } - - ///<summary>Gets items on a to-do list.</summary> - public static void GetItems(this TodoEntity target, TodoGetItemsParameters data) - { - target.CallService("get_items", data); - } - - ///<summary>Gets items on a to-do list.</summary> - public static void GetItems(this IEnumerable<TodoEntity> target, TodoGetItemsParameters data) - { - target.CallService("get_items", data); - } - - ///<summary>Gets items on a to-do list.</summary> - ///<param name="target">The TodoEntity to call this service for</param> - ///<param name="status">Only return to-do items with the specified statuses. Returns not completed actions by default. eg: needs_action</param> - public static void GetItems(this TodoEntity target, IEnumerable<object>? status = null) - { - target.CallService("get_items", new TodoGetItemsParameters { Status = status }); - } - - ///<summary>Gets items on a to-do list.</summary> - ///<param name="target">The IEnumerable<TodoEntity> to call this service for</param> - ///<param name="status">Only return to-do items with the specified statuses. Returns not completed actions by default. eg: needs_action</param> - public static void GetItems(this IEnumerable<TodoEntity> target, IEnumerable<object>? status = null) - { - target.CallService("get_items", new TodoGetItemsParameters { Status = status }); - } - - ///<summary>Removes all to-do list items that have been completed.</summary> - public static void RemoveCompletedItems(this TodoEntity target, object? data = null) - { - target.CallService("remove_completed_items", data); - } - - ///<summary>Removes all to-do list items that have been completed.</summary> - public static void RemoveCompletedItems(this IEnumerable<TodoEntity> target, object? data = null) - { - target.CallService("remove_completed_items", data); - } - - ///<summary>Removes an existing to-do list item by its name.</summary> - public static void RemoveItem(this TodoEntity target, TodoRemoveItemParameters data) - { - target.CallService("remove_item", data); - } - - ///<summary>Removes an existing to-do list item by its name.</summary> - public static void RemoveItem(this IEnumerable<TodoEntity> target, TodoRemoveItemParameters data) - { - target.CallService("remove_item", data); - } - - ///<summary>Removes an existing to-do list item by its name.</summary> - ///<param name="target">The TodoEntity to call this service for</param> - ///<param name="item">The name for the to-do list item.</param> - public static void RemoveItem(this TodoEntity target, string item) - { - target.CallService("remove_item", new TodoRemoveItemParameters { Item = item }); - } - - ///<summary>Removes an existing to-do list item by its name.</summary> - ///<param name="target">The IEnumerable<TodoEntity> to call this service for</param> - ///<param name="item">The name for the to-do list item.</param> - public static void RemoveItem(this IEnumerable<TodoEntity> target, string item) - { - target.CallService("remove_item", new TodoRemoveItemParameters { Item = item }); - } - - ///<summary>Updates an existing to-do list item based on its name.</summary> - public static void UpdateItem(this TodoEntity target, TodoUpdateItemParameters data) - { - target.CallService("update_item", data); - } - - ///<summary>Updates an existing to-do list item based on its name.</summary> - public static void UpdateItem(this IEnumerable<TodoEntity> target, TodoUpdateItemParameters data) - { - target.CallService("update_item", data); - } - - ///<summary>Updates an existing to-do list item based on its name.</summary> - ///<param name="target">The TodoEntity to call this service for</param> - ///<param name="item">The current name of the to-do item. eg: Submit income tax return</param> - ///<param name="rename">The new name for the to-do item eg: Something else</param> - ///<param name="status">A status or confirmation of the to-do item. eg: needs_action</param> - ///<param name="dueDate">The date the to-do item is expected to be completed. eg: 2023-11-17</param> - ///<param name="dueDatetime">The date and time the to-do item is expected to be completed. eg: 2023-11-17 13:30:00</param> - ///<param name="description">A more complete description of the to-do item than provided by the item name. eg: A more complete description of the to-do item than that provided by the summary.</param> - public static void UpdateItem(this TodoEntity target, string item, string? rename = null, object? status = null, DateOnly? dueDate = null, DateTime? dueDatetime = null, string? description = null) - { - target.CallService("update_item", new TodoUpdateItemParameters { Item = item, Rename = rename, Status = status, DueDate = dueDate, DueDatetime = dueDatetime, Description = description }); - } - - ///<summary>Updates an existing to-do list item based on its name.</summary> - ///<param name="target">The IEnumerable<TodoEntity> to call this service for</param> - ///<param name="item">The current name of the to-do item. eg: Submit income tax return</param> - ///<param name="rename">The new name for the to-do item eg: Something else</param> - ///<param name="status">A status or confirmation of the to-do item. eg: needs_action</param> - ///<param name="dueDate">The date the to-do item is expected to be completed. eg: 2023-11-17</param> - ///<param name="dueDatetime">The date and time the to-do item is expected to be completed. eg: 2023-11-17 13:30:00</param> - ///<param name="description">A more complete description of the to-do item than provided by the item name. eg: A more complete description of the to-do item than that provided by the summary.</param> - public static void UpdateItem(this IEnumerable<TodoEntity> target, string item, string? rename = null, object? status = null, DateOnly? dueDate = null, DateTime? dueDatetime = null, string? description = null) - { - target.CallService("update_item", new TodoUpdateItemParameters { Item = item, Rename = rename, Status = status, DueDate = dueDate, DueDatetime = dueDatetime, Description = description }); - } -} - -public static class TtsEntityExtensionMethods -{ - ///<summary>Speaks something using text-to-speech on a media player.</summary> - public static void Speak(this TtsEntity target, TtsSpeakParameters data) - { - target.CallService("speak", data); - } - - ///<summary>Speaks something using text-to-speech on a media player.</summary> - public static void Speak(this IEnumerable<TtsEntity> target, TtsSpeakParameters data) - { - target.CallService("speak", data); - } - - ///<summary>Speaks something using text-to-speech on a media player.</summary> - ///<param name="target">The TtsEntity to call this service for</param> - ///<param name="mediaPlayerEntityId">Media players to play the message.</param> - ///<param name="message">The text you want to convert into speech so that you can listen to it on your device. eg: My name is hanna</param> - ///<param name="cache">Stores this message locally so that when the text is requested again, the output can be produced more quickly.</param> - ///<param name="language">Language to use for speech generation. eg: ru</param> - ///<param name="options">A dictionary containing integration-specific options. eg: platform specific</param> - public static void Speak(this TtsEntity target, string mediaPlayerEntityId, string message, bool? cache = null, string? language = null, object? options = null) - { - target.CallService("speak", new TtsSpeakParameters { MediaPlayerEntityId = mediaPlayerEntityId, Message = message, Cache = cache, Language = language, Options = options }); - } - - ///<summary>Speaks something using text-to-speech on a media player.</summary> - ///<param name="target">The IEnumerable<TtsEntity> to call this service for</param> - ///<param name="mediaPlayerEntityId">Media players to play the message.</param> - ///<param name="message">The text you want to convert into speech so that you can listen to it on your device. eg: My name is hanna</param> - ///<param name="cache">Stores this message locally so that when the text is requested again, the output can be produced more quickly.</param> - ///<param name="language">Language to use for speech generation. eg: ru</param> - ///<param name="options">A dictionary containing integration-specific options. eg: platform specific</param> - public static void Speak(this IEnumerable<TtsEntity> target, string mediaPlayerEntityId, string message, bool? cache = null, string? language = null, object? options = null) - { - target.CallService("speak", new TtsSpeakParameters { MediaPlayerEntityId = mediaPlayerEntityId, Message = message, Cache = cache, Language = language, Options = options }); - } -} - -public static class UpdateEntityExtensionMethods -{ - ///<summary>Removes the skipped version marker from an update.</summary> - public static void ClearSkipped(this IUpdateEntityCore target, object? data = null) - { - target.CallService("clear_skipped", data); - } - - ///<summary>Removes the skipped version marker from an update.</summary> - public static void ClearSkipped(this IEnumerable<IUpdateEntityCore> target, object? data = null) - { - target.CallService("clear_skipped", data); - } - - ///<summary>Installs an update for a device or service.</summary> - public static void Install(this IUpdateEntityCore target, UpdateInstallParameters data) - { - target.CallService("install", data); - } - - ///<summary>Installs an update for a device or service.</summary> - public static void Install(this IEnumerable<IUpdateEntityCore> target, UpdateInstallParameters data) - { - target.CallService("install", data); - } - - ///<summary>Installs an update for a device or service.</summary> - ///<param name="target">The IUpdateEntityCore to call this service for</param> - ///<param name="version">The version to install. If omitted, the latest version will be installed. eg: 1.0.0</param> - ///<param name="backup">If supported by the integration, this creates a backup before starting the update.</param> - public static void Install(this IUpdateEntityCore target, string? version = null, bool? backup = null) - { - target.CallService("install", new UpdateInstallParameters { Version = version, Backup = backup }); - } - - ///<summary>Installs an update for a device or service.</summary> - ///<param name="target">The IEnumerable<IUpdateEntityCore> to call this service for</param> - ///<param name="version">The version to install. If omitted, the latest version will be installed. eg: 1.0.0</param> - ///<param name="backup">If supported by the integration, this creates a backup before starting the update.</param> - public static void Install(this IEnumerable<IUpdateEntityCore> target, string? version = null, bool? backup = null) - { - target.CallService("install", new UpdateInstallParameters { Version = version, Backup = backup }); - } - - ///<summary>Marks currently available update as skipped.</summary> - public static void Skip(this IUpdateEntityCore target, object? data = null) - { - target.CallService("skip", data); - } - - ///<summary>Marks currently available update as skipped.</summary> - public static void Skip(this IEnumerable<IUpdateEntityCore> target, object? data = null) - { - target.CallService("skip", data); - } -} - -public static class WeatherEntityExtensionMethods -{ - ///<summary>Retrieves the forecast from selected weather services.</summary> - public static Task<JsonElement?> GetForecastsAsync(this IWeatherEntityCore target, WeatherGetForecastsParameters data) - { - return target.CallServiceWithResponseAsync("get_forecasts", data); - } - - ///<summary>Retrieves the forecast from selected weather services.</summary> - ///<param name="target">The IWeatherEntityCore to call this service for</param> - ///<param name="type">The scope of the weather forecast.</param> - public static Task<JsonElement?> GetForecastsAsync(this IWeatherEntityCore target, object @type) - { - return target.CallServiceWithResponseAsync("get_forecasts", new WeatherGetForecastsParameters { Type = @type }); - } - - ///<summary>Retrieves the forecast from selected weather services.</summary> - public static void GetForecasts(this IWeatherEntityCore target, WeatherGetForecastsParameters data) - { - target.CallService("get_forecasts", data); - } - - ///<summary>Retrieves the forecast from selected weather services.</summary> - public static void GetForecasts(this IEnumerable<IWeatherEntityCore> target, WeatherGetForecastsParameters data) - { - target.CallService("get_forecasts", data); - } - - ///<summary>Retrieves the forecast from selected weather services.</summary> - ///<param name="target">The IWeatherEntityCore to call this service for</param> - ///<param name="type">The scope of the weather forecast.</param> - public static void GetForecasts(this IWeatherEntityCore target, object @type) - { - target.CallService("get_forecasts", new WeatherGetForecastsParameters { Type = @type }); - } - - ///<summary>Retrieves the forecast from selected weather services.</summary> - ///<param name="target">The IEnumerable<IWeatherEntityCore> to call this service for</param> - ///<param name="type">The scope of the weather forecast.</param> - public static void GetForecasts(this IEnumerable<IWeatherEntityCore> target, object @type) - { - target.CallService("get_forecasts", new WeatherGetForecastsParameters { Type = @type }); - } -} \ No newline at end of file diff --git a/configurations/homie/modules/home-assistant/netdaemon/apps/Frontend/BathroomLight/BathroomLight.cs b/configurations/homie/modules/home-assistant/netdaemon/apps/Frontend/BathroomLight/BathroomLight.cs deleted file mode 100644 index 2156b6fc..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/apps/Frontend/BathroomLight/BathroomLight.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System; - -using HomeAssistantGenerated; - -using NetDaemon.AppModel; -using NetDaemon.HassModel.Entities; - - -namespace NetDaemonConfig.Apps.Frontend.BathroomLight -{ - [NetDaemonApp] - public class BathroomLight - { - // The range of the brightness is 0 to 254 - private const double CONV_RATE = 2.54; - - private LightEntity? Entity { get; set; } - private InputTextEntity? BrightnessInput { get; set; } - private InputTextEntity? TemperatureInput { get; set; } - - private void BrightnessCallback(Action<double, double> callback) - { - double? currentBrightness = this.Entity?.Attributes?.Brightness; - - if (currentBrightness is not null) - { - double currentBrightnessPercent = Math.Floor((double)currentBrightness / CONV_RATE); - double inputBrightnessPercent = double.Parse(this.BrightnessInput?.State ?? "0"); - - if (currentBrightnessPercent != inputBrightnessPercent) - { - callback(currentBrightnessPercent, inputBrightnessPercent); - } - } - } - - private void TemperatureCallback(Action<double, double> callback) - { - double? currentTemperature = this.Entity?.Attributes?.ColorTempKelvin; - - if (currentTemperature is not null) - { - double inputTemperature = double.Parse(this.TemperatureInput?.State ?? "0"); - - if (currentTemperature != inputTemperature) - { - callback((double)currentTemperature, inputTemperature); - } - } - } - - public BathroomLight(Services services, Entities entities) - { - this.Entity = entities.Light.Bathroomceiling; - - this.BrightnessInput = entities.InputText.BathroomLightBrightness; - this.TemperatureInput = entities.InputText.BathroomLightTemperature; - - - // Brightness - this.BrightnessInput - .StateAllChanges() - .Subscribe((_) => - this.BrightnessCallback((_, input) => - services.Light.TurnOn( - target: ServiceTarget.FromEntity(this.Entity.EntityId), - brightness: Math.Floor(input * CONV_RATE + 1)))); - - this.Entity - .StateAllChanges() - .Subscribe((_) => - this.BrightnessCallback((current, _) => - this.BrightnessInput.SetValue(current.ToString()))); - - // Init value - this.BrightnessCallback((current, _) => - this.BrightnessInput.SetValue(current.ToString())); - - - // Temperature - this.TemperatureInput - .StateAllChanges() - .Subscribe((_) => - this.TemperatureCallback((_, input) => - services.Light.TurnOn( - target: ServiceTarget.FromEntity(this.Entity.EntityId), - kelvin: input))); - - this.Entity - .StateAllChanges() - .Subscribe((_) => - this.TemperatureCallback((current, _) => - this.TemperatureInput.SetValue(current.ToString()))); - - // Init value - this.TemperatureCallback((current, _) => - this.TemperatureInput.SetValue(current.ToString())); - } - } -} diff --git a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/PauseUnpause/PauseUnpause.cs b/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/PauseUnpause/PauseUnpause.cs deleted file mode 100644 index 15d2de29..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/PauseUnpause/PauseUnpause.cs +++ /dev/null @@ -1,41 +0,0 @@ -using HomeAssistantGenerated; - -using NetDaemon.AppModel; -using NetDaemon.HassModel; -using NetDaemon.HassModel.Integration; - -using NetDaemonConfig.Apps.Spotify.Types; - - -namespace NetDaemonConfig.Apps.Spotify.PauseUnpause -{ - public record PauseUnpauseData(bool pause); - - [NetDaemonApp] - public class PauseUnpause - { - private static void CallBack(PauseUnpauseData e, Services services) - { - if (e.pause) - { - services.Spotifyplus.PlayerMediaPause( - entityId: Globals.DefaultEntityId, - deviceId: Globals.DefaultDevId); - } - else - { - services.Spotifyplus.PlayerMediaResume( - entityId: Globals.DefaultEntityId, - deviceId: Globals.DefaultDevId); - } - } - - public PauseUnpause(IHaContext ha, Services services) - { - ha.RegisterServiceCallBack<PauseUnpauseData>( - "spotify_pause_unpause", - (e) => Globals.RunSpotifyCallback(services, e, CallBack) - ); - } - } -} diff --git a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayAlbum/PlayAlbum.cs b/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayAlbum/PlayAlbum.cs deleted file mode 100644 index 5556a2c6..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayAlbum/PlayAlbum.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Reflection; -using System.Text.Json; -using System.Threading.Tasks; - -using FuzzySharp; -using FuzzySharp.Extractor; - -using HomeAssistantGenerated; - -using NetDaemon.AppModel; -using NetDaemon.HassModel; -using NetDaemon.HassModel.Integration; - -using NetDaemonConfig.Apps.Spotify.Types; - - -namespace NetDaemonConfig.Apps.Spotify.PlayAlbum -{ - public record PlayAlbumData(string? artist, string? album); - - [NetDaemonApp] - public class PlayAlbum - { - private readonly CultureInfo _cultureInfo = new("fr-CA", false); - - // Snake-case json options - private readonly JsonSerializerOptions _jsonOptions = new() - { - PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower - }; - - private async Task CallBack(PlayAlbumData e, Services services) - { - string uri; - - if (e.artist is not null && e.artist != "") - { - SpotifyplusSearchArtistsResponse? artistResult = ( - await services.Spotifyplus.SearchArtistsAsync( - criteria: e?.artist ?? - throw new TargetException($"The artist {e?.artist} could not be found."), - limitTotal: 1, - entityId: Globals.DefaultEntityId, - // My Defaults - market: "CA", - includeExternal: "audio" - ) - ).Value.Deserialize<SpotifyplusSearchArtistsResponse>(_jsonOptions); - - string artistId = artistResult?.Result?.Items?[0]?.Id ?? - throw new TargetException($"The artist {e?.artist} could not be found."); - - SpotifyPlusGetArtistAlbumsResponse? result = ( - await services.Spotifyplus.GetArtistAlbumsAsync( - artistId: artistId, - entityId: Globals.DefaultEntityId, - market: "CA" - ) - ).Value.Deserialize<SpotifyPlusGetArtistAlbumsResponse>(_jsonOptions); - - List<ArtistAlbumItem> albums = result?.Result?.Items ?? - throw new TargetException($"No albums found for artist {e.artist}"); - - ExtractedResult<ArtistAlbumItem> match = Process.ExtractOne( - new ArtistAlbumItem { Name = e.album?.ToLower(_cultureInfo) }, - albums, - new Func<ArtistAlbumItem, string>((item) => - (item.Name ?? "").ToLower(_cultureInfo)) - ); - - uri = match.Value?.Uri ?? - throw new TargetException($"No matches found for album {e.album}"); - } - else - { - SpotifyplusSearchAlbumsResponse? result = ( - await services.Spotifyplus.SearchAlbumsAsync( - criteria: $"{e?.album}", - limitTotal: 1, - entityId: Globals.DefaultEntityId, - // My Defaults - market: "CA", - includeExternal: "audio" - ) - ).Value.Deserialize<SpotifyplusSearchAlbumsResponse>(_jsonOptions); - - uri = result?.Result?.Items?[0]?.Uri ?? - throw new TargetException( - $"The album {e?.album}{(e?.artist is null ? "" : $" by {e?.artist}")} could not be found." - ); - } - - services.Spotifyplus.PlayerMediaPlayContext( - contextUri: uri, - entityId: Globals.DefaultEntityId, - deviceId: Globals.DefaultDevId, - // My Defaults - positionMs: 0, - delay: 0.50 - ); - } - - public PlayAlbum(IHaContext ha, Services services) - { - ha.RegisterServiceCallBack<PlayAlbumData>( - "spotify_play_album", - (e) => Globals.RunAsyncSpotifyCallback(services, e, CallBack) - ); - } - } -} diff --git a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayArtist/PlayArtist.cs b/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayArtist/PlayArtist.cs deleted file mode 100644 index ad842510..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayArtist/PlayArtist.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System.Reflection; -using System.Text.Json; -using System.Threading.Tasks; - -using HomeAssistantGenerated; - -using NetDaemon.AppModel; -using NetDaemon.HassModel; -using NetDaemon.HassModel.Integration; - -using NetDaemonConfig.Apps.Spotify.Types; - - -namespace NetDaemonConfig.Apps.Spotify.PlayArtist -{ - public record PlayArtistData(string? artist); - - [NetDaemonApp] - public class PlayArtist - { - // Snake-case json options - private readonly JsonSerializerOptions _jsonOptions = new() - { - PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower - }; - - private async Task CallBack(PlayArtistData e, Services services) - { - SpotifyplusSearchArtistsResponse? result = ( - await services.Spotifyplus.SearchArtistsAsync( - criteria: e?.artist ?? throw new TargetException($"The artist {e?.artist} could not be found."), - limitTotal: 1, - entityId: Globals.DefaultEntityId, - // My Defaults - market: "CA", - includeExternal: "audio" - ) - ).Value.Deserialize<SpotifyplusSearchArtistsResponse>(_jsonOptions); - - string uri = result?.Result?.Items?[0]?.Uri ?? - throw new TargetException($"The artist {e?.artist} could not be found."); - - services.Spotifyplus.PlayerMediaPlayContext( - contextUri: uri, - entityId: Globals.DefaultEntityId, - deviceId: Globals.DefaultDevId, - // My Defaults - positionMs: 0, - delay: 0.50 - ); - } - - public PlayArtist(IHaContext ha, Services services) - { - ha.RegisterServiceCallBack<PlayArtistData>( - "spotify_play_artist", - (e) => Globals.RunAsyncSpotifyCallback(services, e, CallBack) - ); - } - } -} diff --git a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayPlaylist/PlayPlaylist.cs b/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayPlaylist/PlayPlaylist.cs deleted file mode 100644 index d5e6993c..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/PlayPlaylist/PlayPlaylist.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Reflection; -using System.Text.Json; -using System.Threading.Tasks; - -using FuzzySharp; -using FuzzySharp.Extractor; - -using HomeAssistantGenerated; - -using NetDaemon.AppModel; -using NetDaemon.HassModel; -using NetDaemon.HassModel.Integration; - -using NetDaemonConfig.Apps.Spotify.Types; - - -namespace NetDaemonConfig.Apps.Spotify.PlayPlaylist -{ - public record PlayPlaylistData(string? playlist); - - [NetDaemonApp] - public class PlayPlaylist - { - private readonly CultureInfo _cultureInfo = new("fr-CA", false); - - // Snake-case json options - private readonly JsonSerializerOptions _jsonOptions = new() - { - PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower - }; - - private async Task CallBack(PlayPlaylistData e, Services services) - { - string query = e?.playlist ?? throw new TargetException("Query not found."); - - SpotifyplusPlaylistResponse? result = ( - await services.Spotifyplus.GetPlaylistFavoritesAsync( - limitTotal: 200, - sortResult: true, - entityId: Globals.DefaultEntityId - ) - ).Value.Deserialize<SpotifyplusPlaylistResponse>(_jsonOptions); - - List<PlaylistsItem> myPlaylists = result?.Result?.Items ?? - throw new TargetException($"No playlists found for query {query}"); - - ExtractedResult<PlaylistsItem> match = Process.ExtractOne( - new PlaylistsItem { Name = query.ToLower(_cultureInfo) }, - myPlaylists, - new Func<PlaylistsItem, string>((item) => (item.Name ?? "").ToLower(_cultureInfo)) - ); - - string uri = match.Value?.Uri ?? throw new TargetException($"No matches found for query {query}"); - - // We search outside the user's playlists if the score is too low - if (match.Score < 85) - { - SpotifyplusPlaylistResponse? otherResult = ( - await services.Spotifyplus.SearchPlaylistsAsync( - criteria: query, - limitTotal: 1, - entityId: Globals.DefaultEntityId, - // My Defaults - market: "CA", - includeExternal: "audio" - ) - ).Value.Deserialize<SpotifyplusPlaylistResponse>(_jsonOptions); - - string potentialUri = otherResult?.Result?.Items?[0]?.Uri ?? - throw new TargetException($"No public matches found for query {query}"); - - uri = potentialUri; - } - - services.Spotifyplus.PlayerMediaPlayContext( - contextUri: uri, - entityId: Globals.DefaultEntityId, - deviceId: Globals.DefaultDevId, - // My Defaults - positionMs: 0, - delay: 0.50 - ); - } - - public PlayPlaylist(IHaContext ha, Services services) - { - ha.RegisterServiceCallBack<PlayPlaylistData>( - "spotify_play_playlist", - (e) => Globals.RunAsyncSpotifyCallback(services, e, CallBack) - ); - } - } -} diff --git a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/PlaySong/PlaySong.cs b/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/PlaySong/PlaySong.cs deleted file mode 100644 index b53a2c9c..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/PlaySong/PlaySong.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System.Reflection; -using System.Text.Json; -using System.Threading.Tasks; - -using HomeAssistantGenerated; - -using NetDaemon.AppModel; -using NetDaemon.HassModel; -using NetDaemon.HassModel.Integration; - -using NetDaemonConfig.Apps.Spotify.Types; - - -namespace NetDaemonConfig.Apps.Spotify.PlaySong -{ - public record PlaySongData(string? artist, string? song); - - [NetDaemonApp] - public class PlaySong - { - // Snake-case json options - private readonly JsonSerializerOptions _jsonOptions = new() - { - PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower - }; - - private async Task CallBack(PlaySongData e, Services services) - { - SpotifyplusSearchTracksResponse? result = ( - await services.Spotifyplus.SearchTracksAsync( - criteria: $"{e?.artist} {e?.song}", - limitTotal: 1, - entityId: Globals.DefaultEntityId, - // My Defaults - market: "CA", - includeExternal: "audio" - ) - ).Value.Deserialize<SpotifyplusSearchTracksResponse>(_jsonOptions); - - string uri = result?.Result?.Items?[0]?.Uri ?? throw new TargetException( - $"The song {e?.song}{(e?.artist is null ? "" : $" by {e?.artist}")} could not be found." - ); - - services.Spotifyplus.PlayerMediaPlayTracks( - uris: uri, - entityId: Globals.DefaultEntityId, - deviceId: Globals.DefaultDevId, - // My Defaults - positionMs: 0, - delay: 0.50 - ); - } - - public PlaySong(IHaContext ha, Services services) - { - ha.RegisterServiceCallBack<PlaySongData>( - "spotify_play_song", - (e) => Globals.RunAsyncSpotifyCallback(services, e, CallBack) - ); - } - } -} diff --git a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/Types/GetArtistAlbumsResponse.cs b/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/Types/GetArtistAlbumsResponse.cs deleted file mode 100644 index 3213584e..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/Types/GetArtistAlbumsResponse.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Collections.Generic; - - -namespace NetDaemonConfig.Apps.Spotify.Types -{ - public record ArtistAlbumItem - { - public string? AlbumType { get; set; } - public List<Artist>? Artists { get; set; } - public List<object>? AvailableMarkets { get; set; } - public ExternalUrls? ExternalUrls { get; set; } - public string? Href { get; set; } - public string? Id { get; set; } - public string? ImageUrl { get; set; } - public List<Image>? Images { get; set; } - public string? Name { get; set; } - public string? ReleaseDate { get; set; } - public string? ReleaseDatePrecision { get; set; } - public Restrictions? Restrictions { get; set; } - public int? TotalTracks { get; set; } - public string? Type { get; set; } - public string? Uri { get; set; } - } - - public record ArtistAlbumResult - { - public double? DateLastRefreshed { get; set; } - public string? Href { get; set; } - public int? Limit { get; set; } - public object? Next { get; set; } - public int? Offset { get; set; } - public object? Previous { get; set; } - public int? Total { get; set; } - public List<ArtistAlbumItem>? Items { get; set; } - } - - public record SpotifyPlusGetArtistAlbumsResponse - { - public UserProfile? UserProfile { get; set; } - public ArtistAlbumResult? Result { get; set; } - } -} diff --git a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/Types/Main.cs b/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/Types/Main.cs deleted file mode 100644 index 1a79feba..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/Types/Main.cs +++ /dev/null @@ -1,160 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -using HomeAssistantGenerated; - -namespace NetDaemonConfig.Apps.Spotify.Types -{ - public static class Globals - { - public const string DefaultDevId = "homie"; - public const string DefaultEntityId = "media_player.spotifyplus"; - - public static void LogExceptions(Services services, Action callback, string extraInfo) - { - try - { - callback(); - } - catch (Exception error) - { - services.Notify.PersistentNotification( - message: error.Message + "\n" + extraInfo, - title: "Erreur Spotify"); - } - } - - public static void RunSpotifyCallback<Params>(Services services, Params e, Action<Params, Services> callback) - { - void Callable() { callback(e, services); } - - // I do this because SpotifyPlus sometimes takes a failed call to successfully reach the speaker - try { Callable(); } - catch (Exception error) - { - Console.WriteLine(error.ToString()); - LogExceptions(services, Callable, e?.ToString() ?? ""); - } - } - - public static async void LogAsyncExceptions(Services services, Func<Task> callback, string extraInfo) - { - try - { - await callback(); - } - catch (Exception error) - { - services.Notify.PersistentNotification( - message: error.Message + "\n" + extraInfo, - title: "Erreur Spotify"); - } - } - - public static async void RunAsyncSpotifyCallback<Params>(Services services, Params e, Func<Params, Services, Task> callback) - { - async Task Callable() { await callback(e, services); } - - // I do this because SpotifyPlus sometimes takes a failed call to successfully reach the speaker - try { await Callable(); } - catch (Exception error) - { - Console.WriteLine(error.ToString()); - LogAsyncExceptions(services, Callable, e?.ToString() ?? ""); - } - } - } - - // https://jsonformatter.org/yaml-to-json - // https://json2csharp.com - // https://github.com/thlucas1/homeassistantcomponent_spotifyplus/blob/master/custom_components/spotifyplus/services.yaml - public record Restrictions { } - - public record UserProfile - { - public string? Country { get; set; } - public string? DisplayName { get; set; } - public string? Email { get; set; } - public string? Id { get; set; } - public string? Product { get; set; } - public string? Type { get; set; } - public string? Uri { get; set; } - } - - public record ExternalUrls - { - public string? Spotify { get; set; } - } - - public record Followers - { - public string? Href { get; set; } - public int? Total { get; set; } - } - - public record Image - { - public string? Url { get; set; } - public int? Height { get; set; } - public int? Width { get; set; } - } - - public record Owner - { - public string? DisplayName { get; set; } - public ExternalUrls? ExternalUrls { get; set; } - public Followers? Followers { get; set; } - public string? Href { get; set; } - public string? Id { get; set; } - public string? Type { get; set; } - public string? Uri { get; set; } - } - - public record Tracks - { - public string? Href { get; set; } - public int? Total { get; set; } - } - - public record Artist - { - public ExternalUrls? ExternalUrls { get; set; } - public string? Href { get; set; } - public string? Id { get; set; } - public string? Name { get; set; } - public string? Type { get; set; } - public string? Uri { get; set; } - } - - public record ExternalIds - { - public object? Ean { get; set; } - public string? Isrc { get; set; } - public object? Upc { get; set; } - } - - public record Album - { - public string? AlbumType { get; set; } - public List<Artist>? Artists { get; set; } - public List<string>? AvailableMarkets { get; set; } - public List<object>? Copyrights { get; set; } - public ExternalIds? ExternalIds { get; set; } - public ExternalUrls? ExternalUrls { get; set; } - public List<object>? Genres { get; set; } - public string? Href { get; set; } - public string? Id { get; set; } - public string? ImageUrl { get; set; } - public List<Image>? Images { get; set; } - public object? Label { get; set; } - public string? Name { get; set; } - public object? Popularity { get; set; } - public string? ReleaseDate { get; set; } - public string? ReleaseDatePrecision { get; set; } - public Restrictions? Restrictions { get; set; } - public int? TotalTracks { get; set; } - public string? Type { get; set; } - public string? Uri { get; set; } - } -} diff --git a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/Types/PlaylistResponse.cs b/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/Types/PlaylistResponse.cs deleted file mode 100644 index c3608cde..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/Types/PlaylistResponse.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Collections.Generic; - - -namespace NetDaemonConfig.Apps.Spotify.Types -{ - public record PlaylistsItem - { - public bool? Collaborative { get; set; } - public string? Description { get; set; } - public ExternalUrls? ExternalUrls { get; set; } - public string? Href { get; set; } - public string? Id { get; set; } - public string? ImageUrl { get; set; } - public List<Image>? Images { get; set; } - public string? Name { get; set; } - public Owner? Owner { get; set; } - public bool? Public { get; set; } - public string? SnapshotId { get; set; } - public Tracks? Tracks { get; set; } - public string? Type { get; set; } - public string? Uri { get; set; } - } - - public record PlaylistsResult - { - public string? Href { get; set; } - public int? Limit { get; set; } - public object? Next { get; set; } - public int? Offset { get; set; } - public object? Previous { get; set; } - public int? Total { get; set; } - public List<PlaylistsItem>? Items { get; set; } - } - - public record SpotifyplusPlaylistResponse - { - public UserProfile? UserProfile { get; set; } - public PlaylistsResult? Result { get; set; } - } -} diff --git a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/Types/SearchAlbumsResponse.cs b/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/Types/SearchAlbumsResponse.cs deleted file mode 100644 index 01375e4d..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/Types/SearchAlbumsResponse.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Collections.Generic; - - -namespace NetDaemonConfig.Apps.Spotify.Types -{ - public record AlbumItem - { - public string? AlbumType { get; set; } - public List<Artist>? Artists { get; set; } - public List<string>? AvailableMarkets { get; set; } - public ExternalUrls? ExternalUrls { get; set; } - public string? Href { get; set; } - public string? Id { get; set; } - public string? ImageUrl { get; set; } - public List<Image>? Images { get; set; } - public string? Name { get; set; } - public string? ReleaseDate { get; set; } - public string? ReleaseDatePrecision { get; set; } - public Restrictions? Restrictions { get; set; } - public int? TotalTracks { get; set; } - public string? Type { get; set; } - public string? Uri { get; set; } - } - - public record AlbumResult - { - public string? Href { get; set; } - public int? Limit { get; set; } - public string? Next { get; set; } - public int? Offset { get; set; } - public object? Previous { get; set; } - public int? Total { get; set; } - public List<AlbumItem>? Items { get; set; } - } - - public record SpotifyplusSearchAlbumsResponse - { - public UserProfile? UserProfile { get; set; } - public AlbumResult? Result { get; set; } - } -} diff --git a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/Types/SearchArtistsResponse.cs b/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/Types/SearchArtistsResponse.cs deleted file mode 100644 index ca2cd87b..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/Types/SearchArtistsResponse.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Collections.Generic; - - -namespace NetDaemonConfig.Apps.Spotify.Types -{ - public record ArtistItem - { - public ExternalUrls? ExternalUrls { get; init; } - public Followers? Followers { get; init; } - public List<string>? Genres { get; init; } - public string? Href { get; init; } - public string? Id { get; init; } - public string? ImageUrl { get; init; } - public List<Image>? Images { get; init; } - public string? Name { get; init; } - public int? Popularity { get; init; } - public string? Type { get; init; } - public string? Uri { get; init; } - } - - public record ArtistResult - { - public string? Href { get; init; } - public int? Limit { get; init; } - public string? Next { get; init; } - public int? Offset { get; set; } - public object? Previous { get; init; } - public int? Total { get; init; } - public List<ArtistItem>? Items { get; init; } - } - - public record SpotifyplusSearchArtistsResponse - { - public UserProfile? UserProfile { get; init; } - public ArtistResult? Result { get; init; } - } -} diff --git a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/Types/SearchTracksResponse.cs b/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/Types/SearchTracksResponse.cs deleted file mode 100644 index 9e8074be..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/apps/Spotify/Types/SearchTracksResponse.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System.Collections.Generic; - - -namespace NetDaemonConfig.Apps.Spotify.Types -{ - public record SongItem - { - public Album? Album { get; set; } - public List<Artist>? Artists { get; set; } - public List<string>? AvailableMarkets { get; set; } - public int? DiscNumber { get; set; } - public int? DurationMs { get; set; } - public bool? Explicit { get; set; } - public ExternalIds? ExternalIds { get; set; } - public ExternalUrls? ExternalUrls { get; set; } - public string? Href { get; set; } - public string? Id { get; set; } - public string? ImageUrl { get; set; } - public bool? IsLocal { get; set; } - public object? IsPlayable { get; set; } - public string? Name { get; set; } - public int? Popularity { get; set; } - public object? PreviewUrl { get; set; } - public Restrictions? Restrictions { get; set; } - public int? TrackNumber { get; set; } - public string? Type { get; set; } - public string? Uri { get; set; } - } - - public record SongResult - { - public string? Href { get; set; } - public int? Limit { get; set; } - public string? Next { get; set; } - public int? Offset { get; set; } - public object? Previous { get; set; } - public int? Total { get; set; } - public List<SongItem>? Items { get; set; } - } - - public record SpotifyplusSearchTracksResponse - { - public UserProfile? UserProfile { get; set; } - public SongResult? Result { get; set; } - } -} diff --git a/configurations/homie/modules/home-assistant/netdaemon/apps/Timer/Setup/Setup.cs b/configurations/homie/modules/home-assistant/netdaemon/apps/Timer/Setup/Setup.cs deleted file mode 100644 index 4f713188..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/apps/Timer/Setup/Setup.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System; -using System.Linq; -using System.Reactive.Linq; -using System.Text.Json; -using System.Text.Json.Serialization; - -using HomeAssistantGenerated; - -using NetDaemon.AppModel; -using NetDaemon.HassModel; -using NetDaemon.HassModel.Entities; - - -namespace NetDaemonConfig.Apps.Timer.Setup -{ - public record TimerFinishedEventData - { - [JsonPropertyName("entity_id")] - public string? entity_id { get; init; } - } - - [NetDaemonApp] - public class Setup - { - private readonly string _timerTarget = "media_player.music_player_daemon"; - - private readonly string _timerTtsTarget = "tts.piper"; - private readonly string _timerTtsMessage = "A set timer has finished."; - - // private readonly string timerMediaLocation = "/path/to/file.mp3"; - - public Setup(IHaContext ha, Services services, Entities entities) - { - ha.Events - .Where(x => x.EventType == "timer.finished") - .Subscribe(x => - { - if (x.DataElement.HasValue) - { - var data = JsonSerializer.Deserialize<TimerFinishedEventData>(x.DataElement.Value); - - if (data?.entity_id?.StartsWith("timer.assist_timer") ?? false) - { - var timer = entities.Timer - .EnumerateAll() - .ToLookup((timer) => timer.EntityId, - (timer) => timer)[data.entity_id].First(); - - if (timer is not null) - { - services.Tts.Speak( - cache: true, - mediaPlayerEntityId: _timerTarget, - target: new ServiceTarget { EntityIds = [_timerTtsTarget] }, - message: _timerTtsMessage); - } - } - } - }); - - /* - entities.Timer.EnumerateAll() - .Where((timer) => timer.EntityId.StartsWith("timer.assist_timer")) - .StateChanges() - .Subscribe((timer) => - { - if (timer.Old?.State != "idle" && timer.New?.State == "idle") - {} - }); - */ - } - } -} diff --git a/configurations/homie/modules/home-assistant/netdaemon/appsettings.json b/configurations/homie/modules/home-assistant/netdaemon/appsettings.json deleted file mode 100644 index ea2d6a6a..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/appsettings.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Debug", - "Microsoft": "Warning" - }, - "ConsoleThemeType": "Ansi" - }, - "HomeAssistant": { - "Host": "homie.nelim.org", - "Port": 443, - "Ssl": true - }, - "NetDaemon": { - "ApplicationConfigurationFolder": "./apps" - }, - "CodeGeneration": { - "Namespace": "HomeAssistantGenerated", - "OutputFile": "HomeAssistantGenerated.cs", - "UseAttributeBaseClasses" : "false" - } -} diff --git a/configurations/homie/modules/home-assistant/netdaemon/default.nix b/configurations/homie/modules/home-assistant/netdaemon/default.nix deleted file mode 100644 index 9570798a..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/default.nix +++ /dev/null @@ -1,103 +0,0 @@ -{ - config, - self, - pkgs, - ... -}: let - inherit (builtins) attrValues replaceStrings; - inherit (config.sops) secrets; - - inherit (pkgs.callPackage ./package.nix {}) netdaemonConfig; -in { - virtualisation.docker.compose."netdaemon" = { - networks.netdaemon = {external = true;}; - - services."netdaemon5" = { - image = pkgs.callPackage ./images/netdaemon.nix pkgs; - restart = "always"; - - env_file = [secrets.netdaemon.path]; - environment = { - HomeAssistant__Host = "homie.nelim.org"; - HomeAssistant__Port = "443"; - HomeAssistant__Ssl = "true"; - NetDaemon__ApplicationAssembly = "netdaemon.dll"; - Logging__LogLevel__Default = "Information"; # use Information/Debug/Trace/Warning/Error - TZ = "America/New_York"; - }; - - volumes = ["${netdaemonConfig}:/data"]; - networks = ["netdaemon"]; - }; - }; - - services.home-assistant = { - customComponents = attrValues { - inherit - (pkgs.scopedPackages.hass-components) - netdaemon - ; - }; - }; - - environment.systemPackages = let - nixFetchDeps = - replaceStrings [(toString self)] ["$FLAKE"] - #nix - '' - let - config = (builtins.getFlake ("$FLAKE")).nixosConfigurations.homie; - inherit (config) pkgs; - - netdaemonConfig = pkgs.callPackage ${toString ./package.nix} {}; - in - netdaemonConfig.fetch-deps - ''; - in [ - (pkgs.writeShellApplication { - name = "bumpNetdaemonDeps"; - - runtimeInputs = with pkgs; [ - dos2unix - dotnet-sdk_9 - ]; - - text = '' - # Install codegen - dotnet tool install --create-manifest-if-needed NetDaemon.HassModel.CodeGen --version "$(cat ./.version)" - - # Run it - dotnet tool run nd-codegen -token "$(sed 's/HomeAssistant__Token=//' ${secrets.netdaemon.path})" - dos2unix ./HomeAssistantGenerated.cs - - # This is to not have it count towards CSharp in the repo - mv ./HomeAssistantGenerated.cs ./HomeAssistantGenerated - - # Update all nugets to latest versions - regex='PackageReference Include="([^"]*)" Version="([^"]*)"' - - find . -type f -name '*.csproj' | while read -r file; do - # Extract unique package names from the .csproj file - packages=$(grep -oP "$regex" "$file" | sed -E 's/.*Include="([^"]*)".*/\1/' | sort -u) - - # Loop through each package and update - for package in $packages; do - echo -e "\033[35mUpdate $file package: $package\033[0m" - dotnet add "$file" package "$package" - done - done - - $(nix build --no-link --print-out-paths --impure --expr "$(cat <<EOF - ${nixFetchDeps} - EOF - )") . - - alejandra -q . - rm -r "$FLAKE/.config" - - sed -i "s/finalImageTag = .*/finalImageTag = \"$(cat ./.version)\";/" ./images/netdaemon.nix - updateImages . - ''; - }) - ]; -} diff --git a/configurations/homie/modules/home-assistant/netdaemon/deps.json b/configurations/homie/modules/home-assistant/netdaemon/deps.json deleted file mode 100644 index 53adcc22..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/deps.json +++ /dev/null @@ -1,322 +0,0 @@ -[ - { - "pname": "Cronos", - "version": "0.10.0", - "hash": "sha256-Y5R1QfcxuL8F3l0bjv+Tpcdj/fdWw6o8Bhkx1FcBLYQ=" - }, - { - "pname": "FuzzySharp", - "version": "2.0.2", - "hash": "sha256-GuWqVOo+AG8MSvIbusLPjKfJFQRJhSSJ9eGWljTBA/c=" - }, - { - "pname": "Microsoft.CodeAnalysis.Analyzers", - "version": "3.11.0", - "hash": "sha256-hQ2l6E6PO4m7i+ZsfFlEx+93UsLPo4IY3wDkNG11/Sw=" - }, - { - "pname": "Microsoft.CodeAnalysis.Common", - "version": "4.13.0", - "hash": "sha256-Bu5ev3JM+fyf9USnLM7AJbd5lFmpVfaxm6EQYoYM9Vc=" - }, - { - "pname": "Microsoft.CodeAnalysis.CSharp", - "version": "4.13.0", - "hash": "sha256-jzO7/2j7rPqu4Xtm4lhh2Ijaiw+aUkiR+yYn+a8mg/M=" - }, - { - "pname": "Microsoft.Extensions.Configuration", - "version": "9.0.4", - "hash": "sha256-01yWDq/dHgU1Trx2OqVsXK/yobwVTClJXB07LrPc8lU=" - }, - { - "pname": "Microsoft.Extensions.Configuration.Abstractions", - "version": "9.0.4", - "hash": "sha256-5hwq73FCWAJJ8Yb1VHaaryJJhUUiVsetPTrPLlo8N9o=" - }, - { - "pname": "Microsoft.Extensions.Configuration.Binder", - "version": "9.0.0", - "hash": "sha256-6ajYWcNOQX2WqftgnoUmVtyvC1kkPOtTCif4AiKEffU=" - }, - { - "pname": "Microsoft.Extensions.Configuration.Binder", - "version": "9.0.4", - "hash": "sha256-l+qlHrdrqgvnveSMCO4qQx1QObAe5lMl80a4Kc3idzw=" - }, - { - "pname": "Microsoft.Extensions.Configuration.CommandLine", - "version": "9.0.4", - "hash": "sha256-usXy7P5VIBusWSmI1WxpXwwDN404TTZveBoUAlJRWEQ=" - }, - { - "pname": "Microsoft.Extensions.Configuration.EnvironmentVariables", - "version": "9.0.4", - "hash": "sha256-9agLzJpXM8i24WSB2pIGaIkQL9fyuIBGK14a1jpH/Vk=" - }, - { - "pname": "Microsoft.Extensions.Configuration.FileExtensions", - "version": "9.0.4", - "hash": "sha256-i6BP99iTLEVt7aSw2Fu0ogUnY6FlVMat+BMIlndHCkQ=" - }, - { - "pname": "Microsoft.Extensions.Configuration.Json", - "version": "9.0.4", - "hash": "sha256-scTrZeY5CKX9kMcN7MYQPJVgEFwDTvO+JOk+G3wXrjs=" - }, - { - "pname": "Microsoft.Extensions.Configuration.UserSecrets", - "version": "9.0.4", - "hash": "sha256-gEYqIFucwNp+4paaEjNkiqGCDG09etqVa8UcclNU17g=" - }, - { - "pname": "Microsoft.Extensions.DependencyInjection", - "version": "9.0.4", - "hash": "sha256-ck7PqIL/3vodYky+d7YX218n+detOoEjZeMr1EqTFPg=" - }, - { - "pname": "Microsoft.Extensions.DependencyInjection.Abstractions", - "version": "9.0.0", - "hash": "sha256-CncVwkKZ5CsIG2O0+OM9qXuYXh3p6UGyueTHSLDVL+c=" - }, - { - "pname": "Microsoft.Extensions.DependencyInjection.Abstractions", - "version": "9.0.4", - "hash": "sha256-6WcGpsAYRhrpHloEom0oVP7Ff4Gh/O1XWJETJJ3LvEQ=" - }, - { - "pname": "Microsoft.Extensions.DependencyModel", - "version": "9.0.0", - "hash": "sha256-xirwlMWM0hBqgTneQOGkZ8l45mHT08XuSSRIbprgq94=" - }, - { - "pname": "Microsoft.Extensions.Diagnostics", - "version": "9.0.4", - "hash": "sha256-fmRuxerdHGVDFFJMpBv9DIzofBSxjLLsi1GvaGq1dUc=" - }, - { - "pname": "Microsoft.Extensions.Diagnostics.Abstractions", - "version": "9.0.4", - "hash": "sha256-VgBfZLr/tqAOCW3i8g8lTgdpLU/g5vHfcOUpyoQESig=" - }, - { - "pname": "Microsoft.Extensions.FileProviders.Abstractions", - "version": "9.0.4", - "hash": "sha256-OkAq+1NUG0d1Ww6zT/hZWcPB5+fCr8AJIWmkpX7CQxU=" - }, - { - "pname": "Microsoft.Extensions.FileProviders.Physical", - "version": "9.0.4", - "hash": "sha256-whn/jRYaH56Lha20yChG5wgIllttTq2EtOwyDW+ZDO4=" - }, - { - "pname": "Microsoft.Extensions.FileSystemGlobbing", - "version": "9.0.4", - "hash": "sha256-lzNTCxATfJvnsl1hlAxhI4cibixYYBq99fK9b9tEo0A=" - }, - { - "pname": "Microsoft.Extensions.Hosting", - "version": "9.0.4", - "hash": "sha256-qb3bcAbLnBvc91p/+C6K7P8g2Fd9yRVvPOvIzGFSu/g=" - }, - { - "pname": "Microsoft.Extensions.Hosting.Abstractions", - "version": "9.0.0", - "hash": "sha256-NhEDqZGnwCDFyK/NKn1dwLQExYE82j1YVFcrhXVczqY=" - }, - { - "pname": "Microsoft.Extensions.Hosting.Abstractions", - "version": "9.0.4", - "hash": "sha256-eEw2h6S0m8Wb52hWo/31uCA5NQbPn/7veYpzNhkzyl0=" - }, - { - "pname": "Microsoft.Extensions.Http", - "version": "9.0.4", - "hash": "sha256-gciOa0FAKivI5f/dzbsbS5HniIx9TJ4BTeBZ9In+fAo=" - }, - { - "pname": "Microsoft.Extensions.Logging", - "version": "9.0.0", - "hash": "sha256-kR16c+N8nQrWeYLajqnXPg7RiXjZMSFLnKLEs4VfjcM=" - }, - { - "pname": "Microsoft.Extensions.Logging", - "version": "9.0.4", - "hash": "sha256-Vj+NGOamKeuMrLNUWlVKFFkz7IKGIv6h1A5X4CK9D5E=" - }, - { - "pname": "Microsoft.Extensions.Logging.Abstractions", - "version": "9.0.0", - "hash": "sha256-iBTs9twjWXFeERt4CErkIIcoJZU1jrd1RWCI8V5j7KU=" - }, - { - "pname": "Microsoft.Extensions.Logging.Abstractions", - "version": "9.0.4", - "hash": "sha256-n0ZRhQ7U/5Kv1hVqUXGoa5gfrhzcy77yFhfonjq6VFc=" - }, - { - "pname": "Microsoft.Extensions.Logging.Configuration", - "version": "9.0.4", - "hash": "sha256-WzinyQZzj7ty00RrCGsGxwDYJlsta74M5UP0ajGTWCE=" - }, - { - "pname": "Microsoft.Extensions.Logging.Console", - "version": "9.0.4", - "hash": "sha256-tofh2lKZm+FvMp0Fx9JOXltOpDSutbGLhspdAM27USQ=" - }, - { - "pname": "Microsoft.Extensions.Logging.Debug", - "version": "9.0.4", - "hash": "sha256-W1L3jKzyeyTli94+N/Di3YtYtfv9usDFdtEnJUzvF+c=" - }, - { - "pname": "Microsoft.Extensions.Logging.EventLog", - "version": "9.0.4", - "hash": "sha256-TQkN+RM5qSHMM4WxXTbEbK5I2j8aBoC/3YvtjBA0gG8=" - }, - { - "pname": "Microsoft.Extensions.Logging.EventSource", - "version": "9.0.4", - "hash": "sha256-fp+/DPSm7gb34634p7ADtMQh8ascCE8ny0A1fCDdQfY=" - }, - { - "pname": "Microsoft.Extensions.Options", - "version": "9.0.4", - "hash": "sha256-QyjtRCG+L9eyH/UWHf/S+7/ZiSOmuGNoKGO9nlXmjxI=" - }, - { - "pname": "Microsoft.Extensions.Options.ConfigurationExtensions", - "version": "9.0.4", - "hash": "sha256-fhI6GGzVC5edaS/QEdl+2WL8/P6u/+wyq9nkLW17X64=" - }, - { - "pname": "Microsoft.Extensions.Primitives", - "version": "9.0.4", - "hash": "sha256-v/Ygyo1TMTUbnhdQSV2wzD4FOgAEWd1mpESo3kZ557g=" - }, - { - "pname": "NetDaemon.AppModel", - "version": "25.14.1", - "hash": "sha256-sq2QVQWY5xZ3M7g0Nt913BkgSiayubpEdqoeyBHPpQo=" - }, - { - "pname": "NetDaemon.AppModel.SourceDeployedApps", - "version": "25.14.1", - "hash": "sha256-YazdkXWn5IowcJr7WhQ8vRTn8aUe0QI0mTO+GSNtkX4=" - }, - { - "pname": "NetDaemon.Client", - "version": "25.14.1", - "hash": "sha256-tIr5QQneaM6+7la4TkMDuJPKZSa6EWxNPwqebzK8hvg=" - }, - { - "pname": "NetDaemon.Extensions.Logging", - "version": "25.14.1", - "hash": "sha256-IjNIIKKDH94vbfqRWo7gii7sFS52QOc6VvoSSn/QFrc=" - }, - { - "pname": "NetDaemon.Extensions.Scheduling", - "version": "25.14.1", - "hash": "sha256-Khm/Ht+kwaYpr8KYesXZCG0SRss7brNBYvPSyNsfsOY=" - }, - { - "pname": "NetDaemon.Extensions.Tts", - "version": "25.14.1", - "hash": "sha256-OkiqpBHWVjoKBkq2Gwd0SIdKx7QQ5m8ioz8H3xSuKdM=" - }, - { - "pname": "NetDaemon.HassModel", - "version": "25.14.1", - "hash": "sha256-yLXh6h1Co4VjJlBdtt1ZCwmq4q78sIUptSPlhXCVfPg=" - }, - { - "pname": "NetDaemon.HassModel.Integration", - "version": "25.14.1", - "hash": "sha256-wq6fIo10KVYhP6IrkmAovQ9mld9wzoeCbkPCCiXCrsg=" - }, - { - "pname": "NetDaemon.Runtime", - "version": "25.14.1", - "hash": "sha256-5AzZMl0jTfeKhi5AfFzYraKnjkGnEY0PZeEI8X13dGs=" - }, - { - "pname": "Serilog", - "version": "4.0.0", - "hash": "sha256-j8hQ5TdL1TjfdGiBO9PyHJFMMPvATHWN1dtrrUZZlNw=" - }, - { - "pname": "Serilog", - "version": "4.2.0", - "hash": "sha256-7f3EpCsEbDxXgsuhE430KVI14p7oDUuCtwRpOCqtnbs=" - }, - { - "pname": "Serilog.AspNetCore", - "version": "9.0.0", - "hash": "sha256-h58CFtXBRvwhTCrhQPHQMKbp98YiK02o+cOyOmktVpQ=" - }, - { - "pname": "Serilog.Extensions.Hosting", - "version": "9.0.0", - "hash": "sha256-bidr2foe7Dp4BJOlkc7ko0q6vt9ITG3IZ8b2BKRa0pw=" - }, - { - "pname": "Serilog.Extensions.Logging", - "version": "9.0.0", - "hash": "sha256-aGkz1V4HVl0rWC1BkcnLhG1EC7WLBoT3tdLdUUTFXaw=" - }, - { - "pname": "Serilog.Formatting.Compact", - "version": "3.0.0", - "hash": "sha256-nejEYqJEMG9P2iFZvbsCUPr5LZRtxbdUTLCI9N71jHY=" - }, - { - "pname": "Serilog.Settings.Configuration", - "version": "9.0.0", - "hash": "sha256-Q/q5UiSrcxoy5a/orod20E2RfiRtHDhxjjGMe1dW35I=" - }, - { - "pname": "Serilog.Sinks.Console", - "version": "6.0.0", - "hash": "sha256-QH8ykDkLssJ99Fgl+ZBFBr+RQRl0wRTkeccQuuGLyro=" - }, - { - "pname": "Serilog.Sinks.Debug", - "version": "3.0.0", - "hash": "sha256-7/LmoRF1rUDFhJ47bTRQQFRgSHnZDO8484r3sCGqYvE=" - }, - { - "pname": "Serilog.Sinks.File", - "version": "6.0.0", - "hash": "sha256-KQmlUpG9ovRpNqKhKe6rz3XMLUjkBqjyQhEm2hV5Sow=" - }, - { - "pname": "System.Collections.Immutable", - "version": "8.0.0", - "hash": "sha256-F7OVjKNwpqbUh8lTidbqJWYi476nsq9n+6k0+QVRo3w=" - }, - { - "pname": "System.Diagnostics.EventLog", - "version": "9.0.4", - "hash": "sha256-afF72ywJo/vfJXt2XiI8Lf2zKcvn0F/p280P1w3Fmk4=" - }, - { - "pname": "System.IO.Pipelines", - "version": "9.0.4", - "hash": "sha256-4E3H0n6UloSxvN41xi7hltJb9+hfaFbqwb/eOQOfNsI=" - }, - { - "pname": "System.Reactive", - "version": "6.0.1", - "hash": "sha256-Lo5UMqp8DsbVSUxa2UpClR1GoYzqQQcSxkfyFqB/d4Q=" - }, - { - "pname": "System.Reflection.Metadata", - "version": "8.0.0", - "hash": "sha256-dQGC30JauIDWNWXMrSNOJncVa1umR1sijazYwUDdSIE=" - }, - { - "pname": "YamlDotNet", - "version": "16.3.0", - "hash": "sha256-4Gi8wSQ8Rsi/3+LyegJr//A83nxn2fN8LN1wvSSp39Q=" - } -] diff --git a/configurations/homie/modules/home-assistant/netdaemon/images/netdaemon.nix b/configurations/homie/modules/home-assistant/netdaemon/images/netdaemon.nix deleted file mode 100644 index d723899a..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/images/netdaemon.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "netdaemon/netdaemon5"; - imageDigest = "sha256:b64b6ee37a3ba7a9f70b368d255774a5df594ec66a107d3de2b0c68423f73150"; - hash = "sha256-xPcM70xBKSTPdIaW4MGNWi81yuBzR4Zg9azSHUMNm/Y="; - finalImageName = imageName; - finalImageTag = "25.14.1"; -} diff --git a/configurations/homie/modules/home-assistant/netdaemon/netdaemon.csproj b/configurations/homie/modules/home-assistant/netdaemon/netdaemon.csproj deleted file mode 100644 index 1735c1f4..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/netdaemon.csproj +++ /dev/null @@ -1,38 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - - <PropertyGroup> - <OutputType>Exe</OutputType> - <TargetFramework>net9.0</TargetFramework> - <LangVersion>13.0</LangVersion> - <Nullable>enable</Nullable> - <RootNamespace>NetDaemonConfig</RootNamespace> - <Version>$([System.IO.File]::ReadAllText(".version"))</Version> - <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild> - </PropertyGroup> - - <ItemGroup> - <None Update="$(MSBuildProjectDir)appsettings.Development.json"> - <CopyToOutputDirectory>Always</CopyToOutputDirectory> - <CopyToPublishDirectory>Never</CopyToPublishDirectory> - </None> - <None Update="$(MSBuildProjectDir)appsettings.json"> - <CopyToOutputDirectory>Always</CopyToOutputDirectory> - </None> - </ItemGroup> - <Target Name="AfterPublishMessage" AfterTargets="Publish"> - <Message Text="Publish done!" Importance="high" /> - </Target> - - <ItemGroup> - <PackageReference Include="NetDaemon.AppModel" Version="25.14.1" /> - <PackageReference Include="NetDaemon.AppModel.SourceDeployedApps" Version="25.14.1" /> - <PackageReference Include="NetDaemon.Runtime" Version="25.14.1" /> - <PackageReference Include="NetDaemon.HassModel" Version="25.14.1" /> - <PackageReference Include="NetDaemon.HassModel.Integration" Version="25.14.1" /> - <PackageReference Include="NetDaemon.Client" Version="25.14.1" /> - <PackageReference Include="NetDaemon.Extensions.Scheduling" Version="25.14.1" /> - <PackageReference Include="NetDaemon.Extensions.Logging" Version="25.14.1" /> - <PackageReference Include="NetDaemon.Extensions.Tts" Version="25.14.1" /> - <PackageReference Include="FuzzySharp" Version="2.0.2" /> - </ItemGroup> -</Project> diff --git a/configurations/homie/modules/home-assistant/netdaemon/package.nix b/configurations/homie/modules/home-assistant/netdaemon/package.nix deleted file mode 100644 index f5357e6c..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/package.nix +++ /dev/null @@ -1,41 +0,0 @@ -{ - lib, - buildDotnetModule, - dotnetCorePackages, -}: let - inherit (lib) any hasInfix hasSuffix removeSuffix; - - srcDirs = ["apps"]; - srcPatterns = [".cs" ".csproj" ".json" ".version" "HomeAssistantGenerated"]; - - pname = "netdaemon-config"; -in - buildDotnetModule { - inherit pname; - version = removeSuffix "\n" (builtins.readFile ./.version); - - src = builtins.path { - name = "netdaemon-src"; - path = ./.; - filter = file: type: - (type == "directory" && any (s: hasInfix s file) srcDirs) - || any (s: hasSuffix s file) srcPatterns; - }; - - preBuild = '' - mv HomeAssistantGenerated HomeAssistantGenerated.cs - ''; - - projectFile = "netdaemon.csproj"; - nugetDeps = ./deps.json; - - dotnet-sdk = dotnetCorePackages.sdk_9_0; - dotnet-runtime = dotnetCorePackages.runtime_9_0; - executables = []; - - postFixup = '' - cp -r $out/lib/${pname} $netdaemonConfig - ''; - - outputs = ["out" "netdaemonConfig"]; - } diff --git a/configurations/homie/modules/home-assistant/netdaemon/program.cs b/configurations/homie/modules/home-assistant/netdaemon/program.cs deleted file mode 100644 index 6147a3df..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/program.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Reactive.Linq; -using System.Reflection; - -using HomeAssistantGenerated; - -using Microsoft.Extensions.Hosting; - -using NetDaemon.AppModel; -using NetDaemon.Extensions.Logging; -using NetDaemon.Extensions.Scheduler; -using NetDaemon.Extensions.Tts; -using NetDaemon.Runtime; - - -try -{ - await Host.CreateDefaultBuilder(args) - .UseNetDaemonDefaultLogging() - .UseNetDaemonRuntime() - .UseNetDaemonTextToSpeech() - .ConfigureServices(static (_, services) => - services - .AddAppsFromAssembly(Assembly.GetExecutingAssembly()) - .AddNetDaemonStateManager() - .AddNetDaemonScheduler() - .AddHomeAssistantGenerated() - ) - .Build() - .RunAsync() - .ConfigureAwait(false); -} -catch (Exception e) -{ - Console.WriteLine($"Failed to start host... {e}"); - throw; -} diff --git a/configurations/homie/modules/home-assistant/spotify/default.nix b/configurations/homie/modules/home-assistant/spotify/default.nix deleted file mode 100644 index e315810e..00000000 --- a/configurations/homie/modules/home-assistant/spotify/default.nix +++ /dev/null @@ -1,92 +0,0 @@ -{ - config, - pkgs, - ... -}: { - services.home-assistant = { - customComponents = builtins.attrValues { - inherit - (pkgs.scopedPackages.hass-components) - spotifyplus - ; - }; - - extraComponents = [ - "spotify" - ]; - - customSentences."assist_spotify" = import ./sentences.nix; - - configFiles. - ".storage/SpotifyWebApiPython_librespot_credentials.json" - .source = config.sops.secrets.spotifyd.path; - - config.intent_script = { - PlayAlbum = { - async_action = false; - action = [ - { - service = "netdaemon.spotify_play_album"; - data = { - artist = "{{ artist }}"; - album = "{{ album }}"; - }; - } - ]; - }; - - PlayArtist = { - async_action = false; - action = [ - { - service = "netdaemon.spotify_play_artist"; - data.artist = "{{ artist }}"; - } - ]; - }; - - PlayPlaylist = { - async_action = false; - action = [ - { - service = "netdaemon.spotify_play_playlist"; - data.playlist = "{{ playlist }}"; - } - ]; - }; - - PlaySong = { - async_action = false; - action = [ - { - service = "netdaemon.spotify_play_song"; - data = { - artist = "{{ artist }}"; - song = "{{ song }}"; - }; - } - ]; - }; - - Pause = { - async_action = false; - action = [ - { - service = "netdaemon.spotify_pause_unpause"; - data.pause = true; - } - ]; - }; - - Unpause = { - async_action = false; - action = [ - { - service = "netdaemon.spotify_pause_unpause"; - data.pause = false; - } - ]; - }; - }; - }; -} diff --git a/configurations/homie/modules/home-assistant/spotify/sentences.nix b/configurations/homie/modules/home-assistant/spotify/sentences.nix deleted file mode 100644 index 7a18de0e..00000000 --- a/configurations/homie/modules/home-assistant/spotify/sentences.nix +++ /dev/null @@ -1,123 +0,0 @@ -{ - language = "en"; - - lists = { - album.wildcard = true; - artist.wildcard = true; - playlist.wildcard = true; - song.wildcard = true; - }; - - # --------------------------------------- - # PlayAlbum - # --------------------------------------- - intents.PlayAlbum.data = [ - { - sentences = [ - "play[ing] [the] album {album} (from|by) [the] [artist] {artist}" - ]; - } - { - sentences = [ - "play[ing] [the] album {album}" - ]; - slots.artist = ""; - } - ]; - - responses.intents.PlayAlbum.default = '' - Searching for the album {{ slots.album }} - {% if slots.artist != "" %} - by {{ slots.artist }} - {% endif %} - on Spotify and playing it. - ''; - - # --------------------------------------- - # PlayArtist - # --------------------------------------- - intents.PlayArtist.data = [ - { - sentences = [ - "play[ing] [some] music (from|by) [the] [artist] {artist}" - "play[ing] [the] artist {artist}" - ]; - } - ]; - - responses.intents.PlayArtist.default = '' - Searching for the artist {{ slots.artist }} on Spotify and playing their top songs. - ''; - - # --------------------------------------- - # PlayPlaylist - # --------------------------------------- - intents.PlayPlaylist.data = [ - { - sentences = [ - "play[ing] [(the|my)] playlist {playlist}" - ]; - } - ]; - - responses.intents.PlayPlaylist.default = '' - Searching for {{ slots.playlist }} in your favorites, or elsewhere if not found, and playing it. - ''; - - # --------------------------------------- - # PlaySong - # --------------------------------------- - intents.PlaySong.data = [ - { - sentences = [ - "play[ing] [the] (song|track) {song} (from|by) [the] [artist] {artist}" - ]; - } - { - sentences = [ - "play[ing] [the] (song|track) {song}" - ]; - slots.artist = ""; - } - ]; - - responses.intents.PlaySong.default = '' - Searching for the song {{ slots.song }} - {% if slots.artist != "" %} - by {{ slots.artist }} - {% endif %} - on Spotify and playing it. - ''; - - # --------------------------------------- - # Pause - # --------------------------------------- - intents.Pause.data = [ - { - sentences = [ - "(pause|stop) [the] [(song|track|music)]" - "(pause|stop) spotify" - ]; - } - ]; - - responses.intents.Pause.default = '' - Pausing the music. - ''; - - # --------------------------------------- - # Unpause - # --------------------------------------- - intents.Unpause.data = [ - { - sentences = [ - "(unpause|resume) [the] [(song|track|music)]" - "(unpause|resume) spotify" - ]; - } - ]; - - responses.intents.Unpause.default = '' - Resuming the music. - ''; -} diff --git a/configurations/homie/modules/home-assistant/timer/default.nix b/configurations/homie/modules/home-assistant/timer/default.nix deleted file mode 100644 index 070c937f..00000000 --- a/configurations/homie/modules/home-assistant/timer/default.nix +++ /dev/null @@ -1,706 +0,0 @@ -# rewrite this in NetDaemon -# From https://github.com/don86nl/ha_intents/blob/main/config/packages/assist_timers.yaml -{lib, ...}: let - inherit (lib) concatStrings concatStringsSep; - - mkTimer = id: { - "assist_timer${toString id}" = { - icon = "mdi:timer-outline"; - name = "Assist - Timer ${toString id}"; - restore = true; - }; - }; - - mkLocation = id: { - "assist_timer${toString id}_location" = { - icon = "mdi:map-marker"; - name = "Assist - Timer ${toString id} Location"; - max = 255; - }; - }; - - entityIdList = concatStringsSep " " [ - ''{{ states.timer '' - ''| rejectattr('state','eq','idle')'' - ''| selectattr('entity_id','match','timer.assist_timer*')'' - ''| map(attribute='entity_id')'' - ]; - - settings = rec { - timer_target = timer_target_default; - timer_target_default = "media_player.music_player_daemon"; - - timer_tts = true; - timer_tts_service = "tts.speak"; - timer_tts_target = "tts.piper"; - timer_volume = 0.4; - timer_tts_message = "A set timer has finished."; - - timer_media_location = "/path/to/file.mp3"; - }; -in { - services.home-assistant = { - customSentences."assist_timers" = import ./sentences.nix; - - config = { - homeassistant.customize."script.assist_timerstart" = {inherit settings;}; - - # Make timers - timer = (mkTimer 1) // (mkTimer 2) // (mkTimer 3); - - # Makes location of a timer customizable from the UI - input_text = (mkLocation 1) // (mkLocation 2) // (mkLocation 3); - - intent_script = { - TimerStart = { - async_action = "false"; - action = [ - { - service = "script.assist_timerstart"; - data.duration = "{{hours | int(default=0)}}:{{ minutes | int(default=0) }}:{{ seconds | int(default=0) }}"; - } - ]; - }; - TimerStop = { - async_action = true; - action = [ - { - service = "script.assist_timerstop"; - data.entity_id = "{{ entity_id }}"; - } - ]; - }; - TimerPause = { - async_action = true; - action = [ - { - service = "script.assist_timerpause"; - data = { - entity_id = "{{ entity_id }}"; - timer_action = "{{ timer_action }}"; - }; - } - ]; - }; - TimerDuration = { - async_action = true; - action = [{stop = "";}]; - }; - }; - - # Automate some logic - automation = [ - { - alias = "Assist - TimerFinished"; - id = "assist_timerfinished"; - description = "Assist automation when set timer time is finished."; - mode = "parallel"; - - condition = [ - { - alias = "Timer was active or paused"; - condition = "template"; - value_template = ''{{ trigger.from_state != trigger.to_state }}''; - } - ]; - - trigger = [ - { - alias = "Assist timer finished or cancelled"; - entity_id = ["timer.assist_timer1" "timer.assist_timer2" "timer.assist_timer3"]; - platform = "state"; - to = "idle"; - } - ]; - - action = [ - { - alias = "Delay for Timer Reached automation"; - delay.seconds = 3; - } - - { - alias = "Reset timer location"; - service = "input_text.set_value"; - - target.entity_id = ''{{ 'input_text.' + trigger.entity_id[6:] + '_location' }}''; - - data = { - value = ""; - }; - } - ]; - } - ]; - - # Scripts to start, pause and stop timers - script = let - entity_id = ''{% if entity_id is set or entity_id != "" %} {{ entity_id }} {% else %} null {% endif %}''; - in { - assist_timerpause = { - alias = "Assist - TimerPause"; - description = "Script for pausing a timer using HA Assist."; - icon = "mdi:assistant"; - mode = "single"; - - variables = { - inherit entity_id; - timer_action = ''{% if timer_action is set or timer_action != "" %} {{ timer_action }} {% else %} resume {% endif %}''; - }; - - sequence = [ - { - choose = [ - { - conditions = [ - { - alias = "Single Timer"; - condition = "template"; - value_template = ''{{ entity_id[0][:18] == 'timer.assist_timer' }}''; - } - ]; - - sequence = [ - { - alias = "Single timer: Idle or active"; - - choose = [ - { - conditions = [ - { - alias = "Timer not active"; - condition = "template"; - value_template = ''{{ states(entity_id) == 'idle' }}''; - } - ]; - - sequence = [ - {stop = "Timer is not active";} - ]; - } - ]; - - default = [ - { - alias = "Pause or resume"; - - choose = [ - { - alias = "Pause"; - - conditions = [ - { - alias = "Action = pause"; - condition = "template"; - value_template = ''{{ timer_action == 'pause' }}''; - } - ]; - - sequence = [ - { - alias = "Pause timer"; - service = "timer.pause"; - - target.entity_id = ''{{ entity_id }}''; - } - {stop = "Pause timer";} - ]; - } - ]; - - default = [ - { - alias = "Resume timer"; - service = "timer.start"; - - target.entity_id = ''{{ entity_id }}''; - } - {stop = "Resume timer";} - ]; - } - ]; - } - ]; - } - - { - alias = "No specific timer"; - - conditions = [ - { - alias = "No specific Timer"; - condition = "template"; - value_template = ''{{ entity_id == 'null' or entity_id | list | length == 0 }}''; - } - - { - alias = "Timer(s) are active"; - condition = "template"; - value_template = ''${entityIdList} | list | length > 0 }}''; - } - ]; - - sequence = [ - { - alias = "No specific timer: # active?"; - - choose = [ - { - conditions = [ - { - alias = "No specific timer asked"; - condition = "template"; - value_template = ''{{ entity_id == 'null' or entity_id | list | length == 0 }}''; - } - - { - alias = "Multiple timers active"; - condition = "template"; - value_template = ''${entityIdList} | list | length > 1 }}''; - } - ]; - - sequence = [ - {stop = "Multiple timers active, none specified";} - ]; - } - ]; - - default = [ - { - alias = "Pause or resume"; - - choose = [ - { - alias = "Pause"; - - conditions = [ - { - alias = "Action = pause"; - condition = "template"; - value_template = ''{{ timer_action == 'pause' }}''; - } - ]; - - sequence = [ - { - alias = "Pause timer"; - service = "timer.pause"; - - target.entity_id = ''${entityIdList} | join(', ') }}''; - } - {stop = "Pause timer";} - ]; - } - ]; - - default = [ - { - alias = "Resume timer"; - service = "timer.start"; - - target.entity_id = ''${entityIdList} | join(', ') }}''; - } - {stop = "Resume timer";} - ]; - } - ]; - } - ]; - } - - { - alias = "All timers"; - - conditions = [ - { - alias = "All timers"; - condition = "template"; - value_template = ''{{ entity_id[0] == 'all' }}''; - } - ]; - - sequence = [ - { - alias = "Timers active?"; - - choose = [ - { - alias = "No timers active"; - - conditions = [ - { - alias = "No timers active"; - condition = "template"; - value_template = ''${entityIdList} | list | length == 0 }}''; - } - ]; - - sequence = [ - {stop = "No timers active";} - ]; - } - ]; - - default = [ - { - alias = "Pause or resume"; - - choose = [ - { - alias = "Pause"; - - conditions = [ - { - alias = "Action = pause"; - condition = "template"; - value_template = ''{{ timer_action == 'pause' }}''; - } - ]; - - sequence = [ - { - alias = "Pause timer"; - service = "timer.pause"; - target.entity_id = ''${entityIdList} | join(', ') }}''; - } - {stop = "Pause timer";} - ]; - } - ]; - - default = [ - { - alias = "Resume timer"; - service = "timer.start"; - - target.entity_id = ''${entityIdList} | join(', ') }}''; - } - {stop = "Resume timer";} - ]; - } - ]; - } - ]; - } - ]; - } - ]; - }; - - assist_timerstart = { - alias = "Assist - TimerStart"; - description = "Script for starting a timer using HA Assist."; - icon = "mdi:assistant"; - mode = "single"; - - variables = {inherit settings;}; - - sequence = [ - { - alias = "Set variables"; - - variables = { - timer_location = concatStrings [ - ''{%- if settings.get('timer_target')[:13] == "media_player." %}'' - ''{{ area_name(settings.get('timer_target')) | lower }}'' - - ''{% elif (settings.get('timer_target')[:7] == "sensor." or settings.get('timer_target')[:11] == "input_text.") and states(settings.get('timer_target'))[:13] == "media_player." %}'' - ''{{- states(settings.get('timer_target')) }}'' - - ''{%- elif settings.get('timer_target')[:13] != "media_player." and settings.get('timer_target')[:7] != "sensor." and settings.get('timer_target')[:11] != "input_text." %}'' - ''{{- settings.get('timer_target') }}'' - - ''{%- elif (settings.get('timer_target')[:7] == "sensor." or settings.get('timer_target')[:11] == "input_text.") and (states(settings.get('timer_target')) != "") and (states(settings.get('timer_target'))[:13] == "media_player.") %}'' - ''{{ area_name(settings.get('timer_target_default')) }} '' - - ''{%- elif (settings.get('timer_target')[:7] == "sensor." or settings.get('timer_target')[:11] == "input_text.") %}'' - ''{% if states(settings.get('timer_target')) != "" and states(settings.get('timer_target')) != "not_home" and states(settings.get('timer_target')) != 0 %}'' - ''{{ states(settings.get('timer_target')) }}'' - - ''{% else %}'' - ''{{- area_name(settings.get('timer_target_default')) | lower }}'' - ''{%- endif %}'' - - ''{%- else %}'' - ''{{- area_name(settings.get('timer_target')) | lower }}'' - ''{%- endif %}'' - ]; - }; - } - - { - alias = "Set timer location"; - service = "input_text.set_value"; - - target.entity_id = concatStrings [ - ''{% if states('timer.assist_timer1') != 'active' and states('timer.assist_timer1') != 'paused' %}'' - ''input_text.assist_timer1_location'' - - ''{% elif states('timer.assist_timer2') != 'active' and states('timer.assist_timer2') != 'paused' %}'' - ''input_text.assist_timer2_location'' - - ''{% else %}'' - ''input_text.assist_timer3_location'' - ''{% endif%}'' - ]; - - data = { - value = ''{{ timer_location }}''; - }; - } - - { - alias = "Start timer"; - service = "timer.start"; - - target.entity_id = concatStrings [ - ''{% if states('timer.assist_timer1') != 'active' and states('timer.assist_timer1') != 'paused' %}'' - ''timer.assist_timer1'' - - ''{% elif states('timer.assist_timer2') != 'active' and states('timer.assist_timer2') != 'paused' %}'' - ''timer.assist_timer2'' - - ''{% else %}'' - ''timer.assist_timer3'' - ''{% endif%}'' - ]; - - data_template = { - duration = ''{{ duration }}''; - }; - } - ]; - }; - - assist_timerstop = { - alias = "Assist - TimerStop"; - description = "Script for stopping a timer using HA Assist."; - icon = "mdi:assistant"; - mode = "single"; - - variables = {inherit entity_id;}; - - sequence = [ - { - alias = "Set variables"; - variables = {inherit entity_id;}; - } - - { - choose = [ - { - alias = "Stop Timer music"; - - conditions = [ - { - alias = "Timer is a media file"; - condition = "template"; - value_template = ''{{ timer_tts == false }}''; - } - - { - condition = "template"; - value_template = '' - {% set mediaplayer = namespace(entity=[]) %} - {% for player in states.media_player %} - {%- if ((state_attr(player.entity_id, 'media_content_id') |lower != 'none' and state_attr(player.entity_id, 'media_content_id')[:47][38:] == 'timer.mp3') or state_attr(player.entity_id, 'media_title') | lower == 'timer') and states(player.entity_id) == 'playing' -%} - {%- set mediaplayer.entity = player.entity_id -%} - {% endif -%} - {% endfor %} - {{ mediaplayer.entity[:12] == 'media_player' }} - ''; - } - ]; - - sequence = [ - { - alias = "Stop timer music"; - service = "media_player.media_stop"; - - target.entity_id = '' - {% set mediaplayer = namespace(entity=[]) %} - {% for player in states.media_player %} - {% if ((state_attr(player.entity_id, 'media_content_id') |lower != 'none' and state_attr(player.entity_id, 'media_content_id')[:47][38:] == 'timer.mp3') or state_attr(player.entity_id, 'media_title') | lower == 'timer') and states(player.entity_id) == 'playing' %} - {% set mediaplayer.entity = player.entity_id %} - {% endif %} - {% endfor %} {{ mediaplayer.entity }}''; - } - ]; - } - - { - conditions = [ - { - alias = "Single Timer"; - condition = "template"; - value_template = ''{{ entity_id[0][:18] == 'timer.assist_timer' }}''; - } - ]; - - sequence = [ - { - alias = "Single timer: Idle or active"; - - choose = [ - { - conditions = [ - { - alias = "Timer not active"; - condition = "template"; - value_template = ''{{ states(entity_id) == 'idle' }}''; - } - ]; - - sequence = [ - {stop = "Timer is not active";} - ]; - } - ]; - - default = [ - { - alias = "Reset timer location value"; - service = "input_text.set_value"; - - target.entity_id = ''${entityIdList} | join('_location, ') | replace('timer.', 'input_text.') }}''; - - data = { - value = "0"; - }; - } - - { - alias = "Cancel single timer"; - service = "timer.cancel"; - - target.entity_id = ''{{ entity_id }}''; - } - - {stop = "Timer cancelled";} - ]; - } - ]; - } - - { - alias = "No specific timer"; - - conditions = [ - { - alias = "No specific Timer"; - condition = "template"; - value_template = ''{{ entity_id == 'null' or entity_id | list | length == 0 }}''; - } - - { - alias = "Timer(s) are active"; - condition = "template"; - value_template = ''${entityIdList} | list | length > 0 }}''; - } - ]; - - sequence = [ - { - alias = "No specific timer: # active?"; - - choose = [ - { - conditions = [ - { - alias = "No specific timer asked"; - condition = "template"; - value_template = ''{{ entity_id == 'null' or entity_id | list | length == 0 }}''; - } - - { - alias = "Multiple timers active"; - condition = "template"; - value_template = ''${entityIdList} | list | length > 1 }}''; - } - ]; - - sequence = [ - {stop = "Multiple timers active, none specified";} - ]; - } - ]; - - default = [ - { - alias = "Cancel single timer"; - service = "timer.cancel"; - - target.entity_id = ''${entityIdList} | join(', ') }}''; - } - - { - alias = "Reset timer location value"; - service = "input_text.set_value"; - metadata = {}; - - target.entity_id = ''${entityIdList} | join('_location, ') | replace('timer.', 'input_text.') }}''; - - data = {value = "0";}; - } - - {stop = "Timer cancelled";} - ]; - } - ]; - } - - { - alias = "All timers"; - - conditions = [ - { - alias = "All timers"; - condition = "template"; - value_template = ''{{ entity_id[0] == 'all' }}''; - } - ]; - - sequence = [ - { - alias = "Timers active?"; - - choose = [ - { - alias = "No timers active"; - - conditions = [ - { - alias = "No timers active"; - condition = "template"; - value_template = ''${entityIdList} | list | length == 0 }}''; - } - ]; - - sequence = [ - {stop = "No timers active";} - ]; - } - ]; - - default = [ - { - alias = "Cancel all timers"; - service = "timer.cancel"; - - target.entity_id = ''${entityIdList} | join(', ') }}''; - } - - {stop = "Cancel all timers";} - ]; - } - ]; - } - ]; - } - ]; - }; - }; - }; - }; -} diff --git a/configurations/homie/modules/home-assistant/timer/sentences.nix b/configurations/homie/modules/home-assistant/timer/sentences.nix deleted file mode 100644 index ce95bcbd..00000000 --- a/configurations/homie/modules/home-assistant/timer/sentences.nix +++ /dev/null @@ -1,942 +0,0 @@ -{ - language = "en"; - - intents = { - TimerDuration.data = [ - { - sentences = [ - "how [much] long[er] on [the] {entity_id} timer" - "how much time is left on [the] {entity_id} timer" - "how long until [the] {entity_id} timer (is finished|finishes)" - ]; - } - { - sentences = [ - "how [much] long[er] on [the] timer[s]" - "how much time is left on [the] {entity_id} timer[s]" - "how long until [the] timer[s] (is finished|finishes)" - ]; - slots.entity_id = "null"; - } - ]; - - TimerPause.data = [ - { - sentences = ["(pause|interrupt) [the] {entity_id} timer[s]"]; - slots.timer_action = "pause"; - } - { - sentences = ["(pause|interrupt) [the] timer[s]"]; - slots = { - entity_id = "null"; - timer_action = "pause"; - }; - } - { - sentences = ["(pause|interrupt) all timer[s]"]; - slots = { - entity_id = "all"; - timer_action = "pause"; - }; - } - { - sentences = ["(resume|continue) [the] {entity_id} timer[s]"]; - slots.timer_action = "resume"; - } - { - sentences = ["(resume|continue) [the] timer[s]"]; - slots = { - entity_id = "null"; - timer_action = "resume"; - }; - } - { - sentences = ["(resume|continue) all timer[s]"]; - slots = { - entity_id = "all"; - timer_action = "resume"; - }; - } - ]; - - TimerStart.data = [ - { - sentences = [ - "(start|set) [a] timer (for|with) {hours} hour[s] [and] {minutes} minute[s] [and] {seconds} second[s]" - ]; - } - - { - sentences = [ - "(start|set) [(a|an)] timer (for|with) {hours} hour[s]" - "(start|set) [(a|an)] {hours} hour[s] timer" - ]; - slots = { - minutes = 0; - seconds = 0; - }; - } - - { - sentences = [ - "(start|set) [a] timer (for|with) {minutes} minute[s]" - "(start|set) [(a|an)] {minutes} minute[s] timer" - ]; - slots = { - hours = 0; - seconds = 0; - }; - } - - { - sentences = [ - "(start|set) [a] timer (for|with) {seconds} second[s]" - "(start|set) [(a|an)] {seconds} second[s] timer" - ]; - slots = { - hours = 0; - minutes = 0; - }; - } - - { - sentences = [ - "(start|set) [a] timer (for|with) {minutes} minute[s] [and] {seconds} second[s]" - ]; - slots.hours = 0; - } - - { - sentences = [ - "(start|set) [a] timer (for|with) {hours} hour[s] [and] {minutes} minute[s]" - ]; - slots.seconds = 0; - } - ]; - - TimerStop.data = [ - {sentences = ["(stop|cancel|turn off) [the] {entity_id} timer[s]"];} - { - sentences = ["(stop|cancel|turn off) [the] timer[s]"]; - slots.entity_id = "null"; - } - ]; - }; - - responses.intents = { - TimerDuration.default = '' - {%- set timer_amount = states.timer - | selectattr('state','eq','active') - | selectattr('entity_id','match','timer.assist_timer*') - | map(attribute='entity_id') - | list - | length -%} - - {% if timer_amount == 0 %} - There are no timers active. - {% else %} - {%- if slots.entity_id != 'all' and slots.entity_id != 'null' %} - {%- set active_timers = states.timer - | selectattr('state','eq','active') - | selectattr('entity_id','match',slots.entity_id) - | list -%} - {%- else%} - {%- set active_timers = states.timer - | selectattr('state','eq','active') - | selectattr('entity_id','match','timer.assist_timer*') - | list -%} - {%- endif %} - - {% if active_timers|length == 0 %} - {%- if slots.entity_id != 'all' and slots.entity_id != 'null' %} - This timer is not active. - {%- else %} - There are no timers active. - {%- endif %} - {% elif active_timers|length > 1 %} - There are {{active_timers|length }} timers active. - {% endif %} - - {% for timer in active_timers %} - {% set timer_id = timer.entity_id %} - {% set timer_finishes_at = state_attr(timer_id, 'finishes_at') %} - - {% set time_remaining = as_datetime(timer_finishes_at) - now() %} - {% set hours_remaining = time_remaining.total_seconds() // 3600 %} - {% set minutes_remaining = (time_remaining.total_seconds() % 3600) // 60 %} - {% set seconds_remaining = time_remaining.total_seconds() % 60 %} - - {% if timer.state == "active" or timer.state == "paused" %} - {% if slots.entity_id != timer_id %} - {{ state_attr(timer_id, 'friendly_name')[9:] }} - - {% if timer.state == "paused" %} - is paused and - {% endif %} - has - {% else %} - There are - {% endif %} - - {% if hours_remaining > 0 %} - {{ hours_remaining | round }} hours - {% endif %} - - {% if minutes_remaining == 1 %} - 1 minute - {% endif %} - - {% if minutes_remaining > 1 %} - {{ minutes_remaining | round }} minutes - {% endif %} - - {% if seconds_remaining == 1 and hours_remaining == 0%} - 1 second - {% endif %} - - {% if seconds_remaining > 1 and hours_remaining == 0 %} - {{ seconds_remaining | round }} seconds - {% endif %} - remaining. - {% endif %} - {% endfor %} - {% endif %} - ''; - - TimerPause.default = '' - {%- if slots.timer_action is set or slots.timer_action != "" -%} - {%- set timer_action = slots.timer_action -%} - {%- else -%} - {%- set timer_action = "resume" -%} - {%- endif -%} - - {%- set timer_amount = states.timer - | selectattr('state','eq','active') - | selectattr('entity_id','match','timer.assist_timer*') - | map(attribute='entity_id') - | list - | length -%} - - {% if timer_amount == 0 %} - There are no timers active. - - {% elif timer_amount > 1 and slots.entity_id == 'null' %} - There are multiple timers active. - {{ (["Please specify which timer you mean.", "Please specify which timer.", "Specify which timer you mean.", ""] | random) }} - - {% elif slots.entity_id == 'all' %} - {{ (["Understood. ", "Okay. ", "Of course. ", ""] | random) }}. - All timers - {% if timer_action == "pause" %} - paused - {% else %} - resumed - {% endif %} - . - - {% elif (as_timestamp(now()) - as_timestamp(states.timer.assist_timer1.last_changed) < 3 and states('timer.assist_timer1') == 'idle') or - (as_timestamp(now()) - as_timestamp(states.timer.assist_timer2.last_changed) < 3 and states('timer.assist_timer2') == 'idle') or - (as_timestamp(now()) - as_timestamp(states.timer.assist_timer3.last_changed) < 3 and states('timer.assist_timer3') == 'idle') %} - Timer - {% if timer_action == "pause" %} - paused - {% else %} - resumed - {% endif %} - . - - {% elif (timer_amount == 1 and slots.entity_id == 'null') or - (slots.entity_id == 'timer.assist_timer1' and states('timer.assist_timer1') != 'idle') or - (slots.entity_id == 'timer.assist_timer2' and states('timer.assist_timer2') != 'idle') or - (slots.entity_id == 'timer.assist_timer3' and states('timer.assist_timer3') != 'idle') %} - {{ (["Understood. ", "Okay. ", "Of course. ", ""] | random) }}Timer - {% if timer_action == "pause" %} - paused - {% else %} - resumed - {% endif %} - . - {% else %} - - This timer is not active. - {% endif %} - ''; - - TimerStart.default = '' - {{ (["Understood. ", "Okay. ", "Of course. ", ""] | random) + - (["I will start a timer for ", "Timer started with ", "Starting timer with ", "Timer active for "] | random)}} - - {% if (slots.hours | int(default=0)) == 1 %} - 1 hour - {% elif (slots.hours | int(default=0)) > 1 %} - {{ (slots.hours | int)}} hours - {% endif %} - - {% if (slots.hours | int(default=0)) > 0 and ((slots.minutes | int(default=0)) > 0 or (slots.seconds | int(default=0)) > 0) %} - and - {% endif %} - - {% if (slots.minutes | int(default=0)) == 1 %} - 1 minute - {% elif (slots.minutes | int(default=0)) > 1 %} - {{ (slots.minutes | int)}} minutes - {% endif %} - - {% if (slots.minutes | int(default=0)) > 0 and (slots.seconds | int(default=0)) > 0 %} - and - {% endif %} - - {% if (slots.seconds | int(default=0)) == 1 %} - 1 second - {% elif (slots.seconds | int(default=0)) > 1 %} - {{ (slots.seconds | int)}} seconds - {% endif %}. - ''; - - TimerStop.default = '' - {%- set timer_amount = states.timer - | selectattr('state','eq','active') - | selectattr('entity_id','match','timer.assist_timer*') - | map(attribute='entity_id') - | list - | length -%} - - {% set mediaplayer = namespace(entity=[]) %} - - {% for player in states.media_player %} - {%- if ((state_attr(player.entity_id, 'media_content_id') | lower != 'none' - and state_attr(player.entity_id, 'media_content_id')[:47][38:] == 'Timer.mp3') - or state_attr(player.entity_id, 'media_title') | lower == 'timer') - and states(player.entity_id) == 'playing' -%} - {%- set mediaplayer.entity = player.entity_id -%} - {% endif -%} - {% endfor %} - - {% if mediaplayer.entity[:12] == 'media_player' %} - {{ (["Understood. ", "Okay. ", "Of course. ", ""] | random) }}Timer stopped. - {% elif timer_amount == 0 and - (as_timestamp(now()) - as_timestamp(states.timer.assist_timer1.last_changed) > 3 and states('timer.assist_timer1') == 'idle') and - (as_timestamp(now()) - as_timestamp(states.timer.assist_timer2.last_changed) > 3 and states('timer.assist_timer2') == 'idle') and - (as_timestamp(now()) - as_timestamp(states.timer.assist_timer3.last_changed) > 3 and states('timer.assist_timer3') == 'idle') %} - There are no timers active. - {% elif (slots_entity_id == 'timer.assist_timer1' and states('timer.assist_timer1') == 'idle') or - (slots_entity_id == 'timer.assist_timer2' and states('timer.assist_timer2') == 'idle') or - (slots_entity_id == 'timer.assist_timer3' and states('timer.assist_timer3') == 'idle') %} - This timer is not active. - {% elif timer_amount > 1 and slots_entity_id == 'null' %} - There are multiple timers active. - {{ (["Please specify which timer you mean.", "Please specify which timer.", "Specify which timer you mean.", ""] | random) }} - {% elif slots_entity_id == 'all' %} - {{ (["Understood. ", "Okay. ", "Of course. ", ""] | random) }}All timers stopped. - {% else %} - {{ (["Understood. ", "Okay. ", "Of course. ", ""] | random) }}Timer stopped. - {% endif %} - ''; - }; - - lists = { - entity_id.values = [ - { - "in" = "(first|one|1)"; - out = "timer.assist_timer1"; - } - { - "in" = "(second|two|2)"; - out = "timer.assist_timer2"; - } - { - "in" = "(third|three|3)"; - out = "timer.assist_timer3"; - } - { - "in" = "(all|every)"; - out = "all"; - } - ]; - - hours.values = [ - { - "in" = "(one|1)"; - out = 1; - } - { - "in" = "(two|2)"; - out = 2; - } - { - "in" = "(three|3)"; - out = 3; - } - { - "in" = "(four|4)"; - out = 4; - } - { - "in" = "(five|5)"; - out = 5; - } - { - "in" = "(six|6)"; - out = 6; - } - { - "in" = "(seven|7)"; - out = 7; - } - { - "in" = "(eight|8)"; - out = 8; - } - { - "in" = "(nine|9)"; - out = 9; - } - { - "in" = "(ten|10)"; - out = 10; - } - { - "in" = "(eleven|11)"; - out = 11; - } - { - "in" = "(twelve|12)"; - out = 12; - } - { - "in" = "(thirteen|13)"; - out = 13; - } - { - "in" = "(fourteen|14)"; - out = 14; - } - { - "in" = "(fifteen|15)"; - out = 15; - } - { - "in" = "(sixteen|16)"; - out = 16; - } - { - "in" = "(seventeen|17)"; - out = 17; - } - { - "in" = "(eighteen|18)"; - out = 18; - } - { - "in" = "(nineteen|19)"; - out = 19; - } - { - "in" = "(twenty|20)"; - out = 20; - } - { - "in" = "(twenty-one|21)"; - out = 21; - } - { - "in" = "(twenty-two|22)"; - out = 22; - } - { - "in" = "(twenty-three|23)"; - out = 23; - } - { - "in" = "(twenty-four|24)"; - out = 24; - } - ]; - - minutes.values = [ - { - "in" = "(one|1)"; - out = 1; - } - { - "in" = "(two|2)"; - out = 2; - } - { - "in" = "(three|3)"; - out = 3; - } - { - "in" = "(four|4)"; - out = 4; - } - { - "in" = "(five|5)"; - out = 5; - } - { - "in" = "(six|6)"; - out = 6; - } - { - "in" = "(seven|7)"; - out = 7; - } - { - "in" = "(eight|8)"; - out = 8; - } - { - "in" = "(nine|9)"; - out = 9; - } - { - "in" = "(ten|10)"; - out = 10; - } - { - "in" = "(eleven|11)"; - out = 11; - } - { - "in" = "(twelve|12)"; - out = 12; - } - { - "in" = "(thirteen|13)"; - out = 13; - } - { - "in" = "(fourteen|14)"; - out = 14; - } - { - "in" = "(fifteen|15)"; - out = 15; - } - { - "in" = "(sixteen|16)"; - out = 16; - } - { - "in" = "(seventeen|17)"; - out = 17; - } - { - "in" = "(eighteen|18)"; - out = 18; - } - { - "in" = "(nineteen|19)"; - out = 19; - } - { - "in" = "(twenty|20)"; - out = 20; - } - { - "in" = "(twenty-one|21)"; - out = 21; - } - { - "in" = "(twenty-two|22)"; - out = 22; - } - { - "in" = "(twenty-three|23)"; - out = 23; - } - { - "in" = "(twenty-four|24)"; - out = 24; - } - { - "in" = "(twenty-five|25)"; - out = 25; - } - { - "in" = "(twenty-six|26)"; - out = 26; - } - { - "in" = "(twenty-seven|27)"; - out = 27; - } - { - "in" = "(twenty-eight|28)"; - out = 28; - } - { - "in" = "(twenty-nine|29)"; - out = 29; - } - { - "in" = "(thirty|30)"; - out = 30; - } - { - "in" = "(thirty-one|31)"; - out = 31; - } - { - "in" = "(thirty-two|32)"; - out = 32; - } - { - "in" = "(thirty-three|33)"; - out = 33; - } - { - "in" = "(thirty-four|34)"; - out = 34; - } - { - "in" = "(thirty-five|35)"; - out = 35; - } - { - "in" = "(thirty-six|36)"; - out = 36; - } - { - "in" = "(thirty-seven|37)"; - out = 37; - } - { - "in" = "(thirty-eight|38)"; - out = 38; - } - { - "in" = "(thirty-nine|39)"; - out = 39; - } - { - "in" = "(forty|40)"; - out = 40; - } - { - "in" = "(forty-one|41)"; - out = 41; - } - { - "in" = "(forty-two|42)"; - out = 42; - } - { - "in" = "(forty-three|43)"; - out = 43; - } - { - "in" = "(forty-four|44)"; - out = 44; - } - { - "in" = "(forty-five|45)"; - out = 45; - } - { - "in" = "(forty-six|46)"; - out = 46; - } - { - "in" = "(forty-seven|47)"; - out = 47; - } - { - "in" = "(forty-eight|48)"; - out = 48; - } - { - "in" = "(forty-nine|49)"; - out = 49; - } - { - "in" = "(fifty|50)"; - out = 50; - } - { - "in" = "(fifty-one|51)"; - out = 51; - } - { - "in" = "(fifty-two|52)"; - out = 52; - } - { - "in" = "(fifty-three|53)"; - out = 53; - } - { - "in" = "(fifty-four|54)"; - out = 54; - } - { - "in" = "(fifty-five|55)"; - out = 55; - } - { - "in" = "(fifty-six|56)"; - out = 56; - } - { - "in" = "(fifty-seven|57)"; - out = 57; - } - { - "in" = "(fifty-eight|58)"; - out = 58; - } - { - "in" = "(fifty-nine|59)"; - out = 59; - } - { - "in" = "(sixty|60)"; - out = 60; - } - ]; - - seconds.values = [ - { - "in" = "(one|1)"; - out = 1; - } - { - "in" = "(two|2)"; - out = 2; - } - { - "in" = "(three|3)"; - out = 3; - } - { - "in" = "(four|4)"; - out = 4; - } - { - "in" = "(five|5)"; - out = 5; - } - { - "in" = "(six|6)"; - out = 6; - } - { - "in" = "(seven|7)"; - out = 7; - } - { - "in" = "(eight|8)"; - out = 8; - } - { - "in" = "(nine|9)"; - out = 9; - } - { - "in" = "(ten|10)"; - out = 10; - } - { - "in" = "(eleven|11)"; - out = 11; - } - { - "in" = "(twelve|12)"; - out = 12; - } - { - "in" = "(thirteen|13)"; - out = 13; - } - { - "in" = "(fourteen|14)"; - out = 14; - } - { - "in" = "(fifteen|15)"; - out = 15; - } - { - "in" = "(sixteen|16)"; - out = 16; - } - { - "in" = "(seventeen|17)"; - out = 17; - } - { - "in" = "(eighteen|18)"; - out = 18; - } - { - "in" = "(nineteen|19)"; - out = 19; - } - { - "in" = "(twenty|20)"; - out = 20; - } - { - "in" = "(twenty-one|21)"; - out = 21; - } - { - "in" = "(twenty-two|22)"; - out = 22; - } - { - "in" = "(twenty-three|23)"; - out = 23; - } - { - "in" = "(twenty-four|24)"; - out = 24; - } - { - "in" = "(twenty-five|25)"; - out = 25; - } - { - "in" = "(twenty-six|26)"; - out = 26; - } - { - "in" = "(twenty-seven|27)"; - out = 27; - } - { - "in" = "(twenty-eight|28)"; - out = 28; - } - { - "in" = "(twenty-nine|29)"; - out = 29; - } - { - "in" = "(thirty|30)"; - out = 30; - } - { - "in" = "(thirty-one|31)"; - out = 31; - } - { - "in" = "(thirty-two|32)"; - out = 32; - } - { - "in" = "(thirty-three|33)"; - out = 33; - } - { - "in" = "(thirty-four|34)"; - out = 34; - } - { - "in" = "(thirty-five|35)"; - out = 35; - } - { - "in" = "(thirty-six|36)"; - out = 36; - } - { - "in" = "(thirty-seven|37)"; - out = 37; - } - { - "in" = "(thirty-eight|38)"; - out = 38; - } - { - "in" = "(thirty-nine|39)"; - out = 39; - } - { - "in" = "(forty|40)"; - out = 40; - } - { - "in" = "(forty-one|41)"; - out = 41; - } - { - "in" = "(forty-two|42)"; - out = 42; - } - { - "in" = "(forty-three|43)"; - out = 43; - } - { - "in" = "(forty-four|44)"; - out = 44; - } - { - "in" = "(forty-five|45)"; - out = 45; - } - { - "in" = "(forty-six|46)"; - out = 46; - } - { - "in" = "(forty-seven|47)"; - out = 47; - } - { - "in" = "(forty-eight|48)"; - out = 48; - } - { - "in" = "(forty-nine|49)"; - out = 49; - } - { - "in" = "(fifty|50)"; - out = 50; - } - { - "in" = "(fifty-one|51)"; - out = 51; - } - { - "in" = "(fifty-two|52)"; - out = 52; - } - { - "in" = "(fifty-three|53)"; - out = 53; - } - { - "in" = "(fifty-four|54)"; - out = 54; - } - { - "in" = "(fifty-five|55)"; - out = 55; - } - { - "in" = "(fifty-six|56)"; - out = 56; - } - { - "in" = "(fifty-seven|57)"; - out = 57; - } - { - "in" = "(fifty-eight|58)"; - out = 58; - } - { - "in" = "(fifty-nine|59)"; - out = 59; - } - { - "in" = "(sixty|60)"; - out = 60; - } - ]; - }; -} diff --git a/configurations/homie/modules/home-assistant/zigbee.nix b/configurations/homie/modules/home-assistant/zigbee.nix deleted file mode 100644 index 4e3fcac9..00000000 --- a/configurations/homie/modules/home-assistant/zigbee.nix +++ /dev/null @@ -1,55 +0,0 @@ -{lib, ...}: let - inherit (lib) mkForce; -in { - services = { - home-assistant = { - extraComponents = [ - "mqtt" - "smlight" - "zha" - ]; - }; - - mosquitto = { - enable = true; - listeners = [ - { - port = 1883; - - acl = ["pattern readwrite #"]; - omitPasswordAuth = true; - settings.allow_anonymous = true; - } - ]; - }; - - zigbee2mqtt = { - enable = true; - settings = { - serial = { - port = "tcp://192.168.0.129:6638"; - baudrate = 115200; - adapter = "zstack"; - disable_led = false; - }; - - mqtt.server = "mqtt://localhost/1883"; - - availability.enabled = true; - - frontend = { - port = 8080; - host = "100.64.0.10"; - }; - - advanced.transmit_power = 20; - }; - }; - }; - - # Make sure it stays running through SMLIGHT reboots - systemd.services."zigbee2mqtt".serviceConfig = { - Restart = mkForce "always"; - StartLimitIntervalSec = 0; - }; -} diff --git a/configurations/homie/modules/music/default.nix b/configurations/homie/modules/music/default.nix deleted file mode 100644 index 8b5d4a5e..00000000 --- a/configurations/homie/modules/music/default.nix +++ /dev/null @@ -1,122 +0,0 @@ -{ - config, - mainUser, - pkgs, - ... -}: { - hardware.bluetooth = { - enable = true; - powerOnBoot = true; - - settings = { - General = { - AlwaysPairable = true; - PairableTimeout = 0; - DiscoverableTimeout = 0; - Experimental = true; - KernelExperimental = true; - }; - - Policy.AutoEnable = true; - }; - }; - - # Have pulseaudio and spotifyd start at boot but after bluetooth - # so bluetooth accepts sound connections from the start. - users.users.${mainUser}.linger = true; - - systemd.user.services = { - pulseaudio = { - after = ["bluetooth.service"]; - wantedBy = ["default.target"]; - }; - spotifyd = { - after = ["pulseaudio.service"]; - wantedBy = ["default.target"]; - }; - - ueboom = { - path = builtins.attrValues { - inherit (pkgs) bluez; - inherit (config.services.pulseaudio) package; - }; - script = '' - if [[ "$(pactl get-default-sink)" == "auto_null" ]]; then - exec bluetoothctl connect 88:C6:26:93:4B:77 - fi - ''; - serviceConfig = { - Restart = "on-failure"; - RestartSec = 3; - RestartPreventExitStatus = 3; - }; - }; - }; - - systemd.user.timers.ueboom = { - after = ["spotifyd.service"]; - timerConfig = { - Unit = "ueboom.service"; - OnCalendar = "*-*-* *:0/10:50"; # Every 10 minutes - Persistent = true; - }; - wantedBy = ["timers.target"]; - }; - - services = { - # Allow pulseaudio to be managed by MPD - pulseaudio = { - enable = true; - - zeroconf = { - discovery.enable = true; - publish.enable = true; - }; - - extraConfig = '' - load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 - ''; - }; - - upower.enable = true; - - mpd = { - enable = true; - - network = { - listenAddress = "127.0.0.1"; - port = 6600; - }; - - extraConfig = '' - audio_output { - type "pulse" - name "UE Boom 2" - sink "bluez_sink.88_C6_26_93_4B_77.a2dp_sink" - server "127.0.0.1" - } - ''; - }; - }; - - home-manager.users.${mainUser}.services.spotifyd = { - enable = true; - - package = pkgs.spotifyd.override { - withMpris = false; - }; - - settings.global = { - device_name = config.networking.hostName; - device_type = "speaker"; - - zeroconf_port = 33798; - - autoplay = false; - backend = "pulseaudio"; - bitrate = 320; - no_audio_cache = true; - volume_normalisation = false; - }; - }; -} diff --git a/configurations/live-image/default.nix b/configurations/live-image/default.nix deleted file mode 100644 index 0d66695b..00000000 --- a/configurations/live-image/default.nix +++ /dev/null @@ -1,57 +0,0 @@ -{ - mainUser, - nixpkgs, - self, - ... -}: { - # ------------------------------------------------ - # Imports - # ------------------------------------------------ - imports = [ - "${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix" - - self.nixosModules.base - self.nixosModules.meta - self.nixosModules.server - ]; - - # ------------------------------------------------ - # `Self` Modules configuration - # ------------------------------------------------ - meta = { - roleDescription = "Basic configuration that serves as my custom ISO target"; - hardwareDescription = "USB key"; - }; - - roles.base = { - enable = true; - user = mainUser; - }; - - roles.server = { - enable = true; - user = mainUser; - sshd.enable = true; - }; - - services.kmscon.enable = true; - - home-manager.users.${mainUser} = { - imports = [ - self.homeManagerModules.neovim - self.homeManagerModules.shell - ]; - - programs = { - bash = { - enable = true; - promptMainColor = "purple"; - }; - - neovim = { - enable = true; - user = mainUser; - }; - }; - }; -} diff --git a/configurations/nos/default.nix b/configurations/nos/default.nix deleted file mode 100644 index 0946e7c1..00000000 --- a/configurations/nos/default.nix +++ /dev/null @@ -1,90 +0,0 @@ -{ - mainUser, - self, - ... -}: { - # ------------------------------------------------ - # Imports - # ------------------------------------------------ - imports = [ - ./hardware-configuration.nix - - ./modules - - self.nixosModules.base - self.nixosModules.docker - self.nixosModules.kmscon - self.nixosModules.meta - self.nixosModules.server - ]; - - # State Version: DO NOT CHANGE - system.stateVersion = "24.05"; - - # ------------------------------------------------ - # User Settings - # ------------------------------------------------ - users.users.${mainUser} = { - isNormalUser = true; - uid = 1000; - - hashedPassword = "$y$j9T$DSLWphPlpiahIw7KQciF1/$FOjIbplU1Fknv5W.A15Xgdk.WNXP.zeWkJiewSUTGPC"; - - extraGroups = [ - "wheel" - "adm" - "borg" - ]; - }; - - networking = { - hostName = "nos"; - resolvconf.enable = true; - firewall.enable = false; - }; - - time.timeZone = "America/Montreal"; - - # ------------------------------------------------ - # `Self` Modules configuration - # ------------------------------------------------ - meta = { - roleDescription = "Custom built NAS and seedbox for Linux ISOs ;)"; - hardwareDescription = "NVIDIA 3060 with i5-3600"; - }; - - roles.base = { - enable = true; - user = mainUser; - }; - - roles.server = { - enable = true; - user = mainUser; - tailscale.enable = true; - sshd.enable = true; - }; - - roles.docker.enable = true; - - services.kmscon.enable = true; - - home-manager.users.${mainUser} = { - imports = [ - self.homeManagerModules.neovim - self.homeManagerModules.shell - ]; - - programs = { - bash = { - enable = true; - promptMainColor = "orange"; - }; - - neovim = { - enable = true; - user = mainUser; - }; - }; - }; -} diff --git a/configurations/nos/hardware-configuration.nix b/configurations/nos/hardware-configuration.nix deleted file mode 100644 index bb192c7d..00000000 --- a/configurations/nos/hardware-configuration.nix +++ /dev/null @@ -1,71 +0,0 @@ -{ - config, - modulesPath, - self, - ... -}: { - nixpkgs.hostPlatform = "x86_64-linux"; - imports = [ - (modulesPath + "/installer/scan/not-detected.nix") - self.nixosModules.nvidia - ]; - - nvidia = { - enable = true; - enableCUDA = true; - }; - - boot = { - kernelModules = ["kvm-intel"]; - - initrd.availableKernelModules = [ - "xhci_pci" - "ahci" - "nvme" - "usbhid" - "usb_storage" - "sd_mod" - ]; - - loader = { - efi.canTouchEfiVariables = true; - timeout = 2; - - systemd-boot = { - enable = true; - consoleMode = "max"; - configurationLimit = 30; - }; - }; - }; - - fileSystems = { - "/" = { - device = "/dev/disk/by-label/NIXROOT"; - fsType = "btrfs"; - }; - - # sudo btrfs subvolume create /@swap - "/swap" = { - device = "/dev/disk/by-label/NIXROOT"; - fsType = "btrfs"; - options = ["subvol=@swap"]; - }; - - "/boot" = { - device = "/dev/disk/by-label/NIXBOOT"; - fsType = "vfat"; - }; - }; - - swapDevices = [ - { - device = "/swap/swapfile"; - size = 16 * 1024; - } - ]; - - zramSwap.enable = true; - - hardware.cpu.intel.updateMicrocode = config.hardware.enableRedistributableFirmware; -} diff --git a/configurations/nos/modules/comics/default.nix b/configurations/nos/modules/comics/default.nix deleted file mode 100644 index 4b2aa8a0..00000000 --- a/configurations/nos/modules/comics/default.nix +++ /dev/null @@ -1,7 +0,0 @@ -{...}: { - imports = [ - ./jdownloader2 - ./kapowarr - ./komga - ]; -} diff --git a/configurations/nos/modules/comics/jdownloader2/default.nix b/configurations/nos/modules/comics/jdownloader2/default.nix deleted file mode 100644 index 9c2b3c92..00000000 --- a/configurations/nos/modules/comics/jdownloader2/default.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ - config, - mainUser, - pkgs, - ... -}: { - virtualisation.docker.compose."jdownloader2".services."jdownloader2" = { - image = pkgs.callPackage ./images/jdownloader2.nix pkgs; - restart = "always"; - - environment = { - USER_ID = toString config.users.users.${mainUser}.uid; - GROUP_ID = toString config.users.users.${mainUser}.uid; - KEEP_APP_RUNNING = 1; - DARK_MODE = 1; - TZ = "America/New_York"; - }; - - ports = [ - "5800:5800" - ]; - - volumes = [ - "/var/lib/jdownloader2:/config:rw" - "/data/downloads/comics:/output:rw" - ]; - }; -} diff --git a/configurations/nos/modules/comics/jdownloader2/images/jdownloader2.nix b/configurations/nos/modules/comics/jdownloader2/images/jdownloader2.nix deleted file mode 100644 index 019af3d7..00000000 --- a/configurations/nos/modules/comics/jdownloader2/images/jdownloader2.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "docker.io/jlesage/jdownloader-2"; - imageDigest = "sha256:a597e25a5be386cac5519f2fc705eadb786727f9f0f2c7440fb5585efa41973f"; - hash = "sha256-kZRMR1cv5jad+BQkxgvuKIcVod42neszkU9/RPh7BNY="; - finalImageName = imageName; - finalImageTag = "latest"; -} diff --git a/configurations/nos/modules/comics/kapowarr/default.nix b/configurations/nos/modules/comics/kapowarr/default.nix deleted file mode 100644 index 64bff20a..00000000 --- a/configurations/nos/modules/comics/kapowarr/default.nix +++ /dev/null @@ -1,12 +0,0 @@ -{mainUser, ...}: { - imports = [./module.nix]; - - services.kapowarr = { - enable = true; - port = 5676; - urlBase = "/kapowarr"; - - user = mainUser; - group = "users"; - }; -} diff --git a/configurations/nos/modules/comics/kapowarr/module.nix b/configurations/nos/modules/comics/kapowarr/module.nix deleted file mode 100644 index 40eb5b20..00000000 --- a/configurations/nos/modules/comics/kapowarr/module.nix +++ /dev/null @@ -1,115 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit - (lib) - getExe - mkEnableOption - mkIf - mkOption - mkPackageOption - # optionalString - types - ; - - cfg = config.services.kapowarr; -in { - options.services.kapowarr = { - enable = mkEnableOption "kapowarr"; - package = mkPackageOption pkgs.selfPackages "kapowarr" {}; - - user = mkOption { - type = types.str; - default = "kapowarr"; - description = "The user account under which Kapowarr runs."; - }; - - group = mkOption { - type = types.str; - default = "kapowarr"; - description = "The group under which Kapowarr runs."; - }; - - port = mkOption { - type = types.port; - default = 5656; - description = "Port where kapowarr should listen for incoming requests."; - }; - - urlBase = mkOption { - type = with types; nullOr str; - default = null; - description = "URL base where kapowarr should listen for incoming requests."; - }; - - dataDir = mkOption { - type = types.path; - default = "/var/lib/kapowarr/"; - description = "The directory where Kapowarr stores its data files."; - }; - - logDir = mkOption { - type = types.path; - default = cfg.dataDir; - defaultText = "/var/lib/kapowarr"; - description = "The directory where Kapowarr stores its log file."; - }; - - openFirewall = mkEnableOption "Open ports in the firewall for Kapowarr."; - }; - - config = mkIf cfg.enable { - systemd.services.kapowarr = { - description = "Kapowarr"; - after = ["network.target"]; - wantedBy = ["multi-user.target"]; - - serviceConfig = { - Type = "simple"; - User = cfg.user; - Group = cfg.group; - StateDirectory = mkIf (cfg.dataDir == "/var/lib/kapowar") "kapowarr"; - ExecStart = toString [ - (getExe cfg.package) - "-d ${cfg.dataDir}" - "-l ${cfg.logDir}" - # "-p ${toString cfg.port}" - # (optionalString (cfg.urlBase != null) "-u ${cfg.urlBase}") - ]; - - # Hardening from komga service - RemoveIPC = true; - NoNewPrivileges = true; - CapabilityBoundingSet = ""; - SystemCallFilter = ["@system-service"]; - ProtectSystem = "full"; - PrivateTmp = true; - ProtectProc = "invisible"; - ProtectClock = true; - ProcSubset = "pid"; - PrivateUsers = true; - PrivateDevices = true; - ProtectHostname = true; - ProtectKernelTunables = true; - RestrictAddressFamilies = [ - "AF_INET" - "AF_INET6" - "AF_NETLINK" - ]; - LockPersonality = true; - RestrictNamespaces = true; - ProtectKernelLogs = true; - ProtectControlGroups = true; - ProtectKernelModules = true; - SystemCallArchitectures = "native"; - RestrictSUIDSGID = true; - RestrictRealtime = true; - }; - }; - - networking.firewall = mkIf cfg.openFirewall {allowedTCPPorts = [cfg.port];}; - }; -} diff --git a/configurations/nos/modules/comics/komga/default.nix b/configurations/nos/modules/comics/komga/default.nix deleted file mode 100644 index adaea9ea..00000000 --- a/configurations/nos/modules/comics/komga/default.nix +++ /dev/null @@ -1,108 +0,0 @@ -{ - config, - lib, - mainUser, - pkgs, - ... -}: let - inherit (lib) concatStringsSep getExe; - inherit (config.sops) secrets; - - cfg = config.services.komga; -in { - services.komga = { - enable = true; - - user = mainUser; - group = mainUser; - - settings = { - server.port = 7080; - }; - }; - - # use with this https://github.com/Snd-R/komf-userscript - systemd.services.komf = let - stateDir = "/var/lib/komf"; - - komfConf = pkgs.writers.writeJSON "application.yml" { - komga = { - baseUri = "https://komga.nelim.org"; - eventListener = { - enabled = true; - metadataLibraryFilter = []; # listen to all events if empty - metadataSeriesExcludeFilter = []; - notificationsLibraryFilter = []; # Will send notifications if any notification source is enabled. If empty will send notifications for all libraries - }; - metadataUpdate.default = { - libraryType = "COMIC"; - bookCovers = true; - seriesCovers = true; - overrideExistingCovers = true; - overrideComicInfo = true; - postProcessing = { - seriesTitle = true; - orderBooks = true; - }; - }; - }; - database.file = "${stateDir}/database.sqlite"; - metadataProviders.defaultProviders.comicVine = { - priority = 1; - enabled = true; - }; - }; - in { - wantedBy = ["multi-user.target"]; - wants = ["network-online.target"]; - after = ["network-online.target" "komga.service"]; - - preStart = '' - ln -sf ${komfConf} ${stateDir}/application.yml - ''; - - serviceConfig = { - User = cfg.user; - Group = cfg.group; - - EnvironmentFile = secrets.komf.path; - - Type = "simple"; - Restart = "on-failure"; - ExecStart = concatStringsSep " " [ - (getExe pkgs.selfPackages.komf) - stateDir - ]; - - StateDirectory = "komf"; - - # Hardening from komga service - RemoveIPC = true; - NoNewPrivileges = true; - CapabilityBoundingSet = ""; - SystemCallFilter = ["@system-service"]; - ProtectSystem = "full"; - PrivateTmp = true; - ProtectProc = "invisible"; - ProtectClock = true; - ProcSubset = "pid"; - PrivateUsers = true; - PrivateDevices = true; - ProtectHostname = true; - ProtectKernelTunables = true; - RestrictAddressFamilies = [ - "AF_INET" - "AF_INET6" - "AF_NETLINK" - ]; - LockPersonality = true; - RestrictNamespaces = true; - ProtectKernelLogs = true; - ProtectControlGroups = true; - ProtectKernelModules = true; - SystemCallArchitectures = "native"; - RestrictSUIDSGID = true; - RestrictRealtime = true; - }; - }; -} diff --git a/configurations/nos/modules/default.nix b/configurations/nos/modules/default.nix deleted file mode 100644 index 2941fca1..00000000 --- a/configurations/nos/modules/default.nix +++ /dev/null @@ -1,13 +0,0 @@ -{...}: { - imports = [ - ./comics - ./docker - ./homepage - ./jellyfin - ./llm - ./mergerfs - ./qbittorrent - ./snapraid - ./subtitles - ]; -} diff --git a/configurations/nos/modules/docker/default.nix b/configurations/nos/modules/docker/default.nix deleted file mode 100644 index 7eb6b50c..00000000 --- a/configurations/nos/modules/docker/default.nix +++ /dev/null @@ -1,40 +0,0 @@ -{ - config, - mainUser, - ... -}: let - globalEnv = { - configPath = "/var/lib/docker-data"; - mainUID = toString config.users.users.${mainUser}.uid; - mainGID = toString config.users.users.${mainUser}.uid; - TZ = "America/New_York"; - }; -in { - imports = [ - (import ./forgejo/compose.nix globalEnv) - (import ./freshrss/compose.nix globalEnv) - (import ./gameyfin/compose.nix globalEnv) - (import ./hauk/compose.nix globalEnv) - (import ./immich/compose.nix globalEnv) - (import ./music/jbots/compose.nix globalEnv) - (import ./nextcloud/compose.nix globalEnv) - (import ./resume/compose.nix globalEnv) - (import ./vaultwarden/compose.nix globalEnv) - (import ./wg-easy/compose.nix globalEnv) - - (import ./media/bazarr/compose.nix globalEnv) - (import ./media/joal/compose.nix globalEnv) - - # Crashes jellyfin - # (import ./media/jellystat/compose.nix globalEnv) - - (import ./media/prowlarr/compose.nix globalEnv) - (import ./media/radarr/compose.nix globalEnv) - (import ./media/seerr/compose.nix globalEnv) - (import ./media/sonarr/compose.nix globalEnv) - ]; - - services.borgbackup.configs.docker = { - paths = [globalEnv.configPath]; - }; -} diff --git a/configurations/nos/modules/docker/forgejo/compose.nix b/configurations/nos/modules/docker/forgejo/compose.nix deleted file mode 100644 index e23f8485..00000000 --- a/configurations/nos/modules/docker/forgejo/compose.nix +++ /dev/null @@ -1,88 +0,0 @@ -{ - configPath, - mainUID, - mainGID, - ... -}: { - config, - pkgs, - ... -}: let - inherit (config.sops) secrets; - - rwPath = configPath + "/forgejo"; -in { - virtualisation.docker.compose."forgejo" = { - networks.proxy_net = {external = true;}; - - services = { - "forgejo" = { - image = pkgs.callPackage ./images/forgejo.nix pkgs; - - ports = [ - # Redirect WAN port 22 to this port - "2222:22" - "3000:3000" - ]; - - networks = ["proxy_net"]; - - restart = "always"; - depends_on = ["forgejo-db"]; - - env_file = [secrets.forgejo.path]; - environment = { - APP_NAME = "Gitea"; - - USER_UID = mainUID; - USER_GID = mainGID; - - ROOT_URL = "https://git.nelim.org"; - SSH_DOMAIN = "git.nelim.org"; - SSH_PORT = "22"; - HTTP_PORT = "3000"; - }; - - volumes = [ - "${rwPath}/data:/data" - "/etc/timezone:/etc/timezone:ro" - "/etc/localtime:/etc/localtime:ro" - ]; - }; - - "forgejo-db" = { - image = pkgs.callPackage ./images/postgres.nix pkgs; - - restart = "always"; - - env_file = [secrets.forgejo-db.path]; - networks = ["proxy_net"]; - - volumes = ["${rwPath}/db:/var/lib/postgresql/data"]; - }; - - "act_runner" = { - image = pkgs.callPackage ./images/act_runner.nix pkgs; - - privileged = true; - user = "root:root"; - networks = ["proxy_net"]; - - restart = "always"; - depends_on = ["forgejo"]; - - env_file = [secrets.forgejo-runner.path]; - environment = { - GITEA_INSTANCE_URL = "https://git.nelim.org"; - GITEA_RUNNER_NAME = "DinD"; - }; - - volumes = ["${rwPath}/act:/data"]; - extra_hosts = ["git.nelim.org:10.0.0.130"]; - }; - }; - }; - - # For accurate stack trace - _file = ./compose.nix; -} diff --git a/configurations/nos/modules/docker/forgejo/images/act_runner.nix b/configurations/nos/modules/docker/forgejo/images/act_runner.nix deleted file mode 100644 index a5f68a1e..00000000 --- a/configurations/nos/modules/docker/forgejo/images/act_runner.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "vegardit/gitea-act-runner"; - imageDigest = "sha256:02ab7bbb1423d790d7fdf39b62851b4422243858e282738744930270bf2e2a99"; - hash = "sha256-kix0y5xsijlXGkK57gLQlvDjRR9s8a46HV3yVJ+yfAg="; - finalImageName = imageName; - finalImageTag = "dind-latest"; -} diff --git a/configurations/nos/modules/docker/forgejo/images/forgejo.nix b/configurations/nos/modules/docker/forgejo/images/forgejo.nix deleted file mode 100644 index ec6aac14..00000000 --- a/configurations/nos/modules/docker/forgejo/images/forgejo.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "codeberg.org/forgejo/forgejo"; - imageDigest = "sha256:e7663b58cc0a1610f31b315150e4fa8a00f6936d98abd6e26ef247f009cc7f52"; - hash = "sha256-wqXqOYhXkY4F4aQ2I6o1c6FZ/VyarJaur/rELD9v3iA="; - finalImageName = imageName; - finalImageTag = "11"; -} diff --git a/configurations/nos/modules/docker/forgejo/images/postgres.nix b/configurations/nos/modules/docker/forgejo/images/postgres.nix deleted file mode 100644 index 540d2a27..00000000 --- a/configurations/nos/modules/docker/forgejo/images/postgres.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "postgres"; - imageDigest = "sha256:1e6c52c366e39e869184256c45757e1c85ba15b3d244b0a2cea640da6df1c4e3"; - hash = "sha256-w31u8URnr3jhPCHDQufnzn8AMPIx9zQ8ICMApHep6lA="; - finalImageName = imageName; - finalImageTag = "14"; -} diff --git a/configurations/nos/modules/docker/freshrss/compose.nix b/configurations/nos/modules/docker/freshrss/compose.nix deleted file mode 100644 index fa8e9975..00000000 --- a/configurations/nos/modules/docker/freshrss/compose.nix +++ /dev/null @@ -1,84 +0,0 @@ -{configPath, ...}: { - config, - pkgs, - ... -}: let - inherit (config.sops) secrets; - - rwPath = configPath + "/freshrss"; -in { - virtualisation.docker.compose."freshrss" = { - networks.proxy_net = {external = true;}; - - services = { - "freshrss" = { - image = pkgs.callPackage ./images/freshrss.nix pkgs; - restart = "always"; - - ports = ["2800:80"]; - networks = ["proxy_net"]; - - volumes = let - rss-bridge = pkgs.stdenv.mkDerivation { - name = "rss-bridge-ext"; - version = "unstable"; - src = pkgs.fetchFromGitHub { - owner = "DevonHess"; - repo = "FreshRSS-Extensions"; - rev = "299c1febc279be77fa217ff5c2965a620903b974"; - hash = "sha256-++kgbrGJohKeOeLjcy7YV3QdCf9GyZDtbntlFmmIC5k="; - }; - installPhase = '' - mkdir $out - cp -ar ./xExtension-RssBridge $out/ - ''; - }; - in [ - "${rwPath}/data:/var/www/FreshRSS/data" - "${rss-bridge}/xExtension-RssBridge:/var/www/FreshRSS/extensions/xExtension-RssBridge:ro" - ]; - - env_file = [secrets.freshrss.path]; - - environment = { - TZ = "America/New_York"; - CRON_MIN = "3,33"; - }; - }; - - "freshrss-db" = { - image = pkgs.callPackage ./images/postgres.nix pkgs; - restart = "always"; - - volumes = [ - "${rwPath}/db:/var/lib/postgresql/data" - ]; - - networks = ["proxy_net"]; - - env_file = [secrets.freshrss.path]; - - environment = { - POSTGRES_DB = "\${DB_BASE:-freshrss}"; - POSTGRES_USER = "\${DB_USER:-freshrss}"; - POSTGRES_PASSWORD = "\${DB_PASSWORD:-freshrss}"; - }; - }; - - "bridge.nelim.org" = { - image = pkgs.callPackage ./images/rss-bridge.nix pkgs; - restart = "always"; - - volumes = [ - "${rwPath}/bridge:/config" - ]; - ports = ["3006:80"]; - - networks = ["proxy_net"]; - }; - }; - }; - - # For accurate stack trace - _file = ./compose.nix; -} diff --git a/configurations/nos/modules/docker/freshrss/images/freshrss.nix b/configurations/nos/modules/docker/freshrss/images/freshrss.nix deleted file mode 100644 index ab9f9042..00000000 --- a/configurations/nos/modules/docker/freshrss/images/freshrss.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "freshrss/freshrss"; - imageDigest = "sha256:bca4407f1f3ecb2e02bd57f704593c64f89bbf3fad53f03ebcf4baecb0122de6"; - hash = "sha256-aZQT5bBjfrAH93z3YV/203LrAdrItI0hPI+/dmvvOZU="; - finalImageName = imageName; - finalImageTag = "latest"; -} diff --git a/configurations/nos/modules/docker/freshrss/images/postgres.nix b/configurations/nos/modules/docker/freshrss/images/postgres.nix deleted file mode 100644 index 540d2a27..00000000 --- a/configurations/nos/modules/docker/freshrss/images/postgres.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "postgres"; - imageDigest = "sha256:1e6c52c366e39e869184256c45757e1c85ba15b3d244b0a2cea640da6df1c4e3"; - hash = "sha256-w31u8URnr3jhPCHDQufnzn8AMPIx9zQ8ICMApHep6lA="; - finalImageName = imageName; - finalImageTag = "14"; -} diff --git a/configurations/nos/modules/docker/freshrss/images/rss-bridge.nix b/configurations/nos/modules/docker/freshrss/images/rss-bridge.nix deleted file mode 100644 index 5f187b7a..00000000 --- a/configurations/nos/modules/docker/freshrss/images/rss-bridge.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "rssbridge/rss-bridge"; - imageDigest = "sha256:8e031d8dfa73601ff60696a4952b6c30a00018a1a4bc32f5b2a8bad109e09857"; - hash = "sha256-PzY9zwTLe+ga9JsZNI1knKylYw+sk89eDruSDBrqyfk="; - finalImageName = imageName; - finalImageTag = "latest"; -} diff --git a/configurations/nos/modules/docker/gameyfin/compose.nix b/configurations/nos/modules/docker/gameyfin/compose.nix deleted file mode 100644 index ecd2962b..00000000 --- a/configurations/nos/modules/docker/gameyfin/compose.nix +++ /dev/null @@ -1,35 +0,0 @@ -{ - mainUID, - mainGID, - ... -}: { - config, - pkgs, - ... -}: let - inherit (config.sops) secrets; -in { - virtualisation.docker.compose."gameyfin" = { - networks.proxy_net = {external = true;}; - - services."gameyfin" = { - image = pkgs.callPackage ./images/gameyfin.nix pkgs; - restart = "always"; - user = "${mainUID}:${mainGID}"; - - env_file = [secrets.gameyfin.path]; - environment.GAMEYFIN_USER = "mathis"; - - volumes = [ - "/data/games:/opt/gameyfin-library" - ]; - - expose = ["8080"]; - ports = ["8074:8080"]; - networks = ["proxy_net"]; - }; - }; - - # For accurate stack trace - _file = ./compose.nix; -} diff --git a/configurations/nos/modules/docker/gameyfin/images/gameyfin.nix b/configurations/nos/modules/docker/gameyfin/images/gameyfin.nix deleted file mode 100644 index 1b468fd9..00000000 --- a/configurations/nos/modules/docker/gameyfin/images/gameyfin.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "grimsi/gameyfin"; - imageDigest = "sha256:f7994b4d4da378d909c173115d71cfeb704980184e42db432bd309d51d92725e"; - sha256 = "07a10aw1x2qbfpcva30l0b33lhxshrsacxr1ia0lbbsch655iymq"; - finalImageName = imageName; - finalImageTag = "latest"; -} diff --git a/configurations/nos/modules/docker/hauk/compose.nix b/configurations/nos/modules/docker/hauk/compose.nix deleted file mode 100644 index 4cee8f29..00000000 --- a/configurations/nos/modules/docker/hauk/compose.nix +++ /dev/null @@ -1,17 +0,0 @@ -{...}: {pkgs, ...}: { - virtualisation.docker.compose."hauk" = { - networks.proxy_net = {external = true;}; - - services."hauk" = { - image = pkgs.callPackage ./images/hauk.nix pkgs; - restart = "always"; - ports = ["3003:80"]; - networks = ["proxy_net"]; - - volumes = ["${./config.php}:/etc/hauk/config.php:ro"]; - }; - }; - - # For accurate stack trace - _file = ./compose.nix; -} diff --git a/configurations/nos/modules/docker/hauk/config.php b/configurations/nos/modules/docker/hauk/config.php deleted file mode 100644 index 9bb98b14..00000000 --- a/configurations/nos/modules/docker/hauk/config.php +++ /dev/null @@ -1,280 +0,0 @@ -<?php const CONFIG = array( - -// The type of storage backend Hauk will use. Valid values include: -// MEMCACHED, REDIS -// -// For MEMCACHED, you need either the `memcached` or `memcache` extensions -// enabled in PHP. -// -// For REDIS, you need `redis` extension enabled. Note that `redis` depends on -// `igbinary`, so if you get an error that a redis extension was not found, even -// though you enabled `redis`, you may have to also install and enable -// `igbinary` in PHP. -"storage_backend" => MEMCACHED, - -/*----------------------------------------------------------------------------*\ -| MEMCACHED SPECIFIC SETTINGS | -\*----------------------------------------------------------------------------*/ - -// Connection to memcached for data storage. To connect via UNIX socket instead -// of TCP, set host to 'unix:///path/to/memcached.sock' and port to 0. -"memcached_host" => 'localhost', -"memcached_port" => 11211, - -// If you use SASL authentication, change both `memcached_binary` and -// `memcached_use_sasl` to true, and enter your SASL username and password. -// Note: SASL authentication is only supported in the PHP `memcached` extension! -// If you are using `memcache` and need SASL, consider switching to `memcached`. -"memcached_binary" => false, -"memcached_use_sasl" => false, -"memcached_sasl_user" => "", -"memcached_sasl_pass" => "", - -// A prefix to use for all variables sent to memcached. Useful if you have a -// shared memcached instance or run multiple instances of Hauk. -"memcached_prefix" => 'hauk', - -/*----------------------------------------------------------------------------*\ -| REDIS SPECIFIC SETTINGS | -\*----------------------------------------------------------------------------*/ - -// Connection to Redis for data storage. To connect via UNIX socket instead of -// TCP, set host to '/path/to/redis.sock'. -"redis_host" => 'localhost', -"redis_port" => 6379, - -// If you use password authentication in Redis, set `redis_use_auth` to true and -// enter the password in `redis_auth`. -"redis_use_auth" => false, -"redis_auth" => '', - -// A prefix to use for all variables sent to Redis. Useful if you have a shared -// Redis instance or run multiple instances of Hauk. -"redis_prefix" => 'hauk', - -/*----------------------------------------------------------------------------*\ -| AUTHENTICATION | -\*----------------------------------------------------------------------------*/ - -// Users must be authenticated to use the Hauk server. The default -// authentication method is using a static server password that is shared by all -// users, without the need for a username. You can, however, use other -// authentication methods. Valid values here include: -// -// - PASSWORD: Use a static, shared server password for everyone -// - HTPASSWD: Require a username and separate password for each user -// - LDAP: Authenticate users against an LDAP server -"auth_method" => PASSWORD, - -/*----------------------------------------------------------------------------*\ -| PASSWORD AUTHENTICATION | -\*----------------------------------------------------------------------------*/ - -// A hashed password that is required for creating sessions and posting location -// data to Hauk. To generate this value on the terminal: -// - MD5 (insecure!): openssl passwd -1 -// - bcrypt (secure): htpasswd -nBC 10 "" | tail -c +2 -"password_hash" => '$2y$10$4ZP1iY8A3dZygXoPgsXYV.S3gHzBbiT9nSfONjhWrvMxVPkcFq1Ka', -// Default value above is empty string (no password) and is VERY INSECURE. -// Trust me, you really should change this unless you intentionally want a -// public instance that anyone in the world can use freely. -// -// Also note that users have the option to save the server password locally on -// their devices using a "Remember password" checkbox. If they choose to do so, -// the password will be stored in plain text (unhashed) on their devices. You -// are encouraged to generate a random password to prevent risks associated with -// credential reuse, should the password somehow be leaked from their devices. - -/*----------------------------------------------------------------------------*\ -| HTPASSWD AUTHENTICATION | -\*----------------------------------------------------------------------------*/ - -// A file that contains a pairing between users and hashed passwords. To -// generate this file on the terminal: -// - htpasswd -cBC 10 /etc/hauk/users.htpasswd <username> -// To add additional users to an existing file: -// - htpasswd -BC 10 /etc/hauk/users.htpasswd <username> -"htpasswd_path" => '/etc/hauk/users.htpasswd', - -/*----------------------------------------------------------------------------*\ -| LDAP AUTHENTICATION | -\*----------------------------------------------------------------------------*/ - -// URI that points to the LDAP server. Use "ldap://" for unencrypted LDAP as -// well as when using StartTLS, use "ldaps://" for regular LDAP over TLS. Port -// number is typically 389 (ldap) or 636 (ldaps). -"ldap_uri" => 'ldaps://ldap.example.com:636', - -// Whether or not you wish to use StartTLS. StartTLS cannot be used in -// combination with `ldaps`. -"ldap_start_tls" => false, - -// Base DN to search for users. -"ldap_base_dn" => 'ou=People,dc=example,dc=com', - -// DN to bind to to perform user search. This should ideally be a read-only -// account as the password is stored in plain-text in this config file. -"ldap_bind_dn" => 'cn=admin,dc=example,dc=com', -"ldap_bind_pass" => 'Adm1nP4ssw0rd', - -// A filter that finds the user trying to authenticate. %s is substituted with -// the username provided by the user in the app. -// -// You can also use this to restrict access to Hauk to only authorized users if -// you do not wish to grant all LDAP users permission to use your Hauk instance. -// For example, (&(uid=%s)(memberOf=cn=HaukUsers,ou=Groups,dc=example,dc=com)) -// will only let the user connect if they are part of the "HaukUsers" group in -// the "Groups" OU. -"ldap_user_filter" => '(uid=%s)', - -/*----------------------------------------------------------------------------*\ -| GENERAL SETTINGS | -\*----------------------------------------------------------------------------*/ - -// Hauk v1.4 and on allows you to request a custom link ID instead of having the -// server randomly generate one. Custom links can use characters A-Z, a-z, 0-9, -// - (dash), and _ (underscore). If you want to disallow the option to request -// custom links, set this to false. -// -// If a user requests particular custom link that is already in use, that user -// will not have their request honored and will get a randomly generated link -// instead. -"allow_link_req" => true, - -// If you want certain links to only be usable by some users, you can reserve -// them here. The following example reserves https://example.com/?WheresAlice -// for user "alice" only, and reserves https://example.com/?TheRealBob -// for use by both "bob" and "charlie". -// -// If you use Tasker or another automation platform to automatically start -// sharing to a specific link ID, it's a good idea to specify it here so that -// others cannot use it while you are inactive. -// -// Note that for this setting to have any effect, you have to specify an -// auth_method that requires both a username and a password, such as HTPASSWD. -"reserved_links" => [ - 'WheresAlice' => ['alice'], - 'TheRealBob' => ['bob', 'charlie'], -], - -// If you want to enable pre-approved custom links only, you can choose to -// enable reservation whitelist mode. If this setting is set to true, custom -// link IDs will only be accepted if they are present in the reserved_links -// array above - requests to share to other links than those in the array will -// not be honored. -"reserve_whitelist" => false, - -// The type of links to generate when making new links for shares. Can be any -// of the following: -// -// | Link style | Example | No. of combinations | Avg. bruteforce time | -// +----------------------------+---------------------------------------+-----------------------+-------------------------------+ -// | LINK_4_PLUS_4_UPPER_CASE | V8LQ-H2UM | 1.79 * 10^12 (34^8) | 28.3 years | -// | LINK_4_PLUS_4_LOWER_CASE | qae3-ulna | 2.82 * 10^12 (36^8) | 44.7 years | -// | LINK_4_PLUS_4_MIXED_CASE | HEq3-tgJ1 | 1.28 * 10^14 (58^8) | 2030 years | -// | LINK_UUID_V4 | 09c8a3b1-e78f-48b1-a604-0da49e99cb5d | 5.32 * 10^36 (2^122) | 84.2 septillion years | -// | LINK_16_HEX | 6cde14c4c6551b41 | 1.84 * 10^19 (2^64) | 292 million years | -// | LINK_16_UPPER_CASE | WVHA2FNMRT9HSKJK | 3.19 * 10^24 (34^16) | 50.6 trillion years | -// | LINK_16_LOWER_CASE | bdyslxszs14cj359 | 7.95 * 10^24 (36^16) | 126 trillion years | -// | LINK_16_MIXED_CASE | 1Ayh2yUXDe3sdF3S | 1.64 * 10^28 (58^16) | 260 quadrillion years | -// | LINK_32_HEX | 22adf21f11491ae8f3ae128e23a6782f | 3.40 * 10^38 (2^128) | 5.39 octillion years | -// | LINK_32_UPPER_CASE | R88M1Z2KPL27XN8MF73KCRYPHJD4QQMT | 1.02 * 10^49 (34^32) | 161 undecillion years | -// | LINK_32_LOWER_CASE | itgbolrbq1c02eot5o46c5wixhdrdb5m | 6.33 * 10^49 (36^32) | 1 duodecillion years | -// | LINK_32_MIXED_CASE | qf5pqr2UKTUT6vREPPSTuqSKkCMojF17 | 2.69 * 10^56 (58^32) | 4.26 quattuordecillion years | -// -// For any MIXED_CASE variants, upper-case I and lower-case L will not appear -// because they are visually very similar and are easily confused. For the same -// reason, MIXED_CASE and UPPER_CASE variants will not generate 0 and O. -// -// The default value is LINK_4_PLUS_4_UPPER_CASE, which is still considered very -// secure. The bruteforce times in the table below are the average time it would -// take to find a valid sharing link, when there is one link active, at 1000 -// guesses per second. For the default setting, this means it would take almost -// 45 years to find the link. -// -// This is assuming that the link is active 24/7 for that entire time. If you -// only have a link active 2% of the time, it would take over 2200 years. -// -// At 1000 guesses per second, you will likely notice that your server is -// noticeably slower and rapidly filling up with access logs. -// -// Very long links are also time-consuming to type, should you find yourself -// in need of typing in a link manually on another computer. This is the reason -// that short links are default. -// -// ---- PLEASE NOTE ---- -// This option is provided to you only because several people have requested it -// as a convenience. You are free to change it, but you should know that -// changing the default here gives you, for all intents and purposes, no -// security advantage in practice. -// -"link_style" => LINK_4_PLUS_4_UPPER_CASE, - -// Leaflet tile URI template for the map frontend. Here are some examples: -// -// - OpenStreetMap directly: -// https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png -// - Mapbox: -// https://api.tiles.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png?access_token=YOUR_ACCESS_TOKEN -// - Thunderforest: -// https://{s}.tile.thunderforest.com/neighbourhood/{z}/{x}/{y}.png?apikey=YOUR_API_KEY -// - Esri: -// https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x} -// - OpenMapSurfer: -// https://maps.heigit.org/openmapsurfer/tiles/roads/webmercator/{z}/{x}/{y}.png -// - Hydda (OSM Sweden): -// https://{s}.tile.openstreetmap.se/hydda/full/{z}/{x}/{y}.png -// -// Make sure you have permission to use the source you choose, and also use a -// proper attribution for that provider. -"map_tile_uri" => 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', - -// Attribution HTML code to be displayed in the bottom right corner of the map. -// The default value is suitable for OpenStreetMap tiles. -"map_attribution" => 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>', - -// Default and maximum zoom levels allowed on the map (0-20), higher value means -// closer zooming. -"default_zoom" => 14, -"max_zoom" => 19, - -// Maximum duration of a single location share, in seconds. -"max_duration" => 604800, - -// Minimum time between each location update, in seconds. -"min_interval" => 1, - -// The time that should pass without any location updates received, in seconds, -// before the user is marked "offline" on the map. -"offline_timeout" => 30, - -// The timeout in seconds for map update requests from the map view. If a web -// request takes this long without a response, the map viewer is considered -// offline and will get a warning notifying them that they have lost their -// network connection. -"request_timeout" => 10, - -// Maximum number of data points stored for each share before old points are -// deleted. Map clients will see up to this amount of data points when they load -// the page. -"max_cached_pts" => 3, - -// Maximum number of data points that may be visible on the map at any time. -// This is used to draw trails behind the current location map marker. Higher -// values will show longer trails, but may reduce performance. -"max_shown_pts" => 100, - -// Number of seconds of data that should be used to calculate velocity. -"v_data_points" => 2, - -// The color of the marker trails. HTML color name or #rrggbb hex color code. -"trail_color" => '#d80037', - -// The unit of measurement of velocity. Valid are: -// KILOMETERS_PER_HOUR, MILES_PER_HOUR, METERS_PER_SECOND -"velocity_unit" => KILOMETERS_PER_HOUR, - -// The publicly accessible URL to reach Hauk, with trailing slash. -"public_url" => 'https://hauk.nelim.org/' - -); diff --git a/configurations/nos/modules/docker/hauk/images/hauk.nix b/configurations/nos/modules/docker/hauk/images/hauk.nix deleted file mode 100644 index fb95ab96..00000000 --- a/configurations/nos/modules/docker/hauk/images/hauk.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "bilde2910/hauk"; - imageDigest = "sha256:c7614b8340c25d91f32bfd00ebb92f81c05a4506410849e83d9102ba6304400e"; - sha256 = "0dx7g8hrm4gz5bwd2v12l0hvyvbwrf9yiyqsn1pvw62ii8j721zp"; - finalImageName = imageName; - finalImageTag = "latest"; -} diff --git a/configurations/nos/modules/docker/immich/.gitignore b/configurations/nos/modules/docker/immich/.gitignore deleted file mode 100644 index 70314f03..00000000 --- a/configurations/nos/modules/docker/immich/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# upload script with secrets -upload.sh diff --git a/configurations/nos/modules/docker/immich/compose.nix b/configurations/nos/modules/docker/immich/compose.nix deleted file mode 100644 index ea6f6df7..00000000 --- a/configurations/nos/modules/docker/immich/compose.nix +++ /dev/null @@ -1,128 +0,0 @@ -{configPath, ...}: { - config, - lib, - pkgs, - ... -}: let - inherit (lib) attrValues; - - inherit (config.sops) secrets; - - rwPath = configPath + "/immich"; - - envFile = "${./env}"; - UPLOAD_LOCATION = "${rwPath}/data"; - synologyPath = "/var/lib/synology-immich"; -in { - # NFS client setup - services.rpcbind.enable = true; - boot.supportedFilesystems = ["nfs"]; - - environment.systemPackages = attrValues { - inherit - (pkgs) - nfs-utils - immich-go # for uploading google photos - ; - }; - - systemd.mounts = let - host = "10.0.0.117"; - in [ - { - type = "nfs"; - mountConfig = { - Options = "noatime"; - }; - what = "${host}:/volume1/Photo-Immich"; - where = synologyPath; - wantedBy = ["multi-user.target"]; - } - ]; - - # Docker compose - virtualisation.docker.compose."immich" = { - networks.proxy_net = {external = true;}; - - services = { - "immich_server" = { - image = pkgs.callPackage ./images/server.nix pkgs; - - restart = "always"; - - env_file = [ - envFile - secrets.immich.path - ]; - - volumes = [ - # "${synologyPath}:/usr/src/app/upload:rw" - "${UPLOAD_LOCATION}:/usr/src/app/upload:rw" - "${synologyPath}:${synologyPath}:rw" - ]; - ports = [ - "2283:2283" - ]; - networks = ["proxy_net"]; - - depends_on = ["immich_redis" "immich_postgres"]; - - environment.NODE_ENV = "production"; - }; - - "immich_machine_learning" = { - image = pkgs.callPackage ./images/machine-learning.nix pkgs; - - restart = "always"; - - env_file = [ - envFile - secrets.immich.path - ]; - networks = ["proxy_net"]; - - volumes = [ - "${rwPath}/cache:/cache" - ]; - }; - - "immich_redis" = { - image = pkgs.callPackage ./images/redis.nix pkgs; - - restart = "always"; - - env_file = [ - envFile - secrets.immich.path - ]; - networks = ["proxy_net"]; - tmpfs = ["/data"]; - }; - - "immich_postgres" = { - image = pkgs.callPackage ./images/postgres.nix pkgs; - - restart = "always"; - - env_file = [ - envFile - secrets.immich.path - ]; - networks = ["proxy_net"]; - - volumes = [ - "${rwPath}/db:/var/lib/postgresql/data" - ]; - - environment = { - POSTGRES_PASSWORD = "\${DB_PASSWORD}"; - POSTGRES_USER = "\${DB_USERNAME}"; - POSTGRES_DB = "\${DB_DATABASE_NAME}"; - }; - }; - }; - }; - - # For accurate stack trace - _file = ./compose.nix; -} diff --git a/configurations/nos/modules/docker/immich/env b/configurations/nos/modules/docker/immich/env deleted file mode 100644 index cbf88f08..00000000 --- a/configurations/nos/modules/docker/immich/env +++ /dev/null @@ -1,5 +0,0 @@ -PUBLIC_LOGIN_PAGE_MESSAGE= - -IMMICH_WEB_URL=http://immich_web:3000 -IMMICH_SERVER_URL=http://immich_server:3001 -IMMICH_MACHINE_LEARNING_URL=http://immich_machine_learning:3003 diff --git a/configurations/nos/modules/docker/immich/images/machine-learning.nix b/configurations/nos/modules/docker/immich/images/machine-learning.nix deleted file mode 100644 index c9f97079..00000000 --- a/configurations/nos/modules/docker/immich/images/machine-learning.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "ghcr.io/immich-app/immich-machine-learning"; - imageDigest = "sha256:d6f07b454c0ec7e4ba3a5926fff2482f8fd1a9922b489122dec33b11a4f37bdd"; - hash = "sha256-4XMrJQzlWsvnMSyDdZsHUa8I4QPHgYaTmo0OKix3ETw="; - finalImageName = imageName; - finalImageTag = "release"; -} diff --git a/configurations/nos/modules/docker/immich/images/postgres.nix b/configurations/nos/modules/docker/immich/images/postgres.nix deleted file mode 100644 index 25596911..00000000 --- a/configurations/nos/modules/docker/immich/images/postgres.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "tensorchord/pgvecto-rs"; - imageDigest = "sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52"; - hash = "sha256-OOY889BAihJ7pIJ0wPvWoaCrKzalTJXdYnXRYtVkCpc="; - finalImageName = imageName; - finalImageTag = "pg14-v0.2.0"; -} diff --git a/configurations/nos/modules/docker/immich/images/redis.nix b/configurations/nos/modules/docker/immich/images/redis.nix deleted file mode 100644 index 1c0181bb..00000000 --- a/configurations/nos/modules/docker/immich/images/redis.nix +++ /dev/null @@ -1,9 +0,0 @@ -# Locked -pkgs: -pkgs.dockerTools.pullImage { - imageName = "redis"; - imageDigest = "sha256:70a7a5b641117670beae0d80658430853896b5ef269ccf00d1827427e3263fa3"; - sha256 = "1d14llwfzjfpzyz7x1a46fzrrg3i6k7z89jqql3sfisb7i4kgp2j"; - finalImageName = "redis"; - finalImageTag = "6.2-alpine"; -} diff --git a/configurations/nos/modules/docker/immich/images/server.nix b/configurations/nos/modules/docker/immich/images/server.nix deleted file mode 100644 index 8bc19c26..00000000 --- a/configurations/nos/modules/docker/immich/images/server.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "ghcr.io/immich-app/immich-server"; - imageDigest = "sha256:7e5b6729b12b5e5cc5d98bcc6f7c27f723fabae4ee77696855808ebd5200bbf8"; - hash = "sha256-4+AK8upcMkTYmTxrp19qfO0yXNHaRs67UnGz9r5v7xY="; - finalImageName = imageName; - finalImageTag = "release"; -} diff --git a/configurations/nos/modules/docker/media/bazarr/compose.nix b/configurations/nos/modules/docker/media/bazarr/compose.nix deleted file mode 100644 index da99b177..00000000 --- a/configurations/nos/modules/docker/media/bazarr/compose.nix +++ /dev/null @@ -1,39 +0,0 @@ -{ - configPath, - mainUID, - mainGID, - TZ, - ... -}: {pkgs, ...}: let - rwPath = configPath + "/media/bazarr"; -in { - virtualisation.docker.compose."bazarr" = { - networks.proxy_net = {external = true;}; - - services."bazarr" = { - image = pkgs.callPackage ./images/bazarr.nix pkgs; - restart = "always"; - - environment = { - PUID = mainUID; - PGID = mainGID; - inherit TZ; - }; - - ports = [ - "6767:6767" - ]; - - volumes = [ - "${rwPath}/data:/config" - "/data:/data" - ]; - - cpus = 0.5; - networks = ["proxy_net"]; - }; - }; - - # For accurate stack trace - _file = ./compose.nix; -} diff --git a/configurations/nos/modules/docker/media/bazarr/images/bazarr.nix b/configurations/nos/modules/docker/media/bazarr/images/bazarr.nix deleted file mode 100644 index 82727f3e..00000000 --- a/configurations/nos/modules/docker/media/bazarr/images/bazarr.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "ghcr.io/linuxserver/bazarr"; - imageDigest = "sha256:b98bdcac54db7ed05524fb63447b855d7fc419428222b3827b1cc9655f95bf51"; - hash = "sha256-NefisUb38Lia+InLyOktZO8anr9PL+yNAgGaz1Vr+ok="; - finalImageName = imageName; - finalImageTag = "latest"; -} diff --git a/configurations/nos/modules/docker/media/jellystat/compose.nix b/configurations/nos/modules/docker/media/jellystat/compose.nix deleted file mode 100644 index 2f937784..00000000 --- a/configurations/nos/modules/docker/media/jellystat/compose.nix +++ /dev/null @@ -1,53 +0,0 @@ -{ - configPath, - TZ, - ... -}: { - config, - pkgs, - ... -}: let - inherit (config.sops) secrets; - - rwPath = configPath + "/jellystat"; -in { - virtualisation.docker.compose."jellystat" = { - networks.proxy_net = {external = true;}; - - services = { - "jellystat" = { - image = pkgs.callPackage ./images/jellystat.nix pkgs; - restart = "always"; - - env_file = [secrets.jellystat.path]; - environment = { - JS_BASE_URL = "jellystat"; - - POSTGRES_IP = "jellystat-db"; - POSTGRES_PORT = 5432; - inherit TZ; - }; - - ports = ["3070:3000"]; - networks = ["proxy_net"]; - - volumes = ["${rwPath}/data:/app/backend/backup-data"]; - - depends_on = ["jellystat-db"]; - }; - - "jellystat-db" = { - image = pkgs.callPackage ./images/postgres.nix pkgs; - restart = "always"; - - env_file = [secrets.jellystat.path]; - networks = ["proxy_net"]; - - volumes = ["${rwPath}/db:/var/lib/postgresql/data"]; - }; - }; - }; - - # For accurate stack trace - _file = ./compose.nix; -} diff --git a/configurations/nos/modules/docker/media/jellystat/images/jellystat.nix b/configurations/nos/modules/docker/media/jellystat/images/jellystat.nix deleted file mode 100644 index 813b8d5b..00000000 --- a/configurations/nos/modules/docker/media/jellystat/images/jellystat.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "cyfershepard/jellystat"; - imageDigest = "sha256:3cb35f261ae2581e90c64e00a5a310247cd886832e7ccd71f79a6205963de44e"; - hash = "sha256-Tah5gZEgIiLHrr0gEqHT67uj9sCFss/QnZcHWpyMdTQ="; - finalImageName = imageName; - finalImageTag = "latest"; -} diff --git a/configurations/nos/modules/docker/media/jellystat/images/postgres.nix b/configurations/nos/modules/docker/media/jellystat/images/postgres.nix deleted file mode 100644 index 08621794..00000000 --- a/configurations/nos/modules/docker/media/jellystat/images/postgres.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "postgres"; - imageDigest = "sha256:78a275d4c891f7b3a33d3f1a78eda9f1d744954d9e20122bfdc97cdda25cddaf"; - hash = "sha256-0cShBpvsoDyE5NmkPX5svlYTYVWVy0rrjwKLn0qYovY="; - finalImageName = imageName; - finalImageTag = "15.2"; -} diff --git a/configurations/nos/modules/docker/media/joal/compose.nix b/configurations/nos/modules/docker/media/joal/compose.nix deleted file mode 100644 index b2a04883..00000000 --- a/configurations/nos/modules/docker/media/joal/compose.nix +++ /dev/null @@ -1,27 +0,0 @@ -{configPath, ...}: {pkgs, ...}: let - rwPath = configPath + "/media/joal"; -in { - virtualisation.docker.compose."joal" = { - networks.proxy_net = {external = true;}; - - services."joal" = { - image = pkgs.callPackage ./images/joal.nix pkgs; - restart = "always"; - - volumes = ["${rwPath}/data:/data"]; - ports = ["5656:5656"]; - - command = [ - "--joal-conf=/data" - "--spring.main.web-environment=true" - "--server.port=5656" - "--joal.ui.path.prefix=joal" - "--joal.ui.secret-token=12345" - ]; - networks = ["proxy_net"]; - }; - }; - - # For accurate stack trace - _file = ./compose.nix; -} diff --git a/configurations/nos/modules/docker/media/joal/images/joal.nix b/configurations/nos/modules/docker/media/joal/images/joal.nix deleted file mode 100644 index 79ad5139..00000000 --- a/configurations/nos/modules/docker/media/joal/images/joal.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "anthonyraymond/joal"; - imageDigest = "sha256:832718170bd2d3da97de1216a6fd2f3caf2d5d56065336320780dadaf4952c1e"; - sha256 = "03wqqhpsjcdgr4q3n9vqyxb59324mxnwn8jn6kj2kb6zq8bz3qrj"; - finalImageName = imageName; - finalImageTag = "latest"; -} diff --git a/configurations/nos/modules/docker/media/prowlarr/compose.nix b/configurations/nos/modules/docker/media/prowlarr/compose.nix deleted file mode 100644 index dbf53572..00000000 --- a/configurations/nos/modules/docker/media/prowlarr/compose.nix +++ /dev/null @@ -1,54 +0,0 @@ -{ - configPath, - mainUID, - mainGID, - TZ, - ... -}: {pkgs, ...}: let - rwPath = configPath + "/media/prowlarr"; -in { - virtualisation.docker.compose."prowlarr" = { - networks.proxy_net = {external = true;}; - - services = { - "prowlarr" = { - image = pkgs.callPackage ./images/prowlarr.nix pkgs; - restart = "always"; - - environment = { - PUID = mainUID; - PGID = mainGID; - inherit TZ; - }; - - volumes = ["${rwPath}/data:/config"]; - - ports = ["9696:9696"]; - networks = ["proxy_net"]; - }; - - "flaresolverr" = { - image = pkgs.callPackage ./images/flaresolverr.nix pkgs; - restart = "always"; - - environment = { - LOG_LEVEL = "info"; - LOG_HTML = "false"; - CAPTCHA_SOLVER = "none"; - inherit TZ; - - # https://github.com/FlareSolverr/FlareSolverr/pull/1300#issuecomment-2379596654 - DRIVER = "nodriver"; - }; - - ports = ["8191:8191"]; - - depends_on = ["prowlarr"]; - networks = ["proxy_net"]; - }; - }; - }; - - # For accurate stack trace - _file = ./compose.nix; -} diff --git a/configurations/nos/modules/docker/media/prowlarr/images/flaresolverr.nix b/configurations/nos/modules/docker/media/prowlarr/images/flaresolverr.nix deleted file mode 100644 index 28429e3f..00000000 --- a/configurations/nos/modules/docker/media/prowlarr/images/flaresolverr.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "alexfozor/flaresolverr"; - imageDigest = "sha256:3e5e1335c31365b5b0d9a737097c6a719de0ba49fed7db65cd828d75ae1bbecb"; - hash = "sha256-8FuBXLmqM/B/uuH/PJuKQIWhHnozSJ2RR0VI7m+rVDw="; - finalImageName = imageName; - finalImageTag = "pr-1300-experimental"; -} diff --git a/configurations/nos/modules/docker/media/prowlarr/images/prowlarr.nix b/configurations/nos/modules/docker/media/prowlarr/images/prowlarr.nix deleted file mode 100644 index ede4fc50..00000000 --- a/configurations/nos/modules/docker/media/prowlarr/images/prowlarr.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "ghcr.io/linuxserver/prowlarr"; - imageDigest = "sha256:e3242cf552ed1818f9e8208c7826e6b3a28b9203c9732fb0dae176b0323954f2"; - hash = "sha256-kdRtOAmw0OBLSEqurQzEkp9bqAL5qjMT1i5kDvE9R80="; - finalImageName = imageName; - finalImageTag = "latest"; -} diff --git a/configurations/nos/modules/docker/media/radarr/compose.nix b/configurations/nos/modules/docker/media/radarr/compose.nix deleted file mode 100644 index 3f729b7e..00000000 --- a/configurations/nos/modules/docker/media/radarr/compose.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ - configPath, - mainUID, - mainGID, - TZ, - ... -}: {pkgs, ...}: let - rwPath = configPath + "/media/radarr"; -in { - virtualisation.docker.compose."radarr" = { - networks.proxy_net = {external = true;}; - - services."radarr" = { - image = pkgs.callPackage ./images/radarr.nix pkgs; - restart = "always"; - - ports = ["7878:7878"]; - - environment = { - PUID = mainUID; - PGID = mainGID; - inherit TZ; - }; - - volumes = [ - "${rwPath}/data:/config" - "/data:/data" - ]; - - cpus = 0.5; - networks = ["proxy_net"]; - }; - }; - - # For accurate stack trace - _file = ./compose.nix; -} diff --git a/configurations/nos/modules/docker/media/radarr/images/radarr.nix b/configurations/nos/modules/docker/media/radarr/images/radarr.nix deleted file mode 100644 index 3291a3a7..00000000 --- a/configurations/nos/modules/docker/media/radarr/images/radarr.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "ghcr.io/linuxserver/radarr"; - imageDigest = "sha256:9a4a7ed79dee5fcc9940b57ddfddfe7c87dea2d13a221ca2fdd2c1c8d9e75c2e"; - hash = "sha256-qWkmwf2RVIn/T/vy2YyJGIR8yc206AoJECkPcEtIWEE="; - finalImageName = imageName; - finalImageTag = "latest"; -} diff --git a/configurations/nos/modules/docker/media/seerr/compose.nix b/configurations/nos/modules/docker/media/seerr/compose.nix deleted file mode 100644 index 372a5123..00000000 --- a/configurations/nos/modules/docker/media/seerr/compose.nix +++ /dev/null @@ -1,31 +0,0 @@ -{ - configPath, - TZ, - ... -}: {pkgs, ...}: let - rwPath = configPath + "/media/seerr"; -in { - virtualisation.docker.compose."seerr" = { - networks.proxy_net = {external = true;}; - - services."seerr" = { - image = pkgs.callPackage ./images/jellyseerr.nix pkgs; - restart = "always"; - - environment = { - LOG_LEVEL = "debug"; - inherit TZ; - }; - - volumes = [ - "${rwPath}/data:/app/config" - ]; - - networks = ["proxy_net"]; - ports = ["5055:5055"]; - }; - }; - - # For accurate stack trace - _file = ./compose.nix; -} diff --git a/configurations/nos/modules/docker/media/seerr/images/jellyseerr.nix b/configurations/nos/modules/docker/media/seerr/images/jellyseerr.nix deleted file mode 100644 index afb56e4d..00000000 --- a/configurations/nos/modules/docker/media/seerr/images/jellyseerr.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "docker.io/fallenbagel/jellyseerr"; - imageDigest = "sha256:2a611369ad1d0d501c2d051fc89b6246ff081fb4a30879fdc75642cf6a37b1a6"; - hash = "sha256-9bl7VECU2oI/tHLuyOWUoTDz7KrrBX5s5AXZ7p0OB+w="; - finalImageName = imageName; - finalImageTag = "latest"; -} diff --git a/configurations/nos/modules/docker/media/sonarr/compose.nix b/configurations/nos/modules/docker/media/sonarr/compose.nix deleted file mode 100644 index 41a93846..00000000 --- a/configurations/nos/modules/docker/media/sonarr/compose.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ - configPath, - mainUID, - mainGID, - TZ, - ... -}: {pkgs, ...}: let - rwPath = configPath + "/media/sonarr"; -in { - virtualisation.docker.compose."sonarr" = { - networks.proxy_net = {external = true;}; - - services."sonarr" = { - image = pkgs.callPackage ./images/sonarr.nix pkgs; - restart = "always"; - - ports = ["8989:8989"]; - - environment = { - PUID = mainUID; - PGID = mainGID; - inherit TZ; - }; - - volumes = [ - "${rwPath}/data:/config" - "/data:/data" - ]; - - cpus = 0.5; - networks = ["proxy_net"]; - }; - }; - - # For accurate stack trace - _file = ./compose.nix; -} diff --git a/configurations/nos/modules/docker/media/sonarr/images/sonarr.nix b/configurations/nos/modules/docker/media/sonarr/images/sonarr.nix deleted file mode 100644 index 30b11cb5..00000000 --- a/configurations/nos/modules/docker/media/sonarr/images/sonarr.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "ghcr.io/linuxserver/sonarr"; - imageDigest = "sha256:cefa1c97ba8f5db60c1c89d04015ead764d3b850b4fbdc5784bdde2a02d72350"; - hash = "sha256-Agmq0CND7zhmahKWriv1m3+XmSP7nvRPg5YBBOmINXc="; - finalImageName = imageName; - finalImageTag = "latest"; -} diff --git a/configurations/nos/modules/docker/music/jbots/compose.nix b/configurations/nos/modules/docker/music/jbots/compose.nix deleted file mode 100644 index 8025bde0..00000000 --- a/configurations/nos/modules/docker/music/jbots/compose.nix +++ /dev/null @@ -1,37 +0,0 @@ -{configPath, ...}: {pkgs, ...}: let - inherit (pkgs.selfPackages) jmusicbot; - - rwPath = configPath + "/music/jbots"; - image = pkgs.callPackage ./images/jmusicbot.nix {inherit pkgs jmusicbot;}; -in { - virtualisation.docker.compose."jbots" = { - networks.proxy_net = {external = true;}; - - services = { - "musicbot_be" = { - container_name = "be"; - restart = "always"; - inherit image; - - volumes = [ - "${rwPath}/be:/jmb/config:rw" - ]; - networks = ["proxy_net"]; - }; - - "musicbot_br" = { - container_name = "br"; - restart = "always"; - inherit image; - - volumes = [ - "${rwPath}/br:/jmb/config:rw" - ]; - networks = ["proxy_net"]; - }; - }; - }; - - # For accurate stack trace - _file = ./compose.nix; -} diff --git a/configurations/nos/modules/docker/music/jbots/images/jmusicbot.nix b/configurations/nos/modules/docker/music/jbots/images/jmusicbot.nix deleted file mode 100644 index 7ef4aed6..00000000 --- a/configurations/nos/modules/docker/music/jbots/images/jmusicbot.nix +++ /dev/null @@ -1,15 +0,0 @@ -# Locked -{ - pkgs, - jmusicbot, -}: -pkgs.dockerTools.buildLayeredImage { - name = "jmusicbot-docker"; - tag = jmusicbot.version; - config = { - created = "now"; - Cmd = ["${jmusicbot}/bin/JMusicBot"]; - WorkingDir = "/jmb/config"; - Volumes."/jmb/config" = {}; - }; -} diff --git a/configurations/nos/modules/docker/nextcloud/compose.nix b/configurations/nos/modules/docker/nextcloud/compose.nix deleted file mode 100644 index a6c7ed31..00000000 --- a/configurations/nos/modules/docker/nextcloud/compose.nix +++ /dev/null @@ -1,163 +0,0 @@ -{configPath, ...}: { - config, - pkgs, - ... -}: let - inherit (config.sops) secrets; - - mainContainerName = "app-server"; - rwPath = configPath + "/nextcloud"; -in { - virtualisation.docker.compose."nextcloud" = { - networks.proxy_net = {external = true;}; - - services = { - "${mainContainerName}" = { - image = pkgs.callPackage ./images/nextcloud.nix pkgs; - restart = "always"; - - expose = [ - "80" - "9000" - ]; - - networks = ["proxy_net"]; - - volumes = [ - "${rwPath}/data:/var/www/html" - "/data/docs:/var/www/drive" - ]; - - env_file = [secrets.nextcloud.path]; - - environment = { - POSTGRES_DB = "nextcloud"; - POSTGRES_HOST = "nextcloud-db"; - REDIS_HOST = "nextcloud-cache"; - NEXTCLOUD_INIT_HTACCESS = "true"; - }; - }; - - "onlyoffice-document-server" = let - filePath = "/var/www/onlyoffice/documentserver/web-apps/apps/*/mobile/dist/js/app.js"; - func = "isSupportEditFeature=function()"; - - entrypoint = - pkgs.writeScript "entrypoint" - # bash - '' - #!/bin/sh - # Fix proxies - sed -i 's/"allowPrivateIPAddress": false,/"allowPrivateIPAddress": true,/' /etc/onlyoffice/documentserver/default.json - sed -i 's/"allowMetaIPAddress": false/"allowMetaIPAddress": true/' /etc/onlyoffice/documentserver/default.json - - # Fix mobile editing - sed -i 's/${func}{return!1}/${func}{return 1}/g' ${filePath} - apt update - apt install imagemagick -y - - exec /app/ds/run-document-server.sh - ''; - in { - image = pkgs.callPackage ./images/onlyoffice.nix pkgs; - restart = "always"; - - environment.JWT_ENABLED = "false"; - - ports = ["8055:80"]; - expose = [ - "80" - "443" - ]; - - networks = ["proxy_net"]; - - entrypoint = "/entrypoint.sh"; - - volumes = [ - "${entrypoint}:/entrypoint.sh" - "${rwPath}/data-onlyoffice:/var/log/onlyoffice" - ]; - tmpfs = [ - "/var/www/onlyoffice/Data" - "/var/lib/postgresql" - "/usr/share/fonts/truetype/custom" - "/var/lib/rabbitmq" - "/var/lib/redis" - "/var/lib/onlyoffice" - ]; - }; - - "nginx-server" = { - image = pkgs.callPackage ./images/nginx.nix pkgs; - restart = "always"; - ports = ["8042:80"]; - - networks = ["proxy_net"]; - volumes = [ - "${./nginx.conf}:/etc/nginx/nginx.conf" - "${rwPath}/data:/var/www/html" - ]; - }; - - "nextcloud-db" = { - image = pkgs.callPackage ./images/postgres.nix pkgs; - restart = "always"; - env_file = [secrets.nextcloud.path]; - volumes = [ - "${rwPath}/database:/var/lib/postgresql/data" - "/etc/localtime:/etc/localtime:ro" - ]; - - networks = ["proxy_net"]; - }; - - "nextcloud-cache" = let - entrypoint = - pkgs.writeScript "entrypoint" - # bash - '' - #!/bin/sh - exec redis-server --requirepass "$REDIS_HOST_PASSWORD" - ''; - in { - image = pkgs.callPackage ./images/redis.nix pkgs; - restart = "always"; - - mem_limit = "2048m"; - mem_reservation = "512m"; - - env_file = [secrets.nextcloud.path]; - - entrypoint = "/entrypoint.sh"; - - volumes = ["${entrypoint}:/entrypoint.sh"]; - tmpfs = ["/data"]; - - networks = ["proxy_net"]; - }; - }; - }; - - # Cron job - systemd.timers.nextcloud-cron = { - description = "Timer For Nextcloud Cron"; - wantedBy = ["timers.target"]; - - timerConfig.OnBootSec = "5m"; - timerConfig.OnUnitActiveSec = "5m"; - }; - systemd.services.nextcloud-cron = { - description = "Nextcloud Cron"; - requires = ["compose-nextcloud.service"]; - after = ["compose-nextcloud.service"]; - - serviceConfig = { - Type = "oneshot"; - ExecStart = "${pkgs.docker}/bin/docker exec -u www-data ${mainContainerName} php -f /var/www/html/cron.php"; - }; - }; - - # For accurate stack trace - _file = ./compose.nix; -} diff --git a/configurations/nos/modules/docker/nextcloud/images/nextcloud.nix b/configurations/nos/modules/docker/nextcloud/images/nextcloud.nix deleted file mode 100644 index 1ecf2f30..00000000 --- a/configurations/nos/modules/docker/nextcloud/images/nextcloud.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "nextcloud"; - imageDigest = "sha256:dcff0b12c4b301ca85074068b262cde17888170cb7f779397e9ee07adaf0aa45"; - hash = "sha256-pX85lZ+smzInK2fmLohrHznjECI3nSoxj/sAvggFW3w="; - finalImageName = imageName; - finalImageTag = "fpm"; -} diff --git a/configurations/nos/modules/docker/nextcloud/images/nginx.nix b/configurations/nos/modules/docker/nextcloud/images/nginx.nix deleted file mode 100644 index f30956d2..00000000 --- a/configurations/nos/modules/docker/nextcloud/images/nginx.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "nginx"; - imageDigest = "sha256:5ed8fcc66f4ed123c1b2560ed708dc148755b6e4cbd8b943fab094f2c6bfa91e"; - hash = "sha256-sH+aeUx4b8iJhHznSnxeJtICQbn/dgg+NFDnzyvTxEE="; - finalImageName = imageName; - finalImageTag = "latest"; -} diff --git a/configurations/nos/modules/docker/nextcloud/images/onlyoffice.nix b/configurations/nos/modules/docker/nextcloud/images/onlyoffice.nix deleted file mode 100644 index 8acd489f..00000000 --- a/configurations/nos/modules/docker/nextcloud/images/onlyoffice.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "onlyoffice/documentserver"; - imageDigest = "sha256:0daa2d1d414d49286bfa9495fc0c936e7e73edaf8944a61102a7a6353a952297"; - hash = "sha256-HO2z4wjDWYTUWaOtrbPC0+XsxMMU/fBDykava6KVLiY="; - finalImageName = imageName; - finalImageTag = "latest"; -} diff --git a/configurations/nos/modules/docker/nextcloud/images/postgres.nix b/configurations/nos/modules/docker/nextcloud/images/postgres.nix deleted file mode 100644 index 5894f51d..00000000 --- a/configurations/nos/modules/docker/nextcloud/images/postgres.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "postgres"; - imageDigest = "sha256:20e49432a20e1a63bb985977c32ec8f110bc609b93de35ad4f19c5486abcefaa"; - sha256 = "0jxkjj726jb1hal4j1vyhnrmbpyrkvawq5nf3dpiad8h3zamvk66"; - finalImageName = imageName; - finalImageTag = "14.2-alpine"; -} diff --git a/configurations/nos/modules/docker/nextcloud/images/redis.nix b/configurations/nos/modules/docker/nextcloud/images/redis.nix deleted file mode 100644 index c49ce9aa..00000000 --- a/configurations/nos/modules/docker/nextcloud/images/redis.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "redis"; - imageDigest = "sha256:558d0845026fe0bf091a00c0ad647ffacf9df385d780d433ca70661f7276f834"; - sha256 = "0bbbzjl2fc2wvwj45j4z8kff2fj82qjk5nsgi79bqzm72x428mjb"; - finalImageName = imageName; - finalImageTag = "7.0.0-alpine"; -} diff --git a/configurations/nos/modules/docker/nextcloud/nginx.conf b/configurations/nos/modules/docker/nextcloud/nginx.conf deleted file mode 100644 index 5d82e1a9..00000000 --- a/configurations/nos/modules/docker/nextcloud/nginx.conf +++ /dev/null @@ -1,196 +0,0 @@ -user www-data; -worker_processes 1; - -error_log /var/log/nginx/error.log warn; -pid /var/run/nginx.pid; - -events { - worker_connections 1024; -} - -http { - upstream backend { - server app-server:9000; - #server unix:/var/run/php/php7.4-fpm.sock; - } - - # Set the `immutable` cache control options only for assets with a cache busting `v` argument - map $arg_v $asset_immutable { - "" ""; - default "immutable"; - } - - include /etc/nginx/mime.types; - default_type application/octet-stream; - - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - - access_log /var/log/nginx/access.log main; - - sendfile on; - #tcp_nopush on; - - keepalive_timeout 65; - - map $http_host $this_host { - "" $host; - default $http_host; - } - - map $http_x_forwarded_proto $the_scheme { - default $http_x_forwarded_proto; - "" $scheme; - } - - map $http_x_forwarded_host $the_host { - default $http_x_forwarded_host; - "" $this_host; - } - - server { - listen 80; - # The below allows for being behind a reverse proxy and allowing the Nextcloud app to connect - server_tokens off; - - # Add headers to serve security related headers - add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;"; - # HTTP response headers borrowed from Nextcloud `.htaccess` - add_header Referrer-Policy "no-referrer" always; - add_header X-Content-Type-Options "nosniff" always; - add_header X-Download-Options "noopen" always; - add_header X-Frame-Options "SAMEORIGIN" always; - add_header X-Permitted-Cross-Domain-Policies "none" always; - add_header X-Robots-Tag "noindex, nofollow" always; - add_header X-XSS-Protection "1; mode=block" always; - - # Remove X-Powered-By, which is an information leak - fastcgi_hide_header X-Powered-By; - - root /var/www/html; - client_max_body_size 10G; # 0=unlimited - set max upload size - fastcgi_buffers 64 4K; - client_body_buffer_size 512k; - - gzip off; - - index index.php index.html /index.php$request_uri; - - # Rule borrowed from `.htaccess` to handle Microsoft DAV clients - location = / { - if ( $http_user_agent ~ ^DavClnt ) { - return 302 /remote.php/webdav/$is_args$args; - } - } - - location ^~ /.well-known { - location = /.well-known/carddav { - return 301 /remote.php/dav/; - } - location = /.well-known/caldav { - return 301 /remote.php/dav/; - } - - #location = /.well-known/webfinger { return 301 /index.php/.well-known/webfinger/; } - #location = /.well-known/nodeinfo { return 301 /index.php/.well-known/nodeinfo/; }} - - location /.well-known/acme-challenge { - try_files $uri $uri/ =404; - } - location /.well-known/pki-validation { - try_files $uri $uri/ =404; - } - - # Let Nextcloud's API for `/.well-known` URIs handle all other - # requests by passing them to the front-end controller. - return 301 /index.php$request_uri; - } - - location = /robots.txt { - allow all; - log_not_found off; - access_log off; - } - - # Rules borrowed from `.htaccess` to hide certain paths from clients - location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { - return 404; - } - location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { - return 404; - } - - location ~* ^/ds-vpath/ { - rewrite /ds-vpath/(.*) /$1 break; - proxy_pass http://onlyoffice-document-server; - proxy_redirect off; - - client_max_body_size 10G; - - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Host $the_host/ds-vpath; - proxy_set_header X-Forwarded-Proto $the_scheme; - } - - location ~ \.php(?:$|/) { - # Required for legacy support - rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri; - - fastcgi_split_path_info ^(.+?\.php)(/.*)$; - set $path_info $fastcgi_path_info; - - try_files $fastcgi_script_name =404; - - include fastcgi_params; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param PATH_INFO $fastcgi_path_info; - fastcgi_param HTTPS off; - - fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice - fastcgi_param front_controller_active true; - fastcgi_pass backend; - - fastcgi_intercept_errors on; - fastcgi_request_buffering off; - - fastcgi_max_temp_file_size 0; - } - - location ~ \.(?:css|js|mjs|svg|gif|png|jpg|ico|wasm|tflite|map)$ { - try_files $uri /index.php$request_uri; - add_header Cache-Control "public, max-age=15778463, $asset_immutable"; - access_log off; # Optional: Don't log access to assets - - location ~ \.wasm$ { - default_type application/wasm; - } - - location ~ \.mjs$ { - default_type text/javascript; - } - } - - - location ~ \.woff2?$ { - try_files $uri /index.php$request_uri; - expires 7d; # Cache-Control policy borrowed from `.htaccess` - access_log off; # Optional: Don't log access to assets - } - - # Rule borrowed from `.htaccess` - location /remote { - return 301 /remote.php$request_uri; - } - - location / { - try_files $uri $uri/ /index.php$request_uri; - } - } -} diff --git a/configurations/nos/modules/docker/resume/compose.nix b/configurations/nos/modules/docker/resume/compose.nix deleted file mode 100644 index dc4af72e..00000000 --- a/configurations/nos/modules/docker/resume/compose.nix +++ /dev/null @@ -1,64 +0,0 @@ -{configPath, ...}: { - config, - pkgs, - ... -}: let - inherit (config.sops) secrets; - - rwPath = configPath + "/resume"; -in { - virtualisation.docker.compose."resume" = { - networks.proxy_net = {external = true;}; - - services = { - "postgres" = { - image = pkgs.callPackage ./images/postgres.nix pkgs; - restart = "always"; - - ports = ["5432:5432"]; - - volumes = [ - "${rwPath}/db:/var/lib/postgresql/data" - ]; - - env_file = [secrets.resume.path]; - networks = ["proxy_net"]; - }; - - "server" = { - image = pkgs.callPackage ./images/resume-server.nix pkgs; - restart = "always"; - - ports = ["3100:3100"]; - - depends_on = ["postgres"]; - - env_file = [secrets.resume.path]; - - environment = { - PUBLIC_URL = "https://resume.nelim.org"; - PUBLIC_SERVER_URL = "https://resauth.nelim.org"; - }; - networks = ["proxy_net"]; - }; - - "client" = { - image = pkgs.callPackage ./images/resume-client.nix pkgs; - restart = "always"; - - ports = ["3060:3000"]; - - depends_on = ["server"]; - - environment = { - PUBLIC_URL = "https://resume.nelim.org"; - PUBLIC_SERVER_URL = "https://resauth.nelim.org"; - }; - networks = ["proxy_net"]; - }; - }; - }; - - # For accurate stack trace - _file = ./compose.nix; -} diff --git a/configurations/nos/modules/docker/resume/images/postgres.nix b/configurations/nos/modules/docker/resume/images/postgres.nix deleted file mode 100644 index dbe28bc7..00000000 --- a/configurations/nos/modules/docker/resume/images/postgres.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "postgres"; - imageDigest = "sha256:ef9d1517df69c4d27dbb9ddcec14f431a2442628603f4e9daa429b92ae6c3cd1"; - hash = "sha256-qrYC2YmySd6lNiw2fsd3MFf5npg4/xgkyiT/Ty3g4ZE="; - finalImageName = imageName; - finalImageTag = "15-alpine"; -} diff --git a/configurations/nos/modules/docker/resume/images/resume-client.nix b/configurations/nos/modules/docker/resume/images/resume-client.nix deleted file mode 100644 index 6e7ca7d8..00000000 --- a/configurations/nos/modules/docker/resume/images/resume-client.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "amruthpillai/reactive-resume"; - imageDigest = "sha256:9cbe8efde6f489da05367b5b2d0f0097b397f76fa1dcefd0352f174e50221826"; - sha256 = "1ybsnr91518m7v2g9drp2pdibml4rsfa5mqnrjckwq1ai9mlg1rj"; - finalImageName = imageName; - finalImageTag = "client-latest"; -} diff --git a/configurations/nos/modules/docker/resume/images/resume-server.nix b/configurations/nos/modules/docker/resume/images/resume-server.nix deleted file mode 100644 index fb3ba582..00000000 --- a/configurations/nos/modules/docker/resume/images/resume-server.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "amruthpillai/reactive-resume"; - imageDigest = "sha256:f14519b5d72fab07a948ce0ac6ac8e09321f1b05865e9d951851467e8be0542f"; - sha256 = "0znbhnixy22i80h2qjylsf8v0mg07scfirh2q5w8njf7sa52w0d6"; - finalImageName = imageName; - finalImageTag = "server-latest"; -} diff --git a/configurations/nos/modules/docker/vaultwarden/compose.nix b/configurations/nos/modules/docker/vaultwarden/compose.nix deleted file mode 100644 index f77f527d..00000000 --- a/configurations/nos/modules/docker/vaultwarden/compose.nix +++ /dev/null @@ -1,32 +0,0 @@ -{configPath, ...}: {pkgs, ...}: let - rwPath = configPath + "/vaultwarden"; -in { - virtualisation.docker.compose."vaultwarden" = { - networks.proxy_net = {external = true;}; - - services = { - "public-vault" = { - image = pkgs.callPackage ./images/vaultwarden.nix pkgs; - restart = "always"; - - ports = ["8781:80"]; - volumes = ["${rwPath}/public-data:/data"]; - environment.WEBSOCKET_ENABLED = "true"; - networks = ["proxy_net"]; - }; - - "private-vault" = { - image = pkgs.callPackage ./images/vaultwarden.nix pkgs; - restart = "always"; - - ports = ["8780:80"]; - volumes = ["${rwPath}/private-data:/data"]; - environment.WEBSOCKET_ENABLED = "true"; - networks = ["proxy_net"]; - }; - }; - }; - - # For accurate stack trace - _file = ./compose.nix; -} diff --git a/configurations/nos/modules/docker/vaultwarden/images/vaultwarden.nix b/configurations/nos/modules/docker/vaultwarden/images/vaultwarden.nix deleted file mode 100644 index cc3da5b9..00000000 --- a/configurations/nos/modules/docker/vaultwarden/images/vaultwarden.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "quay.io/vaultwarden/server"; - imageDigest = "sha256:87edb99945da91bd7504ac1435495595af2e89ad2c7adc151ae5bf091ec8baf2"; - hash = "sha256-paMFOkR+YGL8c8tSQZMdcAS00uFrYl0xHeO/JRW6JzU="; - finalImageName = imageName; - finalImageTag = "latest"; -} diff --git a/configurations/nos/modules/docker/wg-easy/compose.nix b/configurations/nos/modules/docker/wg-easy/compose.nix deleted file mode 100644 index fe615dda..00000000 --- a/configurations/nos/modules/docker/wg-easy/compose.nix +++ /dev/null @@ -1,45 +0,0 @@ -{configPath, ...}: {pkgs, ...}: let - rwPath = configPath + "/wg-easy"; -in { - virtualisation.docker.compose."wg-easy" = { - networks.proxy_net = {external = true;}; - - services."wg-easy" = { - image = pkgs.callPackage ./images/wg-easy.nix pkgs; - restart = "always"; - privileged = true; - - cap_add = [ - "NET_ADMIN" - "SYS_MODULE" - ]; - - sysctls = [ - "net.ipv4.ip_forward=1" - "net.ipv4.conf.all.src_valid_mark=1" - ]; - - environment = { - WG_HOST = "nelim.org"; - WG_PORT = "51820"; - WG_DEFAULT_ADDRESS = "10.6.0.x"; - WG_DEFAULT_DNS = "1.0.0.1"; - }; - - volumes = [ - "${rwPath}/data:/etc/wireguard" - ]; - - ports = [ - "53:51820/udp" - "51822:51820/udp" - "51821:51821/tcp" - ]; - - networks = ["proxy_net"]; - }; - }; - - # For accurate stack trace - _file = ./compose.nix; -} diff --git a/configurations/nos/modules/docker/wg-easy/images/wg-easy.nix b/configurations/nos/modules/docker/wg-easy/images/wg-easy.nix deleted file mode 100644 index b55923c8..00000000 --- a/configurations/nos/modules/docker/wg-easy/images/wg-easy.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "ghcr.io/wg-easy/wg-easy"; - imageDigest = "sha256:66352ccb4b5095992550aa567df5118a5152b6ed31be34b0a8e118a3c3a35bf5"; - sha256 = "0m41f39a68rmhv0k7fbxib7g42zpn06sgrv1iwzc6n946ad440al"; - finalImageName = imageName; - finalImageTag = "latest"; -} diff --git a/configurations/nos/modules/homepage/default.nix b/configurations/nos/modules/homepage/default.nix deleted file mode 100644 index 998495b8..00000000 --- a/configurations/nos/modules/homepage/default.nix +++ /dev/null @@ -1,321 +0,0 @@ -{ - config, - pkgs, - ... -}: { - services.homepage-dashboard = { - enable = true; - - package = pkgs.selfPackages.homepage; - - listenPort = 3020; - allowedHosts = "lan.nelim.org"; - - environmentFile = config.sops.secrets.homepage.path; - - settings = { - title = "bruh"; - theme = "dark"; - color = "gray"; - target = "_self"; - - layout.video = { - style = "columns"; - row = 4; - # columns = 2; - }; - }; - - widgets = [ - { - resources = { - cpu = true; - memory = true; - disk = "/"; - }; - } - { - search = { - provider = "duckduckgo"; - target = "_blank"; - }; - } - ]; - - services = [ - ##################################################### - ## PUBLIC - ##################################################### - { - public = [ - { - jellyfin = rec { - href = "https://jelly.nelim.org"; - icon = "jellyfin.png"; - description = "ourflix"; - widget = { - type = "jellyfin"; - url = href; - key = "{{HOMEPAGE_VAR_JELLY_API}}"; - }; - }; - } - { - accounts = { - href = "https://jelly.nelim.org/accounts"; - icon = "jellyfin.png"; - description = "manage jellyfin users"; - }; - } - { - jellystat = { - href = "https://lan.nelim.org/jellystat"; - icon = "jellyfin.png"; - description = "view jellyfin stats"; - }; - } - { - jellyseerr = rec { - href = "https://seerr.nelim.org"; - icon = "jellyseerr.png"; - description = "request handler"; - widget = { - type = "jellyseerr"; - url = href; - key = "{{HOMEPAGE_VAR_SEERR_API}}"; - }; - }; - } - { - forgejo = { - href = "https://git.nelim.org"; - icon = "forgejo.png"; - description = "git"; - }; - } - { - immich = rec { - href = "https://photos.nelim.org"; - icon = "immich.png"; - description = "gphotos replacement"; - widget = { - type = "immich"; - url = href; - key = "{{HOMEPAGE_VAR_IMMICH_API}}"; - version = 2; - }; - }; - } - { - gameyfin = { - href = "https://games.nelim.org"; - description = "steam (tm)"; - }; - } - { - nextcloud = rec { - href = "https://cloud.nelim.org"; - icon = "nextcloud.png"; - description = "PDrive"; - widget = { - type = "nextcloud"; - url = href; - username = "mathis"; - password = "{{HOMEPAGE_VAR_CLOUD_PASS}}"; - }; - }; - } - { - "public vaultwarden" = { - href = "https://vault.nelim.org"; - icon = "bitwarden.png"; - description = "password manager"; - }; - } - ]; - } - ##################################################### - ## VIDEO AUTOMATION - ##################################################### - { - "video automation" = [ - { - qbit = rec { - href = "https://lan.nelim.org/qbt"; - icon = "qbittorrent.png"; - description = "torrent client"; - widget = { - type = "qbittorrent"; - url = href; - username = "admin"; - password = "{{HOMEPAGE_VAR_QBIT_PASS}}"; - }; - }; - } - { - sonarr = rec { - href = "https://lan.nelim.org/sonarr"; - icon = "sonarr.png"; - description = "fetches tv shows"; - widget = { - type = "sonarr"; - url = href; - key = "{{HOMEPAGE_VAR_SONARR_API}}"; - }; - }; - } - { - radarr = rec { - href = "https://lan.nelim.org/radarr"; - icon = "radarr.png"; - description = "fetches movies"; - widget = { - type = "radarr"; - url = href; - key = "{{HOMEPAGE_VAR_RADARR_API}}"; - }; - }; - } - { - bazarr = rec { - href = "https://lan.nelim.org/bazarr"; - icon = "bazarr.png"; - description = "fetches subs"; - widget = { - type = "bazarr"; - url = href; - key = "{{HOMEPAGE_VAR_BAZARR_API}}"; - }; - }; - } - { - prowlarr = rec { - href = "https://lan.nelim.org/prowlarr"; - icon = "prowlarr.png"; - description = "fetches tracker queries"; - widget = { - type = "prowlarr"; - url = href; - key = "{{HOMEPAGE_VAR_PROWLARR_API}}"; - }; - }; - } - { - joal = { - href = "https://joal.nelim.org"; - icon = "joal.png"; - description = "secret black magic stuff"; - }; - } - ]; - } - ##################################################### - ## MISC PROJECTS - ##################################################### - { - "misc projects" = [ - { - komga = rec { - href = "https://komga.nelim.org"; - icon = "komga.png"; - description = "comic book library"; - widget = { - type = "komga"; - url = href; - username = "{{HOMEPAGE_VAR_KOMGA_USER}}"; - password = "{{HOMEPAGE_VAR_KOMGA_PASSWORD}}"; - key = "{{HOMEPAGE_VAR_COMIC_VINE_KEY}}"; - }; - }; - } - { - kapowarr = { - href = "https://lan.nelim.org/kapowarr"; - icon = "kapowarr.png"; - description = "organizes comic books"; - }; - } - { - jdownloader2 = { - href = "https://lan.nelim.org/jd2"; - icon = "jdownloader2.png"; - description = "multi use download client"; - }; - } - { - freshrss = { - href = "https://rss.nelim.org"; - icon = "freshrss.png"; - description = "rss client"; - }; - } - { - rss-bridge = { - href = "https://bridge.nelim.org"; - icon = "rss-bridge.png"; - description = "make rss feeds from anything"; - }; - } - ]; - } - ##################################################### - ## MANAGEMENT - ##################################################### - { - management = [ - { - cloudflare = { - href = "https://dash.cloudflare.com/3152abbe78daf6d91c57b6fcc424f958/nelim.org/dns"; - icon = "cloudflare.png"; - description = "dns to the world"; - }; - } - { - vaultwarden = { - href = "https://lan.nelim.org/vault"; - icon = "bitwarden.png"; - description = "password manager"; - }; - } - { - wireguard = { - href = "https://wg.nelim.org"; - icon = "wireguard.png"; - description = "wireguard gui"; - }; - } - { - survie = { - icon = "minecraft.png"; - description = "minecwaf"; - widget = { - type = "minecraft"; - url = "udp://mc.nelim.org"; - }; - }; - } - { - creative = { - icon = "minecraft.png"; - description = "minecwaf"; - widget = { - type = "minecraft"; - url = "udp://cv.nelim.org"; - }; - }; - } - { - modded = { - icon = "minecraft.png"; - description = "minecwaf"; - widget = { - type = "minecraft"; - url = "udp://mc2.nelim.org"; - }; - }; - } - ]; - } - ]; - }; -} diff --git a/configurations/nos/modules/jellyfin/default.nix b/configurations/nos/modules/jellyfin/default.nix deleted file mode 100644 index 7cf38cc3..00000000 --- a/configurations/nos/modules/jellyfin/default.nix +++ /dev/null @@ -1,128 +0,0 @@ -{ - config, - nixos-jellyfin, - lib, - mainUser, - pkgs, - ... -}: let - inherit (lib) hasAttr optionals; - - optionalGroup = name: - optionals - (hasAttr name config.users.groups) - [config.users.groups.${name}.name]; -in { - imports = [ - ./jfa-go.nix - nixos-jellyfin.nixosModules.default - ]; - - users.users."jellyfin".extraGroups = - optionalGroup mainUser - ++ optionalGroup "input" - ++ optionalGroup "media" - ++ optionalGroup "render" - ++ optionalGroup "video"; - - services.jellyfin = { - enable = true; - - webPackage = pkgs.jellyfin-web.override { - forceEnableBackdrops = true; - forceDisablePreferFmp4 = true; - }; - - settings = { - system = { - serverName = "Jelly"; - quickConnectAvailable = false; - isStartupWizardCompleted = true; - - enableGroupingIntoCollections = true; - enableExternalContentInSuggestions = false; - - pluginRepositories = [ - { - name = "Jellyfin Stable"; - url = "https://repo.jellyfin.org/releases/plugin/manifest-stable.json"; - } - { - name = "Intro Skipper"; - url = "https://manifest.intro-skipper.org/manifest.json"; - } - { - name = "Merge Versions Plugin"; - url = "https://raw.githubusercontent.com/danieladov/JellyfinPluginManifest/master/manifest.json"; - } - ]; - - enableSlowResponseWarning = false; - }; - - branding = let - importFile = file: "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/${file}.css');"; - in { - customCss = '' - /* Base theme */ - ${importFile "base"} - ${importFile "accentlist"} - ${importFile "fixes"} - - ${importFile "type/dark_withaccent"} - - ${importFile "rounding"} - ${importFile "progress/floating"} - ${importFile "titlepage/title_banner-logo"} - ${importFile "header/header_transparent"} - ${importFile "login/login_frame"} - ${importFile "fields/fields_border"} - ${importFile "cornerindicator/indicator_floating"} - - /* Style backdrop */ - .backdropImage {filter: blur(18px) saturate(120%) contrast(120%) brightness(40%);} - - /* Fix Jellyfin's st**pid skip-intro placement */ - .skip-button { - position: fixed; - bottom: 18%; - right: 16%; - } - - /* Custom Settings */ - :root {--accent: 145,75,245;} - :root {--rounding: 12px;} - - /* https://github.com/CTalvio/Ultrachromic/issues/79 */ - .skinHeader { - color: rgba(var(--accent), 0.8);; - } - .countIndicator, - .fullSyncIndicator, - .mediaSourceIndicator, - .playedIndicator { - background-color: rgba(var(--accent), 0.8); - } - ''; - }; - - encoding = { - hardwareAccelerationType = "nvenc"; - hardwareDecodingCodecs = [ - "h264" - "hevc" - "mpeg2video" - "mpeg4" - "vc1" - "vp8" - "vp9" - "av1" - ]; - allowHevcEncoding = false; - enableThrottling = false; - enableTonemapping = true; - downMixAudioBoost = 1; - }; - }; - }; -} diff --git a/configurations/nos/modules/jellyfin/images/jfa-go.nix b/configurations/nos/modules/jellyfin/images/jfa-go.nix deleted file mode 100644 index 18dab44d..00000000 --- a/configurations/nos/modules/jellyfin/images/jfa-go.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "hrfee/jfa-go"; - imageDigest = "sha256:739977423a29f65811d50d1bb98571db38da109e2f6f2d2dc4384092d009cacc"; - sha256 = "07dcxwqgkk2kb2mr3pvmabbmry39sw03dqymzhs9gws489w4wzcm"; - finalImageName = imageName; - finalImageTag = "unstable"; -} diff --git a/configurations/nos/modules/jellyfin/jfa-go.nix b/configurations/nos/modules/jellyfin/jfa-go.nix deleted file mode 100644 index 56e6d52b..00000000 --- a/configurations/nos/modules/jellyfin/jfa-go.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ - config, - pkgs, - ... -}: let - jellyService = config.systemd.services.jellyfin.serviceConfig; -in { - virtualisation.docker.compose."jfa-go" = { - systemdDependencies = ["jellyfin.service"]; - - networks.proxy_net = {external = true;}; - - services."jfa-go" = { - image = pkgs.callPackage ./images/jfa-go.nix pkgs; - restart = "always"; - - ports = ["8056:8056"]; - networks = ["proxy_net"]; - - volumes = [ - "${jellyService.WorkingDirectory}/jfa-go:/data" - "/etc/localtime:/etc/localtime:ro" - ]; - }; - }; -} diff --git a/configurations/nos/modules/llm/default.nix b/configurations/nos/modules/llm/default.nix deleted file mode 100644 index 2b5684fa..00000000 --- a/configurations/nos/modules/llm/default.nix +++ /dev/null @@ -1,33 +0,0 @@ -{self, ...}: let - tailscaleIP = "100.64.0.4"; -in { - imports = [self.nixosModules.wyoming-plus]; - - # In case tailscale is down - boot.kernel.sysctl."net.ipv4.ip_nonlocal_bind" = 1; - - services = { - # Speech-to-Text - wyoming.faster-whisper.servers."en" = { - enable = true; - uri = "tcp://${tailscaleIP}:10300"; - - # see https://github.com/rhasspy/wyoming-faster-whisper/releases/tag/v2.0.0 - model = "medium"; - language = "en"; - device = "cuda"; - }; - - # Text-to-Intent - ollama = { - enable = true; - acceleration = "cuda"; - - host = tailscaleIP; - port = 11434; - - loadModels = ["mistral-nemo"]; - environmentVariables.OLLAMA_DEBUG = "1"; - }; - }; -} diff --git a/configurations/nos/modules/mergerfs/default.nix b/configurations/nos/modules/mergerfs/default.nix deleted file mode 100644 index a0e08e7e..00000000 --- a/configurations/nos/modules/mergerfs/default.nix +++ /dev/null @@ -1,81 +0,0 @@ -{pkgs, ...}: let - fsPkgs = builtins.attrValues {inherit (pkgs) mergerfs cifs-utils;}; -in { - system.fsPackages = fsPkgs; - environment.systemPackages = fsPkgs; - - fileSystems = { - "MergerFS Data" = { - mountPoint = "/data"; - fsType = "fuse.mergerfs"; - device = "/mnt/drives/?tb*"; - options = [ - "cache.files=partial" - "allow_other" - "category.create=lfs" - "minfreespace=50G" - "fsname=mergerfs" - ]; - }; - - "d1 3tb-1" = { - mountPoint = "/mnt/drives/3tb1"; - fsType = "ext4"; - device = "/dev/disk/by-id/ata-WDC_WD30EFRX-68EUZN0_WD-WMC4N1236473-part1"; - }; - - "d2 3tb-2" = { - mountPoint = "/mnt/drives/3tb2"; - fsType = "ext4"; - device = "/dev/disk/by-id/ata-WDC_WD30EFRX-68EUZN0_WD-WMC4N1233153-part1"; - }; - - "d3 4tb-1" = { - mountPoint = "/mnt/drives/4tb1"; - fsType = "ext4"; - device = "/dev/disk/by-id/ata-WDC_WD40EZAZ-19SF3B0_WD-WX32D81DE8RD-part1"; - }; - - "d4 4tb-2" = { - mountPoint = "/mnt/drives/4tb2"; - fsType = "ext4"; - device = "/dev/disk/by-id/ata-WDC_WD40EZAZ-19SF3B0_WD-WX32D81DE6Z0-part1"; - }; - - "d5 8tb-1" = { - mountPoint = "/mnt/drives/8tb1"; - fsType = "ext4"; - device = "/dev/disk/by-id/ata-WDC_WD8003FFBX-68B9AN0_VAJ99UDL-part1"; - }; - - "p0 8tb-2" = { - mountPoint = "/mnt/drives/parity0"; - fsType = "ext4"; - device = "/dev/disk/by-id/ata-WDC_WD8003FFBX-68B9AN0_VDGL4HZD-part1"; - }; - - "p1 8tb-3" = { - mountPoint = "/mnt/drives/parity1"; - fsType = "ext4"; - device = "/dev/disk/by-id/ata-WDC_WD80EFZZ-68BTXN0_WD-CA13WUYK-part1"; - }; - - "d6 8tb-4" = { - mountPoint = "/mnt/drives/8tb4"; - fsType = "ext4"; - device = "/dev/disk/by-id/ata-WDC_WD80EAZZ-00BKLB0_WD-CA1AVU7K-part1"; - }; - - "d7 8tb-5" = { - mountPoint = "/mnt/drives/8tb5"; - fsType = "ext4"; - device = "/dev/disk/by-id/ata-WDC_WD80EAZZ-00BKLB0_WD-CA1GN0GK-part1"; - }; - - "d8 8tb-6" = { - mountPoint = "/mnt/drives/8tb6"; - fsType = "ext4"; - device = "/dev/disk/by-id/ata-ST8000DM004-2U9188_ZR15JMHV-part1"; - }; - }; -} diff --git a/configurations/nos/modules/qbittorrent/default.nix b/configurations/nos/modules/qbittorrent/default.nix deleted file mode 100644 index 629a613e..00000000 --- a/configurations/nos/modules/qbittorrent/default.nix +++ /dev/null @@ -1,17 +0,0 @@ -{...}: { - imports = [ - ./qbittorrent.nix - ./wireguard.nix - ]; - - users.groups."matt" = { - gid = 1000; - members = ["matt"]; - }; - - services.qbittorrent = { - enable = true; - user = "matt"; - group = "matt"; - }; -} diff --git a/configurations/nos/modules/qbittorrent/qbittorrent.nix b/configurations/nos/modules/qbittorrent/qbittorrent.nix deleted file mode 100644 index 006e598d..00000000 --- a/configurations/nos/modules/qbittorrent/qbittorrent.nix +++ /dev/null @@ -1,138 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - cfg = config.services.qbittorrent; - pkg = pkgs.qbittorrent-nox; - - vue = let - gen = import ./vuetorrent.nix; - in - pkgs.stdenv.mkDerivation { - pname = "vuetorrent"; - inherit (gen) version; - - nativeBuildInputs = [pkgs.unzip]; - src = pkgs.fetchurl { - inherit (gen) url hash; - }; - - postInstall = '' - mkdir $out - cp -a ./* $out - ''; - }; - - inherit - (lib) - mkEnableOption - mkOption - types - mkIf - ; -in { - options.services.qbittorrent = { - enable = mkEnableOption "qbittorrent"; - - dataDir = mkOption { - type = types.path; - default = "/var/lib/qbittorrent"; - description = '' - The directory where qBittorrent will create files. - ''; - }; - - configDir = mkOption { - type = types.path; - default = "${cfg.dataDir}/.config"; - defaultText = "/var/lib/qbittorrent/.config"; - description = '' - The directory where qBittorrent will store its configuration. - ''; - }; - - user = mkOption { - type = types.str; - default = "qbittorrent"; - description = '' - User account under which qBittorrent runs. - ''; - }; - - group = mkOption { - type = types.str; - default = "qbittorrent"; - description = '' - Group under which qBittorrent runs. - ''; - }; - - port = mkOption { - type = types.port; - default = 8080; - description = '' - qBittorrent web UI port. - ''; - }; - - openFirewall = mkOption { - type = types.bool; - default = false; - description = '' - Allow qBittorrent's ports to accept connections from the outside network. - ''; - }; - - openFilesLimit = mkOption { - default = 4096; - description = '' - Number of files to allow qBittorrent to open. - ''; - }; - }; - - config = mkIf cfg.enable { - environment.systemPackages = [pkg]; - - networking.firewall = mkIf cfg.openFirewall { - allowedTCPPorts = [cfg.port]; - allowedUDPPorts = [cfg.port]; - }; - - systemd.services.qbittorrent = { - after = ["network.target"]; - description = "qBittorrent Daemon"; - wantedBy = ["multi-user.target"]; - path = [pkg]; - script = '' - rm -rf ${cfg.configDir}/vuetorrent - ln -sf ${vue} ${cfg.configDir}/vuetorrent - qbittorrent-nox \ - --profile=${cfg.configDir} \ - --webui-port=${toString cfg.port} - ''; - serviceConfig = { - Restart = "on-success"; - User = cfg.user; - Group = cfg.group; - UMask = "0002"; - LimitNOFILE = cfg.openFilesLimit; - }; - }; - - users.users = mkIf (cfg.user == "qbittorrent") { - qbittorrent = { - group = cfg.group; - home = cfg.dataDir; - createHome = true; - description = "qBittorrent Daemon user"; - }; - }; - - users.groups = mkIf (cfg.group == "qbittorrent") { - qbittorrent = {}; - }; - }; -} diff --git a/configurations/nos/modules/qbittorrent/vuetorrent.nix b/configurations/nos/modules/qbittorrent/vuetorrent.nix deleted file mode 100644 index 2b94d81a..00000000 --- a/configurations/nos/modules/qbittorrent/vuetorrent.nix +++ /dev/null @@ -1,6 +0,0 @@ -# This file was autogenerated. DO NOT EDIT! -{ - version = "2.24.1"; - url = "https://github.com/VueTorrent/VueTorrent/releases/download/v2.24.1/vuetorrent.zip"; - hash = "sha256-luW5dHxTeoiuUPFAVEJxG9yS28/9JJ8lW16pI/0ruFU="; -} diff --git a/configurations/nos/modules/qbittorrent/wireguard.nix b/configurations/nos/modules/qbittorrent/wireguard.nix deleted file mode 100644 index 9ab919fc..00000000 --- a/configurations/nos/modules/qbittorrent/wireguard.nix +++ /dev/null @@ -1,78 +0,0 @@ -{ - config, - pkgs, - ... -}: let - inherit (config.sops) secrets; - - wgPort = 51820; - clientIP = "10.2.0.2"; - serverIP = "146.70.198.2"; -in { - networking.wireguard = { - enable = true; - - interfaces = { - wg0 = { - interfaceNamespace = "wg"; - ips = ["${clientIP}/32"]; - - listenPort = wgPort; - - generatePrivateKeyFile = false; - privateKeyFile = secrets.vpn.path; - - peers = [ - { - publicKey = "aQ2NoOYEObG9tDMwdc4VxK6hjW+eA0PLfgbH7ffmagU="; - allowedIPs = ["0.0.0.0/0"]; - endpoint = "${serverIP}:${toString wgPort}"; - } - ]; - }; - }; - }; - - systemd.services = let - joinWgNamespace = { - bindsTo = ["netns@wg.service"]; - requires = ["network-online.target"]; - after = ["wireguard-wg0.service"]; - unitConfig.JoinsNamespaceOf = "netns@wg.service"; - serviceConfig.NetworkNamespacePath = "/var/run/netns/wg"; - }; - - mkPortRoute = service: port: { - description = "Forward to ${service} in wireguard namespace"; - requires = ["${service}.service"]; - after = ["${service}.service"]; - partOf = ["${service}.service"]; - serviceConfig = { - Restart = "on-failure"; - TimeoutStopSec = 300; - }; - wantedBy = ["multi-user.target"]; - script = '' - ${pkgs.iproute2}/bin/ip netns exec wg ${pkgs.iproute2}/bin/ip link set dev lo up - ${pkgs.socat}/bin/socat tcp-listen:${port},fork,reuseaddr exec:'${pkgs.iproute2}/bin/ip netns exec wg ${pkgs.socat}/bin/socat STDIO "tcp-connect:${clientIP}:${port}"',nofork - ''; - }; - in { - # Create namespace for Wireguard - # This allows us to isolate specific programs to Wireguard - "netns@" = { - description = "%I network namespace"; - before = ["network.target"]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - ExecStart = "${pkgs.iproute2}/bin/ip netns add %I"; - ExecStop = "${pkgs.iproute2}/bin/ip netns del %I"; - }; - }; - "wireguard-wg0".wants = ["netns@wg.service"]; - - "qbittorrent" = joinWgNamespace; - "qbittorrent-port-route" = mkPortRoute "qbittorrent" "8080"; - }; -} diff --git a/configurations/nos/modules/snapraid/default.nix b/configurations/nos/modules/snapraid/default.nix deleted file mode 100644 index 5a31599f..00000000 --- a/configurations/nos/modules/snapraid/default.nix +++ /dev/null @@ -1,58 +0,0 @@ -{ - config, - lib, - ... -}: let - inherit - (lib) - attrValues - filterAttrs - hasPrefix - listToAttrs - mapAttrs - optionalString - substring - toInt - ; - - parityDrives = filterAttrs (n: v: hasPrefix "p" n) config.fileSystems; - dataDrives = filterAttrs (n: v: hasPrefix "d" n) config.fileSystems; -in { - services.snapraid = { - enable = true; - - dataDisks = listToAttrs (attrValues (mapAttrs (n: fs: { - name = substring 0 2 n; - value = fs.mountPoint; - }) - dataDrives)); - - parityFiles = attrValues (mapAttrs (n: fs: "${fs.mountPoint}/snapraid.${ - let - i = (toInt (substring 1 1 n)) + 1; - in - optionalString (i != 1) "${toString i}-" - }parity") - parityDrives); - - contentFiles = - ["/var/snapraid.content"] - ++ map (fs: "${fs.mountPoint}/content") (attrValues dataDrives); - - exclude = [ - "*.bak" - "*.unrecoverable" - "/tmp/" - "/lost+found/" - ".AppleDouble" - "._AppleDouble" - ".DS_Store" - ".Thumbs.db" - ".fseventsd" - ".Spotlight-V100" - ".TemporaryItems" - ".Trashes" - ".AppleDB" - ]; - }; -} diff --git a/configurations/nos/modules/subtitles/convert.nix b/configurations/nos/modules/subtitles/convert.nix deleted file mode 100644 index 31f0496e..00000000 --- a/configurations/nos/modules/subtitles/convert.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ - writeShellApplication, - ffmpeg-full, - ... -}: -writeShellApplication { - name = "convert-mkv"; - - runtimeInputs = [ffmpeg-full]; - - text = '' - extension="$1" - file="$2" - - new_file="''${file%."$extension"}.mkv" - - ffmpeg -i "$file" -c copy "$new_file" && - rm "$file" - ''; -} diff --git a/configurations/nos/modules/subtitles/default.nix b/configurations/nos/modules/subtitles/default.nix deleted file mode 100644 index 915fa221..00000000 --- a/configurations/nos/modules/subtitles/default.nix +++ /dev/null @@ -1,54 +0,0 @@ -{ - config, - mainUser, - pkgs, - ... -} @ extraArgs: let - inherit (pkgs.appsPackages) extract-subs; - inherit (pkgs.selfPackages) subscleaner; - - convert-mkv = pkgs.callPackage ./convert.nix {}; - bazarr-bulk = pkgs.callPackage ./syncing.nix ({} // extraArgs); -in { - environment.systemPackages = [ - bazarr-bulk - ]; - - systemd = { - services.manage-subs = { - serviceConfig = { - User = mainUser; - Group = config.users.users.${mainUser}.group; - }; - - path = [ - bazarr-bulk - convert-mkv - extract-subs - subscleaner - ]; - - script = '' - # Make sure every video file is a mkv - find /data/{anime,history,movies,tv} -name '*.mp4' -exec convert-mkv "mp4" "{}" \; - - # Export subs from mkv files - find /data/{anime,history,movies,tv} -name '*.mkv' -printf "%h\0" | - xargs -0 -I '{}' extract-subs '{}' "eng,fre" - - # Remove ads and stuff in subs - find /data/{anime,history,movies,tv} -name '*.srt' | subscleaner - - # Bulk sync everything - # bb movies sync - # bb tv-shows sync - ''; - }; - - timers.manage-subs = { - wantedBy = ["timers.target"]; - partOf = ["manage-subs.service"]; - timerConfig.OnCalendar = ["0:00:00"]; - }; - }; -} diff --git a/configurations/nos/modules/subtitles/syncing.nix b/configurations/nos/modules/subtitles/syncing.nix deleted file mode 100644 index 6e0b8438..00000000 --- a/configurations/nos/modules/subtitles/syncing.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ - bazarr-bulk, - config, - lib, - system, - writeShellApplication, - ... -}: let - inherit (lib) getExe; - - bbPkg = bazarr-bulk.packages.${system}.default; -in - writeShellApplication { - name = "bb"; - text = '' - exec ${getExe bbPkg} --config ${config.sops.secrets.bazarr-bulk.path} "$@" - ''; - } diff --git a/configurations/servivi/default.nix b/configurations/servivi/default.nix deleted file mode 100644 index 3a5f8e14..00000000 --- a/configurations/servivi/default.nix +++ /dev/null @@ -1,103 +0,0 @@ -{ - mainUser, - self, - ... -}: { - # ------------------------------------------------ - # Imports - # ------------------------------------------------ - imports = [ - ./hardware-configuration.nix - - ./modules - - self.nixosModules.base - self.nixosModules.docker - self.nixosModules.kmscon - self.nixosModules.meta - self.nixosModules.server - ]; - - # State Version: DO NOT CHANGE - system.stateVersion = "24.05"; - - # ------------------------------------------------ - # User Settings - # ------------------------------------------------ - users.users = { - ${mainUser} = { - isNormalUser = true; - uid = 1000; - - hashedPassword = "$y$j9T$723InNIdzpJ1.TqxroiXa0$thewApg1l3lpgq.qAwh3k0c/.fu1H1TWRyA8dfjvpP0"; - - extraGroups = [ - "wheel" - "adm" - ]; - }; - - # https://nixos.wiki/wiki/Distributed_build - nixremote = { - isNormalUser = true; - createHome = true; - home = "/var/lib/nixremote"; - homeMode = "500"; - - openssh.authorizedKeys.keys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGOujvC5JLnyjqD1bzl/H0256Gxw/biu7spIHy3YJiDL" - ]; - }; - }; - - networking = { - hostName = "servivi"; - resolvconf.enable = true; - firewall.enable = false; - }; - - time.timeZone = "America/Montreal"; - - # ------------------------------------------------ - # `Self` Modules configuration - # ------------------------------------------------ - meta = { - roleDescription = "Gaming PC in a previous life, it is now used as a build farm and hosts game servers"; - hardwareDescription = "Headless Ryzen 5 3600"; - }; - - roles.base = { - enable = true; - user = mainUser; - }; - - roles.server = { - enable = true; - user = mainUser; - tailscale.enable = true; - sshd.enable = true; - }; - - roles.docker.enable = true; - - services.kmscon.enable = true; - - home-manager.users.${mainUser} = { - imports = [ - self.homeManagerModules.neovim - self.homeManagerModules.shell - ]; - - programs = { - bash = { - enable = true; - promptMainColor = "blue"; - }; - - neovim = { - enable = true; - user = mainUser; - }; - }; - }; -} diff --git a/configurations/servivi/hardware-configuration.nix b/configurations/servivi/hardware-configuration.nix deleted file mode 100644 index 9e5f9e7a..00000000 --- a/configurations/servivi/hardware-configuration.nix +++ /dev/null @@ -1,78 +0,0 @@ -{ - config, - modulesPath, - pkgs, - ... -}: { - nixpkgs.hostPlatform = "x86_64-linux"; - imports = [(modulesPath + "/installer/scan/not-detected.nix")]; - - boot = { - kernelPackages = pkgs.linuxPackages_zen; - - kernelModules = ["kvm-amd"]; - - # Zenpower for ryzen cpu monitoring - extraModulePackages = builtins.attrValues { - inherit - (config.boot.kernelPackages) - zenpower - ; - }; - - blacklistedKernelModules = ["k10temp"]; - - initrd.availableKernelModules = [ - "nvme" - "xhci_pci" - "ahci" - "usb_storage" - "usbhid" - "sd_mod" - ]; - - loader = { - efi.canTouchEfiVariables = true; - timeout = 2; - - systemd-boot = { - enable = true; - consoleMode = "max"; - configurationLimit = 30; - }; - }; - - # Support building binaries for arm64 - binfmt.emulatedSystems = ["aarch64-linux"]; - }; - - fileSystems = { - "/" = { - device = "/dev/disk/by-label/NIXROOT"; - fsType = "btrfs"; - }; - - # sudo btrfs subvolume create /@swap - "/swap" = { - device = "/dev/disk/by-label/NIXROOT"; - fsType = "btrfs"; - options = ["subvol=@swap"]; - }; - - "/boot" = { - device = "/dev/disk/by-label/NIXBOOT"; - fsType = "vfat"; - }; - }; - - swapDevices = [ - { - device = "/swap/swapfile"; - size = 16 * 1024; - } - ]; - - zramSwap.enable = true; - - hardware.cpu.amd.updateMicrocode = config.hardware.enableRedistributableFirmware; -} diff --git a/configurations/servivi/modules/7-days-to-die/default.nix b/configurations/servivi/modules/7-days-to-die/default.nix deleted file mode 100644 index 533f849d..00000000 --- a/configurations/servivi/modules/7-days-to-die/default.nix +++ /dev/null @@ -1,54 +0,0 @@ -{pkgs, ...}: let - gamePath = "/var/lib/steam-servers/7-days-to-die"; - relativeConfig = "serverconfig-7days.xml"; -in { - services.borgbackup.configs."seven-days" = { - paths = ["/var/lib/steam-servers/7-days-to-die"]; - startAt = "02/3:00"; - }; - - nixpkgs.overlays = [ - (final: prev: { - steam = prev.steam.override { - extraPreBwrapCmds = '' - mkdir -p "$HOME/.local/share/sevendays/" - ''; - extraBwrapArgs = [ - ''--bind "${gamePath}/" "$HOME/.local/share/sevendays/"'' - ]; - }; - }) - ]; - - systemd = { - extraConfig = "DefaultLimitNOFILE=10240"; - - services."7-days-to-die" = { - wantedBy = ["multi-user.target"]; - - serviceConfig = { - User = "matt"; - Group = "users"; - }; - - path = builtins.attrValues { - inherit - (pkgs) - steam-run - steamcmd - ; - }; - - script = '' - # Install / Update server - steamcmd +force_install_dir "$HOME/.local/share/sevendays" \ - +login anonymous +app_update 294420 \ - +quit - - # Launch server - exec steam-run sh -c 'cd "$HOME/.local/share/sevendays"; \ - exec ./startserver.sh -configfile=${relativeConfig}' - ''; - }; - }; -} diff --git a/configurations/servivi/modules/binary-cache/default.nix b/configurations/servivi/modules/binary-cache/default.nix deleted file mode 100644 index 6caa61d7..00000000 --- a/configurations/servivi/modules/binary-cache/default.nix +++ /dev/null @@ -1,93 +0,0 @@ -{ - config, - mainUser, - pkgs, - ... -}: let - inherit (builtins) attrValues; - inherit (config.sops) secrets; - - nixFastBuild = pkgs.writeShellApplication { - name = "nixFastBuild"; - - runtimeInputs = attrValues { - inherit - (pkgs) - gnugrep - nix-fast-build - nix-output-monitor - ; - }; - - text = '' - cd "$FLAKE/results" || return - - # Home-assistant sometimes fails some tests when built with everything else - hass="..#nixosConfigurations.homie.config.services.home-assistant.package" - while ! nom build --no-link "$hass"; do - echo "Retrying to build home-assistant" - done - - # Build NixOnDroid activation package - nom build --impure -o ./result-aarch64-linux.nixOnDroidConfigurations_default \ - ..#nixOnDroidConfigurations.default.config.build.activationPackage - - nix-fast-build -f ..#nixFastChecks.all "$@" - ''; - }; -in { - services.nix-serve = { - enable = true; - secretKeyFile = secrets.binary-cache-key.path; - }; - - environment.systemPackages = [pkgs.nix-fast-build nixFastBuild]; - - # Populate cache - systemd = { - services.buildAll = { - serviceConfig = { - Type = "oneshot"; - User = mainUser; - Group = config.users.users.${mainUser}.group; - }; - - path = attrValues { - inherit - (pkgs) - bash - git - nix-fast-build - openssh - ; - - inherit (config.nix) package; - }; - - script = '' - cd /tmp - - if [[ -d ./nix-clone ]]; then - rm -r ./nix-clone - fi - - git clone https://git.nelim.org/matt1432/nixos-configs.git nix-clone - cd nix-clone - - nix-fast-build -f .#nixFastChecks.all - - cd .. - rm -r nix-clone - - # Just to cache mozilla-addons-to-nix - nix run sourcehut:~rycee/mozilla-addons-to-nix -- --help - ''; - }; - - timers.buildAll = { - wantedBy = ["timers.target"]; - partOf = ["buildAll.service"]; - timerConfig.OnCalendar = ["0:00:00"]; - }; - }; -} diff --git a/configurations/servivi/modules/default.nix b/configurations/servivi/modules/default.nix deleted file mode 100644 index 71751ac5..00000000 --- a/configurations/servivi/modules/default.nix +++ /dev/null @@ -1,9 +0,0 @@ -{...}: { - imports = [ - ./7-days-to-die - ./binary-cache - ./minecraft - ./nfs - ./pr-tracker - ]; -} diff --git a/configurations/servivi/modules/minecraft/default.nix b/configurations/servivi/modules/minecraft/default.nix deleted file mode 100644 index 700e8546..00000000 --- a/configurations/servivi/modules/minecraft/default.nix +++ /dev/null @@ -1,113 +0,0 @@ -{ - mainUser, - minix, - pkgs, - ... -}: { - imports = [minix.nixosModules.default]; - - nixpkgs.overlays = [minix.overlays.default]; - - environment.systemPackages = [ - pkgs.curseforge-server-downloader - pkgs.selfPackages.nbted - ]; - - services = { - borgbackup.configs.mc = { - paths = ["/var/lib/minix"]; - startAt = "01/3:00"; - }; - - minix = { - eula = true; - user = mainUser; - - instances = let - jre21 = pkgs.temurin-bin-21; - - defaults = { - spawn-protection = 0; - max-tick-time = 5 * 60 * 1000; - allow-flight = true; - }; - in { - # Modded Ancient Dawn https://www.curseforge.com/minecraft/modpacks/the-ancient-dawn - ad = { - enable = true; - - jvmMaxAllocation = "10G"; - jvmInitialAllocation = "2G"; - jvmPackage = jre21; - - serverConfig = - { - server-port = 25560; - motd = "The Ancient Dawn gaming"; - - extra-options = { - difficulty = "hard"; - enable-command-block = true; - enforce-white-list = true; - white-list = true; - max-players = 10; - view-distance = 12; - simulation-distance = 8; - }; - } - // defaults; - }; - - # Vanilla Survival - sv = { - enable = true; - - jvmMaxAllocation = "10G"; - jvmInitialAllocation = "2G"; - jvmPackage = jre21; - - serverConfig = - { - server-port = 25569; - motd = "1.21 gaming"; - - extra-options = { - difficulty = "hard"; - enable-command-block = true; - enforce-white-list = true; - max-players = 10; - view-distance = 16; - level-seed = "8764718009920"; - }; - } - // defaults; - }; - - # Vanilla Creative - cv = { - enable = true; - - jvmMaxAllocation = "8G"; - jvmInitialAllocation = "2G"; - jvmPackage = jre21; - - serverConfig = - { - server-port = 25566; - motd = "creative mode gaming"; - - extra-options = { - difficulty = "hard"; - enable-command-block = true; - enforce-white-list = true; - gamemode = "creative"; - max-players = 6; - view-distance = 16; - }; - } - // defaults; - }; - }; - }; - }; -} diff --git a/configurations/servivi/modules/nfs/default.nix b/configurations/servivi/modules/nfs/default.nix deleted file mode 100644 index ed2b2ac8..00000000 --- a/configurations/servivi/modules/nfs/default.nix +++ /dev/null @@ -1,26 +0,0 @@ -{lib, ...}: let - inherit (lib) concatMapStringsSep concatStringsSep; -in { - services.nfs.server = { - enable = true; - createMountPoints = true; - - exports = let - mkExport = dir: opts: ips: "/export${dir} ${ - concatMapStringsSep " " - (ip: ip + "(${concatStringsSep "," opts})") - ips - }"; - - mkRootExport = opts: ips: - mkExport "" (opts ++ ["crossmnt" "fsid=0"]) ips; - - allowedIps = ["10.0.0.244" "100.64.0.8" "10.0.0.159" "100.64.0.9"]; - options = ["rw" "no_root_squash" "no_subtree_check"]; - in '' - ${mkRootExport options allowedIps} - ${mkExport "/caddy" options allowedIps} - ${mkExport "/headscale" options allowedIps} - ''; - }; -} diff --git a/configurations/servivi/modules/pr-tracker/default.nix b/configurations/servivi/modules/pr-tracker/default.nix deleted file mode 100644 index 5ea16e6d..00000000 --- a/configurations/servivi/modules/pr-tracker/default.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ - config, - pr-tracker, - ... -}: { - imports = [pr-tracker.nixosModules.default]; - - services.pr-tracker = { - enable = true; - - userAgent = "matt\'s pr-tracker"; - githubApiTokenFile = config.sops.secrets.pr-tracker.path; - }; -} diff --git a/configurations/wim/default.nix b/configurations/wim/default.nix deleted file mode 100644 index 7211a389..00000000 --- a/configurations/wim/default.nix +++ /dev/null @@ -1,128 +0,0 @@ -{ - mainUser, - self, - pkgs, - ... -}: { - # ------------------------------------------------ - # Imports - # ------------------------------------------------ - imports = [ - ./hardware-configuration.nix - - ./modules - - self.nixosModules.base - self.nixosModules.desktop - self.nixosModules.docker - self.nixosModules.kmscon - self.nixosModules.meta - self.nixosModules.plymouth - self.nixosModules.server - ]; - - # State Version: DO NOT CHANGE - system.stateVersion = "23.05"; - - # ------------------------------------------------ - # User Settings - # ------------------------------------------------ - users.users.${mainUser} = { - isNormalUser = true; - uid = 1000; - - hashedPassword = "$y$j9T$ZwnaqAzFjKB/1oJSvypdt.$CtQzgoUWxNutP1DsTBrFHXiTGP6JJp/bMchl1VaADSA"; - - extraGroups = [ - "wheel" - "input" - "uinput" - "adm" - "video" - "libvirtd" - "adbusers" - ]; - }; - - programs.adb.enable = true; - - networking = { - hostName = "wim"; - networkmanager = { - enable = true; - - wifi = { - backend = "wpa_supplicant"; - scanRandMacAddress = false; - }; - }; - firewall.enable = false; - }; - - time.timeZone = "America/Montreal"; - - # ------------------------------------------------ - # `Self` Modules configuration - # ------------------------------------------------ - meta = { - roleDescription = "2-1 Lenovo Laptop that I use for university"; - hardwareDescription = "ThinkPad L13 Yoga Gen 3 (Ryzen 7 PRO 5875U)"; - }; - - roles.base = { - enable = true; - user = mainUser; - }; - - roles.desktop = { - enable = true; - user = mainUser; - - ags.enable = true; - mainMonitor = "eDP-1"; - isLaptop = true; - isTouchscreen = true; - - fontSize = 12.5; - }; - - roles.server = { - enable = true; - user = mainUser; - tailscale.enable = true; - }; - - roles.docker.enable = true; - - boot.plymouth = { - enable = true; - theme = "dracula"; - themePackages = [ - pkgs.scopedPackages.dracula.plymouth - ]; - }; - - services.kmscon.enable = true; - - home-manager.users.${mainUser} = { - imports = [ - self.homeManagerModules.firefox - self.homeManagerModules.neovim - self.homeManagerModules.shell - ]; - - programs = { - bash = { - enable = true; - promptMainColor = "purple"; - }; - - firefox.enableCustomConf = true; - - neovim = { - enable = true; - user = mainUser; - }; - }; - }; -} diff --git a/configurations/wim/hardware-configuration.nix b/configurations/wim/hardware-configuration.nix deleted file mode 100644 index c06ac913..00000000 --- a/configurations/wim/hardware-configuration.nix +++ /dev/null @@ -1,156 +0,0 @@ -{ - config, - modulesPath, - pkgs, - ... -}: { - nixpkgs.hostPlatform = "x86_64-linux"; - imports = [(modulesPath + "/installer/scan/not-detected.nix")]; - - boot = { - kernelPackages = pkgs.linuxPackages_zen; - - kernelParams = [ - "amd_pstate=active" - ]; - kernelModules = ["amdgpu" "kvm-amd" "acpi_call"]; - - extraModulePackages = builtins.attrValues { - inherit - (config.boot.kernelPackages) - acpi_call - zenpower - ; - }; - blacklistedKernelModules = ["k10temp"]; - - initrd = { - availableKernelModules = ["nvme" "xhci_pci" "usb_storage" "sd_mod"]; - - luks.devices."root" = { - device = "/dev/disk/by-uuid/ab82b477-2477-453f-b95f-28e5553ad10d"; - }; - }; - - loader = { - efi.canTouchEfiVariables = true; - - systemd-boot = { - enable = true; - consoleMode = "max"; - configurationLimit = 30; - }; - }; - - # https://github.com/NixOS/nixpkgs/issues/254807#issuecomment-1722351771 - swraid.enable = false; - }; - - fileSystems = { - "/" = { - device = "/dev/disk/by-uuid/6ae4d722-dacf-485a-8d29-b276f540dc91"; - fsType = "btrfs"; - }; - - # sudo btrfs subvolume create /@swap - "/swap" = { - device = "/dev/disk/by-label/NIXROOT"; - fsType = "btrfs"; - options = ["subvol=@swap"]; - }; - - "/boot" = { - device = "/dev/disk/by-label/NIXBOOT"; - fsType = "vfat"; - }; - }; - - swapDevices = [ - { - device = "/swap/swapfile"; - size = 16 * 1024; - } - ]; - - zramSwap.enable = true; - - hardware = { - cpu.amd.updateMicrocode = config.hardware.enableRedistributableFirmware; - - uinput.enable = true; - sensor.iio.enable = true; - - amdgpu.initrd.enable = true; - - graphics = { - enable = true; - enable32Bit = true; - }; - - bluetooth = { - enable = true; - powerOnBoot = false; - }; - }; - - virtualisation = { - libvirtd.enable = true; - waydroid.enable = true; - }; - environment.systemPackages = builtins.attrValues { - inherit - (pkgs) - qemu - powertop - ; - }; - - # enable brightness control - programs.light.enable = true; - - services = { - xserver.videoDrivers = ["modesetting"]; - - # https://www.reddit.com/r/linux/comments/1em8biv/psa_pipewire_has_been_halving_your_battery_life/ - pipewire.wireplumber.extraConfig."10-disable-camera" = { - "wireplumber.profiles" = { - main = { - "monitor.libcamera" = "disabled"; - }; - }; - }; - - tlp = { - enable = true; - settings = { - NMI_WATCHDOG = 0; - - RADEON_DPM_PERF_LEVEL_ON_AC = "auto"; - RADEON_DPM_PERF_LEVEL_ON_BAT = "low"; - RADEON_DPM_STATE_ON_AC = "performance"; - RADEON_DPM_STATE_ON_BAT = "battery"; - - CPU_BOOST_ON_AC = 1; - CPU_BOOST_ON_BAT = 0; - CPU_SCALING_GOVERNOR_ON_AC = "performance"; - CPU_SCALING_GOVERNOR_ON_BAT = "powersave"; - - CPU_ENERGY_PERF_POLICY_ON_AC = "performance"; - CPU_ENERGY_PERF_POLICY_ON_BAT = "power"; - - CPU_MIN_PERF_ON_AC = 0; - CPU_MAX_PERF_ON_AC = 100; - CPU_MIN_PERF_ON_BAT = 0; - CPU_MAX_PERF_ON_BAT = 20; - }; - }; - power-profiles-daemon.enable = false; - - udev.extraRules = - # udev - '' - # give permanent path to keyboard XF86* binds - SUBSYSTEMS=="input", ATTRS{id/product}=="0006", ATTRS{id/vendor}=="0000", SYMLINK += "video-bus" - ''; - }; -} diff --git a/configurations/wim/modules/default.nix b/configurations/wim/modules/default.nix deleted file mode 100644 index d0dc237d..00000000 --- a/configurations/wim/modules/default.nix +++ /dev/null @@ -1,5 +0,0 @@ -{...}: { - imports = [ - ./security - ]; -} diff --git a/configurations/wim/modules/security/default.nix b/configurations/wim/modules/security/default.nix deleted file mode 100644 index 89a9cf69..00000000 --- a/configurations/wim/modules/security/default.nix +++ /dev/null @@ -1,38 +0,0 @@ -{ - lib, - pkgs, - ... -}: let - inherit (lib) mkDefault mkBefore; - inherit (pkgs.selfPackages) pam-fprint-grosshack; - - pam_fprintd_grosshackSo = "${pam-fprint-grosshack}/lib/security/pam_fprintd_grosshack.so"; - - # https://wiki.archlinux.org/title/Fprint#Login_configuration - grosshackConf = '' - # pam-fprint-grosshack - auth sufficient ${pam_fprintd_grosshackSo} timeout=99 - auth sufficient pam_unix.so try_first_pass nullok - ''; -in { - services.fprintd.enable = true; - - # https://www.reddit.com/r/NixOS/comments/z7i83r/fingertip_tip_start_fprintd_at_boot_for_a_quick/ - systemd.services.fprintd = { - wantedBy = ["multi-user.target"]; - serviceConfig.Type = "simple"; - }; - - services.logind.lidSwitch = "lock"; - - security.sudo.extraConfig = '' - Defaults timestamp_timeout=600 - ''; - - # https://stackoverflow.com/a/47041843 - security.pam.services = { - sudo.text = mkDefault (mkBefore grosshackConf); - login.text = mkDefault (mkBefore grosshackConf); - polkit-1.text = mkDefault (mkBefore grosshackConf); - }; -} diff --git a/devShells/README.md b/devShells/README.md deleted file mode 100644 index 59ce05cb..00000000 --- a/devShells/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# DevShells - -This directory contains every derivations for devShells exposed by this flake. - -## List of my devShells found in `self.devShells` - -| Name | Description | -| ---- | ----------- | -| `c-lang` | c-lang shell to be loaded by my Neovim config dynamically. | -| `csharp` | csharp shell to be loaded by my Neovim config dynamically. | -| `flake` | Shell providing some utility scripts concerning the main flake. | -| `json` | json shell to be loaded by my Neovim config dynamically. | -| `lua` | lua shell to be loaded by my Neovim config dynamically. | -| `markdown` | markdown shell to be loaded by my Neovim config dynamically. | -| `netdaemon` | Shell that makes sure we have the right dotnet-sdk version for NetDaemon development. | -| `node` | Shell that provides `bumpNpmDeps`, node and typescript. | -| `rust` | rust shell to be loaded by my Neovim config dynamically. | -| `subtitles-dev` | Shell that provides the dependencies for my subtitle management scripts. | -| `web` | web shell to be loaded by my Neovim config dynamically. | diff --git a/devShells/default.nix b/devShells/default.nix deleted file mode 100644 index 3110e071..00000000 --- a/devShells/default.nix +++ /dev/null @@ -1,42 +0,0 @@ -{ - pkgs, - self, - ... -}: let - inherit (builtins) attrValues; - - neovimShells = import ./neovim-shells {inherit pkgs self;}; - - bumpNpmDeps = pkgs.writeShellApplication { - name = "bumpNpmDeps"; - runtimeInputs = attrValues { - inherit - (pkgs) - prefetch-npm-deps - nodejs_latest - ; - }; - text = '' - # this command might fail but still updates the main lockfile - npm update --package-lock-only || true - - hash="$(prefetch-npm-deps ./package-lock.json)" - echo "$hash" - - if [[ -f ./default.nix ]]; then - sed -i "s#npmDepsHash = .*#npmDepsHash = \"$hash\";#" ./default.nix - fi - ''; - }; -in - { - flake = pkgs.callPackage ./flake {}; - default = self.devShells.${pkgs.system}.flake; - - netdaemon = pkgs.callPackage ./netdaemon {}; - - node = pkgs.callPackage ./node {inherit bumpNpmDeps;}; - - subtitles-dev = pkgs.callPackage ./subtitle-dev {inherit bumpNpmDeps;}; - } - // neovimShells diff --git a/devShells/flake/default.nix b/devShells/flake/default.nix deleted file mode 100644 index bb71d3ea..00000000 --- a/devShells/flake/default.nix +++ /dev/null @@ -1,50 +0,0 @@ -{ - mkShell, - writeShellApplication, - # deps - findutils, - gnused, - nix-output-monitor, - ... -}: -mkShell { - packages = [ - (writeShellApplication { - name = "mkIso"; - - runtimeInputs = [ - nix-output-monitor - ]; - - text = '' - isoConfig="nixosConfigurations.live-image.config.system.build.isoImage" - nom build "$FLAKE#$isoConfig" - ''; - }) - - (writeShellApplication { - name = "fixUidChange"; - - runtimeInputs = [ - findutils - gnused - ]; - - text = '' - GROUP="$1" - OLD_GID="$2" - NEW_GID="$3" - - # Remove generated group entry - sudo sed -i -e "/^$GROUP:/d" /etc/group - - # Change GID on existing files - sudo find / -gid "$OLD_GID" -exec chgrp "$NEW_GID" {} + - ''; - }) - ]; - - meta.description = '' - Shell providing some utility scripts concerning the main flake. - ''; -} diff --git a/devShells/neovim-shells/default.nix b/devShells/neovim-shells/default.nix deleted file mode 100644 index 1791bcb2..00000000 --- a/devShells/neovim-shells/default.nix +++ /dev/null @@ -1,29 +0,0 @@ -{ - pkgs, - self, - ... -}: let - inherit (pkgs.lib) listToAttrs nameValuePair; - mkLangsShells = langs: - listToAttrs (map ( - l: - nameValuePair - l - ((pkgs.callPackage - "${self}/homeManagerModules/neovim/langs/${l}/shell.nix" - ({} // pkgs.selfPackages)) - .overrideAttrs (o: { - meta.description = "${l} shell to be loaded by my Neovim config dynamically."; - })) - ) - langs); -in - mkLangsShells [ - "csharp" - "json" - "lua" - "markdown" - "rust" - "web" - "c-lang" - ] diff --git a/devShells/netdaemon/default.nix b/devShells/netdaemon/default.nix deleted file mode 100644 index 75c41de6..00000000 --- a/devShells/netdaemon/default.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ - mkShell, - dotnetCorePackages, - ... -}: -mkShell { - packages = [ - dotnetCorePackages.sdk_9_0 - ]; - - meta.description = '' - Shell that makes sure we have the right dotnet-sdk version for NetDaemon development. - ''; -} diff --git a/devShells/node/default.nix b/devShells/node/default.nix deleted file mode 100644 index f9a22ec5..00000000 --- a/devShells/node/default.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ - mkShell, - bumpNpmDeps, - nodejs_latest, - typescript, - ... -}: -mkShell { - packages = [ - bumpNpmDeps - nodejs_latest - typescript - ]; - - meta.description = '' - Shell that provides `bumpNpmDeps`, node and typescript. - ''; -} diff --git a/devShells/subtitle-dev/default.nix b/devShells/subtitle-dev/default.nix deleted file mode 100644 index 92678278..00000000 --- a/devShells/subtitle-dev/default.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ - mkShell, - bumpNpmDeps, - ffmpeg-full, - nodejs_latest, - nodePackages, - typescript, - ... -}: -mkShell { - packages = [ - nodejs_latest - typescript - ffmpeg-full - nodePackages.ts-node - - bumpNpmDeps - ]; - - meta.description = '' - Shell that provides the dependencies for my subtitle management scripts. - ''; -} diff --git a/flake.lock b/flake.lock deleted file mode 100644 index 569cd958..00000000 --- a/flake.lock +++ /dev/null @@ -1,2012 +0,0 @@ -{ - "nodes": { - "Kapowarr-src": { - "flake": false, - "locked": { - "lastModified": 1744746361, - "narHash": "sha256-vu0nVGjwQSW5K1WtYeL8ixWQABJG0KgT6erenRK44Zs=", - "owner": "matt1432", - "repo": "Kapowarr", - "rev": "d5a170f80b39b8d3477574211bd775291268a129", - "type": "github" - }, - "original": { - "owner": "matt1432", - "ref": "build-system", - "repo": "Kapowarr", - "type": "github" - } - }, - "ags": { - "inputs": { - "astal": [ - "astal" - ], - "nixpkgs": [ - "nixpkgs" - ], - "systems": [ - "systems" - ] - }, - "locked": { - "lastModified": 1744304930, - "narHash": "sha256-Ud+mprss2S7jEfvkm8S0YYitqCmy8v1WPu+I4/Vgdx8=", - "owner": "matt1432", - "repo": "ags", - "rev": "b9c2222e5b28727840dace04415acb733f76e3bc", - "type": "github" - }, - "original": { - "owner": "matt1432", - "ref": "overlay", - "repo": "ags", - "type": "github" - } - }, - "aquamarine": { - "inputs": { - "hyprutils": [ - "hyprland", - "hyprutils" - ], - "hyprwayland-scanner": [ - "hyprland", - "hyprwayland-scanner" - ], - "nixpkgs": [ - "hyprland", - "nixpkgs" - ], - "systems": [ - "hyprland", - "systems" - ] - }, - "locked": { - "lastModified": 1744289235, - "narHash": "sha256-ZFkHLdimtFzQACsVVyZkZlfYdj4iNy3PkzXfrwmlse8=", - "owner": "hyprwm", - "repo": "aquamarine", - "rev": "c8282f4982b56dfa5e9b9f659809da93f8d37e7a", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "aquamarine", - "type": "github" - } - }, - "astal": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ], - "systems": [ - "systems" - ] - }, - "locked": { - "lastModified": 1744305027, - "narHash": "sha256-6dVuAwHp45Z8iXfTpIxV0D7A9NkWWx37yJ0+nG9AGzs=", - "owner": "matt1432", - "repo": "astal", - "rev": "54a5c81323dc10cad1464af653dd5ca187413882", - "type": "github" - }, - "original": { - "owner": "matt1432", - "ref": "overlay", - "repo": "astal", - "type": "github" - } - }, - "bat-theme-src": { - "flake": false, - "locked": { - "lastModified": 1697829826, - "narHash": "sha256-UyZ3WFfrEEBjtdb//5waVItmjKorkOiNGtu9eeB3lOw=", - "owner": "matt1432", - "repo": "bat", - "rev": "270bce892537311ac92494a2a7663e3ecf772092", - "type": "github" - }, - "original": { - "owner": "matt1432", - "repo": "bat", - "type": "github" - } - }, - "bazarr-bulk": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1727959396, - "narHash": "sha256-T4j2U4AeM+WB4qiSWW2u0nnF1DlZJ5d09qHmdDDZIKE=", - "owner": "mateoradman", - "repo": "bazarr-bulk", - "rev": "c07f52d30edcf95b5fb5090cc4ef04da30b705d6", - "type": "github" - }, - "original": { - "owner": "mateoradman", - "repo": "bazarr-bulk", - "type": "github" - } - }, - "caule-themes-src": { - "flake": false, - "locked": { - "lastModified": 1696467225, - "narHash": "sha256-biNz3ZO3nFfEgchoPu9M3lXiTj9BDxkUaZiCNq0Jy8M=", - "owner": "ricardoquecria", - "repo": "caule-themes-pack-1", - "rev": "0ec8a4b7acf63d8618bcf2fdd968d6256e998acb", - "type": "github" - }, - "original": { - "owner": "ricardoquecria", - "repo": "caule-themes-pack-1", - "type": "github" - } - }, - "curseforge-server-downloader-src": { - "flake": false, - "locked": { - "lastModified": 1691252534, - "narHash": "sha256-GqFj2Rms6BxzWdQTQ9imXKSlov3sDk8Cwwl9lwjIGzM=", - "owner": "Malpiszonekx4", - "repo": "curseforge-server-downloader", - "rev": "91901b2efc64ac54c9135d537e4118e2ac0bd286", - "type": "github" - }, - "original": { - "owner": "Malpiszonekx4", - "repo": "curseforge-server-downloader", - "type": "github" - } - }, - "custom-sidebar-src": { - "flake": false, - "locked": { - "lastModified": 1745155223, - "narHash": "sha256-WnJdrxPJSeg+EmSThH5W+rhSe1osrbAyS76WrXnQwS4=", - "owner": "elchininet", - "repo": "custom-sidebar", - "rev": "a9cfdb768f9bbbc6d31df7bd5d4b02c4e771dfd4", - "type": "github" - }, - "original": { - "owner": "elchininet", - "repo": "custom-sidebar", - "type": "github" - } - }, - "docker-compose": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ], - "systems": [ - "systems" - ] - }, - "locked": { - "lastModified": 1745173751, - "narHash": "sha256-0IBdcx4Ga6hklqoWOSDzIQmu78Vg07BGRBECrtV/UBk=", - "owner": "matt1432", - "repo": "nixos-docker-compose", - "rev": "d99b7ce94eb47ae6a7c560eac4704ff7ccf556a4", - "type": "github" - }, - "original": { - "owner": "matt1432", - "repo": "nixos-docker-compose", - "type": "github" - } - }, - "dracul-ha-src": { - "flake": false, - "locked": { - "lastModified": 1710105609, - "narHash": "sha256-nmGYMwZF8GDWi83BgGG9xEolxnvJK4qS8ya/hFwynSg=", - "owner": "berti24", - "repo": "dracul-ha", - "rev": "ce7a07d8c287762ab2bda6d9132e6ac4aab8e52e", - "type": "github" - }, - "original": { - "owner": "berti24", - "repo": "dracul-ha", - "type": "github" - } - }, - "dracula-plymouth-src": { - "flake": false, - "locked": { - "lastModified": 1720656461, - "narHash": "sha256-pomh/1TJINqt59rle0vnuUKy7KJ3byloM+eQcW00jXo=", - "owner": "matt1432", - "repo": "dracula-plymouth", - "rev": "6f7af346854ea967c3c45316cf5d3aac8491e6ad", - "type": "github" - }, - "original": { - "owner": "matt1432", - "repo": "dracula-plymouth", - "type": "github" - } - }, - "eisa-scripts-src": { - "flake": false, - "locked": { - "lastModified": 1700917419, - "narHash": "sha256-95CAKjBRELX2f7oWSHFWJnI0mikAoxhfUphe9k51Qf4=", - "owner": "Eisa01", - "repo": "mpv-scripts", - "rev": "48d68283cea47ff8e904decc9003b3abc3e2123e", - "type": "github" - }, - "original": { - "owner": "Eisa01", - "repo": "mpv-scripts", - "type": "github" - } - }, - "extended-ollama-conversation-src": { - "flake": false, - "locked": { - "lastModified": 1722207930, - "narHash": "sha256-WF54xX9DF8QJf7kZtsDyCSZRR6ktm6gNpI7WqKSIjZY=", - "owner": "TheNimaj", - "repo": "extended_ollama_conversation", - "rev": "d8ea4190e75b9f8127cd55403e775dd47dd2b79b", - "type": "github" - }, - "original": { - "owner": "TheNimaj", - "repo": "extended_ollama_conversation", - "type": "github" - } - }, - "flake-compat": { - "locked": { - "lastModified": 1733328505, - "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-parts": { - "inputs": { - "nixpkgs-lib": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1743550720, - "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "c621e8422220273271f52058f618c94e405bb0f5", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-root": { - "locked": { - "lastModified": 1723604017, - "narHash": "sha256-rBtQ8gg+Dn4Sx/s+pvjdq3CB2wQNzx9XGFq/JVGCB6k=", - "owner": "srid", - "repo": "flake-root", - "rev": "b759a56851e10cb13f6b8e5698af7b59c44be26e", - "type": "github" - }, - "original": { - "owner": "srid", - "repo": "flake-root", - "type": "github" - } - }, - "flake-utils": { - "inputs": { - "systems": [ - "systems" - ] - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flakegen": { - "inputs": { - "systems": [ - "systems" - ] - }, - "locked": { - "lastModified": 1707120544, - "narHash": "sha256-pXwH9NLXjhjnaz1n7w5m36gVUZ1GVkvtltsLnvVPFJY=", - "owner": "jorsn", - "repo": "flakegen", - "rev": "8b11749b0724700273462a674dd16e5549fe2790", - "type": "github" - }, - "original": { - "owner": "jorsn", - "repo": "flakegen", - "type": "github" - } - }, - "git-theme-src": { - "flake": false, - "locked": { - "lastModified": 1672784534, - "narHash": "sha256-3tKjKn5IHIByj+xgi2AIL1vZANlb0vlYJsPjH6BHGxM=", - "owner": "dracula", - "repo": "git", - "rev": "924d5fc32f7ca15d0dd3a8d2cf1747e81e063c73", - "type": "github" - }, - "original": { - "owner": "dracula", - "repo": "git", - "type": "github" - } - }, - "gitignore": { - "inputs": { - "nixpkgs": [ - "pre-commit-hooks", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "gpu-screen-recorder-src": { - "flake": false, - "locked": { - "lastModified": 1744979475, - "narHash": "sha256-Y19KCSaectrCvXb66ghRwiTFBwBQrBm9xcv1PZUXPuY=", - "ref": "refs/heads/master", - "rev": "a1c09a61af0b1e6cd172dd582c48fec6ebea81c8", - "revCount": 1065, - "type": "git", - "url": "https://repo.dec05eba.com/gpu-screen-recorder" - }, - "original": { - "type": "git", - "url": "https://repo.dec05eba.com/gpu-screen-recorder" - } - }, - "grim-hyprland": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ], - "systems": [ - "systems" - ] - }, - "locked": { - "lastModified": 1741705247, - "narHash": "sha256-4m2QFT8mY6CM3YSebMJhd/kJWaRxTYOS/nvAs2TaIQs=", - "owner": "eriedaberrie", - "repo": "grim-hyprland", - "rev": "4a3d6f5b87b01e92c404b9393b79057b85f58c60", - "type": "github" - }, - "original": { - "owner": "eriedaberrie", - "repo": "grim-hyprland", - "type": "github" - } - }, - "gtk-theme-src": { - "flake": false, - "locked": { - "lastModified": 1745008666, - "narHash": "sha256-jOhG8k3pn+sWFTyYIjtmGyi1k6Eye94s7p6wHHsP1W4=", - "owner": "dracula", - "repo": "gtk", - "rev": "82837065c824158d4242c19ea7dded7645b9a9f1", - "type": "github" - }, - "original": { - "owner": "dracula", - "repo": "gtk", - "type": "github" - } - }, - "home-manager": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1745128386, - "narHash": "sha256-xnNxL9lZC5Ez8AxTgHZZu8pYSNM34+5GD5jGSs8Vq4M=", - "owner": "nix-community", - "repo": "home-manager", - "rev": "f98314bb064cf8f8446c44afbadaaad2505875a7", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "home-manager", - "type": "github" - } - }, - "hyprcursor": { - "inputs": { - "hyprlang": [ - "hyprland", - "hyprlang" - ], - "nixpkgs": [ - "hyprland", - "nixpkgs" - ], - "systems": [ - "hyprland", - "systems" - ] - }, - "locked": { - "lastModified": 1742215578, - "narHash": "sha256-zfs71PXVVPEe56WEyNi2TJQPs0wabU4WAlq0XV7GcdE=", - "owner": "hyprwm", - "repo": "hyprcursor", - "rev": "2fd36421c21aa87e2fe3bee11067540ae612f719", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "hyprcursor", - "type": "github" - } - }, - "hyprgraphics": { - "inputs": { - "hyprutils": [ - "hyprland", - "hyprutils" - ], - "nixpkgs": [ - "hyprland", - "nixpkgs" - ], - "systems": [ - "hyprland", - "systems" - ] - }, - "locked": { - "lastModified": 1743953322, - "narHash": "sha256-prQ5JKopXtzCMX2eT3dXbaVvGmzjMRE2bXStQDdazpM=", - "owner": "hyprwm", - "repo": "hyprgraphics", - "rev": "9d7f2687c84c729afbc3b13f7937655570f2978d", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "hyprgraphics", - "type": "github" - } - }, - "hyprgrass": { - "inputs": { - "hyprland": [ - "hyprland" - ], - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1744930206, - "narHash": "sha256-LlkTIzJhpKPHcetX6VsbmPseGfiBfXcOET7iXZnYWD0=", - "owner": "horriblename", - "repo": "hyprgrass", - "rev": "11eaedb1222a914686d91546cb5765cf8ac32653", - "type": "github" - }, - "original": { - "owner": "horriblename", - "repo": "hyprgrass", - "type": "github" - } - }, - "hyprland": { - "inputs": { - "aquamarine": "aquamarine", - "hyprcursor": "hyprcursor", - "hyprgraphics": "hyprgraphics", - "hyprland-protocols": "hyprland-protocols", - "hyprland-qtutils": "hyprland-qtutils", - "hyprlang": "hyprlang", - "hyprutils": "hyprutils", - "hyprwayland-scanner": "hyprwayland-scanner", - "nixpkgs": [ - "nixpkgs" - ], - "pre-commit-hooks": [ - "pre-commit-hooks" - ], - "systems": [ - "systems" - ], - "xdph": "xdph" - }, - "locked": { - "lastModified": 1745164468, - "narHash": "sha256-JOza51SDXsdHIuIR40wdFTzjZdSIq8RwFpCacDNURgk=", - "owner": "hyprwm", - "repo": "Hyprland", - "rev": "9b4060f09be06250e859b27d6dd3ded5349f5546", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "Hyprland", - "type": "github" - } - }, - "hyprland-plugins": { - "inputs": { - "hyprland": [ - "hyprland" - ], - "nixpkgs": [ - "nixpkgs" - ], - "systems": [ - "systems" - ] - }, - "locked": { - "lastModified": 1745156469, - "narHash": "sha256-3PK27C3XcPoOkEIQnaPi3cdvh7XjIGqkcQ6MeZMvy2E=", - "owner": "hyprwm", - "repo": "hyprland-plugins", - "rev": "faa4e782753ab994333666b7e686b038d420c22f", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "hyprland-plugins", - "type": "github" - } - }, - "hyprland-protocols": { - "inputs": { - "nixpkgs": [ - "hyprland", - "nixpkgs" - ], - "systems": [ - "hyprland", - "systems" - ] - }, - "locked": { - "lastModified": 1743714874, - "narHash": "sha256-yt8F7NhMFCFHUHy/lNjH/pjZyIDFNk52Q4tivQ31WFo=", - "owner": "hyprwm", - "repo": "hyprland-protocols", - "rev": "3a5c2bda1c1a4e55cc1330c782547695a93f05b2", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "hyprland-protocols", - "type": "github" - } - }, - "hyprland-qt-support": { - "inputs": { - "hyprlang": [ - "hyprland", - "hyprland-qtutils", - "hyprlang" - ], - "nixpkgs": [ - "hyprland", - "hyprland-qtutils", - "nixpkgs" - ], - "systems": [ - "hyprland", - "hyprland-qtutils", - "systems" - ] - }, - "locked": { - "lastModified": 1737634706, - "narHash": "sha256-nGCibkfsXz7ARx5R+SnisRtMq21IQIhazp6viBU8I/A=", - "owner": "hyprwm", - "repo": "hyprland-qt-support", - "rev": "8810df502cdee755993cb803eba7b23f189db795", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "hyprland-qt-support", - "type": "github" - } - }, - "hyprland-qtutils": { - "inputs": { - "hyprland-qt-support": "hyprland-qt-support", - "hyprlang": [ - "hyprland", - "hyprlang" - ], - "hyprutils": [ - "hyprland", - "hyprland-qtutils", - "hyprlang", - "hyprutils" - ], - "nixpkgs": [ - "hyprland", - "nixpkgs" - ], - "systems": [ - "hyprland", - "systems" - ] - }, - "locked": { - "lastModified": 1739048983, - "narHash": "sha256-REhTcXq4qs3B3cCDtLlYDz0GZvmsBSh947Ub6pQWGTQ=", - "owner": "hyprwm", - "repo": "hyprland-qtutils", - "rev": "3504a293c8f8db4127cb0f7cfc1a318ffb4316f8", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "hyprland-qtutils", - "type": "github" - } - }, - "hyprlang": { - "inputs": { - "hyprutils": [ - "hyprland", - "hyprutils" - ], - "nixpkgs": [ - "hyprland", - "nixpkgs" - ], - "systems": [ - "hyprland", - "systems" - ] - }, - "locked": { - "lastModified": 1744468525, - "narHash": "sha256-9HySx+EtsbbKlZDlY+naqqOV679VdxP6x6fP3wxDXJk=", - "owner": "hyprwm", - "repo": "hyprlang", - "rev": "f1000c54d266e6e4e9d646df0774fac5b8a652df", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "hyprlang", - "type": "github" - } - }, - "hyprpaper": { - "inputs": { - "hyprgraphics": [ - "hyprland", - "hyprgraphics" - ], - "hyprlang": [ - "hyprland", - "hyprlang" - ], - "hyprutils": [ - "hyprland", - "hyprutils" - ], - "hyprwayland-scanner": [ - "hyprland", - "hyprwayland-scanner" - ], - "nixpkgs": [ - "nixpkgs" - ], - "systems": [ - "systems" - ] - }, - "locked": { - "lastModified": 1742482360, - "narHash": "sha256-B1CsQ7DameEzwdl3mQN0D6E3LA8eJ2XPj4BWufoKjP8=", - "owner": "hyprwm", - "repo": "hyprpaper", - "rev": "05337a4595aa03eedec33f48004e46092917a5ca", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "hyprpaper", - "type": "github" - } - }, - "hyprutils": { - "inputs": { - "nixpkgs": [ - "hyprland", - "nixpkgs" - ], - "systems": [ - "hyprland", - "systems" - ] - }, - "locked": { - "lastModified": 1743950287, - "narHash": "sha256-/6IAEWyb8gC/NKZElxiHChkouiUOrVYNq9YqG0Pzm4Y=", - "owner": "hyprwm", - "repo": "hyprutils", - "rev": "f2dc70e448b994cef627a157ee340135bd68fbc6", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "hyprutils", - "type": "github" - } - }, - "hyprwayland-scanner": { - "inputs": { - "nixpkgs": [ - "hyprland", - "nixpkgs" - ], - "systems": [ - "hyprland", - "systems" - ] - }, - "locked": { - "lastModified": 1739870480, - "narHash": "sha256-SiDN5BGxa/1hAsqhgJsS03C3t2QrLgBT8u+ENJ0Qzwc=", - "owner": "hyprwm", - "repo": "hyprwayland-scanner", - "rev": "206367a08dc5ac4ba7ad31bdca391d098082e64b", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "hyprwayland-scanner", - "type": "github" - } - }, - "jovian": { - "inputs": { - "nix-github-actions": [ - "nix-github-actions" - ], - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1745044299, - "narHash": "sha256-/A/xjRjJY9CGcgOHQ5kTxV7VIJxac86i6NQ5CejMzZc=", - "owner": "Jovian-Experiments", - "repo": "Jovian-NixOS", - "rev": "c7ff1a4578eb11ef84288941aa23e385b6fde635", - "type": "github" - }, - "original": { - "owner": "Jovian-Experiments", - "repo": "Jovian-NixOS", - "type": "github" - } - }, - "kompass": { - "inputs": { - "astal": [ - "astal" - ], - "nixpkgs": [ - "nixpkgs" - ], - "systems": [ - "systems" - ] - }, - "locked": { - "lastModified": 1744618733, - "narHash": "sha256-ngoKLBeBzp2aFsIKg0efEY+xssOJZzUb8cgVayS4IhY=", - "owner": "kotontrion", - "repo": "kompass", - "rev": "c561a4bd8156bee68f336e18d5e4270ab3475e7e", - "type": "github" - }, - "original": { - "owner": "kotontrion", - "repo": "kompass", - "type": "github" - } - }, - "lib-aggregate": { - "inputs": { - "flake-utils": [ - "flake-utils" - ], - "nixpkgs-lib": "nixpkgs-lib" - }, - "locked": { - "lastModified": 1745151208, - "narHash": "sha256-DrWqBD3S5r+wcd9i339uctx8K9rpk4hk5f+vYEwhEhY=", - "owner": "nix-community", - "repo": "lib-aggregate", - "rev": "2b767b1c75e88222eeb3d1735d15da283d0307f9", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "lib-aggregate", - "type": "github" - } - }, - "libratbag-src": { - "flake": false, - "locked": { - "lastModified": 1730154963, - "narHash": "sha256-hI6Xu1RtyJsNga7BaMjQixnyv/V5qkp75FAFcqrvaHE=", - "owner": "libratbag", - "repo": "libratbag", - "rev": "df3c73e95841273908410ed1c563d8ed4ec21edd", - "type": "github" - }, - "original": { - "owner": "libratbag", - "repo": "libratbag", - "type": "github" - } - }, - "material-symbols-src": { - "flake": false, - "locked": { - "lastModified": 1744619244, - "narHash": "sha256-73JYyqWMbLHu6xC9YI12vWGF4lZ8Gbq7YZGIkGyIe9I=", - "owner": "beecho01", - "repo": "material-symbols", - "rev": "1922a4cf6a0b4dff309c3763fb5a784ff0632fb1", - "type": "github" - }, - "original": { - "owner": "beecho01", - "repo": "material-symbols", - "type": "github" - } - }, - "minix": { - "inputs": { - "curseforge-server-downloader-src": "curseforge-server-downloader-src", - "nixpkgs": [ - "nixpkgs" - ], - "systems": [ - "systems" - ] - }, - "locked": { - "lastModified": 1745173850, - "narHash": "sha256-t0evFIgvZ+GNO/YlmZmsiXlH0OIUIrAVDOzisk1eRO8=", - "owner": "matt1432", - "repo": "Minix", - "rev": "a849d6b441852df6a032ff5a775519f06decf6b6", - "type": "github" - }, - "original": { - "owner": "matt1432", - "repo": "Minix", - "type": "github" - } - }, - "modernz-src": { - "flake": false, - "locked": { - "lastModified": 1745028019, - "narHash": "sha256-7d1+7HtuqNrw5n68xorUv6gimbFFHS9nUQeGnIh1zhg=", - "owner": "Samillion", - "repo": "ModernZ", - "rev": "6c49917529ab419a539d04f355a4760279964e57", - "type": "github" - }, - "original": { - "owner": "Samillion", - "repo": "ModernZ", - "type": "github" - } - }, - "mpv-persist-properties-src": { - "flake": false, - "locked": { - "lastModified": 1668485020, - "narHash": "sha256-C2nejhkxAZgfKRl9FrZZqODq2xW6zCbv/sBiqXSAd2k=", - "owner": "d87", - "repo": "mpv-persist-properties", - "rev": "ddb1e6bd7a7d57da9b567ea8dc5227906f416ec6", - "type": "github" - }, - "original": { - "owner": "d87", - "repo": "mpv-persist-properties", - "type": "github" - } - }, - "mpv-pointer-event-src": { - "flake": false, - "locked": { - "lastModified": 1675462432, - "narHash": "sha256-h2E8wiQX2Vh9qyi2VsXzeOE5vnD9Xin5HZ2Wu2LZUOY=", - "owner": "christoph-heinrich", - "repo": "mpv-pointer-event", - "rev": "33c5ede5977817596ace5a9942a8c801ad3b3d28", - "type": "github" - }, - "original": { - "owner": "christoph-heinrich", - "repo": "mpv-pointer-event", - "type": "github" - } - }, - "mpv-touch-gestures-src": { - "flake": false, - "locked": { - "lastModified": 1675464086, - "narHash": "sha256-gmo6sTwN85WS/+wtlylfI22LxyZH48DvXYP5JGCnyU4=", - "owner": "christoph-heinrich", - "repo": "mpv-touch-gestures", - "rev": "f4aa499f038997c1824ff3bfa64ee1d5438d72f2", - "type": "github" - }, - "original": { - "owner": "christoph-heinrich", - "repo": "mpv-touch-gestures", - "type": "github" - } - }, - "netdaemon-src": { - "flake": false, - "locked": { - "lastModified": 1733943150, - "narHash": "sha256-/4hNvihCkS4jOSLWO146EG1wBgkBIdObZg3sLNsWfMM=", - "owner": "net-daemon", - "repo": "integration", - "rev": "2781bf156761a9e3818c710f1240982af1e9f4d9", - "type": "github" - }, - "original": { - "owner": "net-daemon", - "repo": "integration", - "type": "github" - } - }, - "nh": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1743682999, - "narHash": "sha256-bg+aAN8K90r3m/I+xXiXG0gawpbkshwlk93wxUN7KEk=", - "owner": "viperML", - "repo": "nh", - "rev": "9e9a4590b38b62b28f07a1fae973ce7b6ca0687a", - "type": "github" - }, - "original": { - "owner": "viperML", - "repo": "nh", - "type": "github" - } - }, - "nix-develop-nvim-src": { - "flake": false, - "locked": { - "lastModified": 1742049646, - "narHash": "sha256-4v6bxi6v5WE9PTN3eQ9aD/+tIXXPQS+5UIN4VGB3KlI=", - "owner": "matt1432", - "repo": "nix-develop.nvim", - "rev": "66ab22c7618e3b0d548ffd3d23b52b9d60a40160", - "type": "github" - }, - "original": { - "owner": "matt1432", - "repo": "nix-develop.nvim", - "type": "github" - } - }, - "nix-eval-jobs": { - "inputs": { - "flake-parts": [ - "flake-parts" - ], - "nix-github-actions": [ - "nix-github-actions" - ], - "nixpkgs": [ - "nixpkgs" - ], - "treefmt-nix": [ - "treefmt-nix" - ] - }, - "locked": { - "lastModified": 1744371964, - "narHash": "sha256-QuSt8PsB1huFQVXeSASfbXX0r5hmEFLNgYX4dpKewWs=", - "owner": "nix-community", - "repo": "nix-eval-jobs", - "rev": "e376e07271dd405d5427e2dd4a29864fb5347f34", - "type": "github" - }, - "original": { - "owner": "nix-community", - "ref": "v2.28.1", - "repo": "nix-eval-jobs", - "type": "github" - } - }, - "nix-fast-build": { - "inputs": { - "flake-parts": [ - "flake-parts" - ], - "nixpkgs": [ - "nixpkgs" - ], - "treefmt-nix": [ - "treefmt-nix" - ] - }, - "locked": { - "lastModified": 1744962259, - "narHash": "sha256-qiczbsj5lRZc/f0jHxADD0M32hxlPbrhNhWz3zx3MBg=", - "owner": "Mic92", - "repo": "nix-fast-build", - "rev": "188b1f5c400c2349b6c4a1d130dc893d2b29f60c", - "type": "github" - }, - "original": { - "owner": "Mic92", - "repo": "nix-fast-build", - "type": "github" - } - }, - "nix-formatter-pack": { - "inputs": { - "nixpkgs": [ - "nix-on-droid", - "nixpkgs" - ], - "nmd": [ - "nix-on-droid", - "nmd" - ], - "nmt": "nmt" - }, - "locked": { - "lastModified": 1705252799, - "narHash": "sha256-HgSTREh7VoXjGgNDwKQUYcYo13rPkltW7IitHrTPA5c=", - "owner": "Gerschtli", - "repo": "nix-formatter-pack", - "rev": "2de39dedd79aab14c01b9e2934842051a160ffa5", - "type": "github" - }, - "original": { - "owner": "Gerschtli", - "repo": "nix-formatter-pack", - "type": "github" - } - }, - "nix-gaming": { - "inputs": { - "flake-parts": [ - "flake-parts" - ], - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1745114168, - "narHash": "sha256-x+HdFBsfRznwWPpnqXM3yaTVz2CcK5X/ThY6BA3PgcI=", - "owner": "fufexan", - "repo": "nix-gaming", - "rev": "05b70003daf802fd5c0af3903fab5f23fef3c47c", - "type": "github" - }, - "original": { - "owner": "fufexan", - "repo": "nix-gaming", - "type": "github" - } - }, - "nix-github-actions": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1737420293, - "narHash": "sha256-F1G5ifvqTpJq7fdkT34e/Jy9VCyzd5XfJ9TO8fHhJWE=", - "owner": "nix-community", - "repo": "nix-github-actions", - "rev": "f4158fa080ef4503c8f4c820967d946c2af31ec9", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nix-github-actions", - "type": "github" - } - }, - "nix-index-db": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1745120797, - "narHash": "sha256-owQ0VQ+7cSanTVPxaZMWEzI22Q4bGnuvhVjLAJBNQ3E=", - "owner": "Mic92", - "repo": "nix-index-database", - "rev": "69716041f881a2af935021c1182ed5b0cc04d40e", - "type": "github" - }, - "original": { - "owner": "Mic92", - "repo": "nix-index-database", - "type": "github" - } - }, - "nix-on-droid": { - "inputs": { - "home-manager": [ - "home-manager" - ], - "nix-formatter-pack": "nix-formatter-pack", - "nixpkgs": [ - "nixpkgs" - ], - "nixpkgs-docs": "nixpkgs-docs", - "nixpkgs-for-bootstrap": "nixpkgs-for-bootstrap", - "nmd": "nmd" - }, - "locked": { - "lastModified": 1725658585, - "narHash": "sha256-P29z4Gt89n5ps1U7+qmIrj0BuRXGZQSIaOe2+tsPgfw=", - "owner": "nix-community", - "repo": "nix-on-droid", - "rev": "5d88ff2519e4952f8d22472b52c531bb5f1635fc", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nix-on-droid", - "type": "github" - } - }, - "nix-serve-ng": { - "inputs": { - "flake-compat": [ - "flake-compat" - ], - "nixpkgs": [ - "nixpkgs" - ], - "utils": [ - "flake-utils" - ] - }, - "locked": { - "lastModified": 1744237690, - "narHash": "sha256-DEEAPq5whEQv4Pt5JjBWd2YN4B4cr+RXBzp7mTcvZfU=", - "owner": "aristanetworks", - "repo": "nix-serve-ng", - "rev": "101b4a552f3651f5ad8ac8185c6d9c0159e543b9", - "type": "github" - }, - "original": { - "owner": "aristanetworks", - "repo": "nix-serve-ng", - "type": "github" - } - }, - "nixcord": { - "inputs": { - "flake-compat": [ - "flake-compat" - ], - "nixpkgs": [ - "nixpkgs" - ], - "systems": [ - "systems" - ], - "treefmt-nix": [ - "treefmt-nix" - ] - }, - "locked": { - "lastModified": 1745066849, - "narHash": "sha256-euud5ZDWH5U5sam+ZFoJY3UtxPluVUpk3fRSDmIZclk=", - "owner": "kaylorben", - "repo": "nixcord", - "rev": "f4456331e4c89989a7dae4f23a0fd87d81b3e7ad", - "type": "github" - }, - "original": { - "owner": "kaylorben", - "repo": "nixcord", - "type": "github" - } - }, - "nixd": { - "inputs": { - "flake-parts": [ - "flake-parts" - ], - "flake-root": "flake-root", - "nixpkgs": [ - "nixpkgs" - ], - "treefmt-nix": [ - "treefmt-nix" - ] - }, - "locked": { - "lastModified": 1744423808, - "narHash": "sha256-DiivRNDj39u86uUilkmbgbx2c1NqWVQ3fxw6fFfVO14=", - "owner": "nix-community", - "repo": "nixd", - "rev": "3aa27fde1edcf7b126c70a62aad05d120209363c", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nixd", - "type": "github" - } - }, - "nixos-jellyfin": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ], - "systems": [ - "systems" - ] - }, - "locked": { - "lastModified": 1745173825, - "narHash": "sha256-zKaJKlBk9AVHGcWl87cCxh4Z/8Y1ppW36plQ9MTmBRk=", - "owner": "matt1432", - "repo": "nixos-jellyfin", - "rev": "6cf5ea1f14d318273bfab8a0c5caf174b6ae9b7d", - "type": "github" - }, - "original": { - "owner": "matt1432", - "repo": "nixos-jellyfin", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1744932701, - "narHash": "sha256-fusHbZCyv126cyArUwwKrLdCkgVAIaa/fQJYFlCEqiU=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "b024ced1aac25639f8ca8fdfc2f8c4fbd66c48ef", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-docs": { - "locked": { - "lastModified": 1705957679, - "narHash": "sha256-Q8LJaVZGJ9wo33wBafvZSzapYsjOaNjP/pOnSiKVGHY=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "9a333eaa80901efe01df07eade2c16d183761fa3", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "release-23.05", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-for-bootstrap": { - "locked": { - "lastModified": 1720244366, - "narHash": "sha256-WrDV0FPMVd2Sq9hkR5LNHudS3OSMmUrs90JUTN+MXpA=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "49ee0e94463abada1de470c9c07bfc12b36dcf40", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "49ee0e94463abada1de470c9c07bfc12b36dcf40", - "type": "github" - } - }, - "nixpkgs-lib": { - "locked": { - "lastModified": 1745111456, - "narHash": "sha256-6k3oWdGcWOIzh3OQBkIf+HBU+xH5vbZtUhwzXEX4NWI=", - "owner": "nix-community", - "repo": "nixpkgs.lib", - "rev": "eab2ba94b72a8664e0fb92912160151d99db850e", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nixpkgs.lib", - "type": "github" - } - }, - "nmd": { - "inputs": { - "nixpkgs": [ - "nix-on-droid", - "nixpkgs-docs" - ], - "scss-reset": "scss-reset" - }, - "locked": { - "lastModified": 1705050560, - "narHash": "sha256-x3zzcdvhJpodsmdjqB4t5mkVW22V3wqHLOun0KRBzUI=", - "owner": "~rycee", - "repo": "nmd", - "rev": "66d9334933119c36f91a78d565c152a4fdc8d3d3", - "type": "sourcehut" - }, - "original": { - "owner": "~rycee", - "repo": "nmd", - "type": "sourcehut" - } - }, - "nmt": { - "flake": false, - "locked": { - "lastModified": 1648075362, - "narHash": "sha256-u36WgzoA84dMVsGXzml4wZ5ckGgfnvS0ryzo/3zn/Pc=", - "owner": "rycee", - "repo": "nmt", - "rev": "d83601002c99b78c89ea80e5e6ba21addcfe12ae", - "type": "gitlab" - }, - "original": { - "owner": "rycee", - "repo": "nmt", - "type": "gitlab" - } - }, - "nurl": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1726505596, - "narHash": "sha256-WAFqmlsShuQngk6LMFlgz7Oyc41TAQeTa/49phhRizY=", - "owner": "nix-community", - "repo": "nurl", - "rev": "3a3ba7f0d14d92e1266395d826c6e229797d0044", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nurl", - "type": "github" - } - }, - "nvim-theme-src": { - "flake": false, - "locked": { - "lastModified": 1740373692, - "narHash": "sha256-4CVwtc/uig6GcE+orMHxmRFyZOcDiB2huvqNqRMEGXE=", - "owner": "Mofiqul", - "repo": "dracula.nvim", - "rev": "96c9d19ce81b26053055ad6f688277d655b3f7d2", - "type": "github" - }, - "original": { - "owner": "Mofiqul", - "repo": "dracula.nvim", - "type": "github" - } - }, - "pcsd": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ], - "systems": [ - "systems" - ] - }, - "locked": { - "lastModified": 1745177494, - "narHash": "sha256-QPGqmYzTdhr2zUE6vxKade2MqyRo45dJdlqr87pmAVA=", - "owner": "matt1432", - "repo": "nixos-pcsd", - "rev": "a29ceed21b8ce1d88fbbe44ef4e88c4ae6aefbce", - "type": "github" - }, - "original": { - "owner": "matt1432", - "repo": "nixos-pcsd", - "type": "github" - } - }, - "piper-src": { - "flake": false, - "locked": { - "lastModified": 1741362667, - "narHash": "sha256-SgUNP6m/wu+V5F5w4qkMViCV2HvRCCvffbOspJpD9pU=", - "owner": "libratbag", - "repo": "piper", - "rev": "c9f8249b1c1a422d75c74071965ed3aa5cd17dbd", - "type": "github" - }, - "original": { - "owner": "libratbag", - "repo": "piper", - "type": "github" - } - }, - "pokemon-colorscripts-src": { - "flake": false, - "locked": { - "lastModified": 1729309951, - "narHash": "sha256-gKVmpHKt7S2XhSxLDzbIHTjJMoiIk69Fch202FZffqU=", - "owner": "phoneybadger", - "repo": "pokemon-colorscripts", - "rev": "5802ff67520be2ff6117a0abc78a08501f6252ad", - "type": "gitlab" - }, - "original": { - "owner": "phoneybadger", - "repo": "pokemon-colorscripts", - "type": "gitlab" - } - }, - "pr-tracker": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1723582460, - "narHash": "sha256-a3c1S1bcEliqmecn2DppJHG4q6vXnrcHJyQS6VrCwJI=", - "owner": "matt1432", - "repo": "pr-tracker", - "rev": "fbbd75cf31626c6232d94dc3bf6c81f8d9701cb3", - "type": "github" - }, - "original": { - "owner": "matt1432", - "repo": "pr-tracker", - "type": "github" - } - }, - "pre-commit-hooks": { - "inputs": { - "flake-compat": [ - "flake-compat" - ], - "gitignore": "gitignore", - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1742649964, - "narHash": "sha256-DwOTp7nvfi8mRfuL1escHDXabVXFGT1VlPD1JHrtrco=", - "owner": "cachix", - "repo": "git-hooks.nix", - "rev": "dcf5072734cb576d2b0c59b2ac44f5050b5eac82", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "git-hooks.nix", - "type": "github" - } - }, - "root": { - "inputs": { - "Kapowarr-src": "Kapowarr-src", - "ags": "ags", - "astal": "astal", - "bat-theme-src": "bat-theme-src", - "bazarr-bulk": "bazarr-bulk", - "caule-themes-src": "caule-themes-src", - "custom-sidebar-src": "custom-sidebar-src", - "docker-compose": "docker-compose", - "dracul-ha-src": "dracul-ha-src", - "dracula-plymouth-src": "dracula-plymouth-src", - "eisa-scripts-src": "eisa-scripts-src", - "extended-ollama-conversation-src": "extended-ollama-conversation-src", - "flake-compat": "flake-compat", - "flake-parts": "flake-parts", - "flake-utils": "flake-utils", - "flakegen": "flakegen", - "git-theme-src": "git-theme-src", - "gpu-screen-recorder-src": "gpu-screen-recorder-src", - "grim-hyprland": "grim-hyprland", - "gtk-theme-src": "gtk-theme-src", - "home-manager": "home-manager", - "hyprgrass": "hyprgrass", - "hyprland": "hyprland", - "hyprland-plugins": "hyprland-plugins", - "hyprpaper": "hyprpaper", - "jovian": "jovian", - "kompass": "kompass", - "lib-aggregate": "lib-aggregate", - "libratbag-src": "libratbag-src", - "material-symbols-src": "material-symbols-src", - "minix": "minix", - "modernz-src": "modernz-src", - "mpv-persist-properties-src": "mpv-persist-properties-src", - "mpv-pointer-event-src": "mpv-pointer-event-src", - "mpv-touch-gestures-src": "mpv-touch-gestures-src", - "netdaemon-src": "netdaemon-src", - "nh": "nh", - "nix-develop-nvim-src": "nix-develop-nvim-src", - "nix-eval-jobs": "nix-eval-jobs", - "nix-fast-build": "nix-fast-build", - "nix-gaming": "nix-gaming", - "nix-github-actions": "nix-github-actions", - "nix-index-db": "nix-index-db", - "nix-on-droid": "nix-on-droid", - "nix-serve-ng": "nix-serve-ng", - "nixcord": "nixcord", - "nixd": "nixd", - "nixos-jellyfin": "nixos-jellyfin", - "nixpkgs": "nixpkgs", - "nurl": "nurl", - "nvim-theme-src": "nvim-theme-src", - "pcsd": "pcsd", - "piper-src": "piper-src", - "pokemon-colorscripts-src": "pokemon-colorscripts-src", - "pr-tracker": "pr-tracker", - "pre-commit-hooks": "pre-commit-hooks", - "secrets": "secrets", - "sioyek-theme-src": "sioyek-theme-src", - "smartinspect-src": "smartinspect-src", - "sops-nix": "sops-nix", - "spotifyplus-src": "spotifyplus-src", - "spotifywebapi-src": "spotifywebapi-src", - "subscleaner-src": "subscleaner-src", - "systems": "systems", - "treefmt-nix": "treefmt-nix", - "ts-for-gir-src": "ts-for-gir-src", - "tuya-local-src": "tuya-local-src", - "vimplugin-easytables-src": "vimplugin-easytables-src", - "vimplugin-roslyn-nvim-src": "vimplugin-roslyn-nvim-src", - "vimplugin-ts-error-translator-src": "vimplugin-ts-error-translator-src", - "virtualkeyboard-adapter": "virtualkeyboard-adapter", - "wakewords-src": "wakewords-src", - "yamaha-soundbar-src": "yamaha-soundbar-src" - } - }, - "scss-reset": { - "flake": false, - "locked": { - "lastModified": 1631450058, - "narHash": "sha256-muDlZJPtXDIGevSEWkicPP0HQ6VtucbkMNygpGlBEUM=", - "owner": "andreymatin", - "repo": "scss-reset", - "rev": "0cf50e27a4e95e9bb5b1715eedf9c54dee1a5a91", - "type": "github" - }, - "original": { - "owner": "andreymatin", - "repo": "scss-reset", - "type": "github" - } - }, - "secrets": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ], - "sops-nix": [ - "sops-nix" - ] - }, - "locked": { - "lastModified": 1745173940, - "narHash": "sha256-y/4ddSnVOPIIPX64/AufY+I/2l2OtTW1aq8tThXrJME=", - "ref": "refs/heads/main", - "rev": "8dabce58753a5f7e0733285dcbbb8062d3a83ae1", - "revCount": 97, - "type": "git", - "url": "ssh://git@git.nelim.org/matt1432/nixos-secrets" - }, - "original": { - "type": "git", - "url": "ssh://git@git.nelim.org/matt1432/nixos-secrets" - } - }, - "sioyek-theme-src": { - "flake": false, - "locked": { - "lastModified": 1669165291, - "narHash": "sha256-+HzxZA8Bb+cGogK+w4JES4ZFG+ueXEAuLu+0T18fvbc=", - "owner": "dracula", - "repo": "sioyek", - "rev": "b832ab04d880fbe243c0fe9043612be61226426e", - "type": "github" - }, - "original": { - "owner": "dracula", - "repo": "sioyek", - "type": "github" - } - }, - "smartinspect-src": { - "flake": false, - "locked": { - "lastModified": 1743097840, - "narHash": "sha256-O0dbGGQEVVM0ccgilJjRgjeSF7oRJ+J4F+mQG2ga5cA=", - "owner": "thlucas1", - "repo": "SmartInspectPython", - "rev": "20117687c2c9a00569791890dc84a86efd468276", - "type": "github" - }, - "original": { - "owner": "thlucas1", - "repo": "SmartInspectPython", - "type": "github" - } - }, - "sops-nix": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1744669848, - "narHash": "sha256-pXyanHLUzLNd3MX9vsWG+6Z2hTU8niyphWstYEP3/GU=", - "owner": "Mic92", - "repo": "sops-nix", - "rev": "61154300d945f0b147b30d24ddcafa159148026a", - "type": "github" - }, - "original": { - "owner": "Mic92", - "repo": "sops-nix", - "type": "github" - } - }, - "spotifyplus-src": { - "flake": false, - "locked": { - "lastModified": 1744475120, - "narHash": "sha256-nXnAdt4uBeoBY3w+6lVSmanjZ6KnVR3yoIA9vMXXJX8=", - "owner": "thlucas1", - "repo": "homeassistantcomponent_spotifyplus", - "rev": "70fa77270835fb4b998c411b839e72764d3f9e7b", - "type": "github" - }, - "original": { - "owner": "thlucas1", - "repo": "homeassistantcomponent_spotifyplus", - "type": "github" - } - }, - "spotifywebapi-src": { - "flake": false, - "locked": { - "lastModified": 1744034885, - "narHash": "sha256-+vJdkAVCeha6mfSLTvlr6IEcL3TVPNXu4D3Py44IK7g=", - "owner": "thlucas1", - "repo": "SpotifyWebApiPython", - "rev": "4b1c6c1c2e99af7b5c9f7b6227eced649260fe81", - "type": "github" - }, - "original": { - "owner": "thlucas1", - "repo": "SpotifyWebApiPython", - "type": "github" - } - }, - "subscleaner-src": { - "flake": false, - "locked": { - "lastModified": 1743255785, - "narHash": "sha256-/O86aIUwH3kaLPzdH9sM4RnIwJynHwMdlwWzoW40SOI=", - "owner": "rogs", - "repo": "subscleaner", - "rev": "254e6b9c26e7fba2d2f228fb901746ce47c37bb3", - "type": "gitlab" - }, - "original": { - "owner": "rogs", - "repo": "subscleaner", - "type": "gitlab" - } - }, - "systems": { - "locked": { - "lastModified": 1689347949, - "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", - "owner": "nix-systems", - "repo": "default-linux", - "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default-linux", - "type": "github" - } - }, - "treefmt-nix": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1744961264, - "narHash": "sha256-aRmUh0AMwcbdjJHnytg1e5h5ECcaWtIFQa6d9gI85AI=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "8d404a69efe76146368885110f29a2ca3700bee6", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } - }, - "ts-for-gir-src": { - "flake": false, - "locked": { - "lastModified": 1742620702, - "narHash": "sha256-w6dAjvfuDbfsI9Wxg9MSavsHkXAznomrFs5sD2Q/eZg=", - "owner": "gjsify", - "repo": "ts-for-gir", - "rev": "3f4d63534dd03ad8bbcfb57b3308adfafc27f725", - "type": "github" - }, - "original": { - "owner": "gjsify", - "repo": "ts-for-gir", - "type": "github" - } - }, - "tuya-local-src": { - "flake": false, - "locked": { - "lastModified": 1745113967, - "narHash": "sha256-2m5BYQzqRjGpXFbVqKnYHFdBTxzv8vmFYOgZDEZSQvg=", - "owner": "make-all", - "repo": "tuya-local", - "rev": "f059e05c883188b04ca4c14819b4adb09b50b956", - "type": "github" - }, - "original": { - "owner": "make-all", - "repo": "tuya-local", - "type": "github" - } - }, - "vimplugin-easytables-src": { - "flake": false, - "locked": { - "lastModified": 1721939430, - "narHash": "sha256-TtAfbeYKsTLimc9UgcaZ4rsA+TvteWNxjH0w/aRwBA4=", - "owner": "Myzel394", - "repo": "easytables.nvim", - "rev": "ae57fdaad25a5f9ac2773ebdb8782c7bbc7d8932", - "type": "github" - }, - "original": { - "owner": "Myzel394", - "repo": "easytables.nvim", - "type": "github" - } - }, - "vimplugin-roslyn-nvim-src": { - "flake": false, - "locked": { - "lastModified": 1744984504, - "narHash": "sha256-WeY6xU7AJPnCVM274KOlYKZJGlM6MTe2bJTA11OuQoM=", - "owner": "seblj", - "repo": "roslyn.nvim", - "rev": "d06aa2f6c5990dd195eb12e68bc5a96b6fd23bff", - "type": "github" - }, - "original": { - "owner": "seblj", - "repo": "roslyn.nvim", - "type": "github" - } - }, - "vimplugin-ts-error-translator-src": { - "flake": false, - "locked": { - "lastModified": 1731721659, - "narHash": "sha256-fi68jJVNTL2WlTehcl5Q8tijAeu2usjIsWXjcuixkCM=", - "owner": "dmmulroy", - "repo": "ts-error-translator.nvim", - "rev": "47e5ba89f71b9e6c72eaaaaa519dd59bd6897df4", - "type": "github" - }, - "original": { - "owner": "dmmulroy", - "repo": "ts-error-translator.nvim", - "type": "github" - } - }, - "virtualkeyboard-adapter": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1730255698, - "narHash": "sha256-B9mOaEzxKZzJJyIpYPxfrgmU+Z/7XB0r0ETWtVppBEA=", - "owner": "horriblename", - "repo": "fcitx-virtualkeyboard-adapter", - "rev": "35d018b830acb1da934835c431273be352f670bc", - "type": "github" - }, - "original": { - "owner": "horriblename", - "repo": "fcitx-virtualkeyboard-adapter", - "type": "github" - } - }, - "wakewords-src": { - "flake": false, - "locked": { - "lastModified": 1739969293, - "narHash": "sha256-kYiVnuZo/y3YPTc/9R3CQCGbOxiJIP/DsqkAOonvPUM=", - "owner": "fwartner", - "repo": "home-assistant-wakewords-collection", - "rev": "3264b27018c33b0d82279173c7ea8f28f2752866", - "type": "github" - }, - "original": { - "owner": "fwartner", - "repo": "home-assistant-wakewords-collection", - "type": "github" - } - }, - "xdph": { - "inputs": { - "hyprland-protocols": [ - "hyprland", - "hyprland-protocols" - ], - "hyprlang": [ - "hyprland", - "hyprlang" - ], - "hyprutils": [ - "hyprland", - "hyprutils" - ], - "hyprwayland-scanner": [ - "hyprland", - "hyprwayland-scanner" - ], - "nixpkgs": [ - "hyprland", - "nixpkgs" - ], - "systems": [ - "hyprland", - "systems" - ] - }, - "locked": { - "lastModified": 1744644585, - "narHash": "sha256-p0D/e4J6Sv6GSb+9u8OQcVHSE2gPNYB5ygIfGDyEiXQ=", - "owner": "hyprwm", - "repo": "xdg-desktop-portal-hyprland", - "rev": "be6771e754345f18244fb00aae5c9e5ab21ccc26", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "xdg-desktop-portal-hyprland", - "type": "github" - } - }, - "yamaha-soundbar-src": { - "flake": false, - "locked": { - "lastModified": 1738594627, - "narHash": "sha256-YeVZjzE6+hKVJxvg8cfrZx310Lqe1NQwAQZXoIYRuFI=", - "owner": "osk2", - "repo": "yamaha-soundbar", - "rev": "737325097c641d31d94bb928c1f6845080386bf7", - "type": "github" - }, - "original": { - "owner": "osk2", - "repo": "yamaha-soundbar", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/flake.nix b/flake.nix deleted file mode 100644 index 645538b5..00000000 --- a/flake.nix +++ /dev/null @@ -1,523 +0,0 @@ -# Do not modify! This file is generated. -{ - inputs = { - Kapowarr-src = { - flake = false; - owner = "matt1432"; - ref = "build-system"; - repo = "Kapowarr"; - type = "github"; - }; - ags = { - inputs = { - astal.follows = "astal"; - nixpkgs.follows = "nixpkgs"; - systems.follows = "systems"; - }; - owner = "matt1432"; - ref = "overlay"; - repo = "ags"; - type = "github"; - }; - astal = { - inputs = { - nixpkgs.follows = "nixpkgs"; - systems.follows = "systems"; - }; - owner = "matt1432"; - ref = "overlay"; - repo = "astal"; - type = "github"; - }; - bat-theme-src = { - flake = false; - owner = "matt1432"; - repo = "bat"; - type = "github"; - }; - bazarr-bulk = { - inputs.nixpkgs.follows = "nixpkgs"; - owner = "mateoradman"; - repo = "bazarr-bulk"; - type = "github"; - }; - caule-themes-src = { - flake = false; - owner = "ricardoquecria"; - repo = "caule-themes-pack-1"; - type = "github"; - }; - custom-sidebar-src = { - flake = false; - owner = "elchininet"; - repo = "custom-sidebar"; - type = "github"; - }; - docker-compose = { - inputs = { - nixpkgs.follows = "nixpkgs"; - systems.follows = "systems"; - }; - owner = "matt1432"; - repo = "nixos-docker-compose"; - type = "github"; - }; - dracul-ha-src = { - flake = false; - owner = "berti24"; - repo = "dracul-ha"; - type = "github"; - }; - dracula-plymouth-src = { - flake = false; - owner = "matt1432"; - repo = "dracula-plymouth"; - type = "github"; - }; - eisa-scripts-src = { - flake = false; - owner = "Eisa01"; - repo = "mpv-scripts"; - type = "github"; - }; - extended-ollama-conversation-src = { - flake = false; - owner = "TheNimaj"; - repo = "extended_ollama_conversation"; - type = "github"; - }; - flake-compat = { - owner = "edolstra"; - repo = "flake-compat"; - type = "github"; - }; - flake-parts = { - inputs.nixpkgs-lib.follows = "nixpkgs"; - owner = "hercules-ci"; - repo = "flake-parts"; - type = "github"; - }; - flake-utils = { - inputs.systems.follows = "systems"; - owner = "numtide"; - repo = "flake-utils"; - type = "github"; - }; - flakegen = { - inputs.systems.follows = "systems"; - url = "github:jorsn/flakegen"; - }; - git-theme-src = { - flake = false; - owner = "dracula"; - repo = "git"; - type = "github"; - }; - gpu-screen-recorder-src = { - flake = false; - type = "git"; - url = "https://repo.dec05eba.com/gpu-screen-recorder"; - }; - grim-hyprland = { - inputs = { - nixpkgs.follows = "nixpkgs"; - systems.follows = "systems"; - }; - owner = "eriedaberrie"; - repo = "grim-hyprland"; - type = "github"; - }; - gtk-theme-src = { - flake = false; - owner = "dracula"; - repo = "gtk"; - type = "github"; - }; - home-manager = { - inputs.nixpkgs.follows = "nixpkgs"; - owner = "nix-community"; - repo = "home-manager"; - type = "github"; - }; - hyprgrass = { - inputs = { - hyprland.follows = "hyprland"; - nixpkgs.follows = "nixpkgs"; - }; - owner = "horriblename"; - repo = "hyprgrass"; - type = "github"; - }; - hyprland = { - inputs = { - nixpkgs.follows = "nixpkgs"; - pre-commit-hooks.follows = "pre-commit-hooks"; - systems.follows = "systems"; - }; - owner = "hyprwm"; - repo = "Hyprland"; - type = "github"; - }; - hyprland-plugins = { - inputs = { - hyprland.follows = "hyprland"; - nixpkgs.follows = "nixpkgs"; - systems.follows = "systems"; - }; - owner = "hyprwm"; - repo = "hyprland-plugins"; - type = "github"; - }; - hyprpaper = { - inputs = { - hyprgraphics.follows = "hyprland/hyprgraphics"; - hyprlang.follows = "hyprland/hyprlang"; - hyprutils.follows = "hyprland/hyprutils"; - hyprwayland-scanner.follows = "hyprland/hyprwayland-scanner"; - nixpkgs.follows = "nixpkgs"; - systems.follows = "systems"; - }; - owner = "hyprwm"; - repo = "hyprpaper"; - type = "github"; - }; - jovian = { - inputs = { - nix-github-actions.follows = "nix-github-actions"; - nixpkgs.follows = "nixpkgs"; - }; - owner = "Jovian-Experiments"; - repo = "Jovian-NixOS"; - type = "github"; - }; - kompass = { - inputs = { - astal.follows = "astal"; - nixpkgs.follows = "nixpkgs"; - systems.follows = "systems"; - }; - owner = "kotontrion"; - repo = "kompass"; - type = "github"; - }; - lib-aggregate = { - inputs.flake-utils.follows = "flake-utils"; - owner = "nix-community"; - repo = "lib-aggregate"; - type = "github"; - }; - libratbag-src = { - flake = false; - owner = "libratbag"; - repo = "libratbag"; - type = "github"; - }; - material-symbols-src = { - flake = false; - owner = "beecho01"; - repo = "material-symbols"; - type = "github"; - }; - minix = { - inputs = { - nixpkgs.follows = "nixpkgs"; - systems.follows = "systems"; - }; - owner = "matt1432"; - repo = "Minix"; - type = "github"; - }; - modernz-src = { - flake = false; - owner = "Samillion"; - repo = "ModernZ"; - type = "github"; - }; - mpv-persist-properties-src = { - flake = false; - owner = "d87"; - repo = "mpv-persist-properties"; - type = "github"; - }; - mpv-pointer-event-src = { - flake = false; - owner = "christoph-heinrich"; - repo = "mpv-pointer-event"; - type = "github"; - }; - mpv-touch-gestures-src = { - flake = false; - owner = "christoph-heinrich"; - repo = "mpv-touch-gestures"; - type = "github"; - }; - netdaemon-src = { - flake = false; - owner = "net-daemon"; - repo = "integration"; - type = "github"; - }; - nh = { - inputs.nixpkgs.follows = "nixpkgs"; - owner = "viperML"; - repo = "nh"; - type = "github"; - }; - nix-develop-nvim-src = { - flake = false; - owner = "matt1432"; - repo = "nix-develop.nvim"; - type = "github"; - }; - nix-eval-jobs = { - inputs = { - flake-parts.follows = "flake-parts"; - nix-github-actions.follows = "nix-github-actions"; - nixpkgs.follows = "nixpkgs"; - treefmt-nix.follows = "treefmt-nix"; - }; - owner = "nix-community"; - ref = "v2.28.1"; - repo = "nix-eval-jobs"; - type = "github"; - }; - nix-fast-build = { - inputs = { - flake-parts.follows = "flake-parts"; - nixpkgs.follows = "nixpkgs"; - treefmt-nix.follows = "treefmt-nix"; - }; - owner = "Mic92"; - repo = "nix-fast-build"; - type = "github"; - }; - nix-gaming = { - inputs = { - flake-parts.follows = "flake-parts"; - nixpkgs.follows = "nixpkgs"; - }; - owner = "fufexan"; - repo = "nix-gaming"; - type = "github"; - }; - nix-github-actions = { - inputs.nixpkgs.follows = "nixpkgs"; - owner = "nix-community"; - repo = "nix-github-actions"; - type = "github"; - }; - nix-index-db = { - inputs.nixpkgs.follows = "nixpkgs"; - owner = "Mic92"; - repo = "nix-index-database"; - type = "github"; - }; - nix-on-droid = { - inputs = { - home-manager.follows = "home-manager"; - nixpkgs.follows = "nixpkgs"; - }; - owner = "nix-community"; - repo = "nix-on-droid"; - type = "github"; - }; - nix-serve-ng = { - inputs = { - flake-compat.follows = "flake-compat"; - nixpkgs.follows = "nixpkgs"; - utils.follows = "flake-utils"; - }; - owner = "aristanetworks"; - repo = "nix-serve-ng"; - type = "github"; - }; - nixcord = { - inputs = { - flake-compat.follows = "flake-compat"; - nixpkgs.follows = "nixpkgs"; - systems.follows = "systems"; - treefmt-nix.follows = "treefmt-nix"; - }; - owner = "kaylorben"; - repo = "nixcord"; - type = "github"; - }; - nixd = { - inputs = { - flake-parts.follows = "flake-parts"; - nixpkgs.follows = "nixpkgs"; - treefmt-nix.follows = "treefmt-nix"; - }; - owner = "nix-community"; - repo = "nixd"; - type = "github"; - }; - nixos-jellyfin = { - inputs = { - nixpkgs.follows = "nixpkgs"; - systems.follows = "systems"; - }; - owner = "matt1432"; - repo = "nixos-jellyfin"; - type = "github"; - }; - nixpkgs = { - owner = "NixOS"; - ref = "nixos-unstable"; - repo = "nixpkgs"; - type = "github"; - }; - nurl = { - inputs.nixpkgs.follows = "nixpkgs"; - owner = "nix-community"; - repo = "nurl"; - type = "github"; - }; - nvim-theme-src = { - flake = false; - owner = "Mofiqul"; - repo = "dracula.nvim"; - type = "github"; - }; - pcsd = { - inputs = { - nixpkgs.follows = "nixpkgs"; - systems.follows = "systems"; - }; - owner = "matt1432"; - repo = "nixos-pcsd"; - type = "github"; - }; - piper-src = { - flake = false; - owner = "libratbag"; - repo = "piper"; - type = "github"; - }; - pokemon-colorscripts-src = { - flake = false; - owner = "phoneybadger"; - repo = "pokemon-colorscripts"; - type = "gitlab"; - }; - pr-tracker = { - inputs.nixpkgs.follows = "nixpkgs"; - owner = "matt1432"; - repo = "pr-tracker"; - type = "github"; - }; - pre-commit-hooks = { - inputs = { - flake-compat.follows = "flake-compat"; - nixpkgs.follows = "nixpkgs"; - }; - owner = "cachix"; - repo = "git-hooks.nix"; - type = "github"; - }; - secrets = { - inputs = { - nixpkgs.follows = "nixpkgs"; - sops-nix.follows = "sops-nix"; - }; - type = "git"; - url = "ssh://git@git.nelim.org/matt1432/nixos-secrets"; - }; - sioyek-theme-src = { - flake = false; - owner = "dracula"; - repo = "sioyek"; - type = "github"; - }; - smartinspect-src = { - flake = false; - owner = "thlucas1"; - repo = "SmartInspectPython"; - type = "github"; - }; - sops-nix = { - inputs.nixpkgs.follows = "nixpkgs"; - owner = "Mic92"; - repo = "sops-nix"; - type = "github"; - }; - spotifyplus-src = { - flake = false; - owner = "thlucas1"; - repo = "homeassistantcomponent_spotifyplus"; - type = "github"; - }; - spotifywebapi-src = { - flake = false; - owner = "thlucas1"; - repo = "SpotifyWebApiPython"; - type = "github"; - }; - subscleaner-src = { - flake = false; - owner = "rogs"; - repo = "subscleaner"; - type = "gitlab"; - }; - systems = { - owner = "nix-systems"; - repo = "default-linux"; - type = "github"; - }; - treefmt-nix = { - inputs.nixpkgs.follows = "nixpkgs"; - owner = "numtide"; - repo = "treefmt-nix"; - type = "github"; - }; - ts-for-gir-src = { - flake = false; - owner = "gjsify"; - repo = "ts-for-gir"; - type = "github"; - }; - tuya-local-src = { - flake = false; - owner = "make-all"; - repo = "tuya-local"; - type = "github"; - }; - vimplugin-easytables-src = { - flake = false; - owner = "Myzel394"; - repo = "easytables.nvim"; - type = "github"; - }; - vimplugin-roslyn-nvim-src = { - flake = false; - owner = "seblj"; - repo = "roslyn.nvim"; - type = "github"; - }; - vimplugin-ts-error-translator-src = { - flake = false; - owner = "dmmulroy"; - repo = "ts-error-translator.nvim"; - type = "github"; - }; - virtualkeyboard-adapter = { - inputs.nixpkgs.follows = "nixpkgs"; - owner = "horriblename"; - repo = "fcitx-virtualkeyboard-adapter"; - type = "github"; - }; - wakewords-src = { - flake = false; - owner = "fwartner"; - repo = "home-assistant-wakewords-collection"; - type = "github"; - }; - yamaha-soundbar-src = { - flake = false; - owner = "osk2"; - repo = "yamaha-soundbar"; - type = "github"; - }; - }; - outputs = inputs: inputs.flakegen ./_outputs.nix inputs; -} diff --git a/homeManagerModules/README.md b/homeManagerModules/README.md deleted file mode 100644 index cb66c7f0..00000000 --- a/homeManagerModules/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# HomeManagerModules - -This directory contains every home-manager modules exposed by this flake. - -## List of my home-manager modules found in `self.homeManagerModules` - -| Name | Description | -| ---- | ----------- | -| `firefox` | Uses the home-manager firefox module to declare my custom configuration which includes my list of extensions, my adapted [firefox-gx](https://github.com/Godiesc/firefox-gx) theme and other settings. | -| `neovim` | Uses the home-manager neovim module to declare my custom configuration and expands it with toggles for certain LSPs. This configuration loads corresponding devShells of the current language from `self.devShells` dynamically to support various LSPs. | -| `shell` | Extends the bash home-manager options to set some bash options, aliases themes that follow Dracula Theme and settings for CLI programs, such as starship, trash-d, nix-comma, nix-direnv, git, etc. | diff --git a/homeManagerModules/default.nix b/homeManagerModules/default.nix deleted file mode 100644 index e938c018..00000000 --- a/homeManagerModules/default.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ - self ? {}, - description ? false, -}: let - module = mod: desc: - if description - then desc - else mod; -in { - firefox = - module - (import ./firefox self) - '' - Uses the home-manager firefox module to declare my custom configuration - which includes my list of extensions, my adapted [firefox-gx](https://github.com/Godiesc/firefox-gx) - theme and other settings. - ''; - - neovim = - module - (import ./neovim self) - '' - Uses the home-manager neovim module to declare my custom configuration - and expands it with toggles for certain LSPs. This configuration loads - corresponding devShells of the current language from `self.devShells` - dynamically to support various LSPs. - ''; - - shell = - module - (import ./shell self) - '' - Extends the bash home-manager options to set some bash options, aliases - themes that follow Dracula Theme and settings for CLI programs, such as - starship, trash-d, nix-comma, nix-direnv, git, etc. - ''; -} diff --git a/homeManagerModules/firefox/custom-css/default.nix b/homeManagerModules/firefox/custom-css/default.nix deleted file mode 100644 index 63b79799..00000000 --- a/homeManagerModules/firefox/custom-css/default.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ - stdenv, - dart-sass, - ... -}: -stdenv.mkDerivation { - pname = "custom-css"; - version = "0.0.0"; - - src = ./.; - - nativeBuildInputs = [dart-sass]; - - buildPhase = '' - sass ./style.scss ./style.css - ''; - - installPhase = '' - cp -rf ./style.css $out - ''; -} diff --git a/homeManagerModules/firefox/custom-css/style.scss b/homeManagerModules/firefox/custom-css/style.scss deleted file mode 100644 index 5e78fde9..00000000 --- a/homeManagerModules/firefox/custom-css/style.scss +++ /dev/null @@ -1,6 +0,0 @@ -// Hide unused menu rows -#appMenu-mainView .browser-toolbar>* #alltabs-button, -#appMenu-fxa-status2, -#appMenu-fxa-separator { - display: none !important; -} diff --git a/homeManagerModules/firefox/default.nix b/homeManagerModules/firefox/default.nix deleted file mode 100644 index 0724601a..00000000 --- a/homeManagerModules/firefox/default.nix +++ /dev/null @@ -1,277 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (pkgs.scopedPackages) firefoxAddons; - - inherit (lib) attrsToList attrValues mkIf mkOption singleton types; - - mainProfile = "dev-edition-default"; - cfg = config.programs.firefox; - - custom-css = pkgs.callPackage ./custom-css {}; -in { - options.programs.firefox.enableCustomConf = mkOption { - type = types.bool; - default = false; - }; - - config = mkIf cfg.enableCustomConf { - programs.firefox = { - enable = true; - - package = pkgs.firefox-devedition; - - profiles.${mainProfile} = { - isDefault = true; - id = 0; - - userChrome = '' - @import url("file://${custom-css}"); - ''; - - settings = { - # Developer Edition Settings - "xpinstall.signatures.required" = false; - "extensions.experiments.enabled" = true; - - # Use the normal file picker - "widget.use-xdg-desktop-portal.file-picker" = 0; - - # Firefox-gx user.js - /* - Default rules - */ - "toolkit.legacyUserProfileCustomizations.stylesheets" = true; - "svg.context-properties.content.enabled" = true; - "layout.css.color-mix.enabled" = true; - "browser.tabs.delayHidingAudioPlayingIconMS" = 0; - "layout.css.backdrop-filter.enabled" = true; - "browser.newtabpage.activity-stream.improvesearch.handoffToAwesomebar" = false; - "browser.newtabpage.activity-stream.newtabWallpapers.enabled" = true; - "browser.newtabpage.activity-stream.newtabWallpapers.v2.enabled" = true; - - /* - To activate container tabs without any extension - */ - "privacy.userContext.enabled" = true; - "privacy.userContext.ui.enabled" = true; - "privacy.userContext.longPressBehavior" = 2; - - # Open previous windows and tabs - "browser.startup.page" = 3; - - # Prefs - "apz.overscroll.enabled" = false; - "layout.css.devPixelsPerPx" = 1.12; - "browser.search.widget.inNavBar" = true; - "browser.toolbars.bookmarks.visibility" = "always"; - "browser.toolbars.bookmarks.showInPrivateBrowsing" = true; - "ui.key.menuAccessKey" = 0; - - # remove telemetry - "datareporting.policy.dataSubmissionEnabled" = false; - "datareporting.healthreport.uploadEnabled" = false; - "datareporting.healthreport.infoURL" = ""; - "dom.security.https_only_mode" = true; - - # remove first run and warning stuff - "datareporting.policy.firstRunURL" = ""; - "extensions.autoDisableScopes" = 0; - "browser.aboutwelcome.enabled" = false; - "browser.aboutConfig.showWarning" = false; - - # Disable firefox autofill - "signon.rememberSignons" = false; - "extensions.formautofill.addresses.enabled" = false; - "extensions.formautofill.creditCards.enabled" = false; - - # remove new tab stuff - "extensions.pocket.enabled" = false; - "services.sync.prefs.sync.browser.newtabpage.activity-stream.feeds.section.topstories" = false; - "browser.newtabpage.activity-stream.section.highlights.includePocket" = false; - "browser.newtabpage.activity-stream.feeds.system.topstories" = false; - "browser.newtabpage.activity-stream.feeds.section.topstories" = false; - "browser.newtabpage.activity-stream.feeds.topsites" = false; - "browser.newtabpage.activity-stream.asrouter.userprefs.cfr.addons" = false; - "browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features" = false; - }; - - search = { - default = "searxng"; - force = true; - - engines = { - searxng = { - name = "SearXNG"; - urls = singleton { - template = "https://search.nelim.org/search"; - params = attrsToList { - "q" = "{searchTerms}"; - }; - }; - icon = "https://search.nelim.org/favicon.ico"; - definedAliases = ["@s"]; - }; - - code = { - name = "Github Search Code"; - urls = singleton { - template = "https://github.com/search"; - params = attrsToList { - "type" = "code"; - "q" = "NOT is:fork {searchTerms}"; - }; - }; - icon = "https://icon.horse/icon/github.com"; - definedAliases = ["@gs"]; - }; - - nixcode = { - name = "Github Nix Code"; - urls = singleton { - template = "https://github.com/search"; - params = attrsToList { - "type" = "code"; - "q" = "lang:Nix NOT is:fork {searchTerms}"; - }; - }; - icon = "https://icon.horse/icon/github.com"; - definedAliases = ["@gn"]; - }; - - nixpkgs = { - name = "Nixpkgs"; - urls = singleton { - template = "https://github.com/search"; - params = attrsToList { - "type" = "code"; - "q" = "repo:NixOS/nixpkgs {searchTerms}"; - }; - }; - icon = "https://icon.horse/icon/github.com"; - definedAliases = ["@pkgs"]; - }; - - nixwiki = { - name = "NixOS Wiki"; - urls = singleton { - template = "https://wiki.nixos.org/w/index.php"; - params = attrsToList { - "search" = "{searchTerms}"; - }; - }; - icon = "https://wiki.nixos.org/favicon.ico"; - definedAliases = ["@nw"]; - }; - - mynixos = { - name = "MyNixos"; - urls = singleton { - template = "https://mynixos.com/search"; - params = attrsToList { - "q" = "{searchTerms}"; - }; - }; - icon = "https://mynixos.com/favicon.ico"; - definedAliases = ["@mn"]; - }; - - noogle = { - name = "Noogle"; - urls = singleton { - template = "https://noogle.dev/q"; - params = attrsToList { - "term" = "{searchTerms}"; - }; - }; - icon = "https://noogle.dev/favicon.ico"; - definedAliases = ["@ng"]; - }; - - extensions = { - name = "Firefox Add-ons"; - urls = singleton { - template = "https://addons.mozilla.org/en-US/firefox/search"; - params = attrsToList { - "q" = "{searchTerms}"; - }; - }; - icon = "https://addons.mozilla.org/favicon.ico"; - definedAliases = ["@fa"]; - }; - - protondb = { - name = "ProtonDB"; - urls = singleton { - template = "https://www.protondb.com/search"; - params = attrsToList { - "q" = "{searchTerms}"; - }; - }; - icon = "https://www.protondb.com/favicon.ico"; - definedAliases = ["@pdb"]; - }; - - youtube = { - name = "YouTube"; - urls = singleton { - template = "https://www.youtube.com/results"; - params = attrsToList { - "search_query" = "{searchTerms}"; - }; - }; - icon = "https://www.youtube.com/favicon.ico"; - definedAliases = ["@yt" "@youtube"]; - }; - - bing.metaData.hidden = true; - google.metaData.hidden = true; - ebay.metaData.hidden = true; - }; - - order = [ - "searxng" - "ddg" - "mynixos" - "nixwiki" - "code" - "nixcode" - "nixpkgs" - "noogle" - "wikipedia" - "youtube" - "extensions" - "protondb" - ]; - }; - - extensions.packages = attrValues { - inherit - (firefoxAddons) - auto-refresh-page - bitwarden - darkreader - floccus - google-container - image-search-options - istilldontcareaboutcookies - return-youtube-dislikes - sponsorblock - sound-volume - stylus - tampermonkey - ttv-lol-pro - ublock-origin - undoclosetabbutton - ; - }; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/firefox/non-declarative-conf/ffz-settings (2025-3-22).json b/homeManagerModules/firefox/non-declarative-conf/ffz-settings (2025-3-22).json deleted file mode 100644 index 8239394c..00000000 --- a/homeManagerModules/firefox/non-declarative-conf/ffz-settings (2025-3-22).json +++ /dev/null @@ -1 +0,0 @@ -{"version":2,"type":"full","values":{"p:0:chat.lines.borders":0,"p:0:layout.portrait-min-chat":true,"p:0:channel.show-celebrations":false,"p:0:chat.banners.drops":false,"p:0:layout.side-nav.rerun-style":0,"p:0:layout.side-nav.show-friends":0,"p:0:chat.emote-menu.reduced-padding":true,"p:0:channel.auto-click-chat":true,"p:0:chat.emote-menu.icon":true,"p:0:layout.side-nav.hide-offline":true,"p:0:addon.seventv_emotes.animated_avatars":false,"p:0:layout.hide-discover-luna":true,"p:0:chat.emote-menu.clear-search":true,"p:0:chat.points.auto-rewards":true,"p:0:metadata.player-stats":true,"addons.enabled":["7tv-emotes","ffzap-core","ffzap-bttv","first-message-highlighter","pronouns"],"p:0:layout.portrait":true,"p:0:sub-button.prime-notice":false,"p:0:chat.emote-menu.show-quick-nav":true,"p:0:chat.lines.alternate":true,"p:0:chat.rich.all-links":false,"p:0:chat.bits.show":false,"cfg-seen":["i18n.debug.capture","i18n.debug.transform","i18n.locale","i18n.format.date","i18n.format.time","i18n.format.datetime","data.use-staging","chat.update-when-loaded","chat.click-emotes","chat.sub-emotes","chat.emote-dialogs","chat.scrollback-length","chat.delay","chat.pin-resubs","auth.mode","socket.use-cluster","pubsub.enabled","chat.badges.media-queries","chat.badges.version","chat.badges.fix-colors","chat.badges.custom-mod","chat.badges.custom-vip","chat.badges.style","chat.badges.clickable","chat.badges.hidden","chat.emotes.source-priorities","chat.emotes.enabled","chat.emotes.2x","chat.emotes.limit-size","chat.emotes.allow-gigantify","chat.fix-bad-emotes","chat.emotes.animated","chat.effects.enable","chat.effects.FlipX","chat.effects.FlipY","chat.effects.ShrinkX","chat.effects.GrowX","chat.effects.Slide","chat.effects.Appear","chat.effects.Leave","chat.effects.Rotate","chat.effects.Rainbow","chat.effects.HyperRed","chat.effects.Shake","chat.effects.Photocopy","chat.effects.Jam","chat.effects.Bounce","chat.emoji.replace-joiner","chat.emoji.style","chat.actions.size","chat.actions.hover","chat.actions.hover-size","chat.actions.reasons","chat.actions.inline","chat.actions.user-context","chat.actions.room","chat.actions.room-above","chat.actions.rules-as-reasons","debug.link-resolver.source","debug.link-resolver.test","chat.timestamp-size","chat.font-size","chat.font-family","chat.width","chat.name-format","chat.lines.emote-alignment","chat.me-style","chat.timestamp-format","chat.extra-timestamps","chat.lines.alternate","chat.lines.padding","chat.lines.borders","chat.rich.enabled","chat.rich.want-mid","chat.rich.hide-tokens","chat.rich.all-links","chat.rich.minimum-level","chat.filtering.debug","chat.filtering.click-to-reveal","chat.filtering.process-own","chat.filtering.deleted-style","chat.filtering.display-deleted","chat.filtering.display-mod-action","chat.filtering.ignore-clear","chat.filtering.remove-deleted","chat.automod.delete-messages","chat.automod.remove-messages","chat.automod.run-as-mod","chat.filtering.hidden-tokens","chat.filtering.pad-bottom","chat.filtering.highlight-basic-users","chat.filtering.highlight-basic-users-blocked","chat.filtering.highlight-basic-badges","chat.filtering.highlight-basic-badges-blocked","chat.filtering.highlight-basic-terms","chat.filtering.highlight-tokens","chat.filtering.all-mentions","chat.filtering.color-mentions","chat.filtering.bold-mentions","chat.filtering.mention-priority","chat.filtering.mention-color","chat.filtering.highlight-mentions","chat.filtering.show-reasons","chat.filtering.highlight-basic-blocked","chat.filtering.clickable-mentions","tooltip.images","tooltip.badge-images","tooltip.emote-sources","tooltip.emote-images","tooltip.emote-images.animated","tooltip.rich-links","tooltip.link-interaction","tooltip.link-images","tooltip.link-nsfw-images","chat.adjustment-mode","chat.adjustment-contrast","chat.bits.stack","chat.bits.animated","chat.bits.show","chat.bits.cheer-notice","link-cards.enable","link-cards.use-destination","ffz.search.matches-only","layout.display-bits-button","layout.theatre-navigation","layout.minimal-navigation","layout.turbo-cta","layout.prime-offers","layout.hide-discover-luna","ffz.show-new-settings","metadata.clip-download","metadata.player-stats","metadata.stream-delay-warning","metadata.uptime","metadata.viewers","metadata.viewers.no-native","metadata.uptime.no-native","channel.auto-click-off-featured","channel.auto-skip-trailer","channel.auto-click-chat","channel.panel-tips","channel.extra-links","channel.show-celebrations","channel.hide-unfollow","channel.hide-live-indicator","channel.round-avatars","player.hide-event-bar","chat.scroller.freeze","chat.scroller.freeze-requires-hover","chat.scroller.hover-delay","chat.scroller.smooth-scroll","chat.input.hide-identity","chat.inline-preview.enabled","chat.input.show-mod-view","chat.input.show-highlight","chat.input.show-shield","chat.input.show-elevate-your-message","chat.emote-menu.shortcut","chat.emote-menu.modifiers","chat.emote-menu.clear-search","chat.emote-menu.enabled","chat.emote-menu.default-tab","chat.emote-menu.effect-tab","chat.emote-menu.show-emoji","chat.emote-menu.combine-tabs","chat.emote-menu.stay-loaded","chat.emote-menu.icon","chat.emote-menu.show-quick-nav","chat.emote-menu.tall","chat.emote-menu.show-heading","chat.emote-menu.show-search","chat.emote-menu.reduced-padding","chat.emote-menu.tooltips","chat.emote-menu.sort-emotes","chat.emote-menu.sort-tiers-last","chat.hype.display-input","chat.mru.enabled","chat.tab-complete.ffz-emotes","chat.tab-complete.emoji","chat.tab-complete.emotes-without-colon","chat.tab-complete.limit-results","chat.tab-complete.prioritize-favorites","chat.tab-complete.prioritize-prefix-matches","chat.tab-complete.matching","chat.viewer-cards.highlight-chat","chat.viewer-cards.color","chat.subs.native","chat.subs.show","chat.subs.compact","chat.subs.merge-gifts","chat.subs.merge-gifts-visibility","chat.disable-handling","chat.filtering.blocked-callouts","chat.filtering.blocked-types","chat.replies.style","channel.raids.no-autojoin","chat.powerup.effects","chat.hide-community-highlights","chat.subs.gift-banner","chat.banners.last-events","chat.banners.charity","chat.banners.hide-appleplus","chat.banners.hype-train","chat.banners.pinned-message","chat.banners.polls","chat.banners.prediction","chat.callouts.clip","chat.community-chest.show","chat.bits.show-pinned","channel.raids.blocked-channels","chat.banners.shared-chat","chat.banners.drops","chat.points.allow-highlight","chat.points.show-callouts","chat.points.show-button","layout.portrait-min-chat","layout.subtember","layout.portrait","layout.portrait-invert","layout.portrait-threshold","chat.points.show-rewards","chat.points.auto-rewards","chat.drops.auto-rewards","chat.shared-chat.style","chat.shared-chat.username-tooltip","chat.bits.show-rewards","chat.rituals.show","chat.hype.message-style","chat.hype.show-pinned","metadata.modview.hide-info","layout.swap-sidebars","layout.side-nav.hide-stories","layout.side-nav.show","layout.side-nav.hide-viewers","layout.side-nav.show-avatars","layout.side-nav.show-rec-channels","layout.side-nav.show-friends","layout.side-nav.hide-offline","layout.side-nav.rerun-style","whispers.show","layout.theme.global-font","theme.font.size","directory.hidden.style","directory.hidden.reveal","directory.hide-costream-border","directory.uptime","directory.show-flags","directory.hide-live","directory.hide-promoted","directory.hide-vodcasts","directory.wait-flags","directory.hide-recommended","directory.block-users","directory.block-titles","directory.blocked-tags","directory.blur-titles","directory.blur-tags","directory.block-flags","directory.blur-flags","directory.default-sort","clips.layout.big","player.theatre.metadata","player.theatre.no-whispers","player.theatre.auto-enter","player.embed-metadata","player.cast-button.hide","player.clip-button.custom","player.clip-button.hide-native","player.fade-pause-buffer","player.no-autoplay","player.vod.autoplay","player.single-click-pause","player.home.autoplay","player.disable-content-warnings","player.allow-catchup","player.button.reset","player.hide-mouse","player.compressor.enable","player.compressor.default","player.compressor.shortcut","player.compressor.force-legacy","player.compressor.threshold","player.compressor.knee","player.compressor.ratio","player.compressor.attack","player.compressor.release","player.gain.enable","player.gain.no-volume","player.gain.scroll","player.gain.min","player.gain.max","player.gain.default","player.mute-click","player.volume-scroll","player.volume-scroll-steps","player.volume-always-shown","player.captions.font-size","player.captions.font-family","player.ext-hide","player.ext-interaction","player.fullscreen.auto-chat","sub-button.prime-notice","theme.disable-high-contrast","theme.high-contrast-tweaks","theme.disable-auto-dark","theme.legacy-dark-input","theme.color.background","theme.color.text","theme.color.accent","theme.color.tooltip.background","theme.color.tooltip.text","theme.color.chat-background","theme.color.chat-text","theme.color.chat-accent","chat.video-chat.timestamps","chat.video-chat.enabled","experiments","i18n.debug.open","socket.info","tooltip.tos.YouTube","profiles","backup","clear","provider","home","debug.graphql-test","faq","chat.filtering.syntax-help","feedback","feedback.log","changelog","add-ons","addon-changelog","legal","debug.chat-test","directory.game.blocked-games","directory.game.hidden-thumbnails","addon-changelog.unread-mentions-counter","addon-changelog.twir","addon-changelog.thehitless-badges","addon-changelog.smokemotes","addon-changelog.smm2-links","addon-changelog.screenshotter","addon-changelog.repetition-detector","addon-changelog.ragnarok-database","addon-changelog.pronouns","addon-changelog.prattlenot","addon-changelog.poll-shim","addon-changelog.no-bad-emotes","addon-changelog.new-account-highlighter","addon-changelog.modchecker","addon-changelog.inline-tab-completion","addon-changelog.fs-chat","addon-changelog.first-message-highlighter","addon-changelog.ffzap-liriklive","addon-changelog.ffzap-core","addon-changelog.ffzap-bttv","addon-changelog.emoteless","addon-changelog.emote-side-panel","addon-changelog.declutter","addon-changelog.deck","addon-changelog.clip-confirm","addon-changelog.chatterino-homies","addon-changelog.chatterino-badges","addon-changelog.brcm","addon-changelog.better-minecraft-badge","addon-changelog.aplatypuss","addon-changelog.ModTools","addon-changelog.7tv-emotes","addons.dev.server","addon.seventv_emotes.channel_emotes","addon.seventv_emotes.emote_format","addon.seventv_emotes.global_emotes","addon.seventv_emotes.personal_emotes","addon.seventv_emotes.unlisted_emotes","addon.seventv_emotes.update_messages","addon.seventv_emotes.animated_avatars","addon.seventv_emotes.badges","addon.seventv_emotes.nametag_paints","addon.seventv_emotes.nametag_paints_drop_shadows","ffzap.betterttv.arbitrary_emoticons","ffzap.betterttv.channel_emoticons","ffzap.betterttv.global_emoticons","ffzap.betterttv.update_messages","ffzap.betterttv.pro_badges","ffzap.betterttv.pro_emoticons","ffzap.core.message_deletion","ffzap.core.remove_spaces","ffzap.core.enable_highlight_sound","ffzap.core.highlight_sound","ffzap.core.highlight_sound_volume","ffzap.core.highlight_sound_prevent_own_channel","ffzap.core.highlight_sound_types","first_message_highlight.enabled","first_message_highlight.only_moderated_channels","first_message_highlight.forget_user_after","first_message_highlight.highlight_color","first_message_highlight.priority","first_message_highlight.highlight_historical","first_message_highlight.first_time_chatter","first_message_highlight.first_time_chatter_only_moderated_channels","first_message_highlight.first_time_chatter_color","first_message_highlight.first_time_chatter_priority","first_message_highlight.returning_chatter","first_message_highlight.returning_chatter_only_moderated_channels","first_message_highlight.returning_chatter_color","first_message_highlight.returning_chatter_priority","first_message_highlight.pad-bottom","modtools.about","modtools.highlights.clear","modtools.highlight-color","addon.pronouns.border","addon.pronouns.color","addon.pronouns.streamer","addon.pronouns.color.aeaer","addon.pronouns.color.any","addon.pronouns.color.eem","addon.pronouns.color.faefaer","addon.pronouns.color.hehim","addon.pronouns.color.itits","addon.pronouns.color.other","addon.pronouns.color.perper","addon.pronouns.color.sheher","addon.pronouns.color.theythem","addon.pronouns.color.vever","addon.pronouns.color.xexem","addon.pronouns.color.ziehir"],"p:0:layout.side-nav.show-avatars":true,"p:0:chat.filtering.highlight-mentions":true,"p:0:chat.bits.show-pinned":false,"p:0:chat.filtering.display-deleted":"LEGACY","p:0:layout.side-nav.show-rec-channels":1,"p:0:chat.community-chest.show":false,"p:0:layout.turbo-cta":false,"p:0:chat.drops.auto-rewards":true,"p:0:clips.layout.big":true,"p:0:channel.auto-skip-trailer":true,"p:0:first_message_highlight.first_time_chatter":true,"p:0:addon.seventv_emotes.unlisted_emotes":true,"p:0:first_message_highlight.enabled":false,"p:0:chat.points.show-callouts":false,"p:0:addon.seventv_emotes.nametag_paints_drop_shadows":false,"p:0:chat.filtering.ignore-clear":true,"p:0:layout.side-nav.hide-stories":true,"p:0:layout.prime-offers":false,"p:0:chat.points.show-rewards":false,"p:0:addon.seventv_emotes.nametag_paints":false,"cfg-collapsed":["add_ons","appearance","channel","chat.filtering","directory","chat.actions","chat","player","debugging"],"p:0:chat.emote-menu.tall":true,"p:0:layout.display-bits-button":false,"p:0:chat.filtering.show-reasons":1,"p:0:chat.filtering.click-to-reveal":true,"p:0:chat.input.hide-identity":false,"p:0:chat.tab-complete.emotes-without-colon":true,"p:0:directory.hide-promoted":true,"p:0:directory.hide-recommended":true,"p:0:player.cast-button.hide":true,"p:0:player.disable-content-warnings":true,"p:0:player.home.autoplay":false,"p:0:player.single-click-pause":true,"p:0:player.vod.autoplay":false}} \ No newline at end of file diff --git a/homeManagerModules/neovim/.editorconfig b/homeManagerModules/neovim/.editorconfig deleted file mode 100644 index cb0dfb1f..00000000 --- a/homeManagerModules/neovim/.editorconfig +++ /dev/null @@ -1,107 +0,0 @@ -# see https://github.com/CppCXY/EmmyLuaCodeStyle -[*.lua] -# [basic] -indent_style = space -indent_size = 4 -quote_style = single - -max_line_length = 120 -end_of_line = lf - -table_separator_style = comma -trailing_table_separator = smart - -call_arg_parentheses = keep - -# [space] -space_around_table_field_list = true -space_before_attribute = true -space_before_function_open_parenthesis = false -space_before_function_call_open_parenthesis = false -space_before_closure_open_parenthesis = false -space_before_function_call_single_arg = false -space_before_open_square_bracket = false -space_inside_function_call_parentheses = false -space_inside_function_param_list_parentheses = false -space_inside_square_brackets = false - -# like t[#t+1] = 1 -space_around_table_append_operator = false -ignore_spaces_inside_function_call = false - -# detail number or 'keep' -space_before_inline_comment = 1 - -# convert '---' to '--- ' or '--' to '-- ' -space_after_comment_dash = false - -# [operator space] -space_around_math_operator = true -space_around_math_operator.exponent = false -space_around_concat_operator = true -space_around_logical_operator = true -space_around_assign_operator = true - -space_after_comma = true -space_after_comma_in_for_statement = true - -# [align] -align_call_args = false -align_function_params = true -align_continuous_assign_statement = true -align_continuous_rect_table_field = true -align_continuous_line_space = 2 -align_if_branch = false - -# option none / always / contain_curly/ -align_array_table = true - -align_continuous_similar_call_args = false - -align_continuous_inline_comment = true -# option none / always / only_call_stmt -align_chain_expr = none - -# [indent] -never_indent_before_if_condition = false -never_indent_comment_on_if_branch = false -keep_indents_on_empty_lines = false -allow_non_indented_comments = false - -# [line space] - -# The following configuration supports four expressions -# keep -# fixed(n) -# min(n) -# max(n) -# for eg. min(2) - -line_space_after_if_statement = keep - -line_space_after_do_statement = keep - -line_space_after_while_statement = keep - -line_space_after_repeat_statement = keep - -line_space_after_for_statement = keep - -line_space_after_local_or_assign_statement = keep - -line_space_after_function_statement = fixed(2) - -line_space_after_expression_statement = keep - -line_space_after_comment = keep - -line_space_around_block = fixed(1) - -# [line break] -break_all_list_when_line_exceed = false -auto_collapse_lines = false -break_before_braces = false - -# [preference] -ignore_space_after_colon = false -end_statement_with_semicolon = always diff --git a/homeManagerModules/neovim/config/mini.lua b/homeManagerModules/neovim/config/mini.lua deleted file mode 100644 index 58618ab0..00000000 --- a/homeManagerModules/neovim/config/mini.lua +++ /dev/null @@ -1,132 +0,0 @@ --- Taken from https://github.com/grahamc/system-configurations/blob/9e38ebea2a40c497d7d3fe0f05d8ef6a072d238c/dotfiles/neovim/lua/base/mini.lua - ---- ai {{{ -local ai = require('mini.ai'); - -local spec_treesitter = ai.gen_spec.treesitter; -local spec_pair = ai.gen_spec.pair; - -ai.setup({ - custom_textobjects = { - d = spec_treesitter({ a = '@function.outer', i = '@function.inner' }), - f = spec_treesitter({ a = '@call.outer', i = '@call.inner' }), - a = spec_treesitter({ a = '@parameter.outer', i = '@parameter.inner' }), - C = spec_treesitter({ a = '@conditional.outer', i = '@conditional.inner' }), - s = spec_treesitter({ a = '@assignment.lhs', i = '@assignment.rhs' }), - - -- Whole buffer - g = function() - local from = { line = 1, col = 1 }; - local to = { - line = vim.fn.line('$'), - col = math.max(vim.fn.getline('$'):len(), 1), - }; - return { from = from, to = to }; - end, - - -- For markdown - ['*'] = spec_pair('*', '*', { type = 'greedy' }), - ['_'] = spec_pair('_', '_', { type = 'greedy' }), - - -- For lua - [']'] = spec_pair('[', ']', { type = 'greedy' }), - - -- For Nix - ["'"] = spec_pair("'", "'", { type = 'greedy' }), - }, - - silent = true, - - -- If I still want to select next/last I can use around_{next,last} textobjects - search_method = 'cover', - - -- Number of lines within which textobject is searched - n_lines = 100, -}); ---}}} - --- surround {{{ -local open_braces = { - ['['] = ']', - ['('] = ')', - ['<'] = '>', - ['{'] = '}', - ["'"] = "'", - ['"'] = '"', -}; - -local close_braces = { - [']'] = '[', - [')'] = '(', - ['>'] = '<', - ['}'] = '{', -}; - -local function get_braces(char) - if open_braces[char] then - return { char, open_braces[char] }; - elseif close_braces[char] then - return { close_braces[char], char }; - else - return nil; - end; -end; - -local function get_char() - local ret_val, char_num = pcall(vim.fn.getchar); - -- Return nil if error (e.g. <C-c>) or for control characters - if not ret_val or char_num < 32 then - return nil; - end; - local char = vim.fn.nr2char(char_num); - - return char; -end; - -require('mini.surround').setup({ - n_lines = 50, - search_method = 'cover', - silent = true, - custom_surroundings = { - -- Search for two of the input char, d for double. Helpful for lua and Nix - ['d'] = { - input = function() - local char = get_char(); - - if char == nil or char == '' then - return nil; - end; - - local braces = get_braces(char); - - if braces == nil then - return nil; - end; - - return { - string.rep(braces[1], 2) .. '().-()' .. string.rep(braces[2], 2), - }; - end, - - output = function() - local char = get_char(); - - if char == nil or char == '' then - return nil; - end; - - local braces = get_braces(char); - - if braces == nil then - return nil; - end; - - return { - left = string.rep(braces[1], 2), - right = string.rep(braces[2], 2), - }; - end, - }, - }, -}); --- }}} diff --git a/homeManagerModules/neovim/default.nix b/homeManagerModules/neovim/default.nix deleted file mode 100644 index b17ad530..00000000 --- a/homeManagerModules/neovim/default.nix +++ /dev/null @@ -1,118 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (lib) fileContents mkIf mkOption types; - - cfg = config.programs.neovim; -in { - imports = [ - ./git - - (import ./langs self) - (import ./theme self) - ]; - - options.programs.neovim = { - user = mkOption { - type = types.str; - }; - - ideConfig = { - enableBash = mkOption { - type = types.bool; - default = true; - }; - enableGolang = mkOption { - type = types.bool; - default = true; - }; - enableJava = mkOption { - type = types.bool; - default = true; - }; - enableNix = mkOption { - type = types.bool; - default = true; - }; - enablePython = mkOption { - type = types.bool; - default = true; - }; - }; - }; - - config = mkIf cfg.enable { - programs.neovim = { - extraLuaConfig = - # lua - '' - -- by default, the indent is 2 spaces. - vim.opt.smartindent = true; - vim.opt.expandtab = true; - vim.opt.shiftwidth = 2; - vim.opt.softtabstop = 2; - vim.opt.tabstop = 2; - - vim.opt.number = true; - vim.opt.relativenumber = true; - - vim.opt.undofile = true; - vim.opt.undodir = '${config.xdg.cacheHome}/nvim/'; - - -- Always show the signcolumn, otherwise it would shift - -- the text each time diagnostics appear/become resolved - vim.opt.signcolumn = 'yes'; - - -- remove highlight on words - vim.keymap.set('n', '<esc>', ':noh<cr><esc>', { - noremap = true, - silent = true, - }); - - -- https://github.com/seblj/roslyn.nvim/issues/121#issuecomment-2544076963 - vim.opt.cmdheight = 2; - ''; - - plugins = [ - pkgs.vimPlugins.fzfWrapper - pkgs.vimPlugins.fzf-vim - - { - plugin = pkgs.vimPlugins.todo-comments-nvim; - type = "lua"; - config = - # lua - '' - require('todo-comments').setup(); - ''; - } - { - plugin = pkgs.vimPlugins.mini-nvim; - type = "lua"; - config = fileContents ./config/mini.lua; - } - - { - plugin = pkgs.vimPlugins.nvim-config-local; - type = "lua"; - config = - # lua - '' - require('config-local').setup({ - config_files = { '.nvim.lua', '.nvimrc', '.exrc' }, - - -- Where the plugin keeps files data - hashfile = '${config.xdg.cacheHome}/nvim/config-local', - }); - ''; - } - ]; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/git/default.nix b/homeManagerModules/neovim/git/default.nix deleted file mode 100644 index a5006e79..00000000 --- a/homeManagerModules/neovim/git/default.nix +++ /dev/null @@ -1,35 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) mkIf; - - cfg = config.programs.neovim; -in { - config = mkIf cfg.enable { - programs.neovim.plugins = [ - pkgs.vimPlugins.fugitive - - { - plugin = pkgs.vimPlugins.gitsigns-nvim; - type = "lua"; - config = - # lua - '' - local gitsigns = require("gitsigns"); - - vim.keymap.set("v", "gs", function() - gitsigns.stage_hunk({ vim.fn.line('.'), vim.fn.line('v') }); - end); - - gitsigns.setup(); - ''; - } - ]; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/langs/bash/default.nix b/homeManagerModules/neovim/langs/bash/default.nix deleted file mode 100644 index 302e753d..00000000 --- a/homeManagerModules/neovim/langs/bash/default.nix +++ /dev/null @@ -1,63 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) attrValues getExe mkIf; - - cfg = config.programs.neovim; -in { - config = mkIf (cfg.enable && cfg.ideConfig.enableBash) { - programs = { - # I love doing typos - bash.shellAliases = { - nivm = "nvim"; - nivim = "nvim"; - }; - - neovim = { - defaultEditor = true; - viAlias = true; - vimAlias = true; - - # We keep the packages here because shell scripts are too common - extraPackages = attrValues { - inherit - (pkgs.nodePackages) - bash-language-server - ; - - inherit - (pkgs) - shellcheck - ; - }; - - extraLuaConfig = - # lua - '' - vim.api.nvim_create_autocmd('FileType', { - pattern = 'sh', - command = 'setlocal ts=4 sw=4 sts=0 expandtab', - }); - - local default_capabilities = require('cmp_nvim_lsp').default_capabilities(); - - require('lspconfig').bashls.setup({ - capabilities = default_capabilities, - - settings = { - bashIde = { - shellcheckPath = '${getExe pkgs.shellcheck}', - }, - }, - }); - ''; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/langs/c-lang/default.nix b/homeManagerModules/neovim/langs/c-lang/default.nix deleted file mode 100644 index 46f33e3f..00000000 --- a/homeManagerModules/neovim/langs/c-lang/default.nix +++ /dev/null @@ -1,72 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) mkIf; - - cfg = config.programs.neovim; - flakeEnv = config.programs.bash.sessionVariables.FLAKE; -in { - config = mkIf cfg.enable { - programs = { - neovim = { - extraLuaConfig = - # lua - '' - vim.api.nvim_create_autocmd('FileType', { - pattern = { 'cpp', 'c' }, - - callback = function() - vim.cmd[[setlocal ts=4 sw=4 sts=0 expandtab]]; - - if (devShells['c-lang'] == nil) then - devShells['c-lang'] = 1; - - require('nix-develop').nix_develop_extend({'${flakeEnv}#c-lang'}, function() - vim.cmd[[LspStart]]; - end); - end - end, - }); - ''; - - plugins = [ - { - plugin = pkgs.vimPlugins.clangd_extensions-nvim; - type = "lua"; - config = - # lua - '' - local lsp = require('lspconfig'); - local default_capabilities = require('cmp_nvim_lsp').default_capabilities(); - - local clangd_extensions = require('clangd_extensions.inlay_hints'); - - lsp.cmake.setup({ - capabilities = default_capabilities, - autostart = false, - }); - - lsp.clangd.setup({ - capabilities = default_capabilities, - autostart = false, - - handlers = require('lsp-status').extensions.clangd.setup(), - - on_attach = function(_, bufnr) - clangd_extensions.setup_autocmd(); - clangd_extensions.set_inlay_hints(); - end, - }); - ''; - } - ]; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/langs/c-lang/shell.nix b/homeManagerModules/neovim/langs/c-lang/shell.nix deleted file mode 100644 index dc47baaa..00000000 --- a/homeManagerModules/neovim/langs/c-lang/shell.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ - mkShell, - gcc, - clang-tools, - cmake-language-server, - ... -}: -mkShell { - packages = [ - gcc - clang-tools - cmake-language-server - ]; -} diff --git a/homeManagerModules/neovim/langs/config/cmp.lua b/homeManagerModules/neovim/langs/config/cmp.lua deleted file mode 100644 index 54a38adf..00000000 --- a/homeManagerModules/neovim/langs/config/cmp.lua +++ /dev/null @@ -1,50 +0,0 @@ -local cmp = require('cmp'); -local cmp_autopairs = require('nvim-autopairs.completion.cmp'); - -cmp.event:on( - 'confirm_done', - cmp_autopairs.on_confirm_done() -); - -cmp.setup({ - sources = { - { name = 'nvim_lsp' }, - { name = 'buffer' }, - { name = 'path' }, - }, - - snippet = { - expand = function(args) - vim.fn['vsnip#anonymous'](args.body); - end, - }, - - mapping = { - -- Confirm selection - ['<Right>'] = cmp.mapping.confirm({ select = true }), - - -- Next selection - ['<Down>'] = cmp.mapping(function(fallback) - if cmp.visible() then - cmp.select_next_item(); - else - fallback(); - end; - end, { - 'i', - 's', - }), - - -- Previous selection - ['<Up>'] = cmp.mapping(function(fallback) - if cmp.visible() then - cmp.select_prev_item(); - else - fallback(); - end; - end, { - 'i', - 's', - }), - }, -}); diff --git a/homeManagerModules/neovim/langs/csharp/default.nix b/homeManagerModules/neovim/langs/csharp/default.nix deleted file mode 100644 index 87727012..00000000 --- a/homeManagerModules/neovim/langs/csharp/default.nix +++ /dev/null @@ -1,89 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (self.lib.${pkgs.system}) buildPlugin; - inherit (self.inputs) vimplugin-roslyn-nvim-src; - - inherit (lib) mkIf; - - cfg = config.programs.neovim; - flakeEnv = config.programs.bash.sessionVariables.FLAKE; -in { - config = mkIf cfg.enable { - programs = { - neovim = { - plugins = [ - { - plugin = buildPlugin "roslyn-nvim" vimplugin-roslyn-nvim-src; - type = "lua"; - config = - # lua - '' - vim.api.nvim_create_autocmd('User', { - pattern = 'RoslynInitialized', - - callback = function() - vim.lsp.inlay_hint.enable(); - end, - }); - - local startRoslyn = function() - require('roslyn').setup({ - config = { - capabilities = require('cmp_nvim_lsp').default_capabilities(), - - on_attach = function() - vim.lsp.inlay_hint.enable(); - end, - - settings = { - ["csharp|inlay_hints"] = { - csharp_enable_inlay_hints_for_implicit_object_creation = true, - csharp_enable_inlay_hints_for_implicit_variable_types = true, - csharp_enable_inlay_hints_for_lambda_parameter_types = true, - csharp_enable_inlay_hints_for_types = true, - dotnet_enable_inlay_hints_for_indexer_parameters = true, - dotnet_enable_inlay_hints_for_literal_parameters = true, - dotnet_enable_inlay_hints_for_object_creation_parameters = true, - dotnet_enable_inlay_hints_for_other_parameters = true, - dotnet_enable_inlay_hints_for_parameters = true, - dotnet_suppress_inlay_hints_for_parameters_that_differ_only_by_suffix = true, - dotnet_suppress_inlay_hints_for_parameters_that_match_argument_name = true, - dotnet_suppress_inlay_hints_for_parameters_that_match_method_intent = true, - }, - }, - }, - - exe = 'Microsoft.CodeAnalysis.LanguageServer', - }); - end; - - vim.api.nvim_create_autocmd('FileType', { - pattern = { 'cs' }, - - callback = function() - vim.cmd[[setlocal ts=4 sw=4 sts=0 expandtab]]; - - if (devShells['csharp'] == nil) then - devShells['csharp'] = 1; - - require('nix-develop').nix_develop_extend({'${flakeEnv}#csharp'}, function() - startRoslyn(); - vim.cmd[[e]]; -- reload to attach on current file - end); - end - end, - }); - ''; - } - ]; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/langs/csharp/shell.nix b/homeManagerModules/neovim/langs/csharp/shell.nix deleted file mode 100644 index 220f4e4a..00000000 --- a/homeManagerModules/neovim/langs/csharp/shell.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ - mkShell, - dotnetCorePackages, - roslyn-ls, - ... -}: -mkShell { - packages = [ - dotnetCorePackages.sdk_9_0 - roslyn-ls - ]; -} diff --git a/homeManagerModules/neovim/langs/default.nix b/homeManagerModules/neovim/langs/default.nix deleted file mode 100644 index 6482a7c7..00000000 --- a/homeManagerModules/neovim/langs/default.nix +++ /dev/null @@ -1,143 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (self.inputs) nix-develop-nvim-src; - inherit (self.lib.${pkgs.system}) mkVersion; - - inherit (lib) attrValues fileContents mkBefore mkIf; - - cfg = config.programs.neovim; -in { - imports = [ - ./bash - ./c-lang - ./golang - ./hyprlang - ./java - ./json - ./lua - ./python - ./rust - - (import ./csharp self) - (import ./markdown self) - (import ./nix-lang self) - (import ./web self) - ]; - - config = mkIf cfg.enable { - programs.neovim = { - extraLuaConfig = - mkBefore - # lua - '' - -- Init object to keep track of loaded devShells - local devShells = {}; - - -- Add formatting cmd - vim.api.nvim_create_user_command( - 'Format', - function() - vim.lsp.buf.format({ async = true }); - end, - {} - ); - - -- LSP-Status setup - local lsp_status = require('lsp-status'); - lsp_status.register_progress(); - - -- Remove LSP highlighting to use Treesitter - vim.api.nvim_create_autocmd('LspAttach', { - callback = function(args) - local client = vim.lsp.get_client_by_id(args.data.client_id); - client.server_capabilities.semanticTokensProvider = nil; - lsp_status.on_attach(client); - end, - }); - ''; - - plugins = attrValues { - inherit - (pkgs.vimPlugins) - # lsp plugins - nvim-lspconfig - lsp-status-nvim - # completion plugins - cmp-buffer - cmp-nvim-lsp - cmp-path - cmp-spell - vim-vsnip - ; - - nix-develop-nvim = pkgs.vimPlugins.nix-develop-nvim.overrideAttrs (o: { - name = "vimplugin-${o.pname}-${mkVersion nix-develop-nvim-src}"; - src = nix-develop-nvim-src; - }); - - nvim-cmp = { - plugin = pkgs.vimPlugins.nvim-cmp; - type = "lua"; - config = fileContents ./config/cmp.lua; - }; - - nvim-autopairs = { - plugin = pkgs.vimPlugins.nvim-autopairs; - type = "lua"; - config = - # lua - '' - require('nvim-autopairs').setup({}); - ''; - }; - - tiny-inline-diagnostic = { - plugin = pkgs.vimPlugins.tiny-inline-diagnostic-nvim; - type = "lua"; - config = - # lua - '' - -- Disable virtual_text since it's redundant due to tiny-inline-diagnostic. - vim.diagnostic.config({ - virtual_text = false, - }); - - require("tiny-inline-diagnostic").setup({ - -- Available options: - -- "modern", "classic", "minimal", "powerline", - -- "ghost", "simple", "nonerdfont", "amongus" - preset = 'modern', - - options = { - show_source = true, - use_icons_from_diagnostic = false, - - -- Minimum message length before wrapping to a new line - softwrap = 30, - - -- Show all diagnostics under the cursor if multiple diagnostics exist on the same line - -- If set to false, only the diagnostics under the cursor will be displayed - multiple_diag_under_cursor = true, - - multilines = { - enabled = true, - always_show = true, - }, - - enable_on_insert = true, - throttle = 0, - }, - }); - ''; - }; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/langs/golang/default.nix b/homeManagerModules/neovim/langs/golang/default.nix deleted file mode 100644 index 0005ea1c..00000000 --- a/homeManagerModules/neovim/langs/golang/default.nix +++ /dev/null @@ -1,39 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) mkIf; - - cfg = config.programs.neovim; -in { - config = mkIf (cfg.enable && cfg.ideConfig.enableGolang) { - programs = { - neovim = { - extraPackages = with pkgs; [go gopls]; - - plugins = [ - { - plugin = pkgs.vimPlugins.clangd_extensions-nvim; - type = "lua"; - config = - # lua - '' - local lsp = require('lspconfig'); - local default_capabilities = require('cmp_nvim_lsp').default_capabilities(); - - lsp.gopls.setup({ - cmd = { '${pkgs.gopls}/bin/gopls' }, - capabilities = default_capabilities, - }); - ''; - } - ]; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/langs/hyprlang/default.nix b/homeManagerModules/neovim/langs/hyprlang/default.nix deleted file mode 100644 index 95b68a07..00000000 --- a/homeManagerModules/neovim/langs/hyprlang/default.nix +++ /dev/null @@ -1,31 +0,0 @@ -{ - config, - lib, - ... -}: let - inherit (lib) mkIf; - - cfg = config.programs.neovim; -in { - config = mkIf cfg.enable { - programs = { - neovim = { - extraLuaConfig = - # lua - '' - vim.filetype.add({ - pattern = { [ '.*/hypr/.*%.conf' ] = 'hyprlang' }, - }); - - vim.api.nvim_create_autocmd('FileType', { - pattern = 'hyprlang', - command = 'setlocal ts=4 sw=4 sts=0 expandtab', - }); - ''; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/langs/java/default.nix b/homeManagerModules/neovim/langs/java/default.nix deleted file mode 100644 index 22711f80..00000000 --- a/homeManagerModules/neovim/langs/java/default.nix +++ /dev/null @@ -1,79 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) getExe mkIf; - - cfg = config.programs.neovim; - - javaSdk = pkgs.temurin-bin-21; -in { - config = mkIf (cfg.enable && cfg.ideConfig.enableJava) { - programs = { - # We keep the packages here because java is a bit complicated - java = { - enable = true; - package = javaSdk; - }; - - neovim = { - extraLuaConfig = - # lua - '' - vim.api.nvim_create_autocmd('FileType', { - pattern = 'java', - command = 'setlocal ts=4 sw=4 sts=0 expandtab', - }); - ''; - - plugins = [ - { - # TOOD: setup debugger https://github.com/mfussenegger/nvim-jdtls#debugger-via-nvim-dap - plugin = pkgs.vimPlugins.nvim-jdtls; - type = "lua"; - config = - # lua - '' - local startJdtls = function() - local config = { - capabilities = require('cmp_nvim_lsp').default_capabilities(), - - cmd = { '${getExe pkgs.jdt-language-server}' }, - root_dir = vim.fs.dirname(vim.fs.find( - { 'gradlew', '.git', 'mvnw', 'pom.xml' }, - { upward = true } - )[1]), - - settings = { - java = { - configuration = { - runtimes = { - { - name = 'JavaSE-21', - path = '${javaSdk}', - }, - }, - }, - }, - }, - }; - - require('jdtls').start_or_attach(config); - end - - vim.api.nvim_create_autocmd('FileType', { - pattern = 'java', - callback = startJdtls, - }); - ''; - } - ]; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/langs/json/default.nix b/homeManagerModules/neovim/langs/json/default.nix deleted file mode 100644 index 5e24128c..00000000 --- a/homeManagerModules/neovim/langs/json/default.nix +++ /dev/null @@ -1,66 +0,0 @@ -{ - config, - lib, - ... -}: let - inherit (lib) mkIf; - - cfg = config.programs.neovim; - flakeEnv = config.programs.bash.sessionVariables.FLAKE; -in { - config = mkIf cfg.enable { - programs = { - neovim = { - extraLuaConfig = - # lua - '' - vim.api.nvim_create_autocmd('FileType', { - pattern = { 'json', 'yaml', '.clang-.*' }, - - callback = function() - vim.cmd[[setlocal ts=4 sw=4 sts=0 expandtab]]; - - if (devShells['json'] == nil) then - devShells['json'] = 1; - - require('nix-develop').nix_develop_extend({'${flakeEnv}#json'}, function() - vim.cmd[[LspStart]]; - end); - end - end, - }); - - local lsp = require('lspconfig'); - local default_capabilities = require('cmp_nvim_lsp').default_capabilities(); - - lsp.jsonls.setup({ - capabilities = default_capabilities, - autostart = false, - }); - - lsp.yamlls.setup({ - capabilities = default_capabilities, - autostart = false, - - settings = { - yaml = { - format = { - enable = true, - singleQuote = true, - }, - schemas = { - [ - "https://json.schemastore.org/github-workflow.json" - ] = "/.github/workflows/*", - }, - }, - }, - }); - ''; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/langs/json/shell.nix b/homeManagerModules/neovim/langs/json/shell.nix deleted file mode 100644 index d0f02c84..00000000 --- a/homeManagerModules/neovim/langs/json/shell.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ - mkShell, - vscode-langservers-extracted, - yaml-language-server, - ... -}: -mkShell { - packages = [ - vscode-langservers-extracted - yaml-language-server - ]; -} diff --git a/homeManagerModules/neovim/langs/lua/default.nix b/homeManagerModules/neovim/langs/lua/default.nix deleted file mode 100644 index 1258b006..00000000 --- a/homeManagerModules/neovim/langs/lua/default.nix +++ /dev/null @@ -1,61 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) mkIf; - - cfg = config.programs.neovim; - - flakeEnv = config.programs.bash.sessionVariables.FLAKE; -in { - config = mkIf cfg.enable { - programs = { - neovim = { - plugins = [ - { - plugin = pkgs.vimPlugins.lazydev-nvim; - type = "lua"; - config = - # lua - '' - local default_capabilities = require('cmp_nvim_lsp').default_capabilities(); - - vim.api.nvim_create_autocmd('FileType', { - pattern = 'lua', - - callback = function() - vim.cmd[[setlocal ts=4 sw=4 sts=0 expandtab]]; - - if (devShells['lua'] == nil) then - devShells['lua'] = 1; - - require('nix-develop').nix_develop_extend({'${flakeEnv}#lua'}, function() - vim.cmd[[LspStart]]; - end); - end - end, - }); - - require('lazydev').setup({ - library = { - -- Load luvit types when the `vim.uv` word is found - { path = '${pkgs.vimPlugins.luvit-meta}/library', words = { 'vim%.uv' } }, - }, - }); - - require('lspconfig').lua_ls.setup({ - capabilities = default_capabilities, - autostart = false, - }); - ''; - } - ]; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/langs/lua/shell.nix b/homeManagerModules/neovim/langs/lua/shell.nix deleted file mode 100644 index 97af32b7..00000000 --- a/homeManagerModules/neovim/langs/lua/shell.nix +++ /dev/null @@ -1,10 +0,0 @@ -{ - mkShell, - lua-language-server, - ... -}: -mkShell { - packages = [ - lua-language-server - ]; -} diff --git a/homeManagerModules/neovim/langs/markdown/default.nix b/homeManagerModules/neovim/langs/markdown/default.nix deleted file mode 100644 index bb9798bf..00000000 --- a/homeManagerModules/neovim/langs/markdown/default.nix +++ /dev/null @@ -1,175 +0,0 @@ -self: { - config, - lib, - osConfig, - pkgs, - self, - ... -}: let - inherit (self.inputs) vimplugin-easytables-src; - inherit (self.lib.${pkgs.system}) buildPlugin; - - inherit (lib) concatStringsSep mkIf; - - cfg = config.programs.neovim; - flakeEnv = config.programs.bash.sessionVariables.FLAKE; - isServer = osConfig.roles.server.sshd.enable or false; - isDesktop = osConfig.roles.desktop.enable or false; - - githubCSS = pkgs.fetchurl { - url = "https://raw.githubusercontent.com/OzakIOne/markdown-github-dark/5bd0bcf3ad20cf9f58591f97a597fd68fc699f8e/style.css"; - hash = "sha256-deQvQOOyK6iP7kjVrgEdFTyOP80RWXMrETs6gi7DTmo="; - }; -in { - config = mkIf cfg.enable { - programs = { - neovim = { - extraLuaConfig = - # lua - '' - vim.api.nvim_create_autocmd('FileType', { - pattern = { 'markdown', 'tex' }, - - callback = function() - vim.cmd[[setlocal ts=4 sw=4 sts=0 expandtab]]; - - if (devShells['markdown'] == nil) then - devShells['markdown'] = 1; - - require('nix-develop').nix_develop_extend({'${flakeEnv}#markdown'}, function() - vim.cmd[[LspStart]]; - end); - end - end, - }); - - local lsp = require('lspconfig'); - - lsp.texlab.setup({ - capabilities = require('cmp_nvim_lsp').default_capabilities(), - autostart = false, - - settings = { - texlab = { - formatterLineLength = 100, - latexFormatter = 'latexindent', - latexindent = { - modifyLineBreaks = false, - ["local"] = '.indentconfig.yaml'; - }, - }, - }, - }); - ''; - - plugins = [ - { - plugin = buildPlugin "easytables-nvim" vimplugin-easytables-src; - type = "lua"; - config = - # lua - '' - require('easytables').setup(); - ''; - } - - { - plugin = pkgs.vimPlugins.knap; - type = "lua"; - config = let - mdToPDF = "pandoc --css ${githubCSS} %docroot% -o /tmp/%outputfile%"; - mdToPDFViewer = "sioyek /tmp/%outputfile%"; - - mdToHTML = "pandoc --standalone --embed-resource --highlight-style=breezedark --css ${githubCSS} %docroot% -o /tmp/%outputfile%"; - mdToHTMLViewer = - if isServer && !isDesktop - then - concatStringsSep " " [ - "${pkgs.nodePackages.live-server}/bin/live-server" - "--host=0.0.0.0" - "--port=6565" - "--quiet" - "--no-browser" - "--watch=%outputfile%" - "--entry-file=%outputfile%" - "--wait=800" - "/tmp" - ] - else "firefox -new-window /tmp/%outputfile%"; - in - # lua - '' - vim.g.knap_settings = { - -- HTML - htmloutputext = 'html', - htmltohtml = 'none', - htmltohtmlviewerlaunch = 'true', - htmltohtmlviewerrefresh = 'none', - - -- Markdown - mdoutputext = 'html', - markdownoutputext = 'html', - - -- Markdown to PDF - mdtopdf = '${mdToPDF}', - markdowntopdf = '${mdToPDF}', - mdtopdfviewerlaunch = '${mdToPDFViewer}', - markdowntopdfviewerlaunch = '${mdToPDFViewer}', - mdtopdfviewerrefresh = 'none', - markdowntopdfviewerrefresh = 'none', - - -- Markdown to HTML - mdtohtml = '${mdToHTML}', - markdowntohtml = '${mdToHTML}', - mdtohtmlviewerlaunch = '${mdToHTMLViewer}', - markdowntohtmlviewerlaunch = '${mdToHTMLViewer}', - mdtohtmlviewerrefresh = 'none', - markdowntohtmlviewerrefresh = 'none', - - -- LaTeX - texoutputext = 'pdf', - textopdf = 'cp -rf %docroot% /tmp/%docroot%; pdflatex -interaction=batchmode -halt-on-error -synctex=1 /tmp/%docroot%', - textopdfviewerlaunch = 'sioyek --inverse-search \'nvim --headless -es --cmd "lua require(\'"\'"\'knaphelper\'"\'"\').relayjump(\'"\'"\'%servername%\'"\'"\',\'"\'"\'%1\'"\'"\',%2,%3)"\' --new-window /tmp/%outputfile%', - textopdfviewerrefresh = 'none', - textopdfforwardjump = 'sioyek --inverse-search \'nvim --headless -es --cmd "lua require(\'"\'"\'knaphelper\'"\'"\').relayjump(\'"\'"\'%servername%\'"\'"\',\'"\'"\'%1\'"\'"\',%2,%3)"\' --reuse-window --forward-search-file %srcfile% --forward-search-line %line% /tmp/%docroot%/%outputfile%', - textopdfshorterror = 'A=/tmp/%outputfile% ; LOGFILE="''${A%.pdf}.log" ; rubber-info "$LOGFILE" 2>&1 | head -n 1', - }; - - vim.api.nvim_create_autocmd('BufUnload', { - pattern = '*', - callback = function() - os.execute('${pkgs.psmisc}/bin/killall -qr live-server'); - end, - }); - - -- F4 processes the document once, and refreshes the view - vim.keymap.set({ 'n', 'v', 'i' }, '<F4>', function() - require('knap').process_once(); - end); - - -- F5 closes the viewer application, and - -- allows settings to be reset - vim.keymap.set({ 'n', 'v', 'i' }, '<F5>', function() - require('knap').close_viewer(); - end); - - -- F6 toggles the auto-processing on and off - vim.keymap.set({ 'n', 'v', 'i' }, '<F6>', function() - require('knap').toggle_autopreviewing(); - end); - - -- F7 invokes a SyncTeX forward search, or similar, - -- where appropriate - vim.keymap.set({ 'n', 'v', 'i' }, '<F7>', function() - require('knap').forward_jump(); - end); - ''; - } - ]; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/langs/markdown/shell.nix b/homeManagerModules/neovim/langs/markdown/shell.nix deleted file mode 100644 index d26c2d93..00000000 --- a/homeManagerModules/neovim/langs/markdown/shell.nix +++ /dev/null @@ -1,16 +0,0 @@ -{ - mkShell, - pandoc, - texlab, - texliveFull, - rubber, - ... -}: -mkShell { - packages = [ - pandoc - texlab - texliveFull - rubber - ]; -} diff --git a/homeManagerModules/neovim/langs/nix-lang/default.nix b/homeManagerModules/neovim/langs/nix-lang/default.nix deleted file mode 100644 index fd028467..00000000 --- a/homeManagerModules/neovim/langs/nix-lang/default.nix +++ /dev/null @@ -1,96 +0,0 @@ -self: { - config, - lib, - osConfig, - pkgs, - ... -}: let - inherit (builtins) toJSON; - inherit (lib) attrValues getExe hasPrefix mkIf removePrefix; - inherit (osConfig.networking) hostName; - - cfg = config.programs.neovim; - mainHmCfg = osConfig.home-manager.users.${cfg.user} or config; - - defaultFormatter = self.formatter.${pkgs.system}; - formatCmd = pkgs.writeShellApplication { - name = "nix-fmt-cmd"; - runtimeInputs = with pkgs; [jq]; - text = '' - if info="$(nix flake show --json 2> /dev/null)" && [[ "$(jq -r .formatter <<< "$info")" != "null" ]]; then - exec nix fmt -- -- - else - exec ${getExe defaultFormatter} - fi - ''; - }; - - nixdPkg = pkgs.nixd; - - flakeEnv = config.programs.bash.sessionVariables.FLAKE; - flakeDir = "${removePrefix "${mainHmCfg.home.homeDirectory}/" flakeEnv}"; - optionsAttr = - if osConfig != null - then "nixosConfigurations.${hostName}.options" - else "nixOnDroidConfigurations.default"; -in { - config = mkIf (cfg.enable && cfg.ideConfig.enableNix) { - assertions = [ - { - assertion = hasPrefix "${mainHmCfg.home.homeDirectory}/" flakeEnv; - message = '' - Your $FLAKE environment variable needs to point to a directory in - the main users' home to use the neovim module. - ''; - } - ]; - - # We keep the packages here - home.packages = attrValues { - inherit - defaultFormatter - nixdPkg - ; - }; - - # nixd by default kinda spams LspLog - home.sessionVariables.NIXD_FLAGS = "-log=error"; - - xdg.dataFile."${flakeDir}/.nixd.json".text = toJSON { - nixpkgs = { - expr = "import (builtins.getFlake \"${flakeDir}\").inputs.nixpkgs {}"; - }; - options.nixos = { - expr = "(builtins.getFlake \"${flakeDir}\").${optionsAttr}"; - }; - }; - - programs = { - neovim = { - extraPackages = attrValues { - inherit nixdPkg; - }; - - extraLuaConfig = - # lua - '' - require('lspconfig').nixd.setup({ - capabilities = require('cmp_nvim_lsp').default_capabilities(), - - filetypes = { 'nix', 'in.nix' }, - settings = { - nixd = { - formatting = { - command = { '${getExe formatCmd}' }, - }, - }, - }, - }); - ''; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/langs/python/default.nix b/homeManagerModules/neovim/langs/python/default.nix deleted file mode 100644 index 738f67d0..00000000 --- a/homeManagerModules/neovim/langs/python/default.nix +++ /dev/null @@ -1,49 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) attrValues mkIf; - - cfg = config.programs.neovim; - - # We keep the packages here because python is a bit complicated and common - pythonPkgs = py: - (attrValues { - inherit (py) python-lsp-server; - }) - ++ py.python-lsp-server.optional-dependencies.all; -in { - config = mkIf (cfg.enable && cfg.ideConfig.enablePython) { - programs = { - neovim = { - withPython3 = true; - - extraPython3Packages = pythonPkgs; - extraPackages = pythonPkgs pkgs.python3Packages; - - extraLuaConfig = - # lua - '' - require('lspconfig').pylsp.setup({ - capabilities = require('cmp_nvim_lsp').default_capabilities(), - - settings = { - pylsp = { - plugins = { - pycodestyle = { - maxLineLength = 100, - }, - }, - }, - }, - }); - ''; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/langs/rust/default.nix b/homeManagerModules/neovim/langs/rust/default.nix deleted file mode 100644 index afd69a3a..00000000 --- a/homeManagerModules/neovim/langs/rust/default.nix +++ /dev/null @@ -1,44 +0,0 @@ -{ - config, - lib, - ... -}: let - inherit (lib) mkIf; - - cfg = config.programs.neovim; - flakeEnv = config.programs.bash.sessionVariables.FLAKE; -in { - config = mkIf cfg.enable { - programs = { - neovim = { - extraLuaConfig = - # lua - '' - vim.api.nvim_create_autocmd('FileType', { - pattern = { 'rust' }, - - callback = function() - vim.cmd[[setlocal ts=4 sw=4 sts=0 expandtab]]; - - if (devShells['rust'] == nil) then - devShells['rust'] = 1; - - require('nix-develop').nix_develop_extend({'${flakeEnv}#rust'}, function() - vim.cmd[[LspStart]]; - end); - end - end, - }); - - require('lspconfig').rust_analyzer.setup({ - capabilities = require('cmp_nvim_lsp').default_capabilities(), - autostart = false, - }); - ''; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/langs/rust/shell.nix b/homeManagerModules/neovim/langs/rust/shell.nix deleted file mode 100644 index 3360aeb5..00000000 --- a/homeManagerModules/neovim/langs/rust/shell.nix +++ /dev/null @@ -1,16 +0,0 @@ -{ - mkShell, - cargo, - rustc, - rust-analyzer, - rustfmt, - ... -}: -mkShell { - packages = [ - cargo - rustc - rust-analyzer - rustfmt - ]; -} diff --git a/homeManagerModules/neovim/langs/web/default.nix b/homeManagerModules/neovim/langs/web/default.nix deleted file mode 100644 index 6bd9882a..00000000 --- a/homeManagerModules/neovim/langs/web/default.nix +++ /dev/null @@ -1,211 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (self.inputs) vimplugin-ts-error-translator-src; - inherit (self.lib.${pkgs.system}) buildPlugin; - - inherit (lib) mkIf; - - cfg = config.programs.neovim; - flakeEnv = config.programs.bash.sessionVariables.FLAKE; -in { - config = mkIf cfg.enable { - programs = { - neovim = { - withNodeJs = true; - - extraLuaConfig = - # lua - '' - local lsp = require('lspconfig'); - local tsserver = require('typescript-tools'); - local default_capabilities = require('cmp_nvim_lsp').default_capabilities(); - - local loadDevShell = function() - if (devShells['web'] == nil) then - devShells['web'] = 1; - - require('nix-develop').nix_develop_extend({'${flakeEnv}#web'}, function() - vim.cmd[[LspStart]]; - end); - end - end; - - vim.api.nvim_create_autocmd('FileType', { - pattern = { 'javascript', 'javascriptreact', 'javascript.jsx', 'typescript', 'typescriptreact', 'typescript.tsx', 'css', 'scss' }, - - callback = function() - vim.cmd[[setlocal ts=4 sw=4 sts=0 expandtab]]; - - loadDevShell(); - end, - }); - - vim.api.nvim_create_autocmd('FileType', { - pattern = 'html', - - callback = function() - vim.cmd[[setlocal ts=4 sw=4 expandtab]]; - - loadDevShell(); - end, - }); - - vim.api.nvim_create_autocmd('FileType', { - pattern = 'scss', - command = 'setlocal iskeyword+=@-@', - }); - - tsserver.setup({ - capabilities = default_capabilities, - autostart = false, - - handlers = { - -- format error code with better error message - ['textDocument/publishDiagnostics'] = function(err, result, ctx, config) - require('ts-error-translator').translate_diagnostics(err, result, ctx, config) - vim.lsp.diagnostic.on_publish_diagnostics(err, result, ctx, config) - end, - }, - }); - - lsp.eslint.setup({ - capabilities = default_capabilities, - autostart = false, - - -- auto-save - on_attach = function(client, bufnr) - vim.api.nvim_create_autocmd('BufWritePre', { - buffer = bufnr, - command = 'EslintFixAll', - }); - end, - - settings = { - validate = 'on', - packageManager = 'npm', - useESLintClass = true, - useFlatConfig = true, - experimental = { - useFlatConfig = true, - }, - codeAction = { - disableRuleComment = { - enable = true, - location = 'separateLine' - }, - showDocumentation = { - enable = true, - }, - }, - codeActionOnSave = { - mode = 'all', - rules = {}, - }, - format = true, - quiet = false, - onIgnoredFiles = 'off', - rulesCustomizations = {}, - run = 'onType', - problems = { - shortenToSingleLine = false, - }, - nodePath = "", - workingDirectory = { - mode = 'location', - }, - }, - }); - - lsp.cssls.setup({ - capabilities = default_capabilities, - autostart = false, - - settings = { - css = { - validate = false, - }, - less = { - validate = false, - }, - scss = { - validate = false, - }, - }, - }); - - lsp.somesass_ls.setup({ - capabilities = default_capabilities, - autostart = false, - }); - lsp.somesass_ls.manager.config.settings = { - somesass = { - scss = { - completion = { - suggestFromUseOnly = true, - }, - }, - }, - }; - - local html_caps = default_capabilities; - html_caps.textDocument.completion.completionItem.snippetSupport = true; - - lsp.html.setup({ - capabilities = html_caps, - autostart = false, - - settings = { - configurationSection = { "html", "css", "javascript" }, - embeddedLanguages = { - css = true, - javascript = true, - }, - provideFormatter = true, - tabSize = 4, - insertSpaces = true, - indentEmptyLines = false, - wrapAttributes = 'auto', - wrapAttributesIndentSize = 4, - endWithNewline = true, - }, - }); - ''; - - plugins = [ - pkgs.vimPlugins.typescript-tools-nvim - (buildPlugin "ts-error-translator" vimplugin-ts-error-translator-src) - - { - plugin = pkgs.vimPlugins.package-info-nvim; - type = "lua"; - config = - # lua - '' - local packageInfo = require('package-info'); - - packageInfo.setup({ - hide_up_to_date = true, - package_manager = 'npm', - }); - - vim.api.nvim_create_autocmd({ 'BufRead', 'BufNewFile' }, { - pattern = { 'package.json' }, - - callback = function() - packageInfo.show({ force = true }); - end, - }); - ''; - } - ]; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/langs/web/shell.nix b/homeManagerModules/neovim/langs/web/shell.nix deleted file mode 100644 index bca918e4..00000000 --- a/homeManagerModules/neovim/langs/web/shell.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ - mkShell, - neovim-node-client, - nodejs_latest, - vscode-langservers-extracted, - nodePackages, - some-sass-language-server, - ... -}: -mkShell { - packages = [ - neovim-node-client - nodejs_latest - vscode-langservers-extracted - - nodePackages.npm - - some-sass-language-server - ]; -} diff --git a/homeManagerModules/neovim/theme/config/heirline.lua b/homeManagerModules/neovim/theme/config/heirline.lua deleted file mode 100644 index 83ed1edb..00000000 --- a/homeManagerModules/neovim/theme/config/heirline.lua +++ /dev/null @@ -1,443 +0,0 @@ --- Modified from https://github.com/lauranaujokat/nvim/blob/4102c789d05667f636107e3dae4ac589053ee88d/lua/setups/heirline.lua#L4 - -local conditions = require('heirline.conditions'); -local utils = require('heirline.utils'); - ----@class Palette ----@field [string] any -local dracula = require('dracula').colors(); - -local colors = { - bright_bg = dracula.selection, - dark_bg = dracula.menu, - bright_fg = dracula.fg, - red = dracula.red, - dark_red = utils.get_highlight('DiffDelete').bg, - green = dracula.green, - blue = dracula.blue, - gray = utils.get_highlight('NonText').fg, - orange = utils.get_highlight('Constant').fg, - purple = utils.get_highlight('Statement').fg, - cyan = dracula.cyan, - diag_warn = utils.get_highlight('DiagnosticWarn').fg, - diag_error = utils.get_highlight('DiagnosticError').fg, - diag_hint = utils.get_highlight('DiagnosticHint').fg, - diag_info = utils.get_highlight('DiagnosticInfo').fg, - git_del = utils.get_highlight('GitSignsDelete').fg, - git_add = utils.get_highlight('GitSignsAdd').fg, - git_change = utils.get_highlight('GitSignsChange').fg, -}; - -require('heirline').load_colors(colors); - -local ViMode = { - -- get vim current mode, this information will be required by the provider - -- and the highlight functions, so we compute it only once per component - -- evaluation and store it as a component attribute - init = function(self) - self.mode = vim.fn.mode(1); - - -- execute this only once, this is required if you want the ViMode - -- component to be updated on operator pending mode - if not self.once then - vim.api.nvim_create_autocmd('ModeChanged', { - pattern = '*:*o', - command = 'redrawstatus', - }); - self.once = true; - end; - end, - - static = { - mode_names = { - n = 'N', - no = 'N?', - nov = 'N?', - noV = 'N?', - ['no\22'] = 'N?', - niI = 'Ni', - niR = 'Nr', - niV = 'Nv', - nt = 'Nt', - v = 'V', - vs = 'Vs', - V = 'V_', - Vs = 'Vs', - ['\22'] = '^V', - ['\22s'] = '^V', - s = 'S', - S = 'S_', - ['\19'] = '^S', - i = 'I', - ic = 'Ic', - ix = 'Ix', - R = 'R', - Rc = 'Rc', - Rx = 'Rx', - Rv = 'Rv', - Rvc = 'Rv', - Rvx = 'Rv', - c = 'C', - cv = 'Ex', - r = '...', - rm = 'M', - ['r?'] = '?', - ['!'] = '!', - t = 'T', - }, - - mode_colors = { - n = 'red', - i = 'green', - v = 'cyan', - V = 'cyan', - ['\22'] = 'cyan', - c = 'orange', - s = 'purple', - S = 'purple', - ['\19'] = 'purple', - R = 'orange', - r = 'orange', - ['!'] = 'red', - t = 'red', - }, - }, - - -- To be extra meticulous, we can also add some vim statusline syntax to - -- control the padding and make sure our string is always at least 2 - -- characters long. Plus a nice Icon. - provider = function(self) - return ' ' .. self.mode_names[self.mode] .. '%)'; - end, - - -- Same goes for the highlight. Now the foreground will change according to the current mode. - hl = function(self) - local mode = self.mode:sub(1, 1); -- get only the first mode character - return { fg = self.mode_colors[mode], bold = true }; - end, - - -- Re-evaluate the component only on ModeChanged event - update = { - 'ModeChanged', - }, -}; - -local FileNameBlock = { - init = function(self) - self.filename = vim.api.nvim_buf_get_name(0); - end, -}; - --- FileNameBlock children -local FileIcon = { - init = function(self) - local filename = self.filename; - local extension = vim.fn.fnamemodify(filename, ':e'); - self.icon, self.icon_color = - require('nvim-web-devicons').get_icon_color(filename, extension, { default = true }); - end, - - provider = function(self) - return self.icon and (self.icon .. ' '); - end, - - hl = function(self) - return { fg = self.icon_color }; - end, -}; - -local FileName = { - provider = function(self) - -- first, trim the pattern relative to the current directory. For other - -- options, see :h filename-modifers - local filename = vim.fn.fnamemodify(self.filename, ':.'); - if filename == '' then - return '[No Name]'; - end; - -- now, if the filename would occupy more than 1/4th of the available - -- space, we trim the file path to its initials - -- See Flexible Components section below for dynamic truncation - if not conditions.width_percent_below(#filename, 0.25) then - filename = vim.fn.pathshorten(filename); - end; - return filename; - end, - - hl = { fg = utils.get_highlight('Directory').fg }, -}; - -local FileFlags = { - { - condition = function() - return vim.bo.modified; - end, - provider = '[+]', - hl = { fg = 'green' }, - }, - { - condition = function() - return not vim.bo.modifiable or vim.bo.readonly; - end, - provider = '', - hl = { fg = 'orange' }, - }, -}; - -local FileNameModifer = { - hl = function() - if vim.bo.modified then - -- use `force` because we need to override the child's hl foreground - return { fg = 'cyan', bold = true, force = true }; - end; - end, -}; - --- let's add the children to our FileNameBlock component -FileNameBlock = utils.insert( - FileNameBlock, - FileIcon, - utils.insert(FileNameModifer, FileName), -- a new table where FileName is a child of FileNameModifier - unpack(FileFlags), -- A small optimisation, since their parent does nothing - { provider = '%<' } -- this means that the statusline is cut here when there's not enough space -); - -local Ruler = { - provider = ' line: %l col: %c', - hl = { fg = 'green', bold = false }, -}; - -local ScrollRuler = { - -- %l = current line number - -- %L = number of lines in the buffer - -- %c = column number - -- %P = percentage through file of displayed window - provider = '%P', -}; - -local ScrollBar = { - static = { - sbar = { '▁', '▂', '▃', '▄', '▅', '▆', '▇', '█' }, - -- sbar = { '🭶', '🭷', '🭸', '🭹', '🭺', '🭻' } - }, - - provider = function(self) - local curr_line = vim.api.nvim_win_get_cursor(0)[1]; - local lines = vim.api.nvim_buf_line_count(0); - local i = math.floor((curr_line - 1) / lines * #self.sbar) + 1; - return string.rep(self.sbar[i], 2); - end, - - hl = { fg = 'cyan', bg = 'bright_bg' }, -}; - -local LSPActive = { - condition = conditions.lsp_attached, - update = { 'LspAttach', 'LspDetach' }, - - provider = function() - local names = {}; - for _, server in pairs(vim.lsp.get_clients()) do - table.insert(names, server.name); - end; - return ' [' .. table.concat(names, ' ') .. '] '; - end, - - hl = { fg = 'green', bold = false }, -}; - -local spinner_frames = { '⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏' }; - --- From https://github.com/mhartington/dotfiles/blob/5961460e3a492f7815259a692fca5ca2a1df924a/config/nvim/lua/mh/statusline/lsp_status.lua#L4 -local function get_lsp_progress() - local messages = require('lsp-status/messaging').messages; - local buf_messages = messages(); - local msgs = {}; - - for _, msg in ipairs(buf_messages) do - local contents; - - if msg.progress then - contents = msg.title; - - if msg.spinner then - contents = spinner_frames[(msg.spinner % #spinner_frames) + 1] .. ' ' .. contents; - end; - elseif msg.status then - contents = msg.content; - - if msg.uri then - local space = math.min(60, math.floor(0.6 * vim.fn.winwidth(0))); - local filename = vim.uri_to_fname(msg.uri); - - filename = vim.fn.fnamemodify(filename, ':~:.'); - - if #filename > space then - filename = vim.fn.pathshorten(filename); - end; - - contents = '(' .. filename .. ') ' .. contents; - end; - else - contents = msg.content; - end; - - table.insert(msgs, contents); - end; - - return table.concat(msgs, ' '); -end; - -local LSPMessages = { - provider = function() - local progress = get_lsp_progress(); - - if progress == '' then - return ''; - else - return ' ' .. progress; - end; - end, - hl = { fg = 'purple' }, -}; - -local Diagnostics = { - condition = conditions.has_diagnostics, - - static = { - error_icon = ' ', - warn_icon = ' ', - info_icon = ' ', - hint_icon = ' ', - }, - - init = function(self) - self.errors = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.ERROR }); - self.warnings = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.WARN }); - self.hints = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.HINT }); - self.info = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.INFO }); - end, - - update = { 'DiagnosticChanged', 'BufEnter' }, - - { - provider = function(self) - -- 0 is just another output, we can decide to print it or not! - return self.errors > 0 and (self.error_icon .. self.errors); - end, - hl = { fg = 'diag_error' }, - }, - { - provider = function(self) - return self.warnings > 0 and (self.warn_icon .. self.warnings); - end, - hl = { fg = 'diag_warn' }, - }, - { - provider = function(self) - return self.info > 0 and (self.info_icon .. self.info); - end, - hl = { fg = 'diag_info' }, - }, - { - provider = function(self) - return self.hints > 0 and (self.hint_icon .. self.hints); - end, - hl = { fg = 'diag_hint' }, - }, -}; - -local Git = { - condition = conditions.is_git_repo, - - init = function(self) - self.status_dict = vim.b.gitsigns_status_dict; - self.has_changes = self.status_dict.added ~= 0 or - self.status_dict.removed ~= 0 or - self.status_dict.changed ~= 0; - end, - - hl = { fg = 'orange' }, - - { -- git branch name - provider = function(self) - return ' ' .. self.status_dict.head; - end, - hl = { bold = true }, - }, - -- You could handle delimiters, icons and counts similar to Diagnostics - { - condition = function(self) - return self.has_changes; - end, - provider = '(', - }, - { - provider = function(self) - local count = self.status_dict.added or 0; - return count > 0 and ('+' .. count); - end, - hl = { fg = 'git_add' }, - }, - { - provider = function(self) - local count = self.status_dict.removed or 0; - return count > 0 and ('-' .. count); - end, - hl = { fg = 'git_del' }, - }, - { - provider = function(self) - local count = self.status_dict.changed or 0; - return count > 0 and ('~' .. count); - end, - hl = { fg = 'git_change' }, - }, - { - condition = function(self) - return self.has_changes; - end, - provider = ')', - }, -}; - -local Align = { provider = '%=' }; -local Space = { provider = ' ' }; - -Left = utils.surround({ '', '' }, 'bright_bg', { ViMode, Diagnostics, LSPMessages }); -Middle = utils.surround({ '', '' }, 'bright_bg', { LSPActive, FileNameBlock, Ruler }); -Right = utils.surround({ '', '' }, 'bright_bg', { Git, Space, ScrollRuler, Space, ScrollBar }); - -local DefaultStatusline = { - hl = { bg = 'dark_bg' }, - condition = function() - return true; - end, - Left, - Align, - Middle, - Align, - Right, -}; - -local StatusLines = { - hl = function() - if conditions.is_active() then - return 'StatusLine'; - else - return 'StatusLineNC'; - end; - end, - - -- the first statusline with no condition, or which condition returns true is used. - -- think of it as a switch case with breaks to stop fallthrough. - fallthrough = false, - - DefaultStatusline, -}; - --- Make it global -vim.opt.laststatus = 3; - -require('heirline').setup({ - statusline = StatusLines, -}); diff --git a/homeManagerModules/neovim/theme/config/neotree.lua b/homeManagerModules/neovim/theme/config/neotree.lua deleted file mode 100644 index dbb94cbc..00000000 --- a/homeManagerModules/neovim/theme/config/neotree.lua +++ /dev/null @@ -1,65 +0,0 @@ --- Override netrw -vim.g.loaded_netrw = 0; -vim.g.loaded_netrwPlugin = 0; - -require('neo-tree').setup({ - close_if_last_window = true, - enable_refresh_on_write = true, - - window = { - width = 22, - }, - - filesystem = { - use_libuv_file_watcher = true, - group_empty_dirs = true, - - filtered_items = { - visible = false, - hide_dotfiles = false, - hide_gitignored = false, - hide_by_name = {}, - hide_by_pattern = {}, - always_show = {}, - never_show = {}, - never_show_by_pattern = {}, - }, - }, - - source_selector = { - winbar = true, - statusline = false, - }, - - follow_current_file = { - enabled = true, - leave_dirs_open = true, - }, -}); - -local function is_neotree_open() - for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do - if vim.api.nvim_get_option_value('ft', { buf = vim.api.nvim_win_get_buf(win) }) == 'neo-tree' then - return true; - end; - end; - return false; -end; - --- Auto open Neo-Tree on big enough window -vim.api.nvim_create_autocmd({ 'VimEnter', 'VimResized' }, { - pattern = '*', - callback = function() - if vim.api.nvim_eval([[&columns]]) > 100 then - if is_neotree_open() == false then - vim.cmd[[Neotree show]]; - vim.cmd[[Neotree close]]; - vim.cmd[[Neotree show]]; - end; - else - if is_neotree_open() then - vim.cmd[[Neotree close]]; - end; - end; - end, -}); diff --git a/homeManagerModules/neovim/theme/default.nix b/homeManagerModules/neovim/theme/default.nix deleted file mode 100644 index f077e659..00000000 --- a/homeManagerModules/neovim/theme/default.nix +++ /dev/null @@ -1,164 +0,0 @@ -self: { - config, - pkgs, - lib, - ... -}: let - inherit (self.inputs) nvim-theme-src; - inherit (self.lib.${pkgs.system}) mkVersion; - - inherit (lib) attrValues fileContents getExe mkIf; - - cfg = config.programs.neovim; -in { - imports = [./treesitter.nix]; - - config = mkIf cfg.enable { - programs.neovim = { - extraPackages = attrValues { - inherit (pkgs) bat; - }; - - plugins = [ - { - plugin = pkgs.vimPlugins.dracula-nvim.overrideAttrs (o: { - name = "vimplugin-${o.pname}-${mkVersion nvim-theme-src}"; - src = nvim-theme-src; - }); - type = "lua"; - config = - # lua - '' - -- set dot icon in place of trailing whitespaces - vim.opt.listchars = { - tab = '→ ', - trail = '•', - extends = '⟩', - precedes = '⟨', - nbsp = '␣', - }; - vim.opt.list = true; - - -- Add visual indicator for trailing whitespaces - vim.opt.fillchars = { eob = " " }; - vim.fn.matchadd('errorMsg', [[\s\+$]]); - - vim.cmd.colorscheme('dracula'); - ''; - } - { - plugin = pkgs.vimPlugins.indent-blankline-nvim; - type = "lua"; - config = - # lua - '' - -- - local highlight = { - "RainbowRed", - "RainbowYellow", - "RainbowBlue", - "RainbowOrange", - "RainbowGreen", - "RainbowViolet", - "RainbowCyan", - }; - - local hooks = require('ibl.hooks'); - hooks.register(hooks.type.HIGHLIGHT_SETUP, function() - vim.api.nvim_set_hl(0, "RainbowRed", { fg = "#E06C75" }); - vim.api.nvim_set_hl(0, "RainbowYellow", { fg = "#E5C07B" }); - vim.api.nvim_set_hl(0, "RainbowBlue", { fg = "#61AFEF" }); - vim.api.nvim_set_hl(0, "RainbowOrange", { fg = "#D19A66" }); - vim.api.nvim_set_hl(0, "RainbowGreen", { fg = "#98C379" }); - vim.api.nvim_set_hl(0, "RainbowViolet", { fg = "#C678DD" }); - vim.api.nvim_set_hl(0, "RainbowCyan", { fg = "#56B6C2" }); - end); - - require('ibl').setup({ - indent = { - highlight = highlight, - char = "▏", - }, - }); - ''; - } - - { - plugin = pkgs.vimPlugins.nvim-highlight-colors; - type = "lua"; - config = - # lua - '' - -- Ensure termguicolors is enabled if not already - vim.opt.termguicolors = true; - - require('nvim-highlight-colors').setup({}); - ''; - } - - # Deps of heirline config - pkgs.vimPlugins.nvim-web-devicons - { - plugin = pkgs.vimPlugins.heirline-nvim; - type = "lua"; - config = fileContents ./config/heirline.lua; - } - - { - plugin = pkgs.vimPlugins.neo-tree-nvim.overrideAttrs (o: { - postPatch = '' - ${o.postPatch or ""} - for file in $(${pkgs.findutils}/bin/find ./lua/neo-tree -type f -name "*.lua"); do - substituteInPlace "$file" --replace-warn '"git"' '"${getExe pkgs.gitFull}"' - done - ''; - }); - type = "lua"; - config = fileContents ./config/neotree.lua; - } - { - plugin = pkgs.vimPlugins.transparent-nvim; - type = "lua"; - config = - # lua - '' - require('transparent').setup({ - groups = { - 'Normal', - 'NormalNC', - 'Comment', - 'Constant', - 'Special', - 'Identifier', - 'Statement', - 'PreProc', - 'Type', - 'Underlined', - 'Todo', - 'String', - 'Function', - 'Conditional', - 'Repeat', - 'Operator', - 'Structure', - 'LineNr', - 'NonText', - 'SignColumn', - 'CursorLine', - 'CursorLineNr', - 'StatusLine', - 'StatusLineNC', - 'EndOfBuffer', - }, - extra_groups = {}, - exclude_groups = {}, - }); - ''; - } - ]; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/theme/treesitter.nix b/homeManagerModules/neovim/theme/treesitter.nix deleted file mode 100644 index a8a374cb..00000000 --- a/homeManagerModules/neovim/theme/treesitter.nix +++ /dev/null @@ -1,48 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) mkIf; - - cfg = config.programs.neovim; -in { - config = mkIf cfg.enable { - programs.neovim.plugins = [ - { - plugin = pkgs.vimPlugins.nvim-treesitter-context; - type = "lua"; - config = - # lua - '' - require('treesitter-context').setup({ - enable = true, - max_lines = 3, - min_window_height = 20, - }); - - vim.cmd.hi('TreesitterContextBottom', 'gui=underline guisp=Grey'); - ''; - } - - pkgs.vimPlugins.nvim-treesitter-textobjects - - { - plugin = pkgs.vimPlugins.nvim-treesitter.withAllGrammars; - type = "lua"; - config = - # lua - '' - require('nvim-treesitter.configs').setup({ - highlight = { enable = true }, - indent = { enable = true }, - }); - ''; - } - ]; - }; - - # For accurate stack trace - _file = ./treesitter.nix; -} diff --git a/homeManagerModules/shell/config/bashrc b/homeManagerModules/shell/config/bashrc deleted file mode 100644 index 51e63556..00000000 --- a/homeManagerModules/shell/config/bashrc +++ /dev/null @@ -1,27 +0,0 @@ -# Check git status of nix configs -fetchNix() {( - cd "$FLAKE" || exit 1 - git fetch --all --quiet - GIT=$(git -c color.status=always status | - grep -v -e "On branch" \ - -e "up to date" \ - -e 'use "git' \ - -e "nothing to commit") - - CHECK=$(echo "$GIT" | sed '/^$/d') - - if [ "$CHECK" != "" ]; then - echo "$GIT" - echo - fi -)} - -# Check for internet -if wget -q --spider https://git.nelim.org; then - fetchNix -else - echo "Offline" -fi - -# Pokemon Sprite -pokemon-colorscripts -r 1-5 diff --git a/homeManagerModules/shell/config/colorgrid.sh b/homeManagerModules/shell/config/colorgrid.sh deleted file mode 100644 index 2c6dcc03..00000000 --- a/homeManagerModules/shell/config/colorgrid.sh +++ /dev/null @@ -1,31 +0,0 @@ - function colorgrid() { - iter=16 - while [ $iter -lt 52 ] - do - second=$[$iter+36] - third=$[$second+36] - four=$[$third+36] - five=$[$four+36] - six=$[$five+36] - seven=$[$six+36] - if [ $seven -gt 250 ];then seven=$[$seven-251]; fi - - echo -en "\033[38;5;$(echo $iter)m█ " - printf "%03d" $iter - echo -en " \033[38;5;$(echo $second)m█ " - printf "%03d" $second - echo -en " \033[38;5;$(echo $third)m█ " - printf "%03d" $third - echo -en " \033[38;5;$(echo $four)m█ " - printf "%03d" $four - echo -en " \033[38;5;$(echo $five)m█ " - printf "%03d" $five - echo -en " \033[38;5;$(echo $six)m█ " - printf "%03d" $six - echo -en " \033[38;5;$(echo $seven)m█ " - printf "%03d" $seven - - iter=$[$iter+1] - printf '\r\n' - done - } diff --git a/homeManagerModules/shell/config/dracula/fzf.sh b/homeManagerModules/shell/config/dracula/fzf.sh deleted file mode 100644 index 2e9f4e0e..00000000 --- a/homeManagerModules/shell/config/dracula/fzf.sh +++ /dev/null @@ -1,3 +0,0 @@ -# Modified from https://github.com/dracula/fzf - -export FZF_DEFAULT_OPTS='--color=fg:#f8f8f2,hl:#bd93f9 --color=fg+:#f8f8f2,hl+:#bd93f9 --color=info:#ffb86c,prompt:#50fa7b,pointer:#ff79c6 --color=marker:#ff79c6,spinner:#ffb86c,header:#6272a4' diff --git a/homeManagerModules/shell/config/dracula/less.sh b/homeManagerModules/shell/config/dracula/less.sh deleted file mode 100644 index e8b31d19..00000000 --- a/homeManagerModules/shell/config/dracula/less.sh +++ /dev/null @@ -1,10 +0,0 @@ -# Modified from https://github.com/dracula/man-pages - -#man-page colors -export LESS_TERMCAP_mb=$'\e[1;31m' # begin bold -export LESS_TERMCAP_md=$'\e[1;34m' # begin blink -export LESS_TERMCAP_so=$'\e[01;45;37m' # begin reverse video -export LESS_TERMCAP_us=$'\e[01;36m' # begin underline -export LESS_TERMCAP_me=$'\e[0m' # reset bold/blink -export LESS_TERMCAP_se=$'\e[0m' # reset reverse video -export LESS_TERMCAP_ue=$'\e[0m' # reset underline diff --git a/homeManagerModules/shell/default.nix b/homeManagerModules/shell/default.nix deleted file mode 100644 index 470350c0..00000000 --- a/homeManagerModules/shell/default.nix +++ /dev/null @@ -1,108 +0,0 @@ -self: { - config, - lib, - ... -}: let - inherit (lib) fileContents mkIf mkOption types; - - cfg = config.programs.bash; -in { - imports = [ - ./starship - ./trash - (import ./git self) - (import ./misc self) - (import ./nix-tools self) - ]; - - options.programs.bash = { - promptMainColor = mkOption { - type = types.enum (import ./prompt-schemes.nix {}); - default = "purple"; - }; - - promptColors = mkOption { - description = '' - Colors used in starship prompt - ''; - - default = import ./prompt-schemes.nix {color = cfg.promptMainColor;}; - - readOnly = true; - type = types.submodule { - options = let - inherit (types) str; - in { - textColor = mkOption {type = str;}; - firstColor = mkOption {type = str;}; - secondColor = mkOption {type = str;}; - thirdColor = mkOption {type = str;}; - fourthColor = mkOption {type = str;}; - }; - }; - }; - }; - - config = mkIf cfg.enable { - programs.bash = { - enableCompletion = true; - - historyFile = "\$HOME/.cache/.bash_history"; - historyFileSize = 100000; # default - historySize = 10000; # default - historyControl = [ - "erasedups" - "ignorespace" - ]; - historyIgnore = [ - "ls" - "exit" - "logout" - ]; - - shellOptions = [ - "histappend" - "checkwinsize" - "extglob" - "globstar" - "checkjobs" - "autocd" - "cdspell" - "dirspell" - "dotglob" - ]; - - shellAliases = { - # Add whitespace after, to allow - # sudo to inherit all other aliases - sudo = "sudo "; - - ls = "ls -lah --color=auto"; - tree = "tree -a -I node_modules -I .git --gitignore"; - cp = "cp -r"; - }; - - #profileExtra = '' - #''; - bashrcExtra = - # bash - '' - # Check if shell is interactive - [[ $- == *i* ]] || return 0 - - ${fileContents ./config/dracula/less.sh} - ${fileContents ./config/dracula/fzf.sh} - - ${fileContents ./config/colorgrid.sh} - ${fileContents ./config/bashrc} - ''; - #initExtra = '' - #''; - #logoutExtra = '' - #''; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/shell/git/default.nix b/homeManagerModules/shell/git/default.nix deleted file mode 100644 index 61ebf00e..00000000 --- a/homeManagerModules/shell/git/default.nix +++ /dev/null @@ -1,112 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (lib) getExe mkIf; - - cfg = config.programs.bash; - - mkRemoteConf = remote: email: name: { - condition = "hasconfig:remote.*.url:${remote}*/**"; - contents.user = {inherit email name;}; - }; - mkDefaultRemote = remote: mkRemoteConf remote "matt@nelim.org" "matt1432"; - - mkGitAlias = script: "!${getExe script}"; -in { - config.programs = mkIf cfg.enable { - git = { - enable = true; - package = pkgs.gitFull; - - lfs.enable = true; - - signing.format = "ssh"; - - includes = [ - {path = toString pkgs.scopedPackages.dracula.git;} - - (mkDefaultRemote "https://github.com") - (mkDefaultRemote "git@github.com") - (mkDefaultRemote "git@git.nelim.org") - - (mkRemoteConf "git@gitlab.info.uqam.ca" "gj591944@ens.uqam.ca" "Mathis Hurtubise") - ]; - - delta = { - enable = true; - options = { - side-by-side = true; - line-numbers-zero-style = "#E6EDF3"; - }; - }; - - extraConfig = { - help.autocorrect = "prompt"; - - alias = { - diff-clean = "-c delta.side-by-side=false diff"; - diff-patch = "-c delta.side-by-side=false -c delta.keep-plus-minus-markers=true diff"; - - # https://stackoverflow.com/a/18317425 - ignore = "update-index --assume-unchanged"; - unignore = "update-index --no-assume-unchanged"; - ignored = "!git ls-files -v | ${getExe pkgs.gnugrep} \"^[[:lower:]]\""; - - untracked-ignore = mkGitAlias (pkgs.writeShellApplication { - name = "untracked-ignore"; - text = '' - if [ $# -eq 0 ]; then - echo "No file names provided" - exit 1 - fi - for arg in "$@"; do - echo -e "$arg\n" >> .git/info/exclude - done - ''; - }); - untracked-unignore = mkGitAlias (pkgs.writeShellApplication { - name = "untracked-unignore"; - text = '' - if [ $# -eq 0 ]; then - echo "No file names provided" - exit 1 - fi - for arg in "$@"; do - sed -i "s/$arg//" .git/info/exclude - done - ''; - }); - untracked-ignored = mkGitAlias (pkgs.writeShellApplication { - name = "untracked-ignored"; - text = '' - while IFS= read -r line; do - if [[ "$line" != "" ]] && [[ "$line" != "#"* ]]; then - echo "$line" - fi - done < .git/info/exclude - ''; - }); - }; - - diff.sopsdiffer.textconv = "sops decrypt"; - - sendemail = { - smtpserver = "127.0.0.1"; - smtpuser = "matt@nelim.org"; - smtpencryption = "tls"; - smtpserverport = 1025; - smtpsslcertpath = ""; - }; - }; - }; - - # https://github.com/dandavison/delta/issues/630#issuecomment-2003149860 - bash.sessionVariables.LESS = "-R --mouse"; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/shell/misc/default.nix b/homeManagerModules/shell/misc/default.nix deleted file mode 100644 index 61221c25..00000000 --- a/homeManagerModules/shell/misc/default.nix +++ /dev/null @@ -1,61 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (lib) attrValues mkIf; - - cfg = config.programs.bash; -in { - config.programs = mkIf cfg.enable { - fzf = { - enable = true; - enableBashIntegration = true; - }; - - bash = { - sessionVariables = { - inherit (config.home.sessionVariables) RIPGREP_CONFIG_PATH; - }; - - shellAliases = { - rg = "rga"; - cat = "bat "; - man = "BAT_THEME='default' batman "; - }; - }; - - ripgrep = { - enable = true; - package = pkgs.ripgrep-all; - - arguments = [ - "--max-columns=150" - "--max-columns-preview" - "--hidden" - "--glob=!.git/*" - "--smart-case" - "--sort" - "path" - ]; - }; - - jq.enable = true; - htop.enable = true; - - bat = { - enable = true; - - config.theme = "dracula-bat"; - themes.dracula-bat.src = pkgs.scopedPackages.dracula.bat; - - extraPackages = attrValues { - inherit (pkgs.bat-extras) batman; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/shell/nix-tools/default.nix b/homeManagerModules/shell/nix-tools/default.nix deleted file mode 100644 index bbb1d956..00000000 --- a/homeManagerModules/shell/nix-tools/default.nix +++ /dev/null @@ -1,35 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (lib) mkIf; - inherit (self.inputs) nix-index-db; - - cfg = config.programs.bash; -in { - imports = [nix-index-db.hmModules.nix-index]; - - config.programs = mkIf cfg.enable { - direnv = { - enable = true; - enableBashIntegration = true; - - nix-direnv = { - enable = true; - package = pkgs.nix-direnv; - }; - }; - - nix-index-database.comma.enable = true; - - nix-index = { - enable = true; - enableBashIntegration = true; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/shell/prompt-schemes.nix b/homeManagerModules/shell/prompt-schemes.nix deleted file mode 100644 index 98553684..00000000 --- a/homeManagerModules/shell/prompt-schemes.nix +++ /dev/null @@ -1,81 +0,0 @@ -{color ? null}: let - inherit (builtins) attrNames removeAttrs; - - schemes = { - "purple" = { - textColor = "#090c0c"; - firstColor = "#bd93f9"; - secondColor = "#715895"; - thirdColor = "#382c4a"; - fourthColor = "#120e18"; - }; - - "green" = { - textColor = "#090c0c"; - firstColor = "#78ae66"; - secondColor = "#567c49"; - thirdColor = "#334a2c"; - fourthColor = "#11180e"; - }; - - "red" = { - textColor = "#090c0c"; - firstColor = "#e04242"; - secondColor = "#9c2e2e"; - thirdColor = "#591a1a"; - fourthColor = "#160606"; - }; - - "blue" = { - textColor = "#090c0c"; - firstColor = "#6684ee"; - secondColor = "#475ca6"; - thirdColor = "#28345f"; - fourthColor = "#010617"; - }; - - "orange" = { - textColor = "#090c0c"; - firstColor = "#ff9c42"; - secondColor = "#c66b00"; - thirdColor = "#874500"; - fourthColor = "#3a1c00"; - }; - - "yellow" = { - textColor = "#090c0c"; - firstColor = "#ffea42"; - secondColor = "#d4c300"; - thirdColor = "#8f8b00"; - fourthColor = "#3e3c00"; - }; - - "cyan" = { - textColor = "#090c0c"; - firstColor = "#42eaff"; - secondColor = "#00a2b8"; - thirdColor = "#005768"; - fourthColor = "#001f26"; - }; - - "pink" = { - textColor = "#090c0c"; - firstColor = "#ff42cb"; - secondColor = "#b80073"; - thirdColor = "#6b003f"; - fourthColor = "#2d0017"; - }; - - # Template - "color" = { - textColor = "#090c0c"; - firstColor = ""; - secondColor = ""; - thirdColor = ""; - fourthColor = ""; - }; - }; -in - if ! isNull color - then schemes.${color} - else attrNames (removeAttrs schemes ["color"]) diff --git a/homeManagerModules/shell/starship/default.nix b/homeManagerModules/shell/starship/default.nix deleted file mode 100644 index ac488d8e..00000000 --- a/homeManagerModules/shell/starship/default.nix +++ /dev/null @@ -1,84 +0,0 @@ -{ - config, - lib, - ... -}: let - inherit (lib) concatStrings mkIf; - - cfg = config.programs.bash; -in { - programs.starship = mkIf cfg.enable { - enable = true; - enableBashIntegration = true; - - settings = { - format = concatStrings [ - "╭╴" - "[](fg:${cfg.promptColors.firstColor})" - "[ ](bg:${cfg.promptColors.firstColor} fg:#090c0c)" - "[](bg:${cfg.promptColors.secondColor} fg:${cfg.promptColors.firstColor})" - "$username$hostname" - "[](fg:${cfg.promptColors.secondColor} bg:${cfg.promptColors.thirdColor})" - "$directory" - "[](fg:${cfg.promptColors.thirdColor} bg:${cfg.promptColors.fourthColor})" - "$git_branch" - "[](fg:${cfg.promptColors.fourthColor})$shlvl$nix_shell" - "\n╰╴$character" - ]; - - username = { - show_always = true; - style_user = "fg:${cfg.promptColors.textColor} bg:${cfg.promptColors.secondColor}"; - style_root = "fg:red bg:${cfg.promptColors.secondColor} blink"; - format = "[ $user]($style)"; - }; - - hostname = { - ssh_only = false; - style = "fg:${cfg.promptColors.textColor} bg:${cfg.promptColors.secondColor}"; - format = "[@$hostname ]($style)"; - }; - - directory = { - style = "fg:${cfg.promptColors.firstColor} bg:${cfg.promptColors.thirdColor}"; - format = "[ $path ]($style)"; - truncate_to_repo = false; - truncation_length = 0; - - substitutions = { - "Documents" = ""; - "Downloads" = ""; - "Music" = ""; - "Pictures" = ""; - }; - }; - - git_branch = { - style = "fg:${cfg.promptColors.secondColor} bg:${cfg.promptColors.fourthColor}"; - symbol = ""; - format = "[ $symbol $branch ]($style)"; - }; - - shlvl = { - disabled = false; - threshold = 2; - - symbol = " "; - format = "[$symbol]($style)"; - - repeat = true; - repeat_offset = 1; - }; - - nix_shell = { - symbol = "❄️ "; - format = "[ $symbol]($style)"; - }; - - character = { - success_symbol = "[\\$](bold green)"; - error_symbol = "[\\$](bold red)"; - }; - }; - }; -} diff --git a/homeManagerModules/shell/trash/default.nix b/homeManagerModules/shell/trash/default.nix deleted file mode 100644 index 22619966..00000000 --- a/homeManagerModules/shell/trash/default.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) elem mkIf; - - cfg = config.programs.bash; - trashPkg = pkgs.selfPackages.trash-d; - isCorrectPlatform = elem pkgs.system (trashPkg.meta.platforms or [pkgs.system]); -in { - config = mkIf (cfg.enable && isCorrectPlatform) { - home.packages = [trashPkg]; - - programs.bash.shellAliases.rm = "trash"; - }; -} diff --git a/inputs/README.md b/inputs/README.md deleted file mode 100644 index ccd5f2a4..00000000 --- a/inputs/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# Inputs - -To allow use of the full nix language for my inputs, I use [genflake](https://github.com/jorsn/flakegen). -Therefore, the flake I edit is located at `$FLAKE/_outputs.nix`. - -I also prefer using a more descriptive format for my inputs like so: - -```nix -nixpkgs = { - type = "github"; - owner = "NixOS"; - repo = "nixpkgs"; - - # Branch name - ref = "nixos-unstable"; - - # Pin this input to a specific commit - rev = "842d9d80cfd4560648c785f8a4e6f3b096790e19"; -}; -``` - -to make it more clear what is what in the flake URI diff --git a/inputs/default.nix b/inputs/default.nix deleted file mode 100644 index 9db4735d..00000000 --- a/inputs/default.nix +++ /dev/null @@ -1,438 +0,0 @@ -let - inherit (import ./lib.nix) mkInput mkHyprDep mkSrc; - inherit (builtins) listToAttrs map removeAttrs; - - # Inputs - mainInputs = { - systems = mkInput { - owner = "nix-systems"; - repo = "default-linux"; - }; - - nixpkgs = mkInput { - owner = "NixOS"; - repo = "nixpkgs"; - ref = "nixos-unstable"; - }; - - home-manager = mkInput { - owner = "nix-community"; - repo = "home-manager"; - }; - - nix-on-droid = mkInput { - owner = "nix-community"; - repo = "nix-on-droid"; - - inputs.home-manager.follows = "home-manager"; - }; - - sops-nix = mkInput { - owner = "Mic92"; - repo = "sops-nix"; - }; - - secrets = mkInput { - type = "git"; - url = "ssh://git@git.nelim.org/matt1432/nixos-secrets"; - - inputs.sops-nix.follows = "sops-nix"; - }; - }; - - nixTools = { - nix-serve-ng = mkInput { - owner = "aristanetworks"; - repo = "nix-serve-ng"; - - inputs.utils.follows = "flake-utils"; - }; - - nix-fast-build = mkInput { - owner = "Mic92"; - repo = "nix-fast-build"; - }; - - nix-eval-jobs = mkInput { - owner = "nix-community"; - repo = "nix-eval-jobs"; - ref = "v2.28.1"; - }; - - nix-index-db = mkInput { - owner = "Mic92"; - repo = "nix-index-database"; - }; - - nh = mkInput { - owner = "viperML"; - repo = "nh"; - }; - - nurl = mkInput { - owner = "nix-community"; - repo = "nurl"; - }; - - # These are here to make sure all 'systems' and popular inputs are the same - flake-compat = mkInput { - owner = "edolstra"; - repo = "flake-compat"; - }; - flake-utils = mkInput { - owner = "numtide"; - repo = "flake-utils"; - }; - flake-parts = mkInput { - owner = "hercules-ci"; - repo = "flake-parts"; - inputs.nixpkgs-lib.follows = "nixpkgs"; - }; - treefmt-nix = mkInput { - owner = "numtide"; - repo = "treefmt-nix"; - }; - lib-aggregate = mkInput { - owner = "nix-community"; - repo = "lib-aggregate"; - }; - nix-github-actions = mkInput { - owner = "nix-community"; - repo = "nix-github-actions"; - }; - pre-commit-hooks = mkInput { - owner = "cachix"; - repo = "git-hooks.nix"; - inputs.flake-compat.follows = "flake-compat"; - }; - }; - - overlays = { - nix-gaming = mkInput { - owner = "fufexan"; - repo = "nix-gaming"; - }; - }; - - nvimInputs = { - nixd = mkInput { - owner = "nix-community"; - repo = "nixd"; - }; - }; - - clusterInputs = { - pcsd = mkInput { - owner = "matt1432"; - repo = "nixos-pcsd"; - }; - }; - - serviviInputs = { - minix = mkInput { - owner = "matt1432"; - repo = "Minix"; - }; - - pr-tracker = mkInput { - owner = "matt1432"; - repo = "pr-tracker"; - }; - }; - - nosInputs = { - docker-compose = mkInput { - owner = "matt1432"; - repo = "nixos-docker-compose"; - }; - - nixos-jellyfin = mkInput { - owner = "matt1432"; - repo = "nixos-jellyfin"; - }; - - bazarr-bulk = mkInput { - owner = "mateoradman"; - repo = "bazarr-bulk"; - }; - }; - - desktopInputs = { - hyprlandInputs = { - hyprland = mkInput { - owner = "hyprwm"; - repo = "Hyprland"; - }; - - hyprland-plugins = mkHyprDep { - owner = "hyprwm"; - repo = "hyprland-plugins"; - }; - - hyprgrass = mkHyprDep { - owner = "horriblename"; - repo = "hyprgrass"; - }; - - hyprpaper = mkHyprDep { - owner = "hyprwm"; - repo = "hyprpaper"; - }; - - grim-hyprland = mkInput { - owner = "eriedaberrie"; - repo = "grim-hyprland"; - }; - - nixcord = mkInput { - owner = "kaylorben"; - repo = "nixcord"; - }; - }; - - agsInputs = { - astal = mkInput { - # owner = "Aylur"; - repo = "astal"; - - # FIXME: https://github.com/Aylur/astal/pull/314 - owner = "matt1432"; - ref = "overlay"; - }; - - ags = mkInput { - # owner = "Aylur"; - repo = "ags"; - - # FIXME: https://github.com/Aylur/astal/pull/314 - owner = "matt1432"; - ref = "overlay"; - - inputs.astal.follows = "astal"; - }; - - kompass = mkInput { - owner = "kotontrion"; - repo = "kompass"; - - inputs.astal.follows = "astal"; - }; - - virtualkeyboard-adapter = mkInput { - owner = "horriblename"; - repo = "fcitx-virtualkeyboard-adapter"; - }; - }; - }; - - bbsteamieInputs = { - jovian = mkInput { - owner = "Jovian-Experiments"; - repo = "Jovian-NixOS"; - }; - }; - - srcs = [ - # Home-assistant - ## Components - { - name = "extended-ollama-conversation-src"; - owner = "TheNimaj"; - repo = "extended_ollama_conversation"; - } - { - owner = "make-all"; - repo = "tuya-local"; - } - { - name = "netdaemon-src"; - owner = "net-daemon"; - repo = "integration"; - } - { - owner = "osk2"; - repo = "yamaha-soundbar"; - } - - ### SpotifyPlus - { - name = "spotifyplus-src"; - owner = "thlucas1"; - repo = "homeassistantcomponent_spotifyplus"; - } - { - name = "smartinspect-src"; - owner = "thlucas1"; - repo = "SmartInspectPython"; - } - { - name = "spotifywebapi-src"; - owner = "thlucas1"; - repo = "SpotifyWebApiPython"; - } - ### - - ## Voice - { - name = "wakewords-src"; - owner = "fwartner"; - repo = "home-assistant-wakewords-collection"; - } - - ## Themes - { - owner = "berti24"; - repo = "dracul-ha"; - } - { - name = "caule-themes-src"; - owner = "ricardoquecria"; - repo = "caule-themes-pack-1"; - } - - ## Lovelace Components - { - owner = "beecho01"; - repo = "material-symbols"; - } - { - owner = "elchininet"; - repo = "custom-sidebar"; - } - - # Nvim plugins - { - name = "vimplugin-easytables-src"; - owner = "Myzel394"; - repo = "easytables.nvim"; - } - { - name = "vimplugin-ts-error-translator-src"; - owner = "dmmulroy"; - repo = "ts-error-translator.nvim"; - } - { - name = "vimplugin-roslyn-nvim-src"; - owner = "seblj"; - repo = "roslyn.nvim"; - } - { - name = "nix-develop-nvim-src"; - owner = "matt1432"; - repo = "nix-develop.nvim"; - } - - # Overlays & packages - { - name = "Kapowarr-src"; - owner = "matt1432"; - repo = "Kapowarr"; - ref = "build-system"; - # type = "path"; - # path = "/home/matt/git/Kapowarr"; - } - { - type = "gitlab"; - owner = "rogs"; - repo = "subscleaner"; - } - { - type = "gitlab"; - owner = "phoneybadger"; - repo = "pokemon-colorscripts"; - } - { - name = "gpu-screen-recorder-src"; - type = "git"; - url = "https://repo.dec05eba.com/gpu-screen-recorder"; - } - { - owner = "libratbag"; - repo = "libratbag"; - } - { - owner = "libratbag"; - repo = "piper"; - } - { - owner = "gjsify"; - repo = "ts-for-gir"; - } - - # MPV scripts - { - name = "modernz-src"; - owner = "Samillion"; - repo = "ModernZ"; - } - { - owner = "d87"; - repo = "mpv-persist-properties"; - } - { - owner = "christoph-heinrich"; - repo = "mpv-pointer-event"; - } - { - owner = "christoph-heinrich"; - repo = "mpv-touch-gestures"; - } - { - name = "eisa-scripts-src"; - owner = "Eisa01"; - repo = "mpv-scripts"; - } - - ## Theme sources - { - name = "bat-theme-src"; - owner = "matt1432"; - repo = "bat"; - } - { - name = "git-theme-src"; - owner = "dracula"; - repo = "git"; - } - { - name = "gtk-theme-src"; - owner = "dracula"; - repo = "gtk"; - } - { - name = "nvim-theme-src"; - owner = "Mofiqul"; - repo = "dracula.nvim"; - } - { - owner = "matt1432"; - repo = "dracula-plymouth"; - } - { - name = "sioyek-theme-src"; - owner = "dracula"; - repo = "sioyek"; - } - ]; -in - { - flakegen = { - url = "github:jorsn/flakegen"; - inputs.systems.follows = "systems"; - }; - } - // mainInputs - // nixTools - // overlays - // nvimInputs - // clusterInputs - // serviviInputs - // nosInputs - // bbsteamieInputs - // desktopInputs.hyprlandInputs - // desktopInputs.agsInputs - // (listToAttrs (map (x: { - name = x.name or "${x.repo}-src"; - value = mkSrc (removeAttrs x ["name"]); - }) - srcs)) diff --git a/inputs/lib.nix b/inputs/lib.nix deleted file mode 100644 index 2d5ae8dd..00000000 --- a/inputs/lib.nix +++ /dev/null @@ -1,67 +0,0 @@ -let - inherit (builtins) fetchTarball fromJSON readFile removeAttrs; - - lock = fromJSON (readFile ../flake.lock); - lib = import "${fetchTarball { - url = "https://github.com/NixOS/nixpkgs/archive/${lock.nodes.nixpkgs.locked.rev}.tar.gz"; - sha256 = lock.nodes.nixpkgs.locked.narHash; - }}/lib"; - - inherit (lib) attrNames attrValues findFirst foldl' hasAttr matchAttrs optionalAttrs optionals recursiveUpdate; -in rec { - recursiveUpdateList = list: foldl' recursiveUpdate {} list; - - findInput = info: - findFirst - (x: matchAttrs (removeAttrs info ["inputs"]) (x.original or {})) {} - (attrValues lock.nodes); - - mkFollowsFrom = info: target: follows: - optionalAttrs - (hasAttr target ((findInput info).inputs or {})) - {inputs.${target} = {inherit follows;};}; - - /* - * From an attrset, returns a flake input that has its type defaulted - * to `github` and has some of its inputs following this flake's input - * of the same name. - * - * It gets information from the `flake.lock` file and can be used thanks - * to flakegen - */ - mkInput = { - type ? "github", - overrideNixpkgs ? true, - ... - } @ info: let - mkOverride = i: mkFollowsFrom info i i; - in - recursiveUpdateList ([ - (removeAttrs info ["overrideNixpkgs"]) - {inherit type;} - - # Generic inputs - (mkOverride "systems") - (mkOverride "flake-compat") - (mkOverride "flake-utils") - (mkOverride "flake-parts") - (mkOverride "lib-aggregate") - (mkOverride "nix-eval-jobs") - (mkOverride "nix-github-actions") - (mkOverride "pre-commit-hooks") - (mkOverride "treefmt-nix") - ] - # Specify if we can't make an input use this flake's nixpkgs - ++ optionals overrideNixpkgs [(mkOverride "nixpkgs")]); - - mkHyprDep = info: let - inherit (lock.nodes) hyprland; - - mkOverride = i: mkFollowsFrom info i i; - mkHyprOverride = i: mkFollowsFrom info i "hyprland/${i}"; - in - mkInput (recursiveUpdateList ([info (mkOverride "hyprland")] - ++ (map mkHyprOverride (attrNames hyprland.inputs)))); - - mkSrc = info: mkInput (info // {flake = false;}); -} diff --git a/justfile b/justfile deleted file mode 100644 index d82336ef..00000000 --- a/justfile +++ /dev/null @@ -1,32 +0,0 @@ -default: - @just --list - -docs: - nix run "$FLAKE"#gen-docs - -genflake: - #!/usr/bin/env bash - # Get changes from inputs/default.nix - nix run "$FLAKE"#genflake "$FLAKE"/flake.nix && - # Evaluate `follows` from new flake.lock - nix run "$FLAKE"#genflake "$FLAKE"/flake.nix && - # Make sure everything is right - nix run "$FLAKE"#genflake "$FLAKE"/flake.nix - - alejandra -q "$FLAKE"/flake.nix - -[positional-arguments] -l2s action list: - nix run "$FLAKE"#list2series -- "$@" - -[positional-arguments] -mc-mods version action='check': - nix run "$FLAKE"#mc-mods -- "$@" - -[positional-arguments] -pin args: - nix run "$FLAKE"#pin-inputs -- "$@" - -[positional-arguments] -up args: - nix run "$FLAKE"#update-sources -- "$@" diff --git a/lib/README.md b/lib/README.md deleted file mode 100644 index 5f809ae1..00000000 --- a/lib/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Lib - -This directory contains Nix functions separated by what type or program they are associated with. - -| Attribute Set | Description | -| ------------- | ------------------------------------------------------------------------------------------------ | -| `attrs` | [Misc functions dealing with attribute sets](./attrs) | -| `flake` | [Helper functions for top level flake outputs](./flake) | -| `hypr` | [Helper functions to configure hyprland in a cleaner way](./hypr) | -| `pkgs` | [Misc functions dealing with packages](./pkgs) | -| `strings` | [Misc functions dealing with strings](./strings) | diff --git a/lib/attrs/default.nix b/lib/attrs/default.nix deleted file mode 100644 index 546a70e2..00000000 --- a/lib/attrs/default.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ - foldl, - hasAttr, - isAttrs, - isList, - mergeAttrsWithFunc, - unique, - ... -}: { - inherit (import ../../inputs/lib.nix) recursiveUpdateList; - - throws = x: !(builtins.tryEval x).success; - hasVersion = x: isAttrs x && hasAttr "version" x; - mergeAttrsList = list: - foldl (mergeAttrsWithFunc (a: b: - if isList a && isList b - then unique (a ++ b) - else b)) {} - list; -} diff --git a/lib/default.nix b/lib/default.nix deleted file mode 100644 index 6e459e00..00000000 --- a/lib/default.nix +++ /dev/null @@ -1,24 +0,0 @@ -{ - perSystem, - inputs, -}: let - attrs = import ./attrs inputs.nixpkgs.lib; - flake = import ./flake inputs; - hypr = import ./hypr inputs.nixpkgs.lib; - strings = import ./strings inputs.nixpkgs.lib; - - lib = attrs // flake // hypr // strings; -in - # Expose main attrs - lib - # Expose all funcs - // {inherit attrs flake hypr strings;} - # Expose funcs that require pkgs - // perSystem ( - pkgs: - (import ./pkgs { - inherit pkgs; - inherit (inputs) self; - }) - // lib - ) diff --git a/lib/flake/default.nix b/lib/flake/default.nix deleted file mode 100644 index d11bf381..00000000 --- a/lib/flake/default.nix +++ /dev/null @@ -1,119 +0,0 @@ -inputs: let - inherit (builtins) removeAttrs; -in rec { - # Import pkgs from a nixpkgs instance - mkPkgs = { - system, - nixpkgs, - cfg ? {}, - nix ? null, - cudaSupport ? false, - }: - import nixpkgs { - inherit system; - overlays = nixpkgs.lib.unique ([ - # Needed for nix-version overlay - inputs.nix-serve-ng.overlays.default - - (inputs.self.overlays.nix-version {inherit nix;}) - inputs.self.overlays.misc-fixes - inputs.self.overlays.appsPackages - inputs.self.overlays.selfPackages - inputs.self.overlays.scopedPackages - ] - ++ (cfg.overlays or [])); - config = - { - inherit cudaSupport; - allowUnfree = true; - - # In case I need an insecure package in my devShells - permittedInsecurePackages = - [] - ++ (cfg.config.permittedInsecurePackages or []); - } - // (removeAttrs ( - if cfg.config or null == null - then {} - else cfg.config - ) ["permittedInsecurePackages"]); - }; - - # Enable use of `nixpkgs.overlays` on both NixOS and NixOnDroid - allowModularOverrides = { - cudaSupport ? false, - system, - }: ({config, ...}: let - pkgs = mkPkgs { - cfg = config.nixpkgs; - nix = config.nix.package; - inherit system cudaSupport; - inherit (inputs) nixpkgs; - }; - inherit (pkgs.lib) mkForce; - in { - _module.args.pkgs = mkForce pkgs; - }); - - # Default system - mkNixOS = { - extraModules ? [], - cudaSupport ? false, - mainUser ? "matt", - }: - inputs.nixpkgs.lib.nixosSystem rec { - system = "x86_64-linux"; - specialArgs = inputs // {inherit mainUser;}; - modules = - [ - (allowModularOverrides {inherit system cudaSupport;}) - inputs.home-manager.nixosModules.home-manager - {home-manager.extraSpecialArgs = specialArgs;} - ] - ++ extraModules; - }; - - mkNixOnDroid = extraModules: let - system = "aarch64-linux"; - in - inputs.nix-on-droid.lib.nixOnDroidConfiguration rec { - extraSpecialArgs = inputs; - home-manager-path = inputs.home-manager.outPath; - pkgs = mkPkgs { - inherit system; - inherit (inputs) nixpkgs; - }; - - modules = - [ - (allowModularOverrides {inherit system;}) - - ({ - config, - lib, - ... - }: let - inherit (lib) mkForce mkOption types; - in { - # Adapt NixOnDroid to NixOS options - options.environment = { - variables.FLAKE = mkOption { - type = with types; nullOr str; - }; - systemPackages = mkOption { - type = with types; listOf package; - default = []; - }; - }; - - config.environment.packages = config.environment.systemPackages; - - # This disables the assertion that fails because of nixpkgs.overlays - config._module.args.isFlake = mkForce false; - }) - - {home-manager = {inherit extraSpecialArgs;};} - ] - ++ extraModules; - }; -} diff --git a/lib/hypr/default.nix b/lib/hypr/default.nix deleted file mode 100644 index ccbc5936..00000000 --- a/lib/hypr/default.nix +++ /dev/null @@ -1,108 +0,0 @@ -{ - concatStringsSep, - elemAt, - optional, - optionals, - ... -}: rec { - pointToStr = p: "${toString (elemAt p 0)}, ${toString (elemAt p 1)}"; - - mkBezier = { - name, - p0, - p1, - }: - concatStringsSep "," [name (pointToStr p0) (pointToStr p1)]; - - mkAnimation = { - name, - enable ? true, - duration ? 0, # in ds (100ms) - bezier ? "default", - style ? null, - }: - concatStringsSep "," ( - [ - name - ( - if enable - then "1" - else "0" - ) - ] - ++ optionals enable ( - [ - (toString duration) - bezier - ] - ++ optional (style != null) style - ) - ); - - mkLayerRule = { - rule, - namespace, - }: - concatStringsSep "," [rule namespace]; - - mkBind = { - modifier ? "", - key, - dispatcher ? "exec", - command ? null, - }: - concatStringsSep "," ( - [modifier key dispatcher] - ++ optional (command != null) command - ); - - mkMonitor = { - description ? null, - name ? null, - resolution ? null, - refreshRate ? null, - position ? "auto", - scale ? "1", - transform ? null, - mirror ? null, - bitdepth ? null, - vrr ? null, - }: let - transformMap = { - "normal" = 0; - "90" = 1; - "180" = 2; - "270" = 3; - "normalf" = 4; - "90f" = 5; - "180f" = 6; - "270f" = 7; - }; - in - concatStringsSep "," ( - [ - ( - if name != null && description != null - then throw "description or name required" - else if name != null - then name - else "desc:${description}" - ) - ( - if resolution == null && refreshRate != null - then throw "resolution needed if refreshRate is specified" - else if resolution != null && refreshRate != null - then "${resolution}@${toString refreshRate}" - else if resolution != null && refreshRate == null - then resolution - else "preferred" - ) - position - scale - ] - ++ optional (transform != null) "transform, ${toString transformMap.${transform}}" - ++ optional (mirror != null) "mirror, ${mirror}" - ++ optional (bitdepth != null) "bitdepth, ${toString bitdepth}" - ++ optional (vrr != null) "vrr, ${toString vrr}" - ); -} diff --git a/lib/pkgs/default.nix b/lib/pkgs/default.nix deleted file mode 100644 index 4d4fff36..00000000 --- a/lib/pkgs/default.nix +++ /dev/null @@ -1,64 +0,0 @@ -{ - pkgs, - self, -}: let - inherit (builtins) readFile fromJSON; - inherit (self.lib) mkVersion; - inherit (pkgs.lib) concatStringsSep elemAt hasAttr length map optionalString toLower; -in { - buildPlugin = pname: src: - pkgs.vimUtils.buildVimPlugin { - inherit pname src; - version = mkVersion src; - }; - - buildNodeModules = dir: npmDepsHash: let - packageJSON = fromJSON (readFile (dir + /package.json)); - - pkg = pkgs.callPackage ({buildNpmPackage, ...}: - buildNpmPackage { - pname = packageJSON.name; - inherit (packageJSON) version; - - src = dir; - - inherit npmDepsHash; - dontNpmBuild = true; - }) {}; - in "${pkg}/lib/node_modules/${pkg.pname}/node_modules"; - - buildGirTypes = { - configPath, - packages, - pname, - }: let - girNameTable = { - gtk4 = ["Gtk-4.0"]; - gtk4-layer-shell = ["Gtk4LayerShell-1.0" "Gtk4SessionLock-1.0"]; - gtk-session-lock = ["GtkSessionLock-0.1"]; - libadwaita = ["Adw-1"]; - }; - - withGirNames = - map (package: let - in { - inherit package; - girName = - package.girName - or ( - if hasAttr package.pname girNameTable - then concatStringsSep " " girNameTable.${package.pname} - else throw "girName of ${package.name} couldn't be found" - ); - }) - packages; - in { - "${configPath}${optionalString (length packages == 1) "/${toLower (elemAt withGirNames 0).girName}"}" = { - force = true; - source = pkgs.callPackage ./mk-types { - inherit (self.inputs) ts-for-gir-src; - inherit pname withGirNames; - }; - }; - }; -} diff --git a/lib/pkgs/mk-types/.envrc b/lib/pkgs/mk-types/.envrc deleted file mode 100644 index c79171c6..00000000 --- a/lib/pkgs/mk-types/.envrc +++ /dev/null @@ -1 +0,0 @@ -use flake $FLAKE#node diff --git a/lib/pkgs/mk-types/default.nix b/lib/pkgs/mk-types/default.nix deleted file mode 100644 index 2579d360..00000000 --- a/lib/pkgs/mk-types/default.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ - lib, - pname, - withGirNames, - buildNpmPackage, - ts-for-gir-src, - ... -}: let - inherit (lib) concatMapStringsSep; - - buildPhase = '' - npx @ts-for-gir/cli generate \ - ${concatMapStringsSep "\n" (p: " ${p.girName} \\") withGirNames} - ${concatMapStringsSep "\n" (p: " -g ${p.package.dev or p.package}/share/gir-1.0 \\") withGirNames} - -g ${ts-for-gir-src}/girs \ - --ignoreVersionConflicts \ - -o ./types - ''; -in - buildNpmPackage { - pname = "${pname}-types"; - version = "0.0.0"; - - npmDepsHash = "sha256-NKmsPEshXn8nIpKPztSk47HsORMuo1twh4mQo91Bq20="; - - src = ./.; - dontNpmBuild = true; - - buildPhase = '' - echo -e '\n${buildPhase}\n' - ${buildPhase} - ''; - - installPhase = '' - cp -r ./types $out - ''; - } diff --git a/lib/pkgs/mk-types/package-lock.json b/lib/pkgs/mk-types/package-lock.json deleted file mode 100644 index 85998355..00000000 --- a/lib/pkgs/mk-types/package-lock.json +++ /dev/null @@ -1,1664 +0,0 @@ -{ - "name": "mk-types", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "@ts-for-gir/cli": "4.0.0-beta.23" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@gi.ts/parser": { - "version": "4.0.0-beta.23", - "resolved": "https://registry.npmjs.org/@gi.ts/parser/-/parser-4.0.0-beta.23.tgz", - "integrity": "sha512-PH3x+++ZECvsrFvhSITrrYQxyLaVg+PK6oJp81k5m0A5SL58tJOWDteblD72y7m70GnVMGBW/2Xi+IKE+v5xxg==", - "license": "MIT", - "dependencies": { - "fast-xml-parser": "^5.0.9" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@inquirer/checkbox": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.1.5.tgz", - "integrity": "sha512-swPczVU+at65xa5uPfNP9u3qx/alNwiaykiI/ExpsmMSQW55trmZcwhYWzw/7fj+n6Q8z1eENvR7vFfq9oPSAQ==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.10", - "@inquirer/figures": "^1.0.11", - "@inquirer/type": "^3.0.6", - "ansi-escapes": "^4.3.2", - "yoctocolors-cjs": "^2.1.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/confirm": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.9.tgz", - "integrity": "sha512-NgQCnHqFTjF7Ys2fsqK2WtnA8X1kHyInyG+nMIuHowVTIgIuS10T4AznI/PvbqSpJqjCUqNBlKGh1v3bwLFL4w==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.10", - "@inquirer/type": "^3.0.6" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/core": { - "version": "10.1.10", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.10.tgz", - "integrity": "sha512-roDaKeY1PYY0aCqhRmXihrHjoSW2A00pV3Ke5fTpMCkzcGF64R8e0lw3dK+eLEHwS4vB5RnW1wuQmvzoRul8Mw==", - "license": "MIT", - "dependencies": { - "@inquirer/figures": "^1.0.11", - "@inquirer/type": "^3.0.6", - "ansi-escapes": "^4.3.2", - "cli-width": "^4.1.0", - "mute-stream": "^2.0.0", - "signal-exit": "^4.1.0", - "wrap-ansi": "^6.2.0", - "yoctocolors-cjs": "^2.1.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/editor": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.10.tgz", - "integrity": "sha512-5GVWJ+qeI6BzR6TIInLP9SXhWCEcvgFQYmcRG6d6RIlhFjM5TyG18paTGBgRYyEouvCmzeco47x9zX9tQEofkw==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.10", - "@inquirer/type": "^3.0.6", - "external-editor": "^3.1.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/expand": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.12.tgz", - "integrity": "sha512-jV8QoZE1fC0vPe6TnsOfig+qwu7Iza1pkXoUJ3SroRagrt2hxiL+RbM432YAihNR7m7XnU0HWl/WQ35RIGmXHw==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.10", - "@inquirer/type": "^3.0.6", - "yoctocolors-cjs": "^2.1.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/figures": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.11.tgz", - "integrity": "sha512-eOg92lvrn/aRUqbxRyvpEWnrvRuTYRifixHkYVpJiygTgVSBIHDqLh0SrMQXkafvULg3ck11V7xvR+zcgvpHFw==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@inquirer/input": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.1.9.tgz", - "integrity": "sha512-mshNG24Ij5KqsQtOZMgj5TwEjIf+F2HOESk6bjMwGWgcH5UBe8UoljwzNFHqdMbGYbgAf6v2wU/X9CAdKJzgOA==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.10", - "@inquirer/type": "^3.0.6" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/number": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.12.tgz", - "integrity": "sha512-7HRFHxbPCA4e4jMxTQglHJwP+v/kpFsCf2szzfBHy98Wlc3L08HL76UDiA87TOdX5fwj2HMOLWqRWv9Pnn+Z5Q==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.10", - "@inquirer/type": "^3.0.6" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/password": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.12.tgz", - "integrity": "sha512-FlOB0zvuELPEbnBYiPaOdJIaDzb2PmJ7ghi/SVwIHDDSQ2K4opGBkF+5kXOg6ucrtSUQdLhVVY5tycH0j0l+0g==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.10", - "@inquirer/type": "^3.0.6", - "ansi-escapes": "^4.3.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/prompts": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.4.1.tgz", - "integrity": "sha512-UlmM5FVOZF0gpoe1PT/jN4vk8JmpIWBlMvTL8M+hlvPmzN89K6z03+IFmyeu/oFCenwdwHDr2gky7nIGSEVvlA==", - "license": "MIT", - "dependencies": { - "@inquirer/checkbox": "^4.1.5", - "@inquirer/confirm": "^5.1.9", - "@inquirer/editor": "^4.2.10", - "@inquirer/expand": "^4.0.12", - "@inquirer/input": "^4.1.9", - "@inquirer/number": "^3.0.12", - "@inquirer/password": "^4.0.12", - "@inquirer/rawlist": "^4.0.12", - "@inquirer/search": "^3.0.12", - "@inquirer/select": "^4.1.1" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/rawlist": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.0.12.tgz", - "integrity": "sha512-wNPJZy8Oc7RyGISPxp9/MpTOqX8lr0r+lCCWm7hQra+MDtYRgINv1hxw7R+vKP71Bu/3LszabxOodfV/uTfsaA==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.10", - "@inquirer/type": "^3.0.6", - "yoctocolors-cjs": "^2.1.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/search": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.12.tgz", - "integrity": "sha512-H/kDJA3kNlnNIjB8YsaXoQI0Qccgf0Na14K1h8ExWhNmUg2E941dyFPrZeugihEa9AZNW5NdsD/NcvUME83OPQ==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.10", - "@inquirer/figures": "^1.0.11", - "@inquirer/type": "^3.0.6", - "yoctocolors-cjs": "^2.1.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/select": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.1.1.tgz", - "integrity": "sha512-IUXzzTKVdiVNMA+2yUvPxWsSgOG4kfX93jOM4Zb5FgujeInotv5SPIJVeXQ+fO4xu7tW8VowFhdG5JRmmCyQ1Q==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.10", - "@inquirer/figures": "^1.0.11", - "@inquirer/type": "^3.0.6", - "ansi-escapes": "^4.3.2", - "yoctocolors-cjs": "^2.1.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/type": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.6.tgz", - "integrity": "sha512-/mKVCtVpyBu3IDarv0G+59KC4stsD5mDsGpYh+GKs1NZT88Jh52+cuoA1AtLk2Q0r/quNl+1cSUyLRHBFeD0XA==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/@ts-for-gir/cli": { - "version": "4.0.0-beta.23", - "resolved": "https://registry.npmjs.org/@ts-for-gir/cli/-/cli-4.0.0-beta.23.tgz", - "integrity": "sha512-LrJLF3FecEQPrA5TdGic3kOOSlXeNdaFuNe0w67U/ayl9Ld30bQO6Q1jXgZwi+lxWZiNOyx4Xb12O9N3/3Z9sA==", - "license": "Apache-2.0", - "dependencies": { - "@gi.ts/parser": "^4.0.0-beta.23", - "@inquirer/prompts": "^7.4.0", - "@ts-for-gir/generator-base": "^4.0.0-beta.23", - "@ts-for-gir/generator-html-doc": "^4.0.0-beta.23", - "@ts-for-gir/generator-typescript": "^4.0.0-beta.23", - "@ts-for-gir/lib": "^4.0.0-beta.23", - "colorette": "^2.0.20", - "cosmiconfig": "^9.0.0", - "glob": "^11.0.1", - "inquirer": "^12.5.0", - "prettier": "^3.5.3", - "yargs": "^17.7.2" - }, - "bin": { - "ts-for-gir": "lib/start.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@ts-for-gir/generator-base": { - "version": "4.0.0-beta.23", - "resolved": "https://registry.npmjs.org/@ts-for-gir/generator-base/-/generator-base-4.0.0-beta.23.tgz", - "integrity": "sha512-XMDzS6/DSYwt2ldzWfqRbWYR7vF8Q8GCpVl4gzRoUNLDzetsgtcX/pqxCOG+UxzOrWQ98w1ywVkb0jvbjwJU5Q==", - "license": "Apache-2.0", - "dependencies": { - "@ts-for-gir/lib": "^4.0.0-beta.23" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@ts-for-gir/generator-html-doc": { - "version": "4.0.0-beta.23", - "resolved": "https://registry.npmjs.org/@ts-for-gir/generator-html-doc/-/generator-html-doc-4.0.0-beta.23.tgz", - "integrity": "sha512-+VAklnA2WoeCyqBHg1E1K/r2ArtNsbEVHhZrh81bQV6omM8Q9XiETsCaBi5+92cNfbfZ/qDqzif12rEeCCCpxw==", - "license": "Apache-2.0", - "dependencies": { - "@ts-for-gir/generator-base": "^4.0.0-beta.23", - "@ts-for-gir/lib": "^4.0.0-beta.23" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@ts-for-gir/generator-typescript": { - "version": "4.0.0-beta.23", - "resolved": "https://registry.npmjs.org/@ts-for-gir/generator-typescript/-/generator-typescript-4.0.0-beta.23.tgz", - "integrity": "sha512-CX3h04cwbLZYJ//y9EweJqtCQkcrl0gtNUa4TIO0/jL49Ki3ckLgvw57njLsIkfwLvDZ98h0dpeFhdSQPFcCqQ==", - "license": "Apache-2.0", - "dependencies": { - "@ts-for-gir/generator-base": "^4.0.0-beta.23", - "@ts-for-gir/lib": "^4.0.0-beta.23", - "ejs": "^3.1.10", - "xml2js": "^0.6.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@ts-for-gir/lib": { - "version": "4.0.0-beta.23", - "resolved": "https://registry.npmjs.org/@ts-for-gir/lib/-/lib-4.0.0-beta.23.tgz", - "integrity": "sha512-WeZteowisNfYW6IMDCpii59fFPEsJcSm5N/Ec9rIpr0yxGowOBTPohrN2f67MT07MylpxYCR4k7LQObAn1nMsA==", - "license": "Apache-2.0", - "dependencies": { - "@gi.ts/parser": "^4.0.0-beta.23", - "colorette": "^2.0.20", - "ejs": "^3.1.10", - "glob": "^11.0.1", - "lodash": "^4.17.21" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "license": "MIT" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "license": "MIT" - }, - "node_modules/cli-width": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", - "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", - "license": "ISC", - "engines": { - "node": ">= 12" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/cosmiconfig": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.1", - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "license": "MIT" - }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "license": "Apache-2.0", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "license": "MIT" - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "license": "MIT", - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/fast-xml-parser": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.2.0.tgz", - "integrity": "sha512-Uw9+Mjt4SBRud1IcaYuW/O0lW8SKKdMl5g7g24HiIuyH5fQSD+AVLybSlJtqLYEbytVFjWQa5DMGcNgeksdRBg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "dependencies": { - "strnum": "^2.0.5" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/glob": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz", - "integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==", - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^4.0.1", - "minimatch": "^10.0.0", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^2.0.0" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/inquirer": { - "version": "12.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-12.5.2.tgz", - "integrity": "sha512-qoDk/vdSTIaXNXAoNnlg7ubexpJfUo7t8GT2vylxvE49BrLhToFuPPdMViidG2boHV7+AcP1TCkJs/+PPoF2QQ==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.10", - "@inquirer/prompts": "^7.4.1", - "@inquirer/type": "^3.0.6", - "ansi-escapes": "^4.3.2", - "mute-stream": "^2.0.0", - "run-async": "^3.0.0", - "rxjs": "^7.8.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "license": "MIT" - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/jackspeak": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.0.tgz", - "integrity": "sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jake": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", - "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", - "license": "Apache-2.0", - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jake/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/jake/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "license": "MIT" - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "license": "MIT" - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", - "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==", - "license": "ISC", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/minimatch": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", - "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/mute-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", - "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "license": "BlueOak-1.0.0" - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-scurry": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", - "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/prettier": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", - "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/run-async": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", - "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/rxjs": { - "version": "7.8.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", - "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", - "license": "ISC" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strnum": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.0.5.tgz", - "integrity": "sha512-YAT3K/sgpCUxhxNMrrdhtod3jckkpYwH6JAuwmUdXZsmzH1wUyzTMrrK2wYCEEqlKwrWDd35NeuUkbBy/1iK+Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT" - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "license": "MIT", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/xml2js": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", - "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", - "license": "MIT", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "license": "MIT", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yoctocolors-cjs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", - "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/lib/pkgs/mk-types/package.json b/lib/pkgs/mk-types/package.json deleted file mode 100644 index e05f0560..00000000 --- a/lib/pkgs/mk-types/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "@ts-for-gir/cli": "4.0.0-beta.23" - } -} diff --git a/lib/strings/default.nix b/lib/strings/default.nix deleted file mode 100644 index 884c3663..00000000 --- a/lib/strings/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ - concatStrings, - stringToCharacters, - substring, - tail, - toUpper, - ... -}: { - mkVersion = src: "0.0.0+" + src.shortRev; - capitalise = str: (toUpper (substring 0 1 str) + (concatStrings (tail (stringToCharacters str)))); -} diff --git a/modules/README.md b/modules/README.md deleted file mode 100644 index b265894e..00000000 --- a/modules/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# NixosModules - -This directory contains every modules for NixOS exposed by this flake. - -## List of my modules found in `self.nixosModules` - -| Name | Description | -| ---- | ----------- | -| `base` | Sets up locale, nix config, binary caches, general packages and some miscellaneous configs I might want on every device I use. | -| `base-droid` | Sets up locale, nix config, binary caches, general packages and some miscellaneous configs I might want on every nix-on-droid device I use. | -| `borgbackup` | Sets up a wrapper around `services.borgbackup` to setup default behaviour and make configuration of backups easier. | -| `caddy-plus` | Extends the caddy options to allow declaring subdirectory routes and reverse proxy directives through nix code. | -| `desktop` | Sets up a Display Manager, a Desktop Environment and themes for any graphical apps to use the Dracula Theme. This module uses Hyprland as window manager and AGS / Astal for the UI. | -| `docker` | Imports [nixos-docker-compose](https://github.com/matt1432/nixos-docker-compose), sets default options such as BTRFS filesystem and adds an update script for images. | -| `esphome-plus` | Fixes a bug with compilation of m5-atom-stack firmware and allows declaring firmware configurations in nix code. | -| `ha-plus` | Extends the home-assistant options to allow declaring the content of specific configuration files in the home-assistant configuration directory such as custom sentences through nix code. | -| `kmscon` | Extends the kmscon options to add more descriptive ones. | -| `meta` | Adds options to declare the documentation of my devices that will be generated to `./configurations/README.md`. | -| `nvidia` | Abstracts NVIDIA options and miscellaneous fixes behind simpler options. | -| `plymouth` | Sets some boot options to make the boot sequence cleaner. | -| `server` | Sets up sshd, tailscale and related configurations. | -| `tmux` | Uses the home-manager tmux module to declare my custom configuration and links it to `/etc` to set it globally. | -| `wyoming-plus` | Extends the `wyoming.openwakeword` options to allow declaring flags used by the [fork](https://github.com/rhasspy/wyoming-openwakeword/pull/17) of `wyoming-openwakeword` exposed by this module. | diff --git a/modules/ags/config/.envrc b/modules/ags/config/.envrc deleted file mode 100644 index 674cafba..00000000 --- a/modules/ags/config/.envrc +++ /dev/null @@ -1 +0,0 @@ -use flake "$FLAKE#node" diff --git a/modules/ags/config/.gitignore b/modules/ags/config/.gitignore deleted file mode 100644 index 8dfae95e..00000000 --- a/modules/ags/config/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -@girs -node_modules diff --git a/modules/ags/config/app.ts b/modules/ags/config/app.ts deleted file mode 100644 index 4d4f8a6d..00000000 --- a/modules/ags/config/app.ts +++ /dev/null @@ -1,17 +0,0 @@ -// TODO: see if I can bundle each config separately with nix - -import { programArgs } from 'system'; - -import binto from './configurations/binto'; -import wim from './configurations/wim'; - -import greeter from './configurations/greeter'; - - -switch (programArgs[0]) { - case 'binto': binto(); break; - - case 'wim': wim(); break; - - case 'greeter': greeter(); break; -} diff --git a/modules/ags/config/configurations/binto.ts b/modules/ags/config/configurations/binto.ts deleted file mode 100644 index f62900ba..00000000 --- a/modules/ags/config/configurations/binto.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { execAsync } from 'astal'; -import { App } from 'astal/gtk3'; - -import style from '../style/main.scss'; - -import AppLauncher from '../widgets/applauncher'; -import AudioWindow from '../widgets/audio/binto'; -import Bar from '../widgets/bar/binto'; -import BgLayer from '../widgets/bg-layer'; -import Calendar from '../widgets/date/binto'; -import Clipboard from '../widgets/clipboard'; -import { NotifPopups, NotifCenter } from '../widgets/notifs/binto'; -import OnScreenDisplay from '../widgets/on-screen-display'; -import PowerMenu from '../widgets/powermenu'; -import Screenshot from '../widgets/screenshot'; - -import { closeAll, perMonitor } from '../lib'; -import Brightness from '../services/brightness'; -import GpuScreenRecorder from '../services/gpu-screen-recorder'; -import MonitorClicks from '../services/monitor-clicks'; - - -export default () => { - App.start({ - css: style, - - requestHandler(request, respond) { - if (request.startsWith('open')) { - App.get_window(request.replace('open ', ''))?.set_visible(true); - respond('window opened'); - } - else if (request.startsWith('closeAll')) { - closeAll(); - respond('closed all windows'); - } - else if (request.startsWith('fetchCapsState')) { - Brightness.get_default().fetchCapsState(); - respond('fetched caps_lock state'); - } - else if (request.startsWith('popup')) { - popup_osd(request.replace('popup ', '')); - respond('osd popped up'); - } - else if (request.startsWith('save-replay')) { - GpuScreenRecorder.get_default().saveReplay(); - respond('saving replay'); - } - }, - - main: () => { - execAsync('hyprpaper').catch(() => { /**/ }); - - perMonitor((monitor) => BgLayer(monitor, false)); - - AppLauncher(); - AudioWindow(); - Bar(); - Calendar(); - Clipboard(); - NotifPopups(); - NotifCenter(); - OnScreenDisplay(); - PowerMenu(); - Screenshot(); - - Brightness.get_default({ caps: 'input2::capslock' }); - GpuScreenRecorder.get_default(); - MonitorClicks.get_default(); - }, - }); -}; diff --git a/modules/ags/config/configurations/greeter.ts b/modules/ags/config/configurations/greeter.ts deleted file mode 100644 index e6bc9976..00000000 --- a/modules/ags/config/configurations/greeter.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { subprocess } from 'astal'; -import { App } from 'astal/gtk3'; - -import Greeter from '../widgets/greeter'; - -import style from '../style/greeter.scss'; - - -export default () => { - App.start({ - css: style, - instanceName: 'greeter', - - main: () => { - Greeter(subprocess('hyprpaper')); - }, - }); -}; diff --git a/modules/ags/config/configurations/wim.ts b/modules/ags/config/configurations/wim.ts deleted file mode 100644 index 2f93afbe..00000000 --- a/modules/ags/config/configurations/wim.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { execAsync } from 'astal'; -import { App } from 'astal/gtk3'; - -import style from '../style/main.scss'; - -import AppLauncher from '../widgets/applauncher'; -import AudioWindow from '../widgets/audio/wim'; -import Bar from '../widgets/bar/wim'; -import BgLayer from '../widgets/bg-layer'; -import BluetoothWindow from '../widgets/bluetooth/wim'; -import BrightnessSlider from '../widgets/brightness-slider/main'; -import Calendar from '../widgets/date/wim'; -import Clipboard from '../widgets/clipboard'; -import Corners from '../widgets/corners'; -import IconBrowser from '../widgets/icon-browser'; -import NetworkWindow from '../widgets/network/wim'; -import { NotifPopups, NotifCenter } from '../widgets/notifs/wim'; -import OnScreenDisplay from '../widgets/on-screen-display'; -import OnScreenKeyboard from '../widgets/on-screen-keyboard'; -import PowerMenu from '../widgets/powermenu'; -import Screenshot from '../widgets/screenshot'; - -import { closeAll, perMonitor } from '../lib'; -import Brightness from '../services/brightness'; -import MonitorClicks from '../services/monitor-clicks'; -import Tablet from '../services/tablet'; - - -export default () => { - App.start({ - css: style, - - requestHandler(request, respond) { - if (request.startsWith('open')) { - App.get_window(request.replace('open ', ''))?.set_visible(true); - respond('window opened'); - } - else if (request.startsWith('closeAll')) { - closeAll(); - respond('closed all windows'); - } - else if (request.startsWith('fetchCapsState')) { - Brightness.get_default().fetchCapsState(); - respond('fetched caps_lock state'); - } - else if (request.startsWith('Brightness.screen')) { - Brightness.get_default().screen += parseFloat(request.replace('Brightness.screen ', '')); - respond('screen brightness changed'); - } - else if (request.startsWith('popup')) { - popup_osd(request.replace('popup ', '')); - respond('osd popped up'); - } - - else if (request.startsWith('show-osk')) { - const tablet = Tablet.get_default(); - - if (tablet.currentMode === 'tablet') { - if (tablet.oskState) { - respond('osk state was unchanged'); - } - else { - tablet.oskState = true; - tablet.oskAutoChanged = true; - respond('osk was shown'); - } - } - else { - respond('osk state was unchanged'); - } - } - - else if (request.startsWith('hide-osk')) { - const tablet = Tablet.get_default(); - - if (tablet.currentMode === 'tablet') { - if (tablet.oskState && tablet.oskAutoChanged) { - tablet.oskState = false; - tablet.oskAutoChanged = true; - respond('osd was hidden'); - } - else { - respond('osk state was unchanged'); - } - } - else { - respond('osk state was unchanged'); - } - } - }, - - main: () => { - execAsync('hyprpaper').catch(() => { /**/ }); - - perMonitor((monitor) => BgLayer(monitor, true)); - - AppLauncher(); - AudioWindow(); - Bar(); - BluetoothWindow(); - BrightnessSlider(); - Calendar(); - Clipboard(); - Corners(); - IconBrowser(); - NetworkWindow(); - NotifPopups(); - NotifCenter(); - OnScreenDisplay(); - OnScreenKeyboard(); - PowerMenu(); - Screenshot(); - - Brightness.get_default({ - kbd: 'tpacpi::kbd_backlight', - caps: 'input1::capslock', - }); - MonitorClicks.get_default(); - }, - }); -}; diff --git a/modules/ags/config/default.nix b/modules/ags/config/default.nix deleted file mode 100644 index 8f4757db..00000000 --- a/modules/ags/config/default.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ - npmDepsHash = "sha256-2F8VeLRljwyK0s4q/3EUUm1aQkZtvwI5KqgLxKKwkLc="; -} diff --git a/modules/ags/config/env.d.ts b/modules/ags/config/env.d.ts deleted file mode 100644 index 9cdf81ce..00000000 --- a/modules/ags/config/env.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -declare const SRC: string; - -declare module 'inline:*' { - const content: string; - - export default content; -} - -declare module '*.scss' { - const content: string; - - export default content; -} - -declare module '*.blp' { - const content: string; - - export default content; -} - -declare module '*.css' { - const content: string; - - export default content; -} diff --git a/modules/ags/config/eslint.config.ts b/modules/ags/config/eslint.config.ts deleted file mode 100644 index c8613917..00000000 --- a/modules/ags/config/eslint.config.ts +++ /dev/null @@ -1,456 +0,0 @@ -import eslint from '@eslint/js'; -import jsdoc from 'eslint-plugin-jsdoc'; -import stylistic from '@stylistic/eslint-plugin'; -import tseslint from 'typescript-eslint'; - - -export default tseslint.config({ - files: ['**/*.{js,ts,tsx}'], - ignores: ['node_modules/**', 'types/**'], - - extends: [ - eslint.configs.recommended, - jsdoc.configs['flat/recommended-typescript'], - stylistic.configs['recommended-flat'], - ...tseslint.configs.recommended, - ...tseslint.configs.stylistic, - ], - - rules: { - // JSDoc settings - 'jsdoc/tag-lines': ['warn', 'any', { startLines: 1 }], - 'jsdoc/check-line-alignment': ['warn', 'always', { - tags: ['param', 'arg', 'argument', 'property', 'prop'], - }], - 'jsdoc/no-types': 'off', - - // Newer settings - '@typescript-eslint/no-extraneous-class': ['off'], - '@typescript-eslint/no-implied-eval': ['off'], - 'class-methods-use-this': 'off', - '@stylistic/no-multiple-empty-lines': 'off', - '@stylistic/jsx-indent-props': 'off', - 'no-use-before-define': 'off', - '@typescript-eslint/no-use-before-define': 'error', - '@stylistic/indent-binary-ops': 'off', - '@stylistic/max-statements-per-line': [ - 'error', - { max: 2 }, - ], - - // Pre-flat config - '@typescript-eslint/no-unused-vars': [ - 'error', - { - args: 'all', - argsIgnorePattern: '^_', - caughtErrors: 'all', - caughtErrorsIgnorePattern: '^_', - destructuredArrayIgnorePattern: '^_', - varsIgnorePattern: '^_', - ignoreRestSiblings: true, - }, - ], - - 'array-callback-return': [ - 'error', - { - allowImplicit: true, - checkForEach: true, - }, - ], - 'no-constructor-return': [ - 'error', - ], - 'no-unreachable-loop': [ - 'error', - { - ignore: [ - 'ForInStatement', - 'ForOfStatement', - ], - }, - ], - 'block-scoped-var': [ - 'error', - ], - 'curly': [ - 'warn', - ], - 'default-case-last': [ - 'warn', - ], - 'default-param-last': [ - 'error', - ], - 'eqeqeq': [ - 'error', - 'smart', - ], - 'func-names': [ - 'warn', - 'never', - ], - 'func-style': [ - 'warn', - 'expression', - ], - 'logical-assignment-operators': [ - 'warn', - 'always', - ], - 'no-array-constructor': [ - 'error', - ], - 'no-empty-function': [ - 'warn', - ], - 'no-empty-static-block': [ - 'warn', - ], - 'no-extend-native': [ - 'error', - ], - 'no-extra-bind': [ - 'warn', - ], - 'no-implicit-coercion': [ - 'warn', - ], - 'no-iterator': [ - 'error', - ], - 'no-labels': [ - 'error', - ], - 'no-lone-blocks': [ - 'error', - ], - 'no-lonely-if': [ - 'error', - ], - 'no-loop-func': [ - 'error', - ], - /* - 'no-magic-numbers': [ - 'error', - { - ignore: [ - -1, - 0.1, - 0, - 1, - 2, - 3, - 4, - 5, - 10, - 12, - 33, - 66, - 100, - 255, - 360, - 450, - 500, - 1000, - ], - ignoreDefaultValues: true, - ignoreClassFieldInitialValues: true, - }, - ], - */ - 'no-multi-assign': [ - 'error', - ], - 'no-new-wrappers': [ - 'error', - ], - 'no-object-constructor': [ - 'error', - ], - 'no-proto': [ - 'error', - ], - 'no-return-assign': [ - 'error', - ], - 'no-sequences': [ - 'error', - ], - 'no-shadow': [ - 'error', - { - builtinGlobals: true, - allow: [ - 'Window', - ], - }, - ], - 'no-undef-init': [ - 'warn', - ], - 'no-undefined': [ - 'error', - ], - 'no-useless-constructor': [ - 'warn', - ], - 'no-useless-escape': [ - 'off', - ], - 'no-useless-return': [ - 'error', - ], - 'no-var': [ - 'error', - ], - 'no-void': [ - 'off', - ], - 'no-with': [ - 'error', - ], - 'object-shorthand': [ - 'error', - 'always', - ], - 'one-var': [ - 'error', - 'never', - ], - 'operator-assignment': [ - 'warn', - 'always', - ], - 'prefer-arrow-callback': [ - 'error', - ], - 'prefer-const': [ - 'error', - ], - 'prefer-object-has-own': [ - 'error', - ], - 'prefer-regex-literals': [ - 'error', - ], - 'prefer-template': [ - 'warn', - ], - 'no-prototype-builtins': 'off', - '@typescript-eslint/no-var-requires': [ - 'off', - ], - '@stylistic/array-bracket-newline': [ - 'warn', - 'consistent', - ], - '@stylistic/array-bracket-spacing': [ - 'warn', - 'never', - ], - '@stylistic/arrow-parens': [ - 'warn', - 'always', - ], - '@stylistic/brace-style': [ - 'warn', - 'stroustrup', - { allowSingleLine: true }, - ], - '@stylistic/comma-dangle': [ - 'warn', - 'always-multiline', - ], - '@stylistic/comma-spacing': [ - 'warn', - { - before: false, - after: true, - }, - ], - '@stylistic/comma-style': [ - 'error', - 'last', - ], - '@stylistic/dot-location': [ - 'error', - 'property', - ], - '@stylistic/function-call-argument-newline': [ - 'warn', - 'consistent', - ], - '@stylistic/function-paren-newline': [ - 'warn', - 'consistent', - ], - '@stylistic/indent': [ - 'warn', - 4, - { - SwitchCase: 1, - ignoreComments: true, - ignoredNodes: ['TemplateLiteral > *'], - }, - ], - '@stylistic/key-spacing': [ - 'warn', - { - beforeColon: false, - afterColon: true, - }, - ], - '@stylistic/keyword-spacing': [ - 'warn', - { - before: true, - }, - ], - '@stylistic/linebreak-style': [ - 'error', - 'unix', - ], - '@stylistic/lines-between-class-members': [ - 'warn', - 'always', - { - exceptAfterSingleLine: true, - }, - ], - '@stylistic/max-len': [ - 'warn', - { - code: 105, - ignoreComments: true, - ignoreTrailingComments: true, - ignoreUrls: true, - }, - ], - '@stylistic/multiline-ternary': [ - 'warn', - 'always-multiline', - ], - '@stylistic/new-parens': [ - 'error', - ], - '@stylistic/no-mixed-operators': [ - 'warn', - ], - '@stylistic/no-mixed-spaces-and-tabs': [ - 'error', - ], - '@stylistic/no-multi-spaces': [ - 'error', - ], - '@stylistic/no-tabs': [ - 'error', - ], - '@stylistic/no-trailing-spaces': [ - 'error', - ], - '@stylistic/no-whitespace-before-property': [ - 'warn', - ], - '@stylistic/nonblock-statement-body-position': [ - 'error', - 'below', - ], - '@stylistic/object-curly-newline': [ - 'warn', - { - consistent: true, - }, - ], - '@stylistic/object-curly-spacing': [ - 'warn', - 'always', - ], - '@stylistic/operator-linebreak': [ - 'warn', - 'after', - ], - '@stylistic/padded-blocks': [ - 'error', - 'never', - ], - '@stylistic/padding-line-between-statements': [ - 'warn', - { - blankLine: 'always', - prev: '*', - next: 'return', - }, - { - blankLine: 'always', - prev: [ - 'const', - 'let', - 'var', - ], - next: '*', - }, - { - blankLine: 'any', - prev: [ - 'const', - 'let', - 'var', - ], - next: [ - 'const', - 'let', - 'var', - ], - }, - { - blankLine: 'always', - prev: [ - 'case', - 'default', - ], - next: '*', - }, - ], - '@stylistic/quote-props': [ - 'error', - 'consistent-as-needed', - ], - '@stylistic/quotes': [ - 'error', - 'single', - { - avoidEscape: true, - }, - ], - '@stylistic/semi': [ - 'error', - 'always', - ], - '@stylistic/semi-spacing': [ - 'warn', - ], - '@stylistic/space-before-blocks': [ - 'warn', - ], - '@stylistic/space-before-function-paren': [ - 'warn', - 'never', - ], - '@stylistic/space-infix-ops': [ - 'warn', - ], - '@stylistic/spaced-comment': [ - 'warn', - 'always', - ], - '@stylistic/switch-colon-spacing': [ - 'warn', - ], - '@stylistic/wrap-regex': [ - 'warn', - ], - }, -}); diff --git a/modules/ags/config/lib/cairo.ts b/modules/ags/config/lib/cairo.ts deleted file mode 100644 index b01c69b8..00000000 --- a/modules/ags/config/lib/cairo.ts +++ /dev/null @@ -1,47 +0,0 @@ -type PointProps = [number, number] | { - x: number - y: number -} | number; - -export class Point { - public x = 0; - public y = 0; - - get values(): [number, number] { - return [this.x, this.y]; - } - - constructor(props?: PointProps, y?: number) { - if (typeof props === 'number') { - if (y) { - this.x = props; - this.y = y; - } - else { - throw new Error('Wrong props'); - } - } - else if (Array.isArray(props)) { - this.x = props[0]; - this.y = props[1]; - } - else if (props) { - this.x = props.x; - this.y = props.y; - } - } -} - -export type BezierPoints = [number, number, number, number]; - -export class Bezier { - private _points: BezierPoints; - - get points() { - return [...this._points] as BezierPoints; - } - - constructor(x1: number, y1: number, x2: number, y2: number) { - this._points = [x1, y1, x2, y2]; - } -} diff --git a/modules/ags/config/lib/hypr.ts b/modules/ags/config/lib/hypr.ts deleted file mode 100644 index ad032722..00000000 --- a/modules/ags/config/lib/hypr.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { Gdk } from 'astal/gtk3'; - -import AstalHyprland from 'gi://AstalHyprland'; - - -export const get_hyprland_monitor = (monitor: Gdk.Monitor): AstalHyprland.Monitor | undefined => { - const hyprland = AstalHyprland.get_default(); - - const manufacturer = monitor.get_manufacturer()?.replace(',', ''); - const model = monitor.get_model()?.replace(',', ''); - const start = `${manufacturer} ${model}`; - - return hyprland.get_monitors().find((m) => m.get_description()?.startsWith(start)); -}; - -export const get_hyprland_monitor_desc = (monitor: Gdk.Monitor): string => { - const hyprland = AstalHyprland.get_default(); - - const manufacturer = monitor.get_manufacturer()?.replace(',', ''); - const model = monitor.get_model()?.replace(',', ''); - const start = `${manufacturer} ${model}`; - - return `desc:${hyprland - .get_monitors() - .find((m) => m.get_description()?.startsWith(start))?.get_description()}`; -}; - -export const get_gdkmonitor_from_desc = (desc: string): Gdk.Monitor => { - const display = Gdk.Display.get_default(); - - for (let m = 0; m < (display?.get_n_monitors() ?? 0); m++) { - const monitor = display?.get_monitor(m); - - if (monitor && desc === get_hyprland_monitor_desc(monitor)) { - return monitor; - } - } - - throw Error(`Monitor ${desc} not found`); -}; - -export const get_monitor_desc = (mon: AstalHyprland.Monitor): string => { - return `desc:${mon.get_description()}`; -}; - -export const hyprMessage = (message: string) => new Promise<string>(( - resolution = () => { /**/ }, - rejection = () => { /**/ }, -) => { - const hyprland = AstalHyprland.get_default(); - - try { - hyprland.message_async(message, (_, asyncResult) => { - const result = hyprland.message_finish(asyncResult); - - resolution(result); - }); - } - catch (e) { - rejection(e); - } -}); - -export const centerCursor = (): void => { - const hyprland = AstalHyprland.get_default(); - - let x: number; - let y: number; - const monitor = hyprland.get_focused_monitor(); - - switch (monitor.get_transform()) { - case 1: - x = monitor.get_x() - (monitor.get_height() / 2); - y = monitor.get_y() - (monitor.get_width() / 2); - break; - - case 2: - x = monitor.get_x() - (monitor.get_width() / 2); - y = monitor.get_y() - (monitor.get_height() / 2); - break; - - case 3: - x = monitor.get_x() + (monitor.get_height() / 2); - y = monitor.get_y() + (monitor.get_width() / 2); - break; - - default: - x = monitor.get_x() + (monitor.get_width() / 2); - y = monitor.get_y() + (monitor.get_height() / 2); - break; - } - - hyprMessage(`dispatch movecursor ${x} ${y}`); -}; diff --git a/modules/ags/config/lib/index.ts b/modules/ags/config/lib/index.ts deleted file mode 100644 index 0b00a1a5..00000000 --- a/modules/ags/config/lib/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './cairo'; -export * from './hypr'; -export * from './notify'; -export * from './windows'; diff --git a/modules/ags/config/lib/notify.ts b/modules/ags/config/lib/notify.ts deleted file mode 100644 index 3c29275b..00000000 --- a/modules/ags/config/lib/notify.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { subprocess } from 'astal'; - -/* Types */ -interface NotifyAction { - id: string - label: string - callback: () => void -} -interface NotifySendProps { - actions?: NotifyAction[] - appName?: string - body?: string - category?: string - hint?: string - iconName: string - replaceId?: number - title: string - urgency?: 'low' | 'normal' | 'critical' -} - -const escapeShellArg = (arg: string | undefined): string => `'${arg?.replace(/'/g, '\'\\\'\'') ?? ''}'`; - -export const notifySend = ({ - actions = [], - appName, - body, - category, - hint, - iconName, - replaceId, - title, - urgency = 'normal', -}: NotifySendProps) => new Promise<number>((resolve) => { - let printedId = false; - - const cmd = [ - 'notify-send', - '--print-id', - `--icon=${escapeShellArg(iconName)}`, - escapeShellArg(title), - escapeShellArg(body ?? ''), - // Optional params - appName ? `--app-name=${escapeShellArg(appName)}` : '', - category ? `--category=${escapeShellArg(category)}` : '', - hint ? `--hint=${escapeShellArg(hint)}` : '', - replaceId ? `--replace-id=${replaceId.toString()}` : '', - `--urgency=${urgency}`, - ].concat( - actions.map(({ id, label }) => `--action=${escapeShellArg(id)}=${escapeShellArg(label)}`), - ).join(' '); - - subprocess( - cmd, - (out) => { - if (!printedId) { - resolve(parseInt(out)); - printedId = true; - } - else { - actions.find((action) => action.id === out)?.callback(); - } - }, - (err) => { - console.error(`[Notify] ${err}`); - }, - ); -}); diff --git a/modules/ags/config/lib/windows.ts b/modules/ags/config/lib/windows.ts deleted file mode 100644 index adafbbcb..00000000 --- a/modules/ags/config/lib/windows.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { idle } from 'astal'; -import { App, Gdk, Gtk } from 'astal/gtk3'; - -/* Types */ -import PopupWindow from '../widgets/misc/popup-window'; - -export interface Layer { - address: string - x: number - y: number - w: number - h: number - namespace: string -} -export interface Levels { - 0?: Layer[] | null - 1?: Layer[] | null - 2?: Layer[] | null - 3?: Layer[] | null -} -export interface Layers { - levels: Levels -} -export type LayerResult = Record<string, Layers>; -export interface CursorPos { - x: number - y: number -} - -export const closeAll = () => { - (App.get_windows() as PopupWindow[]) - .filter((w) => w && - w.close_on_unfocus && - w.close_on_unfocus !== 'stay') - .forEach((w) => { - App.get_window(w.name)?.set_visible(false); - }); -}; - -export const perMonitor = (window: (monitor: Gdk.Monitor) => Gtk.Widget) => idle(() => { - const display = Gdk.Display.get_default(); - const windows = new Map<Gdk.Monitor, Gtk.Widget>(); - - const createWindow = (monitor: Gdk.Monitor) => { - windows.set(monitor, window(monitor)); - }; - - for (let m = 0; m < (display?.get_n_monitors() ?? 0); m++) { - const monitor = display?.get_monitor(m); - - if (monitor) { - createWindow(monitor); - } - } - - display?.connect('monitor-added', (_, monitor) => { - createWindow(monitor); - }); - - display?.connect('monitor-removed', (_, monitor) => { - windows.get(monitor)?.destroy(); - windows.delete(monitor); - }); -}); diff --git a/modules/ags/config/package-lock.json b/modules/ags/config/package-lock.json deleted file mode 100644 index 0bf2d946..00000000 --- a/modules/ags/config/package-lock.json +++ /dev/null @@ -1,1712 +0,0 @@ -{ - "name": "ags", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "ags", - "version": "0.0.0", - "dependencies": { - "@eslint/js": "9.25.0", - "@stylistic/eslint-plugin": "4.2.0", - "astal": "https://gitpkg.vercel.app/Aylur/astal/lang/gjs/src?c96126c7e261737270ad7ae35b27674c318648e6", - "eslint": "9.25.0", - "eslint-plugin-jsdoc": "50.6.9", - "fzf": "0.5.2", - "jiti": "2.4.2", - "typescript-eslint": "8.30.1" - } - }, - "node_modules/@es-joy/jsdoccomment": { - "version": "0.49.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.49.0.tgz", - "integrity": "sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==", - "license": "MIT", - "dependencies": { - "comment-parser": "1.4.1", - "esquery": "^1.6.0", - "jsdoc-type-pratt-parser": "~4.1.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.1.tgz", - "integrity": "sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==", - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", - "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.6", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz", - "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", - "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/js": { - "version": "9.25.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.25.0.tgz", - "integrity": "sha512-iWhsUS8Wgxz9AXNfvfOPFSW4VfMXdVhp1hjkZVhXCrpgh/aLcc45rX6MPu+tIVUWDw0HfNwth7O28M1xDxNf9w==", - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", - "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.13.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", - "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", - "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pkgr/core": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.2.tgz", - "integrity": "sha512-fdDH1LSGfZdTH2sxdpVMw31BanV28K/Gry0cVFxaNP77neJSkd82mM8ErPNYs9e+0O7SdHBLTDzDgwUuy18RnQ==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/@stylistic/eslint-plugin": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-4.2.0.tgz", - "integrity": "sha512-8hXezgz7jexGHdo5WN6JBEIPHCSFyyU4vgbxevu4YLVS5vl+sxqAAGyXSzfNDyR6xMNSH5H1x67nsXcYMOHtZA==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/utils": "^8.23.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", - "estraverse": "^5.3.0", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "eslint": ">=9.0.0" - } - }, - "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.30.1.tgz", - "integrity": "sha512-v+VWphxMjn+1t48/jO4t950D6KR8JaJuNXzi33Ve6P8sEmPr5k6CEXjdGwT6+LodVnEa91EQCtwjWNUCPweo+Q==", - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.30.1", - "@typescript-eslint/type-utils": "8.30.1", - "@typescript-eslint/utils": "8.30.1", - "@typescript-eslint/visitor-keys": "8.30.1", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.0.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.30.1.tgz", - "integrity": "sha512-H+vqmWwT5xoNrXqWs/fesmssOW70gxFlgcMlYcBaWNPIEWDgLa4W9nkSPmhuOgLnXq9QYgkZ31fhDyLhleCsAg==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "8.30.1", - "@typescript-eslint/types": "8.30.1", - "@typescript-eslint/typescript-estree": "8.30.1", - "@typescript-eslint/visitor-keys": "8.30.1", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.30.1.tgz", - "integrity": "sha512-+C0B6ChFXZkuaNDl73FJxRYT0G7ufVPOSQkqkpM/U198wUwUFOtgo1k/QzFh1KjpBitaK7R1tgjVz6o9HmsRPg==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.30.1", - "@typescript-eslint/visitor-keys": "8.30.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.30.1.tgz", - "integrity": "sha512-64uBF76bfQiJyHgZISC7vcNz3adqQKIccVoKubyQcOnNcdJBvYOILV1v22Qhsw3tw3VQu5ll8ND6hycgAR5fEA==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "8.30.1", - "@typescript-eslint/utils": "8.30.1", - "debug": "^4.3.4", - "ts-api-utils": "^2.0.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.30.1.tgz", - "integrity": "sha512-81KawPfkuulyWo5QdyG/LOKbspyyiW+p4vpn4bYO7DM/hZImlVnFwrpCTnmNMOt8CvLRr5ojI9nU1Ekpw4RcEw==", - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.30.1.tgz", - "integrity": "sha512-kQQnxymiUy9tTb1F2uep9W6aBiYODgq5EMSk6Nxh4Z+BDUoYUSa029ISs5zTzKBFnexQEh71KqwjKnRz58lusQ==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.30.1", - "@typescript-eslint/visitor-keys": "8.30.1", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.0.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.30.1.tgz", - "integrity": "sha512-T/8q4R9En2tcEsWPQgB5BQ0XJVOtfARcUvOa8yJP3fh9M/mXraLxZrkCfGb6ChrO/V3W+Xbd04RacUEqk1CFEQ==", - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.30.1", - "@typescript-eslint/types": "8.30.1", - "@typescript-eslint/typescript-estree": "8.30.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.30.1.tgz", - "integrity": "sha512-aEhgas7aJ6vZnNFC7K4/vMGDGyOiqWcYZPpIWrTKuTAlsvDNKy2GFDqh9smL+iq069ZvR0YzEeq0B8NJlLzjFA==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.30.1", - "eslint-visitor-keys": "^4.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/are-docs-informative": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", - "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/astal": { - "resolved": "https://gitpkg.vercel.app/Aylur/astal/lang/gjs/src?c96126c7e261737270ad7ae35b27674c318648e6", - "integrity": "sha512-St+iJL44OmiAw/3FjXwGmLSOYIBLdwQ3w9cfqZTl15ooMcZpI0iGMxLiw+IirTt/s6L1u+yM1oRt3D2D8kVnXg==", - "license": "LGPL-2.1" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/comment-parser": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", - "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", - "license": "MIT", - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "license": "MIT" - }, - "node_modules/es-module-lexer": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", - "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", - "license": "MIT" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.25.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.25.0.tgz", - "integrity": "sha512-MsBdObhM4cEwkzCiraDv7A6txFXEqtNXOb877TsSp2FCkBNl8JfVQrmiuDqC1IkejT6JLPzYBXx/xAiYhyzgGA==", - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.20.0", - "@eslint/config-helpers": "^0.2.1", - "@eslint/core": "^0.13.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.25.0", - "@eslint/plugin-kit": "^0.2.8", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.3.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-jsdoc": { - "version": "50.6.9", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.6.9.tgz", - "integrity": "sha512-7/nHu3FWD4QRG8tCVqcv+BfFtctUtEDWc29oeDXB4bwmDM2/r1ndl14AG/2DUntdqH7qmpvdemJKwb3R97/QEw==", - "license": "BSD-3-Clause", - "dependencies": { - "@es-joy/jsdoccomment": "~0.49.0", - "are-docs-informative": "^0.0.2", - "comment-parser": "1.4.1", - "debug": "^4.3.6", - "escape-string-regexp": "^4.0.0", - "espree": "^10.1.0", - "esquery": "^1.6.0", - "parse-imports": "^2.1.1", - "semver": "^7.6.3", - "spdx-expression-parse": "^4.0.0", - "synckit": "^0.9.1" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", - "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/espree": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", - "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.14.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "license": "MIT" - }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "license": "ISC" - }, - "node_modules/fzf": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fzf/-/fzf-0.5.2.tgz", - "integrity": "sha512-Tt4kuxLXFKHy8KT40zwsUPUkg1CrsgY25FxA2U/j/0WgEDCk3ddc/zLTCCcbSHX9FcKtLuVaDGtGE/STWC+j3Q==", - "license": "BSD-3-Clause" - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "license": "MIT" - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsdoc-type-pratt-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", - "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", - "license": "MIT", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "license": "MIT" - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "license": "MIT" - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-imports": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.2.1.tgz", - "integrity": "sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==", - "license": "Apache-2.0 AND MIT", - "dependencies": { - "es-module-lexer": "^1.5.3", - "slashes": "^3.0.12" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/slashes": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz", - "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", - "license": "ISC" - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", - "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.21", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", - "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", - "license": "CC0-1.0" - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/synckit": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", - "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", - "license": "MIT", - "dependencies": { - "@pkgr/core": "^0.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", - "license": "MIT", - "engines": { - "node": ">=18.12" - }, - "peerDependencies": { - "typescript": ">=4.8.4" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "license": "Apache-2.0", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-eslint": { - "version": "8.30.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.30.1.tgz", - "integrity": "sha512-D7lC0kcehVH7Mb26MRQi64LMyRJsj3dToJxM1+JVTl53DQSV5/7oUGWQLcKl1C1KnoVHxMMU2FNQMffr7F3Row==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/eslint-plugin": "8.30.1", - "@typescript-eslint/parser": "8.30.1", - "@typescript-eslint/utils": "8.30.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/modules/ags/config/package.json b/modules/ags/config/package.json deleted file mode 100644 index 170c8e65..00000000 --- a/modules/ags/config/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "ags", - "version": "0.0.0", - "main": "app.ts", - "dependencies": { - "astal": "https://gitpkg.vercel.app/Aylur/astal/lang/gjs/src?c96126c7e261737270ad7ae35b27674c318648e6", - "@eslint/js": "9.25.0", - "@stylistic/eslint-plugin": "4.2.0", - "eslint": "9.25.0", - "eslint-plugin-jsdoc": "50.6.9", - "fzf": "0.5.2", - "jiti": "2.4.2", - "typescript-eslint": "8.30.1" - } -} diff --git a/modules/ags/config/services/brightness.ts b/modules/ags/config/services/brightness.ts deleted file mode 100644 index 4d68b25c..00000000 --- a/modules/ags/config/services/brightness.ts +++ /dev/null @@ -1,175 +0,0 @@ -import { execAsync, interval } from 'astal'; -import GObject, { register, property } from 'astal/gobject'; - - -const SCREEN_ICONS: Record<number, string> = { - 90: 'display-brightness-high-symbolic', - 70: 'display-brightness-medium-symbolic', - 20: 'display-brightness-low-symbolic', - 5: 'display-brightness-off-symbolic', -}; - -const INTERVAL = 500; - -@register() -export default class Brightness extends GObject.Object { - declare private _kbd: string | undefined; - declare private _caps: string | undefined; - - declare private _screen: number; - - @property(Number) - get screen() { - return this._screen; - }; - - set screen(percent) { - if (percent < 0) { - percent = 0; - } - - if (percent > 1) { - percent = 1; - } - - percent = parseFloat(percent.toFixed(2)); - - execAsync(`brightnessctl s ${percent * 100}% -q`) - .then(() => { - this._screen = percent; - this.notify('screen'); - this._getScreenIcon(); - }) - .catch(console.error); - } - - private _screenIcon = 'display-brightness-high-symbolic'; - - @property(String) - get screenIcon() { - return this._screenIcon; - } - - public hasKbd = false; - declare private _kbdMax: number | undefined; - declare private _kbdLevel: number | undefined; - - @property(Number) - get kbdLevel() { - if (!this._kbdMax) { - console.error('[get kbdLevel] No Keyboard brightness'); - - return -1; - } - - return this._kbdLevel; - } - - set kbdLevel(value) { - if (!this._kbdMax || !value) { - console.error('[set kbdLevel] No Keyboard brightness'); - - return; - } - - if (value < 0 || value > this._kbdMax) { - return; - } - - execAsync(`brightnessctl -d ${this._kbd} s ${value} -q`) - .then(() => { - this._kbdLevel = value; - this.notify('kbd-level'); - }) - .catch(console.error); - } - - declare private _capsLevel: number; - - @property(Number) - get capsLevel() { - return this._capsLevel; - } - - private _capsIcon = 'caps-lock-symbolic'; - - @property(String) - get capsIcon() { - return this._capsIcon; - } - - public constructor({ kbd, caps }: { kbd?: string, caps?: string } = {}) { - super(); - - try { - (async() => { - if (kbd) { - this.hasKbd = true; - this._kbd = kbd; - this._monitorKbdState(); - this._kbdMax = Number(await execAsync(`brightnessctl -d ${this._kbd} m`)); - } - - this._caps = caps; - this._screen = Number(await execAsync('brightnessctl g')) / - Number(await execAsync('brightnessctl m')); - this.notify('screen'); - })(); - } - catch (_e) { - console.error('missing dependency: brightnessctl'); - } - } - - private static _default: InstanceType<typeof Brightness> | undefined; - - public static get_default({ kbd, caps }: { kbd?: string, caps?: string } = {}) { - if (!Brightness._default) { - Brightness._default = new Brightness({ kbd, caps }); - } - - return Brightness._default; - } - - private _getScreenIcon() { - const brightness = this._screen * 100; - - for (const threshold of [4, 19, 69, 89]) { - if (brightness > threshold + 1) { - this._screenIcon = SCREEN_ICONS[threshold + 1]; - this.notify('screen-icon'); - } - } - } - - private _monitorKbdState() { - const timer = interval(INTERVAL, () => { - execAsync(`brightnessctl -d ${this._kbd} g`) - .then( - (out) => { - if (parseInt(out) !== this._kbdLevel) { - this._kbdLevel = parseInt(out); - this.notify('kbd-level'); - } - }, - ) - .catch(() => { - timer?.cancel(); - }); - }); - } - - public fetchCapsState() { - execAsync(`brightnessctl -d ${this._caps} g`) - .then((out) => { - this._capsLevel = Number(out); - this._capsIcon = this._capsLevel ? - 'caps-lock-symbolic' : - 'capslock-disabled-symbolic'; - - this.notify('caps-icon'); - this.notify('caps-level'); - }) - .catch(logError); - } -} diff --git a/modules/ags/config/services/gpu-screen-recorder.ts b/modules/ags/config/services/gpu-screen-recorder.ts deleted file mode 100644 index 7b7251d7..00000000 --- a/modules/ags/config/services/gpu-screen-recorder.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { execAsync, subprocess } from 'astal'; -import GObject, { register } from 'astal/gobject'; - -import { notifySend } from '../lib'; - - -const APP_NAME = 'gpu-screen-recorder'; -const ICON_NAME = 'nvidia'; - -@register() -export default class GpuScreenRecorder extends GObject.Object { - private _lastNotifID: number | undefined; - - public constructor() { - super(); - - try { - subprocess( - ['gsr-start'], - (path) => { - if (!this._lastNotifID) { - console.error('[GpuScreenRecorder] ID of warning notif not found'); - - setTimeout(() => { - this._onSaved(path); - }, 1000); - } - else { - this._onSaved(path); - } - }, - () => { /**/ }, - ); - } - catch (_e) { - console.error('Missing dependency for gpu-screen-recorder'); - } - } - - private static _default: InstanceType<typeof GpuScreenRecorder> | undefined; - - public static get_default() { - if (!GpuScreenRecorder._default) { - GpuScreenRecorder._default = new GpuScreenRecorder(); - } - - return GpuScreenRecorder._default; - } - - public saveReplay() { - execAsync(['gpu-save-replay']) - .then(async() => { - this._lastNotifID = await notifySend({ - appName: APP_NAME, - iconName: ICON_NAME, - title: 'Saving Replay', - body: 'Last 20 minutes', - }); - }) - .catch((err) => { - console.error(`[GpuScreenRecorder save-replay] ${err}`); - }); - } - - private _onSaved(path: string) { - notifySend({ - appName: APP_NAME, - iconName: ICON_NAME, - replaceId: this._lastNotifID, - - title: 'Replay Saved', - body: `Saved to ${path}`, - - actions: [ - { - id: 'folder', - label: 'Open Folder', - - callback: () => execAsync([ - 'xdg-open', - path.substring(0, path.lastIndexOf('/')), - ]).catch(print), - }, - - { - id: 'video', - label: 'Open Video', - - callback: () => execAsync(['xdg-open', path]).catch(print), - }, - - { - id: 'kdenlive', - label: 'Edit in kdenlive', - - callback: () => execAsync([ - 'bash', - '-c', - `kdenlive -i ${path}`, - ]).catch(print), - }, - ], - }); - } -} diff --git a/modules/ags/config/services/monitor-clicks.ts b/modules/ags/config/services/monitor-clicks.ts deleted file mode 100644 index 1c337bc4..00000000 --- a/modules/ags/config/services/monitor-clicks.ts +++ /dev/null @@ -1,204 +0,0 @@ -import { subprocess } from 'astal'; -import { App } from 'astal/gtk3'; -import GObject, { register, signal } from 'astal/gobject'; - -import AstalIO from 'gi://AstalIO'; - -import { hyprMessage } from '../lib'; - -const ON_RELEASE_TRIGGERS = [ - 'released', - 'TOUCH_UP', - 'HOLD_END', -]; -const ON_CLICK_TRIGGERS = [ - 'pressed', - 'TOUCH_DOWN', -]; - -/* Types */ -import PopupWindow from '../widgets/misc/popup-window'; -import { CursorPos, Layer, LayerResult } from '../lib'; - - -@register() -export default class MonitorClicks extends GObject.Object { - @signal(Boolean) - declare procStarted: (state: boolean) => void; - - @signal(Boolean) - declare procDestroyed: (state: boolean) => void; - - @signal(String) - declare released: (procLine: string) => void; - - @signal(String) - declare clicked: (procLine: string) => void; - - private process = null as AstalIO.Process | null; - - constructor() { - super(); - this._initAppConnection(); - } - - private _startProc() { - if (this.process) { - return; - } - - this.process = subprocess( - ['libinput', 'debug-events'], - (output) => { - if (output.includes('cancelled')) { - return; - } - - if (ON_RELEASE_TRIGGERS.some((p) => output.includes(p))) { - MonitorClicks.detectClickedOutside('released'); - this.emit('released', output); - } - - if (ON_CLICK_TRIGGERS.some((p) => output.includes(p))) { - MonitorClicks.detectClickedOutside('clicked'); - this.emit('clicked', output); - } - }, - ); - this.emit('proc-started', true); - } - - private _killProc() { - if (this.process) { - this.process.kill(); - this.process = null; - this.emit('proc-destroyed', true); - } - } - - private _initAppConnection() { - App.connect('window-toggled', () => { - const anyVisibleAndClosable = - (App.get_windows() as PopupWindow[]).some((w) => { - const closable = w.close_on_unfocus && - !( - w.close_on_unfocus === 'none' || - w.close_on_unfocus === 'stay' - ); - - return w.visible && closable; - }); - - if (anyVisibleAndClosable) { - this._startProc(); - } - - else { - this._killProc(); - } - }); - } - - private static _default: InstanceType<typeof MonitorClicks> | undefined; - - public static get_default() { - if (!MonitorClicks._default) { - MonitorClicks._default = new MonitorClicks(); - } - - return MonitorClicks._default; - } - - public static async detectClickedOutside(clickStage: string) { - const toClose = ((App.get_windows() as PopupWindow[])).some((w) => { - const closable = ( - w.close_on_unfocus && - w.close_on_unfocus === clickStage - ); - - return w.visible && closable; - }); - - if (!toClose) { - return; - } - - try { - const layers = JSON.parse(await hyprMessage('j/layers')) as LayerResult; - const pos = JSON.parse(await hyprMessage('j/cursorpos')) as CursorPos; - - Object.values(layers).forEach((key) => { - const overlayLayer = key.levels['3']; - - if (overlayLayer) { - const noCloseWidgetsNames = [ - 'bar-', - 'osk', - 'noanim-', - ]; - - const getNoCloseWidgets = (names: string[]) => { - const arr = [] as Layer[]; - - names.forEach((name) => { - arr.push( - overlayLayer.find( - (n) => n.namespace.startsWith(name), - ) || - // Return an empty Layer if widget doesn't exist - { - address: '', - x: 0, - y: 0, - w: 0, - h: 0, - namespace: '', - }, - ); - }); - - return arr; - }; - const clickIsOnWidget = (w: Layer) => { - return ( - pos.x > w.x && pos.x < w.x + w.w && - pos.y > w.y && pos.y < w.y + w.h - ); - }; - - const noCloseWidgets = getNoCloseWidgets(noCloseWidgetsNames); - - const widgets = overlayLayer.filter((n) => { - let window = null as null | PopupWindow; - - if (App.get_windows().some((win) => win.name === n.namespace)) { - window = (App.get_window(n.namespace) as PopupWindow); - } - - return window && - window.close_on_unfocus && - window.close_on_unfocus === - clickStage; - }); - - if (noCloseWidgets.some(clickIsOnWidget)) { - // Don't handle clicks when on certain widgets - } - else { - widgets.forEach((w) => { - if (!( - pos.x > w.x && pos.x < w.x + w.w && - pos.y > w.y && pos.y < w.y + w.h - )) { - App.get_window(w.namespace)?.set_visible(false); - } - }); - } - } - }); - } - catch (e) { - console.log(e); - } - } -} diff --git a/modules/ags/config/services/tablet.ts b/modules/ags/config/services/tablet.ts deleted file mode 100644 index f00f481a..00000000 --- a/modules/ags/config/services/tablet.ts +++ /dev/null @@ -1,213 +0,0 @@ -import { execAsync, subprocess } from 'astal'; -import GObject, { register, property, signal } from 'astal/gobject'; - -import { hyprMessage } from '../lib'; - -/* Types */ -import AstalIO from 'gi://AstalIO'; -type RotationName = 'normal' | 'right-up' | 'bottom-up' | 'left-up'; - - -const ROTATION_MAP: Record<RotationName, 0 | 1 | 2 | 3> = { - 'normal': 0, - 'right-up': 3, - 'bottom-up': 2, - 'left-up': 1, -}; - -const SCREEN = 'desc:BOE 0x0964'; - -const DEVICES = [ - 'wacom-hid-52eb-finger', - 'wacom-hid-52eb-pen', -]; - -@register() -export default class Tablet extends GObject.Object { - @signal(Boolean) - declare autorotateChanged: (running: boolean) => void; - - @signal(Boolean) - declare inputsChanged: (blocked: boolean) => void; - - - private _currentMode: 'laptop' | 'tablet' = 'laptop'; - - @property(String) - get currentMode() { - return this._currentMode; - } - - set currentMode(val) { - this._currentMode = val; - - if (this._currentMode === 'tablet') { - execAsync(['brightnessctl', '-d', 'tpacpi::kbd_backlight', 's', '0']).catch(print); - - this.startAutorotate(); - this._blockInputs(); - this._startInputDetection(); - } - else if (this._currentMode === 'laptop') { - execAsync(['brightnessctl', '-d', 'tpacpi::kbd_backlight', 's', '2']).catch(print); - - this.killAutorotate(); - this._unblockInputs(); - this._stopInputDetection(); - this.oskState = false; - } - - this.notify('current-mode'); - } - - - private _oskState = false; - - @property(Boolean) - get oskState() { - return this._oskState; - } - - set oskState(val) { - this._oskState = val; - // this is set to true after this setter in the request. - this.oskAutoChanged = false; - this.notify('osk-state'); - } - - public toggleOsk() { - this.oskState = !this.oskState; - } - - - private _oskAutoChanged = false; - - @property(Boolean) - get oskAutoChanged() { - return this._oskAutoChanged; - } - - set oskAutoChanged(val) { - this._oskAutoChanged = val; - } - - - private _inputDetection = null as AstalIO.Process | null; - - private _startInputDetection() { - if (this._inputDetection) { - return; - } - - this._inputDetection = subprocess(['fcitx5', - '--disable', 'all', - '--enable', 'keyboard,virtualkeyboardadapter,wayland,waylandim'], - () => { /**/ }, - () => { /**/ }); - } - - private _stopInputDetection() { - if (this._inputDetection) { - this._inputDetection.kill(); - this._inputDetection = null; - } - } - - - private _autorotate = null as AstalIO.Process | null; - - get autorotateState() { - return this._autorotate !== null; - } - - - private _blockedInputs = null as AstalIO.Process | null; - - private _blockInputs() { - if (this._blockedInputs) { - return; - } - - this._blockedInputs = subprocess(['libinput', 'debug-events', '--grab', - '--device', '/dev/input/by-path/platform-i8042-serio-0-event-kbd', - '--device', '/dev/input/by-path/platform-i8042-serio-1-event-mouse', - '--device', '/dev/input/by-path/platform-AMDI0010:02-event-mouse', - '--device', '/dev/input/by-path/platform-thinkpad_acpi-event', - '--device', '/dev/video-bus'], - () => { /**/ }); - - this.emit('inputs-changed', true); - } - - private _unblockInputs() { - if (this._blockedInputs) { - this._blockedInputs.kill(); - this._blockedInputs = null; - - this.emit('inputs-changed', false); - } - } - - - public toggleMode() { - if (this.currentMode === 'laptop') { - this.currentMode = 'tablet'; - } - else if (this.currentMode === 'tablet') { - this.currentMode = 'laptop'; - } - } - - - public startAutorotate() { - if (this._autorotate) { - return; - } - - this._autorotate = subprocess( - ['monitor-sensor'], - (output) => { - if (output.includes('orientation changed')) { - const index = output.split(' ').at(-1) as RotationName | undefined; - - if (!index) { - return; - } - - const orientation = ROTATION_MAP[index]; - - hyprMessage( - `keyword monitor ${SCREEN},transform,${orientation}`, - ).catch(print); - - const batchRotate = DEVICES.map((dev) => - `keyword device:${dev}:transform ${orientation}; `); - - hyprMessage(`[[BATCH]] ${batchRotate.flat()}`); - } - }, - ); - - this.emit('autorotate-changed', true); - } - - public killAutorotate() { - if (this._autorotate) { - this._autorotate.kill(); - this._autorotate = null; - - this.emit('autorotate-changed', false); - } - } - - - private static _default: InstanceType<typeof Tablet> | undefined; - - public static get_default() { - if (!Tablet._default) { - Tablet._default = new Tablet(); - } - - return Tablet._default; - } -} diff --git a/modules/ags/config/style/colors.scss b/modules/ags/config/style/colors.scss deleted file mode 100644 index 603a0f30..00000000 --- a/modules/ags/config/style/colors.scss +++ /dev/null @@ -1,96 +0,0 @@ -// Vars from my Gradient theme -$accent_color: #bd93f9; -$accent_bg_color: #bd93f9; -$accent_fg_color: #f8f8f2; -$destructive_color: #ff5555; -$destructive_bg_color: #ff5555; -$destructive_fg_color: #f8f8f2; -$success_color: #50fa7b; -$success_bg_color: #50fa7b; -$success_fg_color: #f8f8f2; -$warning_color: #f1fa8c; -$warning_bg_color: #f1fa8c; -$warning_fg_color: rgba(0, 0, 0, 0.8); -$error_color: #ff5555; -$error_bg_color: #ff5555; -$error_fg_color: #f8f8f2; -$window_bg_color: #282a36; -$window_fg_color: #f8f8f2; -$view_bg_color: #282a36; -$view_fg_color: #f8f8f2; -$headerbar_bg_color: #282a36; -$headerbar_fg_color: #f8f8f2; -$headerbar_border_color: #ffffff; -$headerbar_backdrop_color: $window_bg_color; -$headerbar_shade_color: rgba(0, 0, 0, 0.36); -$card_bg_color: rgba(255, 255, 255, 0.08); -$card_fg_color: #f8f8f2; -$card_shade_color: rgba(0, 0, 0, 0.36); -$dialog_bg_color: #282a36; -$dialog_fg_color: #f8f8f2; -$popover_bg_color: #282a36; -$popover_fg_color: #f8f8f2; -$shade_color: #383838; -$scrollbar_outline_color: rgba(0, 0, 0, 0.5); -$green_1: #8ff0a4; -$green_2: #57e389; -$green_3: #33d17a; -$green_4: #2ec27e; -$green_5: #26a269; -$yellow_1: #f9f06b; -$yellow_2: #f8e45c; -$yellow_3: #f6d32d; -$yellow_4: #f5c211; -$yellow_5: #e5a50a; -$orange_1: #ffbe6f; -$orange_2: #ffa348; -$orange_3: #ff7800; -$orange_4: #e66100; -$orange_5: #c64600; -$red_1: #f66151; -$red_2: #ed333b; -$red_3: #e01b24; -$red_4: #c01c28; -$red_5: #a51d2d; -$purple_1: #dc8add; -$purple_2: #c061cb; -$purple_3: #9141ac; -$purple_4: #813d9c; -$purple_5: #613583; -$brown_1: #cdab8f; -$brown_2: #b5835a; -$brown_3: #986a44; -$brown_4: #865e3c; -$brown_5: #63452c; -$light_1: #ffffff; -$light_2: #f6f5f4; -$light_3: #deddda; -$light_4: #c0bfbc; -$light_5: #9a9996; -$dark_1: #77767b; -$dark_2: #5e5c64; -$dark_3: #3d3846; -$dark_4: #241f31; -$dark_5: #000000; -$blue_1: #99c1f1; -$blue_2: #62a0ea; -$blue_3: #3584e4; -$blue_4: #1c71d8; -$blue_5: #1a5fb4; - -// Other colors -$black: #151720; -$dimblack: #1a1c25; -$lightblack: #262831; -$red: #dd6777; -$blue: #86aaec; -$cyan: #93cee9; -$blue-desaturated: #93cee9; -$magenta: #c296eb; -$purple: #c296eb; -$green: #90ceaa; -$aquamarine: #90ceaa; -$yellow: #ecd3a0; -$accent: $blue; -$javacafe-magenta: #c296eb; -$javacafe-blue: #86aaec; diff --git a/modules/ags/config/style/common.scss b/modules/ags/config/style/common.scss deleted file mode 100644 index dc2c7755..00000000 --- a/modules/ags/config/style/common.scss +++ /dev/null @@ -1,59 +0,0 @@ -@use 'colors'; - -window, -viewport, -stack { - all: unset; -} - -progressbar { - border-radius: 999px; - background: transparent; - border: none; - - trough { - background: #363847; - min-height: inherit; - border-radius: inherit; - border: none; - } - - progress { - background: #79659f; - min-height: inherit; - border-radius: inherit; - border: none; - } - - &:disabled { - opacity: 0.5; - } -} - -scale { - contents { - trough { - min-height: 10px; - } - } -} - -circularprogress { - background: #363847; - min-height: 35px; - min-width: 35px; - font-size: 4px; - color: #79659f; - - &.disabled { - opacity: 0.5; - } -} - -.widget { - margin: 10px; - padding: 5px; - border-radius: 7px; - background-color: colors.$window_bg_color; - box-shadow: 8px 8px colors.$accent_color; -} diff --git a/modules/ags/config/style/greeter.scss b/modules/ags/config/style/greeter.scss deleted file mode 100644 index 823e51ca..00000000 --- a/modules/ags/config/style/greeter.scss +++ /dev/null @@ -1,18 +0,0 @@ -@use 'colors'; - -window { - all: unset; - background-color: transparent; -} - - -.base { - background-color: colors.$window_bg_color; - border: 1.3px solid colors.$accent_bg_color; - border-radius: 12px; - padding: 5px; -} - -dropdown popover.menu { - padding-top: 0; -} diff --git a/modules/ags/config/style/main.scss b/modules/ags/config/style/main.scss deleted file mode 100644 index c74c832a..00000000 --- a/modules/ags/config/style/main.scss +++ /dev/null @@ -1,17 +0,0 @@ -@use 'common'; - -@use '../widgets/applauncher'; -@use '../widgets/audio'; -@use '../widgets/bar'; -@use '../widgets/bluetooth'; -@use '../widgets/clipboard'; -@use '../widgets/date'; -@use '../widgets/icon-browser'; -@use '../widgets/media-player'; -@use '../widgets/misc'; -@use '../widgets/network'; -@use '../widgets/notifs'; -@use '../widgets/on-screen-display'; -@use '../widgets/on-screen-keyboard'; -@use '../widgets/powermenu'; -@use '../widgets/screenshot'; diff --git a/modules/ags/config/tsconfig.json b/modules/ags/config/tsconfig.json deleted file mode 100644 index dd1cebcc..00000000 --- a/modules/ags/config/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "compilerOptions": { - "experimentalDecorators": true, - "jsx": "react-jsx", - "jsxImportSource": "astal/gtk3", - "lib": [ - "ES2022" - ], - "module": "ES2022", - "moduleResolution": "Bundler", - "noEmit": true, - "skipLibCheck": true, - "strict": true, - "target": "ES2022" - } -} diff --git a/modules/ags/config/widgets/applauncher/_index.scss b/modules/ags/config/widgets/applauncher/_index.scss deleted file mode 100644 index cbba15fc..00000000 --- a/modules/ags/config/widgets/applauncher/_index.scss +++ /dev/null @@ -1,6 +0,0 @@ -.applauncher { - .app { - margin: 20px; - font-size: 16px; - } -} diff --git a/modules/ags/config/widgets/applauncher/app-item.tsx b/modules/ags/config/widgets/applauncher/app-item.tsx deleted file mode 100644 index e7ff2291..00000000 --- a/modules/ags/config/widgets/applauncher/app-item.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import { Gtk, Widget } from 'astal/gtk3'; -import { register } from 'astal/gobject'; - -/* Types */ -import AstalApps from 'gi://AstalApps'; -type AppItemProps = Widget.BoxProps & { - app: AstalApps.Application -}; - - -@register() -export class AppItem extends Widget.Box { - readonly app: AstalApps.Application; - - constructor({ - app, - hexpand = true, - className = '', - ...rest - }: AppItemProps) { - super({ - ...rest, - className: `app ${className}`, - hexpand, - }); - this.app = app; - - const icon = ( - <icon - icon={this.app.get_icon_name()} - css="font-size: 42px; margin-right: 25px;" - /> - ); - - const textBox = ( - <box vertical> - <label - className="title" - label={app.get_name()} - xalign={0} - truncate - valign={Gtk.Align.CENTER} - /> - - {app.description !== '' && ( - <label - className="description" - label={app.get_description()} - wrap - xalign={0} - justify={Gtk.Justification.LEFT} - valign={Gtk.Align.CENTER} - /> - )} - </box> - ); - - this.add(icon); - this.add(textBox); - } -} - -export default AppItem; diff --git a/modules/ags/config/widgets/applauncher/index.tsx b/modules/ags/config/widgets/applauncher/index.tsx deleted file mode 100644 index 675b0921..00000000 --- a/modules/ags/config/widgets/applauncher/index.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { App } from 'astal/gtk3'; - -import AstalApps from 'gi://AstalApps'; - -import SortedList from '../misc/sorted-list'; - -import { launchApp } from './launch'; -import AppItem from './app-item'; - - -export default () => SortedList({ - name: 'applauncher', - - create_list: () => AstalApps.Apps.new().get_list(), - - create_row: (app) => <AppItem app={app} />, - - fzf_options: { - selector: (app) => app.get_name() + app.get_executable(), - - tiebreakers: [ - (a, b) => b.item.get_frequency() - a.item.get_frequency(), - ], - }, - - unique_props: ['name', 'executable'], - - on_row_activated: (row) => { - const app = (row.get_children()[0] as AppItem).app; - - launchApp(app); - App.get_window('win-applauncher')?.set_visible(false); - }, - - sort_func: (a, b, entry, fzfResults) => { - const row1 = (a.get_children()[0] as AppItem).app; - const row2 = (b.get_children()[0] as AppItem).app; - - if (entry.text === '' || entry.text === '-') { - a.set_visible(true); - b.set_visible(true); - - return row2.get_frequency() - row1.get_frequency(); - } - else { - const s1 = fzfResults.find((r) => r.item.get_name() === row1.get_name())?.score ?? 0; - const s2 = fzfResults.find((r) => r.item.get_name() === row2.get_name())?.score ?? 0; - - a.set_visible(s1 !== 0); - b.set_visible(s2 !== 0); - - return s2 - s1; - } - }, -}); diff --git a/modules/ags/config/widgets/applauncher/launch.ts b/modules/ags/config/widgets/applauncher/launch.ts deleted file mode 100644 index de59122f..00000000 --- a/modules/ags/config/widgets/applauncher/launch.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { execAsync } from 'astal'; - -import AstalApps from 'gi://AstalApps'; - - -const bash = async(strings: TemplateStringsArray | string, ...values: unknown[]) => { - const cmd = typeof strings === 'string' ? - strings : - strings.flatMap((str, i) => `${str}${values[i] ?? ''}`) - .join(''); - - return execAsync(['bash', '-c', cmd]).catch((err) => { - console.error(cmd, err); - - return ''; - }); -}; - -export const launchApp = (app: AstalApps.Application) => { - const exe = app.executable - .split(/\s+/) - .filter((str) => !str.startsWith('%') && !str.startsWith('@')) - .join(' '); - - bash(`${exe} &`); - - app.set_frequency(app.get_frequency() + 1); -}; diff --git a/modules/ags/config/widgets/audio/_index.scss b/modules/ags/config/widgets/audio/_index.scss deleted file mode 100644 index 93ede090..00000000 --- a/modules/ags/config/widgets/audio/_index.scss +++ /dev/null @@ -1,44 +0,0 @@ -@use 'sass:color'; -@use '../../style/colors'; - -.widget.audio { - .header { - .header-btn { - font-size: 30px; - margin: 5px; - transition: background 400ms; - - &.active { - background: colors.$window_bg_color; - } - } - } - - scrollable { - margin: 5px; - min-height: 400px; - - box { - .item-btn { - margin: 3px; - } - } - } - - .stream { - margin: 5px; - padding: 10px; - border-radius: 8px; - background-color: color.adjust(colors.$window_bg_color, $lightness: -3%); - - .body { - .toggle { - padding: 5px; - - icon { - font-size: 26px; - } - } - } - } -} diff --git a/modules/ags/config/widgets/audio/binto.tsx b/modules/ags/config/widgets/audio/binto.tsx deleted file mode 100644 index 06b389c8..00000000 --- a/modules/ags/config/widgets/audio/binto.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { Astal } from 'astal/gtk3'; - -import PopupWindow from '../misc/popup-window'; -import { get_gdkmonitor_from_desc } from '../../lib'; - -import AudioWidget from './main'; - - -export default () => ( - <PopupWindow - name="audio" - gdkmonitor={get_gdkmonitor_from_desc('desc:Acer Technologies Acer K212HQL T3EAA0014201')} - anchor={Astal.WindowAnchor.RIGHT | Astal.WindowAnchor.BOTTOM} - transition="slide bottom" - > - <AudioWidget /> - </PopupWindow> -); diff --git a/modules/ags/config/widgets/audio/main.tsx b/modules/ags/config/widgets/audio/main.tsx deleted file mode 100644 index f0dde3ac..00000000 --- a/modules/ags/config/widgets/audio/main.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import { bind, Variable } from 'astal'; -import { Gtk, Widget } from 'astal/gtk3'; - -import AstalWp from 'gi://AstalWp'; - -import Separator from '../misc/separator'; - -import Streams from './streams'; -import Profiles from './profiles'; - - -export default () => { - const audio = AstalWp.get_default()?.get_audio(); - - if (!audio) { - throw new Error('Could not find default audio devices.'); - } - - const Shown = Variable<string>('outputs'); - - const stack = ( - <stack - shown={bind(Shown)} - transitionType={Gtk.StackTransitionType.SLIDE_LEFT_RIGHT} - > - - <scrollable - name="outputs" - hscroll={Gtk.PolicyType.NEVER} - - setup={(self) => setTimeout(() => { - self.add(( - <box vertical> - {bind(audio, 'speakers').as(Streams)} - </box> - )); - }, 1000)} - /> - - <scrollable - name="inputs" - hscroll={Gtk.PolicyType.NEVER} - - setup={(self) => setTimeout(() => { - self.add(( - <box vertical> - {bind(audio, 'microphones').as(Streams)} - </box> - )); - }, 1000)} - /> - - <scrollable - name="profiles" - hscroll={Gtk.PolicyType.NEVER} - - setup={(self) => setTimeout(() => { - self.add(( - <box vertical> - {bind(audio, 'devices').as(Profiles)} - </box> - )); - }, 1000)} - /> - - </stack> - ) as Widget.Stack; - - const StackButton = ({ label = '', iconName = '' }) => ( - <button - cursor="pointer" - className={bind(Shown).as((shown) => - `header-btn${shown === label ? ' active' : ''}`)} - - onButtonReleaseEvent={() => { - Shown.set(label); - }} - > - <box halign={Gtk.Align.CENTER}> - <icon icon={iconName} /> - - <Separator size={8} /> - - {label} - </box> - </button> - ) as Widget.Button; - - return ( - <box - className="audio widget" - vertical - > - <box - className="header" - homogeneous - > - <StackButton label="outputs" iconName="audio-speakers-symbolic" /> - <StackButton label="inputs" iconName="audio-input-microphone-symbolic" /> - <StackButton label="profiles" iconName="application-default-symbolic" /> - </box> - - {stack} - </box> - ); -}; diff --git a/modules/ags/config/widgets/audio/profiles.tsx b/modules/ags/config/widgets/audio/profiles.tsx deleted file mode 100644 index e5cc2de1..00000000 --- a/modules/ags/config/widgets/audio/profiles.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { bind } from 'astal'; - -import AstalWp from 'gi://AstalWp'; - -import { ComboBoxText } from '../misc/subclasses'; - - -export default (devices: AstalWp.Device[]) => devices - .sort((a, b) => a.get_description().localeCompare(b.description)) - .map((device) => ( - <box className="stream" vertical> - - <label label={bind(device, 'description')} /> - - <ComboBoxText - setup={(self) => { - const profiles = (device.get_profiles() ?? []).sort((a, b) => { - if (a.get_description() === 'Off') { - return 1; - } - else if (b.get_description() === 'Off') { - return -1; - } - else { - return a.get_description().localeCompare(b.get_description()); - } - }); - - profiles.forEach((profile) => { - self.append(profile.get_index().toString(), profile.get_description()); - }); - - self.set_active( - profiles.indexOf( - device.get_profile(device.get_active_profile())!, - ), - ); - }} - - onChanged={(self) => { - const activeId = self.get_active_id(); - - if (activeId) { - device.set_active_profile(parseInt(activeId)); - } - }} - /> - - </box> - )); diff --git a/modules/ags/config/widgets/audio/streams.tsx b/modules/ags/config/widgets/audio/streams.tsx deleted file mode 100644 index b4332e73..00000000 --- a/modules/ags/config/widgets/audio/streams.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { bind } from 'astal'; -import { Gtk } from 'astal/gtk3'; - -import AstalWp from 'gi://AstalWp'; - -import { RadioButton } from '../misc/subclasses'; -import Separator from '../misc/separator'; - - -export default (streams: AstalWp.Endpoint[]) => { - let group: RadioButton | undefined; - - return streams - .sort((a, b) => a.get_description().localeCompare(b.get_description())) - .map((stream) => ( - <box className="stream" vertical> - - <box className="title"> - - <RadioButton - cursor="pointer" - css="margin-top: 1px;" - - onRealize={(self) => { - if (!group) { - group = self; - } - else { - self.group = group; - } - - self.active = stream.get_is_default(); - self.hook(stream, 'notify::is-default', () => { - self.active = stream.get_is_default(); - }); - }} - - onButtonReleaseEvent={() => { - stream.set_is_default(true); - }} - /> - - <Separator size={8} /> - - <label label={bind(stream, 'description')} /> - - </box> - - <Separator size={4} vertical /> - - <box className="body"> - - <button - cursor="pointer" - className="toggle" - valign={Gtk.Align.END} - - onButtonReleaseEvent={() => { - stream.set_mute(!stream.get_mute()); - }} - > - <icon - icon={bind(stream, 'mute').as((isMuted) => { - if (stream.get_media_class() === AstalWp.MediaClass.AUDIO_MICROPHONE) { - return isMuted ? - 'audio-input-microphone-muted-symbolic' : - 'audio-input-microphone-symbolic'; - } - else { - return isMuted ? - 'audio-volume-muted-symbolic' : - 'audio-speakers-symbolic'; - } - })} - /> - </button> - - <Separator size={4} /> - - <slider - hexpand - halign={Gtk.Align.FILL} - drawValue - cursor="pointer" - - value={bind(stream, 'volume')} - onDragged={(self) => { - stream.set_volume(self.value); - }} - /> - - </box> - - </box> - )); -}; diff --git a/modules/ags/config/widgets/audio/wim.tsx b/modules/ags/config/widgets/audio/wim.tsx deleted file mode 100644 index b3327738..00000000 --- a/modules/ags/config/widgets/audio/wim.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { Astal } from 'astal/gtk3'; - -import PopupWindow from '../misc/popup-window'; - -import AudioWidget from './main'; - - -export default () => ( - <PopupWindow - name="audio" - anchor={Astal.WindowAnchor.RIGHT | Astal.WindowAnchor.TOP} - > - <AudioWidget /> - </PopupWindow> -); diff --git a/modules/ags/config/widgets/bar/_index.scss b/modules/ags/config/widgets/bar/_index.scss deleted file mode 100644 index 7eaec5e6..00000000 --- a/modules/ags/config/widgets/bar/_index.scss +++ /dev/null @@ -1,81 +0,0 @@ -@use 'sass:color'; -@use '../../style/colors'; - -.bar { - margin-left: 5px; - margin-right: 15px; - margin-bottom: 13px; - - .bar-item { - padding: 5px 10px 5px 10px; - border-radius: 7px; - background-color: color.adjust(colors.$window_bg_color, $lightness: -3%); - font-size: 20px; - min-height: 35px; - - transition: background-color 300ms; - - &:hover { - background-color: color.adjust(colors.$window_bg_color, $lightness: 3%); - } - - &.bluetooth icon, - &.heart-toggle label, - &.keyboard icon, - &.network icon, - &.tablet-mode icon { - min-width: 30px; - } - - &.battery icon { - &.charging { - color: green; - } - - &.low { - color: red; - } - } - - .workspaces { - .button { - margin: 0 2.5px; - min-height: 22px; - min-width: 22px; - border-radius: 100%; - border: 2px solid transparent; - } - - .occupied { - border: 2px solid colors.$window_bg_color; - background: colors.$accent_color; - transition: background-color 0.3s ease-in-out; - } - - .urgent { - border: 2px solid colors.$window_bg_color; - background: red; - transition: background-color 0.3s ease-in-out; - } - - .active { - border: 2px solid #50fa7b; - transition: margin-left 0.3s cubic-bezier(0.165, 0.84, 0.44, 1); - } - } - - &.system-tray { - .tray-item { - all: unset; - font-size: 30px; - min-width: 36px; - border-radius: 100%; - transition: background-color 300ms; - - &:hover { - background: colors.$window_bg_color; - } - } - } - } -} diff --git a/modules/ags/config/widgets/bar/binto.tsx b/modules/ags/config/widgets/bar/binto.tsx deleted file mode 100644 index be063eb8..00000000 --- a/modules/ags/config/widgets/bar/binto.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { Astal, Gtk } from 'astal/gtk3'; - -import Audio from './items/audio'; -import Clock from './items/clock'; -import CurrentIcon from './items/current-icon'; -import Network from './items/network'; -import NotifButton from './items/notif-button'; -import SysTray from './items/tray'; - -import BarRevealer from './fullscreen'; -import Separator from '../misc/separator'; -import { get_gdkmonitor_from_desc } from '../../lib'; - - -export default () => ( - <BarRevealer - gdkmonitor={get_gdkmonitor_from_desc('desc:Acer Technologies Acer K212HQL T3EAA0014201')} - exclusivity={Astal.Exclusivity.EXCLUSIVE} - anchor={ - Astal.WindowAnchor.BOTTOM | - Astal.WindowAnchor.LEFT | - Astal.WindowAnchor.RIGHT - } - > - <centerbox className="bar widget"> - <box hexpand halign={Gtk.Align.START}> - <CurrentIcon /> - - {/* <Separator size={8} />*/} - - <SysTray /> - - <Separator size={8} /> - </box> - - <box> - <Clock /> - </box> - - <box hexpand halign={Gtk.Align.END}> - <Network /> - - <Separator size={8} /> - - <NotifButton /> - - <Separator size={8} /> - - <Audio /> - - <Separator size={2} /> - </box> - </centerbox> - - </BarRevealer> -); diff --git a/modules/ags/config/widgets/bar/fullscreen.tsx b/modules/ags/config/widgets/bar/fullscreen.tsx deleted file mode 100644 index f47c47bc..00000000 --- a/modules/ags/config/widgets/bar/fullscreen.tsx +++ /dev/null @@ -1,193 +0,0 @@ -import { App, Astal, Gdk, Gtk, Widget } from 'astal/gtk3'; -import { bind, idle, Variable } from 'astal'; - -import AstalHyprland from 'gi://AstalHyprland'; - -import { get_hyprland_monitor_desc, get_monitor_desc, hyprMessage } from '../../lib'; - - -const FullscreenState = Variable({ - monitors: [] as string[], - clientAddrs: new Map() as Map<string, string>, -}); - -export default ({ - anchor, - gdkmonitor = Gdk.Display.get_default()?.get_monitor(0) as Gdk.Monitor, - child, - ...rest -}: { - anchor: Astal.WindowAnchor - gdkmonitor?: Gdk.Monitor -} & Widget.WindowProps) => { - const hyprland = AstalHyprland.get_default(); - - const monitor = get_hyprland_monitor_desc(gdkmonitor); - const BarVisible = Variable(false); - - hyprland.connect('event', async() => { - const arrayEquals = (a1: unknown[], a2: unknown[]) => - a1.sort().toString() === a2.sort().toString(); - - const mapEquals = (m1: Map<string, string>, m2: Map<string, string>) => - m1.size === m2.size && - Array.from(m1.keys()).every((key) => m1.get(key) === m2.get(key)); - - try { - const newMonitors = JSON.parse(await hyprMessage('j/monitors')) as AstalHyprland.Monitor[]; - - const fs = FullscreenState.get(); - const fsClients = hyprland.get_clients().filter((c) => { - const mon = newMonitors.find((m) => m.id === c.get_monitor()?.id); - - return c.fullscreenClient !== 0 && - c.workspace.id === mon?.activeWorkspace.id; - }); - - const monitors = fsClients.map((c) => - get_monitor_desc(c.monitor)); - - const clientAddrs = new Map(fsClients.map((c) => [ - get_monitor_desc(c.monitor), - c.address ?? '', - ])); - - const hasChanged = - !arrayEquals(monitors, fs.monitors) || - !mapEquals(clientAddrs, fs.clientAddrs); - - if (hasChanged) { - FullscreenState.set({ - monitors, - clientAddrs, - }); - } - } - catch (e) { - console.log(e); - } - }); - - FullscreenState.subscribe((v) => { - BarVisible.set(!v.monitors.includes(monitor)); - }); - - const barCloser = ( - <window - name={`noanim-bar-${monitor}-closer`} - namespace={`noanim-bar-${monitor}-closer`} - css="all: unset;" - visible={false} - gdkmonitor={gdkmonitor} - layer={Astal.Layer.OVERLAY} - anchor={ - Astal.WindowAnchor.TOP | - Astal.WindowAnchor.BOTTOM | - Astal.WindowAnchor.LEFT | - Astal.WindowAnchor.RIGHT - } - > - <eventbox - on_hover={() => { - barCloser.visible = false; - BarVisible.set(false); - }} - > - <box css="padding: 1px;" /> - </eventbox> - </window> - ); - - // Hide bar instantly when out of focus - hyprland.connect('notify::focused-workspace', () => { - const addr = FullscreenState.get().clientAddrs.get(monitor); - - if (addr) { - const client = hyprland.get_client(addr); - - if (client?.workspace.id !== hyprland.get_focused_workspace().get_id()) { - BarVisible.set(true); - barCloser.visible = false; - } - else { - BarVisible.set(false); - barCloser.visible = true; - } - } - }); - - const buffer = ( - <box - css="min-height: 10px;" - visible={bind(BarVisible).as((v) => !v)} - /> - ); - - const vertical = anchor >= (Astal.WindowAnchor.LEFT | Astal.WindowAnchor.RIGHT); - const isBottomOrLeft = ( - anchor === (Astal.WindowAnchor.LEFT | Astal.WindowAnchor.RIGHT | Astal.WindowAnchor.BOTTOM) - ) || ( - anchor === (Astal.WindowAnchor.LEFT | Astal.WindowAnchor.TOP | Astal.WindowAnchor.BOTTOM) - ); - - let transition: Gtk.RevealerTransitionType; - - if (vertical) { - transition = isBottomOrLeft ? - Gtk.RevealerTransitionType.SLIDE_UP : - Gtk.RevealerTransitionType.SLIDE_DOWN; - } - else { - transition = isBottomOrLeft ? - Gtk.RevealerTransitionType.SLIDE_RIGHT : - Gtk.RevealerTransitionType.SLIDE_LEFT; - } - - const barWrap = ( - <revealer - reveal_child={bind(BarVisible)} - transitionType={transition} - > - {child} - </revealer> - ); - - const win = ( - <window - name={`noanim-bar-${monitor}`} - namespace={`noanim-bar-${monitor}`} - layer={Astal.Layer.OVERLAY} - gdkmonitor={gdkmonitor} - anchor={anchor} - {...rest} - > - <eventbox - onHover={() => { - if (!BarVisible.get()) { - barCloser.visible = true; - BarVisible.set(true); - } - }} - > - <box - css="min-height: 1px; padding: 1px;" - hexpand - halign={Gtk.Align.FILL} - vertical={vertical} - > - {isBottomOrLeft ? - [buffer, barWrap] : - [barWrap, buffer]} - </box> - </eventbox> - </window> - ) as Widget.Window; - - App.add_window(win); - - idle(() => { - BarVisible.set(true); - }); - - return win; -}; diff --git a/modules/ags/config/widgets/bar/items/audio.tsx b/modules/ags/config/widgets/bar/items/audio.tsx deleted file mode 100644 index 4b542f2d..00000000 --- a/modules/ags/config/widgets/bar/items/audio.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { bind } from 'astal'; -import { App } from 'astal/gtk3'; - -import AstalWp from 'gi://AstalWp'; - -import PopupWindow from '../../misc/popup-window'; - - -export default () => { - const speaker = AstalWp.get_default()?.get_audio()?.get_default_speaker(); - - if (!speaker) { - throw new Error('Could not find default audio devices.'); - } - - return ( - <button - cursor="pointer" - className="bar-item audio" - - onButtonReleaseEvent={(self) => { - const win = App.get_window('win-audio') as PopupWindow; - - win.set_x_pos( - self.get_allocation(), - 'right', - ); - - win.set_visible(!win.get_visible()); - }} - > - <overlay passThrough> - <circularprogress - startAt={0.75} - endAt={0.75} - value={bind(speaker, 'volume')} - - rounded - className={bind(speaker, 'mute').as((muted) => muted ? 'disabled' : '')} - /> - - <icon icon={bind(speaker, 'volumeIcon')} /> - </overlay> - </button> - ); -}; diff --git a/modules/ags/config/widgets/bar/items/battery.tsx b/modules/ags/config/widgets/bar/items/battery.tsx deleted file mode 100644 index 5a242622..00000000 --- a/modules/ags/config/widgets/bar/items/battery.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { bind } from 'astal'; - -import AstalBattery from 'gi://AstalBattery'; - -import Separator from '../../misc/separator'; - - -const LOW_BATT = 20; - -export default () => { - const battery = AstalBattery.get_default(); - - return ( - <box className="bar-item battery"> - <icon - setup={(self) => { - const update = () => { - const percent = Math.round(battery.get_percentage() * 100); - const level = Math.floor(percent / 10) * 10; - const isCharging = battery.get_charging(); - const charged = percent === 100 && isCharging; - const iconName = charged ? - 'battery-level-100-charged-symbolic' : - `battery-level-${level}${isCharging ? - '-charging' : - ''}-symbolic`; - - self.set_icon(iconName); - - self.toggleClassName('charging', isCharging); - self.toggleClassName('charged', charged); - self.toggleClassName('low', percent < LOW_BATT); - }; - - update(); - - battery.connect('notify::percentage', () => update()); - battery.connect('notify::icon-name', () => update()); - battery.connect('notify::battery-icon-name', () => update()); - }} - /> - - <Separator size={8} /> - - <label label={bind(battery, 'percentage').as((v) => `${Math.round(v * 100)}%`)} /> - </box> - ); -}; diff --git a/modules/ags/config/widgets/bar/items/bluetooth.tsx b/modules/ags/config/widgets/bar/items/bluetooth.tsx deleted file mode 100644 index ff69a78f..00000000 --- a/modules/ags/config/widgets/bar/items/bluetooth.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import { bind, Variable } from 'astal'; -import { App, Gtk } from 'astal/gtk3'; - -import AstalBluetooth from 'gi://AstalBluetooth'; - -import PopupWindow from '../../misc/popup-window'; - - -export default () => { - const bluetooth = AstalBluetooth.get_default(); - - const Hovered = Variable(false); - - return ( - <button - className="bar-item bluetooth" - cursor="pointer" - - onHover={() => Hovered.set(true)} - onHoverLost={() => Hovered.set(false)} - - onButtonReleaseEvent={(self) => { - const win = App.get_window('win-bluetooth') as PopupWindow; - - win.set_x_pos( - self.get_allocation(), - 'right', - ); - - win.set_visible(!win.get_visible()); - }} - > - {bind(bluetooth, 'isPowered').as((isPowered) => { - if (!isPowered) { - return (<icon icon="bluetooth-disabled-symbolic" />); - } - else { - return ( - <box> - {bind(bluetooth, 'isConnected').as((isConnected) => { - const device = bluetooth - .get_devices() - .find((dev) => dev.get_connected()); - - if (!isConnected || !device) { - return (<icon icon="bluetooth-active-symbolic" />); - } - else { - return ( - <> - <icon icon={bind(device, 'icon')} /> - - <revealer - revealChild={bind(Hovered)} - transitionType={Gtk.RevealerTransitionType.SLIDE_LEFT} - > - <label label={bind(device, 'name')} /> - </revealer> - </> - ); - } - })} - </box> - ); - } - })} - </button> - ); -}; diff --git a/modules/ags/config/widgets/bar/items/brightness.tsx b/modules/ags/config/widgets/bar/items/brightness.tsx deleted file mode 100644 index 674092f4..00000000 --- a/modules/ags/config/widgets/bar/items/brightness.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { bind } from 'astal'; -import { App } from 'astal/gtk3'; - -import Brightness from '../../../services/brightness'; - -import PopupWindow from '../../misc/popup-window'; - - -export default () => { - const brightness = Brightness.get_default(); - - return ( - <button - cursor="pointer" - className="bar-item brightness" - - onButtonReleaseEvent={(self) => { - const win = App.get_window('win-brightness-slider') as PopupWindow; - - win.set_x_pos( - self.get_allocation(), - 'right', - ); - - win.set_visible(!win.get_visible()); - }} - > - <overlay passThrough> - <circularprogress - startAt={0.75} - endAt={0.75} - value={bind(brightness, 'screen')} - rounded - /> - - <icon icon={bind(brightness, 'screenIcon')} /> - </overlay> - </button> - ); -}; diff --git a/modules/ags/config/widgets/bar/items/clock.tsx b/modules/ags/config/widgets/bar/items/clock.tsx deleted file mode 100644 index 2489ffd1..00000000 --- a/modules/ags/config/widgets/bar/items/clock.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { bind, Variable } from 'astal'; -import { App } from 'astal/gtk3'; - -import GLib from 'gi://GLib'; -import PopupWindow from '../../misc/popup-window'; - - -export default () => { - const timeVar = Variable<string>('').poll(1000, (prev) => { - const time = GLib.DateTime.new_now_local(); - - const dayName = time.format('%a. '); - const dayNum = time.get_day_of_month(); - const date = time.format(' %b. '); - const hour = (new Date().toLocaleString([], { - hour: 'numeric', - minute: 'numeric', - hour12: true, - }) ?? '') - .replace('a.m.', 'AM') - .replace('p.m.', 'PM'); - - return (dayNum && dayName && date) ? - (dayName + dayNum + date + hour) : - prev; - }); - - return ( - <button - className="bar-item" - cursor="pointer" - - onButtonReleaseEvent={(self) => { - const win = App.get_window('win-calendar') as PopupWindow; - - win.set_x_pos( - self.get_allocation(), - 'right', - ); - - win.set_visible(!win.get_visible()); - }} - - setup={(self) => { - App.connect('window-toggled', (_, win) => { - if (win.get_name() === 'win-notif-center') { - self.toggleClassName('toggle-on', win.get_visible()); - } - }); - }} - > - <label label={bind(timeVar)} /> - </button> - ); -}; diff --git a/modules/ags/config/widgets/bar/items/current-client.tsx b/modules/ags/config/widgets/bar/items/current-client.tsx deleted file mode 100644 index 6a4e97e0..00000000 --- a/modules/ags/config/widgets/bar/items/current-client.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import { bind, Variable } from 'astal'; -import { Gtk } from 'astal/gtk3'; - -import AstalApps from 'gi://AstalApps'; -import AstalHyprland from 'gi://AstalHyprland'; - -import Separator from '../../misc/separator'; - - -export default () => { - const applications = AstalApps.Apps.new(); - const hyprland = AstalHyprland.get_default(); - - const visibleIcon = Variable<boolean>(false); - const focusedIcon = Variable<string>(''); - const focusedTitle = Variable<string>(''); - - let lastFocusedAddress: string | null; - - - const updateVars = ( - client: AstalHyprland.Client | null = hyprland.get_focused_client(), - ) => { - lastFocusedAddress = client ? client.get_address() : null; - - const app = applications.fuzzy_query( - client?.get_class() ?? '', - )[0]; - - const icon = app?.get_icon_name(); - - if (icon) { - visibleIcon.set(true); - focusedIcon.set(icon); - } - else { - visibleIcon.set(false); - } - - focusedTitle.set(client?.get_title() ?? ''); - const id = client?.connect('notify::title', (c) => { - if (c.get_address() !== lastFocusedAddress) { - c.disconnect(id); - } - else { - focusedTitle.set(c.get_title()); - } - }); - }; - - updateVars(); - hyprland.connect('notify::focused-client', () => updateVars()); - - return ( - <revealer - transitionType={Gtk.RevealerTransitionType.SLIDE_RIGHT} - revealChild={bind(focusedTitle).as((title) => title !== '')} - > - <box> - <Separator size={8} /> - - <box className="bar-item current-window"> - <revealer - transitionType={Gtk.RevealerTransitionType.SLIDE_RIGHT} - revealChild={bind(visibleIcon)} - > - <box> - <icon - css="font-size: 32px;" - icon={bind(focusedIcon)} - /> - - <Separator size={8} /> - </box> - </revealer> - - <label - label={bind(focusedTitle)} - truncate - maxWidthChars={35} - /> - </box> - </box> - </revealer> - ); -}; diff --git a/modules/ags/config/widgets/bar/items/current-icon.tsx b/modules/ags/config/widgets/bar/items/current-icon.tsx deleted file mode 100644 index b67cf286..00000000 --- a/modules/ags/config/widgets/bar/items/current-icon.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { bind, Variable } from 'astal'; -import { Gtk } from 'astal/gtk3'; - -import AstalApps from 'gi://AstalApps'; -import AstalHyprland from 'gi://AstalHyprland'; - -import Separator from '../../misc/separator'; - - -export default () => { - const applications = AstalApps.Apps.new(); - const hyprland = AstalHyprland.get_default(); - - const visibleIcon = Variable<boolean>(false); - const focusedIcon = Variable<string>(''); - - const updateVars = ( - client: AstalHyprland.Client | null = hyprland.get_focused_client(), - ) => { - const app = applications.fuzzy_query( - client?.get_class() ?? '', - )[0]; - - const icon = app?.get_icon_name(); - - if (icon) { - visibleIcon.set(true); - focusedIcon.set(icon); - } - else { - visibleIcon.set(false); - } - }; - - updateVars(); - hyprland.connect('notify::focused-client', () => updateVars()); - - return ( - <revealer - transitionType={Gtk.RevealerTransitionType.SLIDE_RIGHT} - revealChild={bind(visibleIcon)} - > - <box> - <box className="bar-item current-window"> - <icon - css="font-size: 32px;" - icon={bind(focusedIcon)} - /> - </box> - - <Separator size={8} /> - </box> - </revealer> - ); -}; diff --git a/modules/ags/config/widgets/bar/items/heart.tsx b/modules/ags/config/widgets/bar/items/heart.tsx deleted file mode 100644 index 92c2d52b..00000000 --- a/modules/ags/config/widgets/bar/items/heart.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { Variable } from 'astal'; - -import Persist from '../../misc/persist'; - -const HeartState = Variable(''); - -Persist({ - name: 'heart', - variable: HeartState, - condition: '', - whenFalse: '', -}); - - -export default () => ( - <button - className="bar-item heart-toggle" - cursor="pointer" - - onButtonReleaseEvent={() => { - HeartState.set(HeartState.get() === '' ? '' : ''); - }} - > - <label - label={HeartState()} - css="margin-left: -6px; margin-right: 4px; font-size: 28px;" - /> - </button> -); diff --git a/modules/ags/config/widgets/bar/items/keyboard-layout.tsx b/modules/ags/config/widgets/bar/items/keyboard-layout.tsx deleted file mode 100644 index 3b71f009..00000000 --- a/modules/ags/config/widgets/bar/items/keyboard-layout.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import { Variable } from 'astal'; -import { Label } from 'astal/gtk3/widget'; - -import AstalHyprland from 'gi://AstalHyprland'; - -import { hyprMessage } from '../../../lib'; -import { Gtk } from 'astal/gtk3'; - -/* Types */ -interface Keyboard { - address: string - name: string - rules: string - model: string - layout: string - variant: string - options: string - active_keymap: string - main: boolean -} - - -const DEFAULT_KB = 'at-translated-set-2-keyboard'; - -export default () => { - const Hovered = Variable(false); - - const hyprland = AstalHyprland.get_default(); - - const getKbdLayout = (self: Label, _: string, layout?: string) => { - if (layout) { - if (layout === 'error') { - return; - } - - const shortName = layout.match(/\(([A-Za-z]+)\)/); - - self.label = shortName ? shortName[1] : layout; - } - else { - // At launch, kb layout is undefined - hyprMessage('j/devices').then((obj) => { - const keyboards = Array.from(JSON.parse(obj) - .keyboards) as Keyboard[]; - const kb = keyboards.find((v) => v.name === DEFAULT_KB); - - if (kb) { - layout = kb.active_keymap; - - const shortName = layout - .match(/\(([A-Za-z]+)\)/); - - self.label = shortName ? shortName[1] : layout; - } - else { - self.label = 'None'; - } - }).catch(print); - } - }; - - return ( - <button - className="bar-item keyboard" - cursor="pointer" - - onHover={() => Hovered.set(true)} - onHoverLost={() => Hovered.set(false)} - > - <box> - <icon icon="input-keyboard-symbolic" /> - - <revealer - revealChild={Hovered()} - transitionType={Gtk.RevealerTransitionType.SLIDE_LEFT} - > - <label - setup={(self) => { - self.hook(hyprland, 'keyboard-layout', getKbdLayout); - getKbdLayout(self, ''); - }} - /> - </revealer> - </box> - </button> - ); -}; diff --git a/modules/ags/config/widgets/bar/items/network.tsx b/modules/ags/config/widgets/bar/items/network.tsx deleted file mode 100644 index bf349db3..00000000 --- a/modules/ags/config/widgets/bar/items/network.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import { bind, Variable } from 'astal'; -import { App, Gtk } from 'astal/gtk3'; - -import AstalNetwork from 'gi://AstalNetwork'; - -/* Types */ -import PopupWindow from '../../misc/popup-window'; - - -export default () => { - const network = AstalNetwork.get_default(); - - const Hovered = Variable(false); - - return ( - <button - className="bar-item network" - cursor="pointer" - - onHover={() => Hovered.set(true)} - onHoverLost={() => Hovered.set(false)} - - onButtonReleaseEvent={(self) => { - const win = App.get_window('win-network') as PopupWindow; - - win.set_x_pos( - self.get_allocation(), - 'right', - ); - - win.set_visible(!win.get_visible()); - }} - > - {bind(network, 'primary').as((primary) => { - if (primary === AstalNetwork.Primary.UNKNOWN) { - return (<icon icon="network-wireless-signal-none-symbolic" />); - } - else if (primary === AstalNetwork.Primary.WIFI) { - const Wifi = network.get_wifi(); - - if (!Wifi || Wifi.get_access_points().length === 0) { return; } - - return ( - <box> - <icon icon={bind(Wifi, 'iconName')} /> - - <revealer - revealChild={bind(Hovered)} - transitionType={Gtk.RevealerTransitionType.SLIDE_LEFT} - > - {bind(Wifi, 'activeAccessPoint').as((ap) => ap && ( - <label label={bind(ap, 'ssid')} /> - ))} - </revealer> - </box> - ); - } - else { - const Wired = network.get_wired(); - - if (!Wired) { return; } - - return (<icon icon={bind(Wired, 'iconName')} />); - } - })} - </button> - ); -}; diff --git a/modules/ags/config/widgets/bar/items/notif-button.tsx b/modules/ags/config/widgets/bar/items/notif-button.tsx deleted file mode 100644 index 0082aa54..00000000 --- a/modules/ags/config/widgets/bar/items/notif-button.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { bind } from 'astal'; -import { App } from 'astal/gtk3'; - -import AstalNotifd from 'gi://AstalNotifd'; - -import Separator from '../../misc/separator'; - -const SPACING = 4; - -// Types -import PopupWindow from '../../misc/popup-window'; - - -export default () => { - const notifications = AstalNotifd.get_default(); - - return ( - <button - className="bar-item" - cursor="pointer" - - onButtonReleaseEvent={(self) => { - const win = App.get_window('win-notif-center') as PopupWindow; - - win.set_x_pos( - self.get_allocation(), - 'right', - ); - - win.set_visible(!win.get_visible()); - }} - - setup={(self) => { - App.connect('window-toggled', (_, win) => { - if (win.get_name() === 'win-notif-center') { - self.toggleClassName('toggle-on', win.get_visible()); - } - }); - }} - > - <box> - <icon - icon={bind(notifications, 'notifications').as((notifs) => { - if (notifications.get_dont_disturb()) { - return 'notification-disabled-symbolic'; - } - else if (notifs.length > 0) { - return 'notification-new-symbolic'; - } - else { - return 'notification-symbolic'; - } - })} - /> - - <Separator size={SPACING} /> - - <label label={bind(notifications, 'notifications').as((n) => String(n.length))} /> - </box> - </button> - ); -}; diff --git a/modules/ags/config/widgets/bar/items/tray.tsx b/modules/ags/config/widgets/bar/items/tray.tsx deleted file mode 100644 index d5705525..00000000 --- a/modules/ags/config/widgets/bar/items/tray.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import { App, Gtk, Widget } from 'astal/gtk3'; -import { bind, idle } from 'astal'; - -import AstalTray from 'gi://AstalTray'; - - -const SKIP_ITEMS = ['.spotify-wrapped']; - -const TrayItem = (item: AstalTray.TrayItem) => { - if (item.iconThemePath) { - App.add_icons(item.get_icon_theme_path()); - } - - return ( - <revealer - transitionType={Gtk.RevealerTransitionType.SLIDE_RIGHT} - revealChild={false} - > - <menubutton - className="tray-item" - cursor="pointer" - - usePopover={false} - tooltipMarkup={bind(item, 'tooltipMarkup')} - actionGroup={bind(item, 'actionGroup').as((ag) => ['dbusmenu', ag])} - menuModel={bind(item, 'menuModel')} - > - <icon gicon={bind(item, 'gicon')} /> - </menubutton> - </revealer> - ); -}; - -export default () => { - const tray = AstalTray.get_default(); - - const itemMap = new Map<string, Widget.Revealer>(); - - return ( - <box - className="bar-item system-tray" - visible={bind(tray, 'items').as((items) => items.length !== 0)} - setup={(self) => { - self - .hook(tray, 'item-added', (_, item: string) => { - if (itemMap.has(item) || SKIP_ITEMS.includes(tray.get_item(item).get_title())) { - return; - } - - const widget = TrayItem(tray.get_item(item)) as Widget.Revealer; - - itemMap.set(item, widget); - - self.add(widget); - - idle(() => { - widget.set_reveal_child(true); - }); - }) - - .hook(tray, 'item-removed', (_, item: string) => { - if (!itemMap.has(item)) { - return; - } - - const widget = itemMap.get(item); - - widget?.set_reveal_child(false); - - setTimeout(() => { - widget?.destroy(); - }, 1000); - }); - }} - /> - ); -}; diff --git a/modules/ags/config/widgets/bar/items/workspaces.tsx b/modules/ags/config/widgets/bar/items/workspaces.tsx deleted file mode 100644 index 86cc8b30..00000000 --- a/modules/ags/config/widgets/bar/items/workspaces.tsx +++ /dev/null @@ -1,177 +0,0 @@ -import { Gtk, Widget } from 'astal/gtk3'; -import { timeout } from 'astal'; - -import AstalHyprland from 'gi://AstalHyprland'; - -import { hyprMessage } from '../../../lib'; - - -const URGENT_DURATION = 1000; - -const Workspace = ({ id = 0 }) => { - const hyprland = AstalHyprland.get_default(); - - return ( - <revealer - name={id.toString()} - transitionType={Gtk.RevealerTransitionType.SLIDE_RIGHT} - > - <eventbox - cursor="pointer" - tooltip_text={id.toString()} - - onClickRelease={() => { - hyprMessage(`dispatch workspace ${id}`).catch(console.log); - }} - > - <box - valign={Gtk.Align.CENTER} - className="button" - - setup={(self) => { - const update = ( - _: Widget.Box, - client?: AstalHyprland.Client, - ) => { - const workspace = hyprland.get_workspace(id); - const occupied = workspace && workspace.get_clients().length > 0; - - self.toggleClassName('occupied', occupied); - - if (!client) { - return; - } - - const isUrgent = client && - client.get_workspace().get_id() === id; - - if (isUrgent) { - self.toggleClassName('urgent', true); - - // Only show for a sec when urgent is current workspace - if (hyprland.get_focused_workspace().get_id() === id) { - timeout(URGENT_DURATION, () => { - self.toggleClassName('urgent', false); - }); - } - } - }; - - update(self); - self - .hook(hyprland, 'event', () => update(self)) - - // Deal with urgent windows - .hook(hyprland, 'urgent', update) - - .hook(hyprland, 'notify::focused-workspace', () => { - if (hyprland.get_focused_workspace().get_id() === id) { - self.toggleClassName('urgent', false); - } - }); - }} - /> - </eventbox> - </revealer> - ); -}; - -export default () => { - const Hyprland = AstalHyprland.get_default(); - - const L_PADDING = 2; - const WS_WIDTH = 30; - - const updateHighlight = (self: Widget.Box) => { - const currentId = Hyprland.get_focused_workspace().get_id().toString(); - - const indicators = ((self.get_parent() as Widget.Overlay) - .get_child() as Widget.Box) - .get_children() as Widget.Revealer[]; - - const currentIndex = indicators.findIndex((w) => w.name === currentId); - - if (currentIndex >= 0) { - self.set_css(`margin-left: ${L_PADDING + (currentIndex * WS_WIDTH)}px`); - } - }; - - const highlight = ( - <box - className="button active" - - valign={Gtk.Align.CENTER} - halign={Gtk.Align.START} - - setup={(self) => { - self.hook(Hyprland, 'notify::focused-workspace', updateHighlight); - }} - /> - ) as Widget.Box; - - let workspaces: Widget.Revealer[] = []; - - return ( - <box - className="bar-item" - > - <overlay - className="workspaces" - passThrough - overlay={highlight} - > - <box - setup={(self) => { - const refresh = () => { - (self.get_children() as Widget.Revealer[]).forEach((rev) => { - rev.set_reveal_child(false); - }); - - workspaces.forEach((ws) => { - ws.set_reveal_child(true); - }); - }; - - const updateWorkspaces = () => { - Hyprland.get_workspaces().forEach((ws) => { - const currentWs = (self.get_children() as Widget.Revealer[]) - .find((ch) => ch.name === ws.get_id().toString()); - - if (!currentWs && ws.get_id() > 0) { - self.add(Workspace({ id: ws.get_id() })); - } - }); - - // Make sure the order is correct - workspaces.forEach((workspace, i) => { - (workspace.get_parent() as Widget.Box) - .reorder_child(workspace, i); - }); - }; - - const updateAll = () => { - workspaces = (self.get_children() as Widget.Revealer[]) - .filter((ch) => { - return Hyprland.get_workspaces().find((ws) => { - return ws.get_id().toString() === ch.name; - }); - }) - .sort((a, b) => parseInt(a.name ?? '0') - parseInt(b.name ?? '0')); - - updateWorkspaces(); - refresh(); - - // Make sure the highlight doesn't go too far - const TEMP_TIMEOUT = 100; - - timeout(TEMP_TIMEOUT, () => updateHighlight(highlight)); - }; - - updateAll(); - self.hook(Hyprland, 'event', updateAll); - }} - /> - </overlay> - </box> - ); -}; diff --git a/modules/ags/config/widgets/bar/wim.tsx b/modules/ags/config/widgets/bar/wim.tsx deleted file mode 100644 index 65c9c95a..00000000 --- a/modules/ags/config/widgets/bar/wim.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import { bind } from 'astal'; -import { Astal, Gtk } from 'astal/gtk3'; - -import Audio from './items/audio'; -import Battery from './items/battery'; -import Bluetooth from './items/bluetooth'; -import Brightness from './items/brightness'; -import Clock from './items/clock'; -import CurrentClient from './items/current-client'; -import Heart from './items/heart'; -import Keyboard from './items/keyboard-layout'; -import Network from './items/network'; -import NotifButton from './items/notif-button'; -import SysTray from './items/tray'; -import Workspaces from './items/workspaces'; - -import BarRevealer from './fullscreen'; -import Separator from '../misc/separator'; -import Tablet from '../../services/tablet'; - - -export default () => ( - <BarRevealer - exclusivity={Astal.Exclusivity.EXCLUSIVE} - anchor={ - Astal.WindowAnchor.TOP | - Astal.WindowAnchor.LEFT | - Astal.WindowAnchor.RIGHT - } - > - <centerbox className="bar widget"> - <box hexpand halign={Gtk.Align.START}> - <Workspaces /> - - <Separator size={8} /> - - <SysTray /> - - <Separator size={8} /> - - <button - className="bar-item tablet-mode" - cursor="pointer" - - onButtonReleaseEvent={() => { - const tablet = Tablet.get_default(); - - tablet.toggleMode(); - }} - > - <icon - icon={bind(Tablet.get_default(), 'currentMode') - .as((mode) => `${mode}-symbolic`)} - /> - </button> - - <Separator size={8} /> - - <Heart /> - - <CurrentClient /> - - <Separator size={8} /> - </box> - - <box> - <Clock /> - </box> - - <box hexpand halign={Gtk.Align.END}> - <Network /> - - <Separator size={8} /> - - <Bluetooth /> - - <Separator size={8} /> - - <Keyboard /> - - <Separator size={8} /> - - <NotifButton /> - - <Separator size={8} /> - - <Audio /> - - <Separator size={8} /> - - <Brightness /> - - <Separator size={8} /> - - <Battery /> - - <Separator size={2} /> - </box> - </centerbox> - - </BarRevealer> -); diff --git a/modules/ags/config/widgets/bg-layer/index.tsx b/modules/ags/config/widgets/bg-layer/index.tsx deleted file mode 100644 index 345e70d6..00000000 --- a/modules/ags/config/widgets/bg-layer/index.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { Astal, Gdk } from 'astal/gtk3'; - - -export default ( - monitor = Gdk.Display.get_default()?.get_monitor(0) as Gdk.Monitor, - gradient = true, -) => { - return ( - <window - name="bg-layer" - namespace="bg-layer" - gdkmonitor={monitor} - layer={Astal.Layer.BACKGROUND} - exclusivity={Astal.Exclusivity.IGNORE} - anchor={ - Astal.WindowAnchor.TOP | - Astal.WindowAnchor.BOTTOM | - Astal.WindowAnchor.LEFT | - Astal.WindowAnchor.RIGHT - } - css={ - gradient ? - ` - background-image: -gtk-gradient (linear, - left top, left bottom, - from(rgba(0, 0, 0, 0.5)), - to(rgba(0, 0, 0, 0))); - ` : - ` - background-color: rgba(0, 0, 0, 0.4); - ` - } - /> - ); -}; diff --git a/modules/ags/config/widgets/bluetooth/_index.scss b/modules/ags/config/widgets/bluetooth/_index.scss deleted file mode 100644 index 96c5194e..00000000 --- a/modules/ags/config/widgets/bluetooth/_index.scss +++ /dev/null @@ -1,32 +0,0 @@ -@use 'sass:color'; -@use '../../style/colors'; - -.bluetooth.widget { - margin-top: 0; - - * { - font-size: 20px; - } - - row { - all: unset; - } - - .toggle-button { - padding: 4px; - min-width: 30px; - min-height: 30px; - - transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out; - - box-shadow: 2px 1px 2px colors.$accent-color; - margin: 4px 4px 4px 4px; - background-color: colors.$window_bg_color; - - &.active { - box-shadow: 0 0 0 white; - margin: 6px 4px 2px 4px; - background-color: color.adjust(colors.$window_bg_color, $lightness: -3%); - } - } -} diff --git a/modules/ags/config/widgets/bluetooth/device.tsx b/modules/ags/config/widgets/bluetooth/device.tsx deleted file mode 100644 index 5313781f..00000000 --- a/modules/ags/config/widgets/bluetooth/device.tsx +++ /dev/null @@ -1,161 +0,0 @@ -import { bind, idle } from 'astal'; -import { Gtk, Widget } from 'astal/gtk3'; -import { register } from 'astal/gobject'; - -import AstalBluetooth from 'gi://AstalBluetooth'; - -import Separator from '../misc/separator'; - -/* Types */ -interface DevToggleProps { - label: string - prop: keyof AstalBluetooth.Device - onToggle: (active: boolean) => void -} - - -@register() -export default class DeviceWidget extends Widget.Revealer { - readonly dev: AstalBluetooth.Device; - - constructor({ dev }: { dev: AstalBluetooth.Device }) { - const bluetooth = AstalBluetooth.get_default(); - - const DevToggle = ({ label, prop, onToggle }: DevToggleProps) => ( - <centerbox> - <label - label={label} - valign={Gtk.Align.CENTER} - halign={Gtk.Align.START} - /> - - <box /> - - <switch - cursor="pointer" - valign={Gtk.Align.CENTER} - halign={Gtk.Align.END} - - active={bind(dev, prop).as(Boolean)} - - setup={(self) => { - self.connect('notify::active', () => { - onToggle(self.active); - }); - }} - /> - </centerbox> - ); - - const rev = ( - <revealer - transitionType={Gtk.RevealerTransitionType.SLIDE_DOWN} - > - <box vertical halign={Gtk.Align.FILL} hexpand> - <Separator size={8} vertical /> - - <DevToggle - label="Connected" - prop="connected" - onToggle={(active) => { - if (active) { - dev.connect_device(); - } - else { - dev.disconnect_device(); - } - }} - /> - - <Separator size={8} vertical /> - - <DevToggle - label="Trusted" - prop="trusted" - onToggle={(active) => { - dev.set_trusted(active); - }} - /> - - <Separator size={8} vertical /> - - <DevToggle - label="Paired" - prop="paired" - onToggle={(active) => { - if (active) { - dev.pair(); - } - else { - bluetooth.get_adapter()?.remove_device(dev); - } - }} - /> - - <Separator size={8} vertical /> - - <DevToggle - label="Blocked" - prop="blocked" - onToggle={(active) => { - dev.set_blocked(active); - }} - /> - - <Separator size={8} vertical /> - </box> - </revealer> - ) as Widget.Revealer; - - const button = ( - <button - cursor="pointer" - onButtonReleaseEvent={() => { - rev.set_reveal_child(!rev.get_reveal_child()); - }} - > - <box> - <icon - icon={bind(dev, 'connected').as((isConnected) => isConnected ? - 'check-active-symbolic' : - 'check-mixed-symbolic')} - - css={bind(dev, 'paired').as((isPaired) => isPaired ? - '' : - 'opacity: 0;')} - /> - - <Separator size={8} /> - - <icon - icon={bind(dev, 'icon').as((iconName) => - iconName ? `${iconName}-symbolic` : 'help-browser-symbolic')} - /> - - <Separator size={8} /> - - <label label={bind(dev, 'name')} /> - </box> - </button> - ); - - super({ - revealChild: false, - transitionType: Gtk.RevealerTransitionType.SLIDE_DOWN, - - child: ( - <box vertical> - {button} - {rev} - <Separator size={8} vertical /> - </box> - ), - }); - - this.dev = dev; - - this.connect('realize', () => idle(() => { - this.set_reveal_child(true); - })); - }; -}; diff --git a/modules/ags/config/widgets/bluetooth/main.tsx b/modules/ags/config/widgets/bluetooth/main.tsx deleted file mode 100644 index 963ef9dc..00000000 --- a/modules/ags/config/widgets/bluetooth/main.tsx +++ /dev/null @@ -1,152 +0,0 @@ -import { bind } from 'astal'; -import { Gtk } from 'astal/gtk3'; - -import AstalBluetooth from 'gi://AstalBluetooth'; - -import { ListBox, ToggleButton } from '../misc/subclasses'; -import Separator from '../misc/separator'; - -import DeviceWidget from './device'; - - -const calculateDevSort = (dev: AstalBluetooth.Device) => { - let value = 0; - - if (dev.get_connected()) { - value += 1000; - } - if (dev.get_paired()) { - value += 100; - } - if (dev.get_blocked()) { - value += 10; - } - if (dev.get_icon()) { - if (dev.get_icon() === 'audio-headset') { - value += 9; - } - if (dev.get_icon() === 'audio-headphones') { - value += 8; - } - if (dev.get_icon() === 'audio-card') { - value += 7; - } - if (dev.get_icon() === 'computer') { - value += 6; - } - if (dev.get_icon() === 'phone') { - value += 5; - } - } - - return value; -}; - -export default () => { - const bluetooth = AstalBluetooth.get_default(); - - const deviceList = ( - <scrollable - className="list" - - css="min-height: 300px;" - hscroll={Gtk.PolicyType.NEVER} - vscroll={Gtk.PolicyType.AUTOMATIC} - > - <ListBox - selectionMode={Gtk.SelectionMode.SINGLE} - - setup={(self) => { - bluetooth.devices - .filter((dev) => dev.get_name()) - .forEach((dev) => { - self.add(<DeviceWidget dev={dev} />); - }); - - self.hook(bluetooth, 'device-added', (_, dev) => { - if (dev.get_name()) { - self.add(<DeviceWidget dev={dev} />); - self.invalidate_sort(); - } - }); - - self.hook(bluetooth, 'device-removed', (_, dev) => { - const children = self - .get_children() - .map((ch) => ch.get_child()) as DeviceWidget[]; - - const devWidget = children.find((ch) => ch.dev === dev); - - if (devWidget) { - devWidget.set_reveal_child(false); - - setTimeout(() => { - devWidget.get_parent()?.destroy(); - }, devWidget.get_transition_duration() + 100); - } - }); - - self.set_sort_func((a, b) => { - const devA = (a.get_child() as DeviceWidget).dev; - const devB = (b.get_child() as DeviceWidget).dev; - - const sort = calculateDevSort(devB) - calculateDevSort(devA); - - return sort !== 0 ? sort : devA.get_name().localeCompare(devB.get_name()); - }); - }} - /> - </scrollable> - ); - - return ( - <box - className="bluetooth widget" - vertical - > - <centerbox homogeneous> - <switch - cursor="pointer" - valign={Gtk.Align.CENTER} - halign={Gtk.Align.START} - - active={bind(bluetooth, 'isPowered')} - - setup={(self) => { - self.connect('notify::active', () => { - bluetooth.get_adapter()?.set_powered(self.active); - }); - }} - /> - - <box /> - - <ToggleButton - cursor="pointer" - halign={Gtk.Align.END} - - className="toggle-button" - - sensitive={bind(bluetooth, 'isPowered')} - - onToggled={(self) => { - self.toggleClassName('active', self.active); - - if (self.active) { - bluetooth.get_adapter()?.start_discovery(); - } - else { - bluetooth.get_adapter()?.stop_discovery(); - } - }} - > - <icon icon="emblem-synchronizing-symbolic" css="font-size: 30px;" /> - </ToggleButton> - </centerbox> - - <Separator size={8} vertical /> - - {deviceList} - </box> - ); -}; diff --git a/modules/ags/config/widgets/bluetooth/wim.tsx b/modules/ags/config/widgets/bluetooth/wim.tsx deleted file mode 100644 index 3f618638..00000000 --- a/modules/ags/config/widgets/bluetooth/wim.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { Astal } from 'astal/gtk3'; - -import PopupWindow from '../misc/popup-window'; - -import BluetoothWidget from './main'; - - -export default () => ( - <PopupWindow - name="bluetooth" - anchor={Astal.WindowAnchor.RIGHT | Astal.WindowAnchor.TOP} - > - <BluetoothWidget /> - </PopupWindow> -); diff --git a/modules/ags/config/widgets/brightness-slider/main.tsx b/modules/ags/config/widgets/brightness-slider/main.tsx deleted file mode 100644 index e1a01631..00000000 --- a/modules/ags/config/widgets/brightness-slider/main.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { bind } from 'astal'; -import { Astal, Gtk } from 'astal/gtk3'; - -import Brightness from '../../services/brightness'; - -import PopupWindow from '../misc/popup-window'; - - -export default () => { - const brightness = Brightness.get_default(); - - return ( - <PopupWindow - name="brightness-slider" - anchor={Astal.WindowAnchor.RIGHT | Astal.WindowAnchor.TOP} - > - <box className="widget" widthRequest={500}> - <slider - hexpand - halign={Gtk.Align.FILL} - drawValue - cursor="pointer" - - min={0} - max={100} - - value={bind(brightness, 'screen').as((v) => v * 100)} - onDragged={(self) => { - brightness.screen = Number((self.value / 100).toFixed(2)); - }} - /> - </box> - </PopupWindow> - ); -}; diff --git a/modules/ags/config/widgets/clipboard/_index.scss b/modules/ags/config/widgets/clipboard/_index.scss deleted file mode 100644 index 8ff3349a..00000000 --- a/modules/ags/config/widgets/clipboard/_index.scss +++ /dev/null @@ -1,4 +0,0 @@ -.clipboard .list row box { - margin: 20px; - font-size: 16px; -} diff --git a/modules/ags/config/widgets/clipboard/clip-item.tsx b/modules/ags/config/widgets/clipboard/clip-item.tsx deleted file mode 100644 index dea0f33b..00000000 --- a/modules/ags/config/widgets/clipboard/clip-item.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { execAsync } from 'astal'; -import { register } from 'astal/gobject'; -import { Gtk, Widget } from 'astal/gtk3'; - -export interface EntryObject { - id: number - content: string - entry: string -} - -const SCALE = 150; -const BINARY_DATA = /\[\[ binary data (\d+) (KiB|MiB) (\w+) (\d+)x(\d+) \]\]/; - -export const CLIP_SCRIPT = `${SRC}/widgets/clipboard/cliphist.sh`; - -@register() -export class ClipItem extends Widget.Box { - declare id: number; - declare content: string; - - public show_image(file: string, width: string | number, height: string | number) { - this.children[2].destroy(); - - const initCss = () => { - const _widthPx = Number(width); - const heightPx = Number(height); - const maxWidth = 400; - const widthPx = (_widthPx / heightPx) * SCALE; - - let css = `background-image: url("${file}");`; - - if (widthPx > maxWidth) { - const newHeightPx = (SCALE / widthPx) * maxWidth; - - css += `min-height: ${newHeightPx}px; min-width: ${maxWidth}px;`; - } - else { - css += `min-height: 150px; min-width: ${widthPx}px;`; - } - - return css; - }; - - const icon = ( - <box - valign={Gtk.Align.CENTER} - css={initCss()} - /> - ); - - this.children = [...this.children, icon]; - }; - - constructor({ item }: { item: EntryObject }) { - super({ - children: [ - <label - label={item.id.toString()} - xalign={0} - valign={Gtk.Align.CENTER} - />, - <label - label="・" - xalign={0} - valign={Gtk.Align.CENTER} - />, - <label - label={item.content} - xalign={0} - valign={Gtk.Align.CENTER} - truncate - />, - ], - }); - - this.id = item.id; - this.content = item.content; - - const matches = this.content.match(BINARY_DATA); - - if (matches) { - // const size = matches[1]; - const format = matches[3]; - const width = matches[4]; - const height = matches[5]; - - if (format === 'png') { - execAsync(`${CLIP_SCRIPT} --save-by-id ${this.id}`) - .then((file) => { - this.show_image(file, width, height); - }) - .catch(print); - } - } - } -} diff --git a/modules/ags/config/widgets/clipboard/cliphist.sh b/modules/ags/config/widgets/clipboard/cliphist.sh deleted file mode 100755 index 149ac683..00000000 --- a/modules/ags/config/widgets/clipboard/cliphist.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash -# https://github.com/koeqaife/hyprland-material-you/blob/d23cf9d524522c8c215664c2c3334c2b51609cae/ags/scripts/cliphist.sh - -get() { - cliphist list | iconv -f "$(locale charmap)" -t UTF-8 -c -} - -copy_by_id() { - id=$1 - cliphist decode "$id" | wl-copy -} - -clear() { - cliphist wipe -} - -save_cache_file() { - id=$1 - - output_file="/tmp/ags/cliphist/$id.png" - - if [[ ! -f "$output_file" ]]; then - mkdir -p "/tmp/ags/cliphist/" - cliphist decode "$id" >"$output_file" - fi - - echo "$output_file" -} - -clear_tmp() { - rm "/tmp/ags/cliphist/*" -} - -if [[ "$1" == "--get" ]]; then - get -elif [[ "$1" == "--copy-by-id" ]]; then - { copy_by_id "$2"; } -elif [[ "$1" == "--save-by-id" ]]; then - { save_cache_file "$2"; } -elif [[ "$1" == "--clear-cache" ]]; then - clear_tmp -elif [[ "$1" == "--clear" ]]; then - clear -fi diff --git a/modules/ags/config/widgets/clipboard/index.tsx b/modules/ags/config/widgets/clipboard/index.tsx deleted file mode 100644 index 6c30ed1f..00000000 --- a/modules/ags/config/widgets/clipboard/index.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { execAsync } from 'astal'; -import { App } from 'astal/gtk3'; - -import SortedList from '../misc/sorted-list'; - -import { CLIP_SCRIPT, ClipItem, EntryObject } from './clip-item'; - - -export default () => SortedList<EntryObject>({ - name: 'clipboard', - - create_list: async() => { - const output = await execAsync(`${CLIP_SCRIPT} --get`) - .then((str) => str) - .catch((err) => { - print(err); - - return ''; - }); - - return output - .split('\n') - .filter((line) => line.trim() !== '') - .map((entry) => { - const [id, ...content] = entry.split('\t'); - - return { id: parseInt(id.trim()), content: content.join(' ').trim(), entry }; - }); - }, - - create_row: (item) => <ClipItem item={item} />, - - fzf_options: { - selector: (item) => item.content, - }, - - unique_props: ['id'], - - on_row_activated: (row) => { - const clip = row.get_children()[0] as ClipItem; - - execAsync(`${CLIP_SCRIPT} --copy-by-id ${clip.id}`); - App.get_window('win-clipboard')?.set_visible(false); - }, - - sort_func: (a, b, entry, fzfResults) => { - const row1 = a.get_children()[0] as ClipItem; - const row2 = b.get_children()[0] as ClipItem; - - if (entry.text === '' || entry.text === '-') { - a.set_visible(true); - b.set_visible(true); - - return row2.id - row1.id; - } - else { - const s1 = fzfResults.find((r) => r.item.id === row1.id)?.score ?? 0; - const s2 = fzfResults.find((r) => r.item.id === row2.id)?.score ?? 0; - - a.set_visible(s1 !== 0); - b.set_visible(s2 !== 0); - - return s2 - s1; - } - }, -}); diff --git a/modules/ags/config/widgets/corners/index.tsx b/modules/ags/config/widgets/corners/index.tsx deleted file mode 100644 index a8c34d28..00000000 --- a/modules/ags/config/widgets/corners/index.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import { Astal } from 'astal/gtk3'; - -import RoundedCorner from './screen-corners'; - - -const TopLeft = () => ( - <window - name="cornertl" - layer={Astal.Layer.OVERLAY} - exclusivity={Astal.Exclusivity.IGNORE} - anchor={ - Astal.WindowAnchor.TOP | Astal.WindowAnchor.LEFT - } - clickThrough={true} - > - {RoundedCorner('topleft')} - </window> -); - -const TopRight = () => ( - <window - name="cornertr" - layer={Astal.Layer.OVERLAY} - exclusivity={Astal.Exclusivity.IGNORE} - anchor={ - Astal.WindowAnchor.TOP | Astal.WindowAnchor.RIGHT - } - clickThrough={true} - > - {RoundedCorner('topright')} - </window> -); - -const BottomLeft = () => ( - <window - name="cornerbl" - layer={Astal.Layer.OVERLAY} - exclusivity={Astal.Exclusivity.IGNORE} - anchor={ - Astal.WindowAnchor.BOTTOM | Astal.WindowAnchor.LEFT - } - clickThrough={true} - > - {RoundedCorner('bottomleft')} - </window> -); - -const BottomRight = () => ( - <window - name="cornerbr" - layer={Astal.Layer.OVERLAY} - exclusivity={Astal.Exclusivity.IGNORE} - anchor={ - Astal.WindowAnchor.BOTTOM | Astal.WindowAnchor.RIGHT - } - clickThrough={true} - > - {RoundedCorner('bottomright')} - </window> -); - - -export default () => [ - TopLeft(), - TopRight(), - BottomLeft(), - BottomRight(), -]; diff --git a/modules/ags/config/widgets/corners/screen-corners.tsx b/modules/ags/config/widgets/corners/screen-corners.tsx deleted file mode 100644 index d1555b30..00000000 --- a/modules/ags/config/widgets/corners/screen-corners.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import { Gtk } from 'astal/gtk3'; -import Cairo from 'cairo'; - - -export default ( - place = 'top left', - css = 'background-color: black;', -) => ( - <box - halign={place.includes('left') ? Gtk.Align.START : Gtk.Align.END} - valign={place.includes('top') ? Gtk.Align.START : Gtk.Align.END} - - css={` - padding: 1px; margin: - ${place.includes('top') ? '-1px' : '0'} - ${place.includes('right') ? '-1px' : '0'} - ${place.includes('bottom') ? '-1px' : '0'} - ${place.includes('left') ? '-1px' : '0'}; - `} - > - <drawingarea - css={` - border-radius: 8px; - border-width: 0.068rem; - ${css} - `} - - setup={(widget) => { - const styleContext = widget.get_style_context(); - - let radius = styleContext.get_property('border-radius', Gtk.StateFlags.NORMAL) as number; - - widget.set_size_request(radius, radius); - - widget.connect('draw', (_, cairoContext: Cairo.Context) => { - const bgColor = styleContext.get_background_color(Gtk.StateFlags.NORMAL); - const borderColor = styleContext.get_color(Gtk.StateFlags.NORMAL); - const borderWidth = styleContext.get_border(Gtk.StateFlags.NORMAL).left; - - radius = styleContext.get_property('border-radius', Gtk.StateFlags.NORMAL) as number; - - widget.set_size_request(radius, radius); - - switch (place) { - case 'topleft': - cairoContext.arc(radius, radius, radius, Math.PI, 3 * Math.PI / 2); - cairoContext.lineTo(0, 0); - break; - - case 'topright': - cairoContext.arc(0, radius, radius, 3 * Math.PI / 2, 2 * Math.PI); - cairoContext.lineTo(radius, 0); - break; - - case 'bottomleft': - cairoContext.arc(radius, 0, radius, Math.PI / 2, Math.PI); - cairoContext.lineTo(0, radius); - break; - - case 'bottomright': - cairoContext.arc(0, 0, radius, 0, Math.PI / 2); - cairoContext.lineTo(radius, radius); - break; - } - - cairoContext.closePath(); - cairoContext.setSourceRGBA(bgColor.red, bgColor.green, bgColor.blue, bgColor.alpha); - cairoContext.fill(); - cairoContext.setLineWidth(borderWidth); - cairoContext.setSourceRGBA( - borderColor.red, - borderColor.green, - borderColor.blue, - borderColor.alpha, - ); - cairoContext.stroke(); - }); - }} - /> - </box> -); diff --git a/modules/ags/config/widgets/date/_index.scss b/modules/ags/config/widgets/date/_index.scss deleted file mode 100644 index fb3e8218..00000000 --- a/modules/ags/config/widgets/date/_index.scss +++ /dev/null @@ -1,68 +0,0 @@ -@use '../../style/colors'; - -.date { - margin-top: 0; -} - -.timebox { - margin: 30px 0; - - .time-container { - .content { - font-weight: bolder; - font-size: 60px; - } - - .divider { - margin: 8px 15px; - padding: 0 1px; - background: linear-gradient(colors.$red, colors.$magenta, colors.$blue, colors.$cyan); - } - } - - .date-container { - margin-top: 2px; - } -} - -.cal-box { - padding: 0 1rem .2rem; - margin: 0 12px 18px; - - calendar { - font-size: 20px; - background-color: inherit; - padding: .5rem .10rem 0; - margin-left: 10px; - - &>* { - border: solid 0 transparent; - } - - &.highlight { - padding: 10rem; - } - } -} - -calendar:selected { - color: colors.$cyan; -} - -calendar.header { - color: colors.$cyan; - font-weight: bold; -} - -calendar.button { - color: colors.$cyan; -} - -calendar.highlight { - color: colors.$green; - font-weight: bold; -} - -calendar:indeterminate { - color: colors.$lightblack; -} diff --git a/modules/ags/config/widgets/date/binto.tsx b/modules/ags/config/widgets/date/binto.tsx deleted file mode 100644 index 796c80dc..00000000 --- a/modules/ags/config/widgets/date/binto.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { Astal } from 'astal/gtk3'; - -import PopupWindow from '../misc/popup-window'; -import { get_gdkmonitor_from_desc } from '../../lib'; - -import DateWidget from './main'; - - -export default () => ( - <PopupWindow - name="calendar" - gdkmonitor={get_gdkmonitor_from_desc('desc:Acer Technologies Acer K212HQL T3EAA0014201')} - anchor={Astal.WindowAnchor.BOTTOM} - transition="slide bottom" - > - <DateWidget /> - </PopupWindow> -); diff --git a/modules/ags/config/widgets/date/main.tsx b/modules/ags/config/widgets/date/main.tsx deleted file mode 100644 index 5ded8ff0..00000000 --- a/modules/ags/config/widgets/date/main.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import { bind, Variable } from 'astal'; -import { Gtk } from 'astal/gtk3'; - -import GLib from 'gi://GLib'; - - -const Divider = () => ( - <box - className="divider" - vertical - /> -); - -const Time = () => { - const hour = Variable<string>('').poll(1000, () => GLib.DateTime.new_now_local().format('%H') || ''); - const min = Variable<string>('').poll(1000, () => GLib.DateTime.new_now_local().format('%M') || ''); - - const fullDate = Variable<string>('').poll(1000, () => { - const time = GLib.DateTime.new_now_local(); - - const dayNameMonth = time.format('%A, %B '); - const dayNum = time.get_day_of_month(); - const date = time.format(', %Y'); - - return dayNum && dayNameMonth && date ? - dayNameMonth + dayNum + date : - ''; - }); - - return ( - <box - className="timebox" - vertical - > - <box - className="time-container" - halign={Gtk.Align.CENTER} - valign={Gtk.Align.CENTER} - > - <label - className="content" - label={bind(hour)} - /> - - <Divider /> - - <label - className="content" - label={bind(min)} - /> - </box> - - <box - className="date-container" - halign={Gtk.Align.CENTER} - > - <label - css="font-size: 20px;" - label={bind(fullDate)} - /> - </box> - </box> - ); -}; - -export default () => { - const cal = new Gtk.Calendar({ - show_day_names: true, - show_heading: true, - }); - - cal.show_all(); - - return ( - <box - className="date widget" - vertical - > - <Time /> - - <box className="cal-box"> - {cal} - </box> - </box> - ); -}; diff --git a/modules/ags/config/widgets/date/wim.tsx b/modules/ags/config/widgets/date/wim.tsx deleted file mode 100644 index c8c5dd6d..00000000 --- a/modules/ags/config/widgets/date/wim.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { Astal } from 'astal/gtk3'; - -import PopupWindow from '../misc/popup-window'; - -import DateWidget from './main'; - - -export default () => ( - <PopupWindow - name="calendar" - anchor={Astal.WindowAnchor.TOP} - > - <DateWidget /> - </PopupWindow> -); diff --git a/modules/ags/config/widgets/greeter/index.tsx b/modules/ags/config/widgets/greeter/index.tsx deleted file mode 100644 index db3659fe..00000000 --- a/modules/ags/config/widgets/greeter/index.tsx +++ /dev/null @@ -1,136 +0,0 @@ -import { idle, readFile, Process } from 'astal'; -import { App, Astal, Gtk, Widget } from 'astal/gtk3'; - -import AstalGreet from 'gi://AstalGreet'; - -import { centerCursor } from '../../lib'; - - -export default (hyprpaper: InstanceType<typeof Process>) => { - const DEFAULT_NAME = 'matt'; - const PARSED_INDEX = { - name: 0, - uid: 2, - gid: 3, - desc: 4, - home: 5, - shell: 6, - }; - - const parsePasswd = (fileContent: string) => { - const splitUsers = fileContent.split('\n'); - const parsedUsers = splitUsers.map((u) => { - const user = u.split(':'); - - return { - name: user[PARSED_INDEX.name], - uid: Number(user[PARSED_INDEX.uid]), - gid: Number(user[PARSED_INDEX.gid]), - desc: user[PARSED_INDEX.desc], - home: user[PARSED_INDEX.home], - shell: user[PARSED_INDEX.shell], - }; - }); - - // Filter out system users, nixbld users and nobody - return parsedUsers.filter((u) => { - return u.uid >= 1000 && - !u.name.includes('nixbld') && - u.name !== 'nobody'; - }); - }; - - const users = parsePasswd(readFile('/etc/passwd')); - - const dropdown = new Gtk.ComboBoxText(); - - dropdown.show_all(); - - users.forEach((u) => { - dropdown.append(null, u.name); - }); - - const response = <label /> as Widget.Label; - - const password = ( - <entry - placeholderText="Password" - visibility={false} - - setup={(self) => idle(() => { - self.grab_focus(); - })} - - onActivate={(self) => { - AstalGreet.login( - dropdown.get_active_text() ?? '', - self.get_text() || '', - 'Hyprland', - (_, res) => { - try { - AstalGreet.login_finish(res); - App.get_window('greeter')?.set_visible(false); - hyprpaper.kill(); - - setTimeout(() => { - App.quit(); - }, 500); - } - catch (error) { - response.set_label(JSON.stringify(error)); - } - }, - ); - }} - /> - ); - - return ( - <window - name="greeter" - application={App} - keymode={Astal.Keymode.ON_DEMAND} - visible={false} - setup={(self) => { - centerCursor(); - setTimeout(() => { - self.set_visible(true); - password.grab_focus(); - }, 1000); - }} - > - <box - vertical - halign={Gtk.Align.CENTER} - valign={Gtk.Align.CENTER} - hexpand - vexpand - className="base" - > - <box - vertical - halign={Gtk.Align.CENTER} - valign={Gtk.Align.CENTER} - hexpand - vexpand - className="linked" - - setup={() => { - idle(() => { - const usernames = users.map((u) => u.name); - - if (usernames.includes(DEFAULT_NAME)) { - dropdown.set_active(usernames.indexOf(DEFAULT_NAME)); - } - }); - }} - > - {dropdown} - {password} - </box> - - {response} - </box> - </window> - ); -}; diff --git a/modules/ags/config/widgets/icon-browser/_index.scss b/modules/ags/config/widgets/icon-browser/_index.scss deleted file mode 100644 index d0788534..00000000 --- a/modules/ags/config/widgets/icon-browser/_index.scss +++ /dev/null @@ -1,4 +0,0 @@ -.icon-browser .list row box { - margin: 20px; - font-size: 16px; -} diff --git a/modules/ags/config/widgets/icon-browser/index.tsx b/modules/ags/config/widgets/icon-browser/index.tsx deleted file mode 100644 index 4ce12117..00000000 --- a/modules/ags/config/widgets/icon-browser/index.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { Gtk, Widget } from 'astal/gtk3'; - -import SortedList from '../misc/sorted-list'; - - -export default () => SortedList({ - name: 'icon-browser', - - create_list: () => Gtk.IconTheme.get_default().list_icons(null) - .filter((icon) => icon.endsWith('symbolic')) - .sort(), - - create_row: (icon) => ( - <box> - <icon css="font-size: 60px; margin-right: 25px;" icon={icon} /> - <label label={icon} /> - </box> - ), - - on_row_activated: (row) => { - const icon = ((row.get_children()[0] as Widget.Box).get_children()[0] as Widget.Icon).icon; - - console.log(icon); - }, - - sort_func: (a, b, entry, fzfResults) => { - const row1 = ((a.get_children()[0] as Widget.Box).get_children()[0] as Widget.Icon).icon; - const row2 = ((b.get_children()[0] as Widget.Box).get_children()[0] as Widget.Icon).icon; - - if (entry.text === '' || entry.text === '-') { - a.set_visible(true); - b.set_visible(true); - - return row1.charCodeAt(0) - row2.charCodeAt(0); - } - else { - const s1 = fzfResults.find((r) => r.item === row1)?.score ?? 0; - const s2 = fzfResults.find((r) => r.item === row2)?.score ?? 0; - - a.set_visible(s1 !== 0); - b.set_visible(s2 !== 0); - - return s2 - s1; - } - }, -}); diff --git a/modules/ags/config/widgets/media-player/_index.scss b/modules/ags/config/widgets/media-player/_index.scss deleted file mode 100644 index 7d100b13..00000000 --- a/modules/ags/config/widgets/media-player/_index.scss +++ /dev/null @@ -1,124 +0,0 @@ -@use '../../style/colors'; - -.media-player { - margin-top: 9px; - min-width: 100px; - min-height: 100px; - - * { - all: unset; - } - - .arrow { - transition: -gtk-icon-transform 0.3s ease-in-out; - margin-bottom: 12px; - } - - .player { - padding: 10px; - min-width: 400px; - min-height: 200px; - border-radius: 30px; - border-top: 2px solid colors.$accent_color; - border-bottom: 2px solid colors.$accent_color; - transition: background 250ms; - - .top { - font-size: 23px; - } - - .metadata { - .title { - font-weight: 500; - transition: text 250ms; - } - - .artist { - font-weight: 400; - font-size: 15px; - transition: text 250ms; - } - } - - .bottom { - font-size: 30px; - } - - .pausebutton { - transition: background-color ease .2s, color ease .2s; - font-size: 18px; - } - - .playing { - transition: background-color ease .2s, color ease .2s; - border-radius: 15px; - } - - .stopped, - .paused { - transition: background-color ease .2s, color ease .2s; - border-radius: 26px; - padding: 4px 6px; - } - - button label { - min-width: 35px; - } - } - - .player-icon, .position-indicator { - min-width: 18px; - margin: 7px; - } - - .position-indicator { - background-color: rgba(255, 255, 255, 0.7); - box-shadow: 0 0 5px 0 rgba(255, 255, 255, 0.3); - border-radius: 100%; - } - - .previous, - .next, - .shuffle, - .loop { - border-radius: 100%; - transition: color 200ms; - - &:hover { - border-radius: 100%; - background-color: rgba(127, 132, 156, 0.4); - transition: color 200ms; - } - } - - .loop { - label { - padding-right: 8px; - } - } - - .position-slider { - min-height: 20px; - - highlight { - margin: 0; - border-radius: 2em; - } - - trough { - margin: 0 8px; - border-radius: 2em; - } - - slider { - margin: -8px; - min-height: 20px; - border-radius: 10px; - transition: background-color 0.5s ease-in-out; - } - - slider:hover { - transition: background-color 0.5s ease-in-out; - } - } -} diff --git a/modules/ags/config/widgets/media-player/gesture.ts b/modules/ags/config/widgets/media-player/gesture.ts deleted file mode 100644 index b434d895..00000000 --- a/modules/ags/config/widgets/media-player/gesture.ts +++ /dev/null @@ -1,214 +0,0 @@ -import { timeout } from 'astal'; -import { Gtk } from 'astal/gtk3'; -import { property, register } from 'astal/gobject'; -import { CenterBox, CenterBoxProps, EventBox, Overlay, OverlayProps } from 'astal/gtk3/widget'; - -import Mpris from 'gi://AstalMpris'; - -const MAX_OFFSET = 200; -const OFFSCREEN = 500; -const ANIM_DURATION = 500; -const TRANSITION = `transition: margin ${ANIM_DURATION}ms ease, - opacity ${ANIM_DURATION}ms ease;`; - -/* Types */ -export interface Gesture { - attribute?: object - setup?: (self: PlayerGesture) => void - props?: OverlayProps -} - - -@register() -export class PlayerBox extends CenterBox { - @property(String) - declare bgStyle: string; - - @property(Object) - declare player: Mpris.Player; - - constructor(props: Omit<CenterBoxProps, 'setup'> & { - bgStyle?: string - player?: Mpris.Player - setup?: (self: PlayerBox) => void - }) { - super(props as CenterBoxProps); - } -} - -@register() -export class PlayerGesture extends Overlay { - private _widget: EventBox; - private _gesture: Gtk.GestureDrag; - - players = new Map(); - setup = false; - dragging = false; - - set overlays(value) { - super.overlays = value; - } - - get overlays() { - return super.overlays.filter((overlay) => overlay !== this.child); - } - - includesWidget(playerW: PlayerBox) { - return this.overlays.find((w) => w === playerW); - } - - showTopOnly() { - this.overlays.forEach((over) => { - over.visible = over === this.overlays.at(-1); - }); - } - - moveToTop(player: PlayerBox) { - player.visible = true; - this.reorder_overlay(player, -1); - timeout(ANIM_DURATION, () => { - this.showTopOnly(); - }); - } - - dragUpdate(realGesture: Gtk.GestureDrag) { - if (realGesture) { - this.overlays.forEach((over) => { - over.visible = true; - }); - } - else { - this.showTopOnly(); - } - - // Don't allow gesture when only one player - if (this.overlays.length <= 1) { - return; - } - - this.dragging = true; - let offset = this._gesture.get_offset()[1]; - const playerBox = this.overlays.at(-1) as PlayerBox; - - if (!offset) { - return; - } - - // Slide right - if (offset >= 0) { - playerBox.css = ` - margin-left: ${offset}px; - margin-right: -${offset}px; - ${playerBox.bgStyle} - `; - } - - // Slide left - else { - offset = Math.abs(offset); - playerBox.css = ` - margin-left: -${offset}px; - margin-right: ${offset}px; - ${playerBox.bgStyle} - `; - } - } - - dragEnd() { - // Don't allow gesture when only one player - if (this.overlays.length <= 1) { - return; - } - - this.dragging = false; - const offset = this._gesture.get_offset()[1]; - - const playerBox = this.overlays.at(-1) as PlayerBox; - - // If crosses threshold after letting go, slide away - if (offset && Math.abs(offset) > MAX_OFFSET) { - // Disable inputs during animation - this._widget.sensitive = false; - - // Slide away right - if (offset >= 0) { - playerBox.css = ` - ${TRANSITION} - margin-left: ${OFFSCREEN}px; - margin-right: -${OFFSCREEN}px; - opacity: 0.7; ${playerBox.bgStyle} - `; - } - - // Slide away left - else { - playerBox.css = ` - ${TRANSITION} - margin-left: -${OFFSCREEN}px; - margin-right: ${OFFSCREEN}px; - opacity: 0.7; ${playerBox.bgStyle} - `; - } - - timeout(ANIM_DURATION, () => { - // Put the player in the back after anim - this.reorder_overlay(playerBox, 0); - // Recenter player - playerBox.css = playerBox.bgStyle; - - this._widget.sensitive = true; - - this.showTopOnly(); - }); - } - else { - // Recenter with transition for animation - playerBox.css = `${TRANSITION} ${playerBox.bgStyle}`; - - timeout(ANIM_DURATION, () => { - this.showTopOnly(); - }); - } - } - - constructor({ - setup = () => { /**/ }, - widget, - ...props - }: Omit<OverlayProps, 'setup'> & { - widget: EventBox - setup: (self: PlayerGesture) => void - }) { - super(props); - setup(this); - - this._widget = widget; - this._gesture = Gtk.GestureDrag.new(this); - - this.hook(this._gesture, 'drag-update', (_, realGesture) => this.dragUpdate(realGesture)); - this.hook(this._gesture, 'drag-end', () => this.dragEnd()); - } -} - -export default ({ - setup = () => { /**/ }, - ...props -}: Gesture) => { - const widget = new EventBox(); - - // Have empty PlayerBox to define the size of the widget - const emptyPlayer = new PlayerBox({ - className: 'player', - }); - - const content = new PlayerGesture({ - ...props, - setup, - widget, - child: emptyPlayer, - }); - - widget.add(content); - - return widget; -}; diff --git a/modules/ags/config/widgets/media-player/mpris.ts b/modules/ags/config/widgets/media-player/mpris.ts deleted file mode 100644 index 0866285d..00000000 --- a/modules/ags/config/widgets/media-player/mpris.ts +++ /dev/null @@ -1,497 +0,0 @@ -import { bind, execAsync, idle, type Variable } from 'astal'; -import { Gdk, Gtk } from 'astal/gtk3'; -import { Box, Button, CenterBoxProps, Icon, Label, Slider, Stack } from 'astal/gtk3/widget'; -import { kebabify } from 'astal/binding'; - -import Mpris from 'gi://AstalMpris'; - -import Separator from '../misc/separator'; - -import { PlayerBox, PlayerGesture } from './gesture'; - -const ICON_SIZE = 32; - -const icons = { - mpris: { - fallback: 'audio-x-generic-symbolic', - shuffle: { - enabled: '', - disabled: '', - }, - loop: { - none: '', - track: '', - playlist: '', - }, - playing: 'media-playback-pause-symbolic', - paused: 'media-playback-start-symbolic', - stopped: 'media-playback-stop-symbolic', - prev: '', - next: '', - }, -}; - -/* Types */ -export interface Colors { - imageAccent: string - buttonAccent: string - buttonText: string - hoverAccent: string -} - - -export const CoverArt = ( - player: Mpris.Player, - colors: Variable<Colors>, - props: CenterBoxProps, -) => new PlayerBox({ - ...props, - vertical: true, - - bgStyle: '', - player, - - setup: (self: PlayerBox) => { - const setCover = () => { - execAsync(['bash', '-c', `[[ -f "${player.coverArt}" ]] && - coloryou "${player.coverArt}" | grep -v Warning`]) - .then((out) => { - if (!player.coverArt) { - return; - } - - colors.set(JSON.parse(out)); - - self.bgStyle = ` - background: radial-gradient(circle, - rgba(0, 0, 0, 0.4) 30%, - ${colors.get().imageAccent}), - url("${player.coverArt}"); - background-size: cover; - background-position: center; - `; - - if (!(self.get_parent() as PlayerGesture).dragging) { - self.css = self.bgStyle; - } - }).catch(() => { - colors.set({ - imageAccent: '#6b4fa2', - buttonAccent: '#ecdcff', - buttonText: '#25005a', - hoverAccent: '#d4baff', - }); - - self.bgStyle = ` - background: radial-gradient(circle, - rgba(0, 0, 0, 0.4) 30%, - ${(colors as Variable<Colors>).get().imageAccent}), - rgb(0, 0, 0); - background-size: cover; - background-position: center; - `; - self.css = self.bgStyle; - }); - }; - - player.connect('notify::cover-art', () => setCover()); - idle(() => setCover()); - }, -}); - -export const TitleLabel = (player: Mpris.Player) => new Label({ - xalign: 0, - max_width_chars: 40, - truncate: true, - justify: Gtk.Justification.LEFT, - className: 'title', - label: bind(player, 'title'), -}); - -export const ArtistLabel = (player: Mpris.Player) => new Label({ - xalign: 0, - max_width_chars: 40, - truncate: true, - justify: Gtk.Justification.LEFT, - className: 'artist', - label: bind(player, 'artist'), -}); - - -export const PlayerIcon = (player: Mpris.Player, overlay: PlayerGesture) => { - const playerIcon = ( - p: Mpris.Player, - widget?: PlayerGesture, - playerBox?: PlayerBox, - ) => new Button({ - tooltip_text: p.identity || '', - - onButtonReleaseEvent: () => { - if (widget && playerBox) { - widget.moveToTop(playerBox); - } - }, - - child: new Icon({ - css: `font-size: ${ICON_SIZE}px;`, - className: widget ? 'position-indicator' : 'player-icon', - - setup: (self) => { - idle(() => { - if (p.entry === null) { return; } - - self.icon = Icon.lookup_icon(p.entry) ? - p.entry : - icons.mpris.fallback; - }); - }, - }), - }); - - return new Box({ - setup(self) { - const update = () => { - const grandPa = self.get_parent()?.get_parent(); - - if (!grandPa) { - return; - } - - const thisIndex = overlay.overlays.indexOf(grandPa); - - self.children = (overlay.overlays as PlayerBox[]) - .map((playerBox, i) => { - self.children.push(Separator({ size: 2 })); - - return i === thisIndex ? - playerIcon(player) : - playerIcon(playerBox.player, overlay, playerBox); - }) - .reverse(); - }; - - self.hook(Mpris.get_default(), 'player-added', update); - self.hook(Mpris.get_default(), 'player-closed', update); - - idle(() => update()); - }, - }); -}; - -const display = Gdk.Display.get_default(); - -export const PositionSlider = ( - player: Mpris.Player, - colors: Variable<Colors>, -) => new Slider({ - className: 'position-slider', - valign: Gtk.Align.CENTER, - hexpand: true, - draw_value: false, - - onDragged: ({ value }) => { - player.position = player.length * value; - }, - - onButtonPressEvent: (self) => { - if (!display) { - return; - } - self.window.set_cursor(Gdk.Cursor.new_from_name( - display, - 'grabbing', - )); - }, - - onButtonReleaseEvent: (self) => { - if (!display) { - return; - } - self.window.set_cursor(Gdk.Cursor.new_from_name( - display, - 'pointer', - )); - }, - - onEnterNotifyEvent: (self) => { - if (!display) { - return; - } - self.window.set_cursor(Gdk.Cursor.new_from_name( - display, - 'pointer', - )); - }, - - onLeaveNotifyEvent: (self) => { - self.window.set_cursor(null); - }, - - setup: (self) => { - const update = () => { - if (!self.dragging) { - self.visible = player.length > 0; - if (player.length > 0) { - self.value = player.position / player.length; - } - } - }; - - const interval = setInterval(() => { - if (player) { - update(); - } - else { - interval.destroy(); - } - }, 1000); - - self.hook(colors, () => { - if (colors.get()) { - const c = colors.get(); - - self.css = ` - highlight { background-color: ${c.buttonAccent}; } - slider { background-color: ${c.buttonAccent}; } - slider:hover { background-color: ${c.hoverAccent}; } - trough { background-color: ${c.buttonText}; } - `; - } - }); - - player.connect('notify::position', () => update()); - }, -}); - -const PlayerButton = ({ - player, - colors, - children = [], - onClick, - prop, -}: { - player: Mpris.Player - colors: Variable<Colors> - children: Label[] | Icon[] - onClick: keyof Mpris.Player - prop: keyof Mpris.Player -}) => { - let hovered = false; - const stack = new Stack({ children }); - - return new Button({ - cursor: 'pointer', - - child: stack, - - onButtonReleaseEvent: () => (player[onClick] as () => void)(), - - onHover: () => { - hovered = true; - - if (prop === 'playbackStatus' && colors.get()) { - const c = colors.get(); - - children.forEach((ch) => { - ch.css = ` - background-color: ${c.hoverAccent}; - color: ${c.buttonText}; - min-height: 40px; - min-width: 36px; - margin-bottom: 1px; - margin-right: 1px; - `; - }); - } - }, - - onHoverLost: () => { - hovered = false; - if (prop === 'playbackStatus' && colors.get()) { - const c = colors.get(); - - children.forEach((ch) => { - ch.css = ` - background-color: ${c.buttonAccent}; - color: ${c.buttonText}; - min-height: 42px; - min-width: 38px; - `; - }); - } - }, - - setup: (self) => { - if (player[prop] && (player[prop] as boolean) !== false) { - stack.shown = String(player[prop]); - } - - player.connect(`notify::${kebabify(prop)}`, () => { - if (player[prop] !== 0) { - stack.shown = String(player[prop]); - } - }); - - self.hook(colors, () => { - if (!Mpris.get_default().get_players().find((p) => player === p)) { - return; - } - - if (colors.get()) { - const c = colors.get(); - - if (prop === 'playbackStatus') { - if (hovered) { - children.forEach((ch) => { - ch.css = ` - background-color: ${c.hoverAccent}; - color: ${c.buttonText}; - min-height: 40px; - min-width: 36px; - margin-bottom: 1px; - margin-right: 1px; - `; - }); - } - else { - children.forEach((ch) => { - ch.css = ` - background-color: ${c.buttonAccent}; - color: ${c.buttonText}; - min-height: 42px; - min-width: 38px; - `; - }); - } - } - else { - self.css = ` - * { color: ${c.buttonAccent}; } - *:hover { color: ${c.hoverAccent}; } - `; - } - } - }); - }, - }); -}; - -export const ShuffleButton = ( - player: Mpris.Player, - colors: Variable<Colors>, -) => PlayerButton({ - player, - colors, - children: [ - (new Label({ - name: Mpris.Shuffle.ON.toString(), - className: 'shuffle enabled', - label: icons.mpris.shuffle.enabled, - })), - (new Label({ - name: Mpris.Shuffle.OFF.toString(), - className: 'shuffle disabled', - label: icons.mpris.shuffle.disabled, - })), - ], - onClick: 'shuffle', - prop: 'shuffleStatus', -}); - -export const LoopButton = ( - player: Mpris.Player, - colors: Variable<Colors>, -) => PlayerButton({ - player, - colors, - children: [ - (new Label({ - name: Mpris.Loop.NONE.toString(), - className: 'loop none', - label: icons.mpris.loop.none, - })), - (new Label({ - name: Mpris.Loop.TRACK.toString(), - className: 'loop track', - label: icons.mpris.loop.track, - })), - (new Label({ - name: Mpris.Loop.PLAYLIST.toString(), - className: 'loop playlist', - label: icons.mpris.loop.playlist, - })), - ], - onClick: 'loop', - prop: 'loopStatus', -}); - -export const PlayPauseButton = ( - player: Mpris.Player, - colors: Variable<Colors>, -) => PlayerButton({ - player, - colors, - children: [ - (new Icon({ - name: Mpris.PlaybackStatus.PLAYING.toString(), - className: 'pausebutton playing', - icon: icons.mpris.playing, - })), - (new Icon({ - name: Mpris.PlaybackStatus.PAUSED.toString(), - className: 'pausebutton paused', - icon: icons.mpris.paused, - })), - (new Icon({ - name: Mpris.PlaybackStatus.STOPPED.toString(), - className: 'pausebutton stopped paused', - icon: icons.mpris.stopped, - })), - ], - onClick: 'play_pause', - prop: 'playbackStatus', -}); - -export const PreviousButton = ( - player: Mpris.Player, - colors: Variable<Colors>, -) => PlayerButton({ - player, - colors, - children: [ - (new Label({ - name: 'true', - className: 'previous', - label: icons.mpris.prev, - })), - (new Label({ - name: 'false', - className: 'previous', - label: icons.mpris.prev, - })), - ], - onClick: 'previous', - prop: 'canGoPrevious', -}); - -export const NextButton = ( - player: Mpris.Player, - colors: Variable<Colors>, -) => PlayerButton({ - player, - colors, - children: [ - (new Label({ - name: 'true', - className: 'next', - label: icons.mpris.next, - })), - (new Label({ - name: 'false', - className: 'next', - label: icons.mpris.next, - })), - ], - onClick: 'next', - prop: 'canGoNext', -}); diff --git a/modules/ags/config/widgets/media-player/player.ts b/modules/ags/config/widgets/media-player/player.ts deleted file mode 100644 index ea20cd1d..00000000 --- a/modules/ags/config/widgets/media-player/player.ts +++ /dev/null @@ -1,183 +0,0 @@ -import { Variable } from 'astal'; -import { Gtk } from 'astal/gtk3'; -import { Box, CenterBox } from 'astal/gtk3/widget'; - -import Mpris from 'gi://AstalMpris'; - -import Separator from '../misc/separator'; - -import * as mpris from './mpris'; - -import PlayerGesture, { - PlayerGesture as PlayerGestureClass, - PlayerBox as PlayerBoxClass, -} from './gesture'; - -const FAVE_PLAYER = 'org.mpris.MediaPlayer2.spotify'; -const SPACING = 8; - - -const Top = ( - player: Mpris.Player, - overlay: PlayerGestureClass, -) => new Box({ - className: 'top', - halign: Gtk.Align.START, - valign: Gtk.Align.START, - - children: [ - mpris.PlayerIcon(player, overlay), - ], -}); - -const Center = ( - player: Mpris.Player, - colors: Variable<mpris.Colors>, -) => new Box({ - className: 'center', - - children: [ - (new CenterBox({ - vertical: true, - - start_widget: new Box({ - className: 'metadata', - vertical: true, - halign: Gtk.Align.START, - valign: Gtk.Align.CENTER, - hexpand: true, - - children: [ - mpris.TitleLabel(player), - mpris.ArtistLabel(player), - ], - }), - })), - - (new CenterBox({ - vertical: true, - - center_widget: mpris.PlayPauseButton(player, colors), - })), - - ], -}); - -const Bottom = ( - player: Mpris.Player, - colors: Variable<mpris.Colors>, -) => new Box({ - className: 'bottom', - - children: [ - mpris.PreviousButton(player, colors), - Separator({ size: SPACING }), - - mpris.PositionSlider(player, colors), - Separator({ size: SPACING }), - - mpris.NextButton(player, colors), - Separator({ size: SPACING }), - - mpris.ShuffleButton(player, colors), - Separator({ size: SPACING }), - - mpris.LoopButton(player, colors), - ], -}); - -const PlayerBox = ( - player: Mpris.Player, - colors: Variable<mpris.Colors>, - overlay: PlayerGestureClass, -) => { - const widget = mpris.CoverArt(player, colors, { - className: `player ${player.identity}`, - hexpand: true, - - start_widget: Top(player, overlay), - center_widget: Center(player, colors), - end_widget: Bottom(player, colors), - }); - - widget.visible = false; - - return widget; -}; - -export default () => { - const content = PlayerGesture({ - setup: (self) => { - const addPlayer = (player: Mpris.Player) => { - if (!player || self.players.has(player.bus_name)) { - return; - } - - // Get the one on top so we can move it up later - const previousFirst = self.overlays.at(-1) as PlayerBoxClass; - - // Make the new player - const colorsVar = Variable({ - imageAccent: '#6b4fa2', - buttonAccent: '#ecdcff', - buttonText: '#25005a', - hoverAccent: '#d4baff', - }); - - self.players.set( - player.bus_name, - PlayerBox(player, colorsVar, self), - ); - self.add_overlay(self.players.get(player.bus_name)); - - // Select favorite player at startup - if (!self.setup && self.players.has(FAVE_PLAYER)) { - self.moveToTop(self.players.get(FAVE_PLAYER)); - self.setup = true; - } - - // Move previousFirst on top again - else { - self.moveToTop(previousFirst); - } - }; - - const removePlayer = (player: Mpris.Player) => { - if (!player || !self.players.has(player.bus_name)) { - return; - } - - const toDelete = self.players.get(player.bus_name); - - // Get the one on top so we can move it up later - const previousFirst = self.overlays.at(-1) as PlayerBoxClass; - - // Move previousFirst on top again - if (previousFirst !== toDelete) { - self.moveToTop(previousFirst); - } - else { - self.moveToTop(self.players.has(FAVE_PLAYER) ? - self.players.get(FAVE_PLAYER) : - self.overlays[0]); - } - - // Remake overlays without deleted one - self.remove(toDelete); - self.players.delete(player.bus_name); - }; - - const mprisDefault = Mpris.get_default(); - - self.hook(mprisDefault, 'player-added', (_, player) => addPlayer(player)); - self.hook(mprisDefault, 'player-closed', (_, player) => removePlayer(player)); - - mprisDefault.players.forEach(addPlayer); - }, - }); - - return new Box({ - className: 'media-player', - child: content, - }); -}; diff --git a/modules/ags/config/widgets/misc/_index.scss b/modules/ags/config/widgets/misc/_index.scss deleted file mode 100644 index a75d8a85..00000000 --- a/modules/ags/config/widgets/misc/_index.scss +++ /dev/null @@ -1,29 +0,0 @@ -@use '../../style/colors'; - -.sorted-list { - .search { - icon { - font-size: 20px; - min-width: 40px; - min-height: 40px - } - - // entry {} - } - - .list { - row { - border-radius: 10px; - - &:hover, &:selected { - icon { - -gtk-icon-shadow: 2px 2px colors.$accent_color; - } - } - } - - .placeholder { - font-size: 20px; - } - } -} diff --git a/modules/ags/config/widgets/misc/persist.ts b/modules/ags/config/widgets/misc/persist.ts deleted file mode 100644 index dd22f703..00000000 --- a/modules/ags/config/widgets/misc/persist.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { execAsync, readFileAsync, timeout, GLib, type Variable } from 'astal'; - -const { get_home_dir } = GLib; - - -export default <T>({ - name, - variable, - condition = true, - whenTrue = condition, - whenFalse = false, -}: { - name: string - variable: Variable<T> - condition?: boolean | string - whenTrue?: boolean | string - whenFalse?: boolean | string -}) => { - const cacheFile = `${get_home_dir()}/.cache/ags/.${name}`; - - const stateCmd = () => ['bash', '-c', - `echo ${variable.get() === condition} > ${cacheFile}`]; - - const monitorState = () => { - variable.subscribe(() => { - execAsync(stateCmd()).catch(print); - }); - }; - - readFileAsync(cacheFile) - .then((content) => { - // JSON.parse was the only way I found to reliably - // convert a string of 'true' or 'false' into a bool - const value = (JSON.parse(content) ? whenTrue : whenFalse) as T; - - variable.set(value); - - timeout(1000, () => { - monitorState(); - }); - }) - .catch(() => { - execAsync(stateCmd()) - .then(() => { - monitorState(); - }) - .catch(print); - }); -}; diff --git a/modules/ags/config/widgets/misc/popup-window.tsx b/modules/ags/config/widgets/misc/popup-window.tsx deleted file mode 100644 index 21eb8ff4..00000000 --- a/modules/ags/config/widgets/misc/popup-window.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import { App, Astal, Gtk, Widget } from 'astal/gtk3'; -import { property, register } from 'astal/gobject'; -import { Binding, idle } from 'astal'; - -import { hyprMessage } from '../../lib'; - -/* Types */ -type CloseType = 'none' | 'stay' | 'released' | 'clicked'; -type HyprTransition = 'slide' | 'slide top' | 'slide bottom' | 'slide left' | - 'slide right' | 'popin' | 'fade'; -type PopupCallback = (self?: Widget.Window) => void; - -export type PopupWindowProps = Widget.WindowProps & { - transition?: HyprTransition | Binding<HyprTransition> - close_on_unfocus?: CloseType | Binding<CloseType> - on_open?: PopupCallback - on_close?: PopupCallback -}; - - -@register() -export class PopupWindow extends Widget.Window { - @property(String) - declare transition: HyprTransition | Binding<HyprTransition>; - - @property(String) - declare close_on_unfocus: CloseType | Binding<CloseType>; - - on_open: PopupCallback; - on_close: PopupCallback; - - constructor({ - transition = 'slide top', - close_on_unfocus = 'released', - on_open = () => { /**/ }, - on_close = () => { /**/ }, - - name, - visible = false, - layer = Astal.Layer.OVERLAY, - ...rest - }: PopupWindowProps) { - super({ - ...rest, - name: `win-${name}`, - namespace: `win-${name}`, - visible: false, - layer, - setup: () => idle(() => { - // Add way to make window open on startup - if (visible) { - this.visible = true; - } - }), - }); - - App.add_window(this); - - const setTransition = (_: PopupWindow, t: HyprTransition | Binding<HyprTransition>) => { - hyprMessage(`keyword layerrule animation ${t}, ${this.name}`).catch(console.log); - }; - - this.connect('notify::transition', setTransition); - - this.close_on_unfocus = close_on_unfocus; - this.transition = transition; - this.on_open = on_open; - this.on_close = on_close; - - this.connect('notify::visible', () => { - // Make sure we have the right animation - setTransition(this, this.transition); - - if (this.visible) { - this.on_open(this); - } - else { - this.on_close(this); - } - }); - }; - - async set_x_pos( - alloc: Gtk.Allocation, - side = 'right' as 'left' | 'right', - ) { - const monitor = this.gdkmonitor ?? - this.get_display().get_monitor_at_point(alloc.x, alloc.y); - - const width = monitor.get_geometry().width; - - this.margin_right = side === 'right' ? - (width - alloc.x - alloc.width) : - this.margin_right; - - this.margin_left = side === 'right' ? - this.margin_left : - (alloc.x - alloc.width); - } -} - -export default PopupWindow; diff --git a/modules/ags/config/widgets/misc/separator.tsx b/modules/ags/config/widgets/misc/separator.tsx deleted file mode 100644 index aaf0aeca..00000000 --- a/modules/ags/config/widgets/misc/separator.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { Widget } from 'astal/gtk3'; - - -export default ({ - size, - vertical = false, - css = '', - ...rest -}: { size: number } & Widget.BoxProps) => ( - <box - css={`${vertical ? 'min-height' : 'min-width'}: ${size}px; ${css}`} - {...rest} - /> -); diff --git a/modules/ags/config/widgets/misc/smooth-progress.tsx b/modules/ags/config/widgets/misc/smooth-progress.tsx deleted file mode 100644 index d5dad201..00000000 --- a/modules/ags/config/widgets/misc/smooth-progress.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { bind } from 'astal'; -import { Gtk, Widget } from 'astal/gtk3'; -import { register, property } from 'astal/gobject'; - -type SmoothProgressProps = Widget.BoxProps & { - transition_duration?: string -}; - - -// PERF: this is kinda laggy -@register() -class SmoothProgress extends Widget.Box { - @property(Number) - declare fraction: number; - - @property(String) - declare transition_duration: string; - - constructor({ - transition_duration = '1s', - ...rest - }: SmoothProgressProps = {}) { - super(rest); - this.transition_duration = transition_duration; - - const background = ( - <box - className="background" - hexpand - vexpand - halign={Gtk.Align.FILL} - valign={Gtk.Align.FILL} - /> - ); - - const progress = ( - <box - className="progress" - vexpand - valign={Gtk.Align.FILL} - css={bind(this, 'fraction').as((fraction) => { - return ` - transition: margin-right ${this.transition_duration} linear; - margin-right: ${ - Math.abs(fraction - 1) * background.get_allocated_width() - }px; - `; - })} - /> - ); - - this.add(( - <overlay overlay={progress}> - {background} - </overlay> - )); - this.show_all(); - } -} - -export default SmoothProgress; diff --git a/modules/ags/config/widgets/misc/sorted-list.tsx b/modules/ags/config/widgets/misc/sorted-list.tsx deleted file mode 100644 index 4c50497b..00000000 --- a/modules/ags/config/widgets/misc/sorted-list.tsx +++ /dev/null @@ -1,201 +0,0 @@ -// This is definitely not good practice but I couldn't figure out how to extend PopupWindow -// so here we are with a cursed function that returns a prop of the class. - -import { Astal, Gtk, Widget } from 'astal/gtk3'; -import { idle } from 'astal'; - -import { AsyncFzf, AsyncFzfOptions, FzfResultItem } from 'fzf'; - -import PopupWindow from '../misc/popup-window'; -import { centerCursor } from '../../lib'; - -export interface SortedListProps<T> { - create_list: () => T[] | Promise<T[]> - create_row: (item: T) => Gtk.Widget - fzf_options?: AsyncFzfOptions<T> - unique_props?: (keyof T)[] - on_row_activated: (row: Gtk.ListBoxRow) => void - sort_func: ( - a: Gtk.ListBoxRow, - b: Gtk.ListBoxRow, - entry: Widget.Entry, - fzf: FzfResultItem<T>[], - ) => number - name: string -}; - - -export class SortedList<T> { - private item_list: T[] = []; - private fzf_results: FzfResultItem<T>[] = []; - - readonly window: PopupWindow; - private _item_map = new Map<T, Gtk.Widget>(); - - readonly create_list: () => T[] | Promise<T[]>; - readonly create_row: (item: T) => Gtk.Widget; - readonly fzf_options: AsyncFzfOptions<T>; - readonly unique_props: (keyof T)[] | undefined; - - readonly on_row_activated: (row: Gtk.ListBoxRow) => void; - - readonly sort_func: ( - a: Gtk.ListBoxRow, - b: Gtk.ListBoxRow, - entry: Widget.Entry, - fzf: FzfResultItem<T>[], - ) => number; - - - constructor({ - create_list, - create_row, - fzf_options = {} as AsyncFzfOptions<T>, - unique_props, - on_row_activated, - sort_func, - name, - }: SortedListProps<T>) { - const list = new Gtk.ListBox({ - selectionMode: Gtk.SelectionMode.SINGLE, - }); - - list.connect('row-activated', (_, row) => { - this.on_row_activated(row); - }); - - const placeholder = ( - <revealer> - <label - label=" Couldn't find a match" - className="placeholder" - /> - </revealer> - ) as Widget.Revealer; - - const on_text_change = (text: string) => { - // @ts-expect-error this works - (new AsyncFzf<T[]>(this.item_list, this.fzf_options)).find(text) - .then((out) => { - this.fzf_results = out; - list.invalidate_sort(); - - const visibleApplications = list - .get_children() - .filter((row) => row.get_visible()) - .length; - - placeholder.set_reveal_child(visibleApplications <= 0); - }) - .catch(() => { /**/ }); - }; - - const entry = ( - <entry - onChanged={(self) => on_text_change(self.text)} - hexpand - /> - ) as Widget.Entry; - - list.set_sort_func((a, b) => { - return this.sort_func(a, b, entry, this.fzf_results); - }); - - const refreshItems = () => idle(async() => { - // Delete items that don't exist anymore - const new_list = await this.create_list(); - - [...this._item_map].forEach(([item, widget]) => { - if (!new_list.some((new_item) => - this.unique_props?.every((prop) => item[prop] === new_item[prop]) ?? - item === new_item)) { - widget.get_parent()?.destroy(); - this._item_map.delete(item); - } - }); - - // Add missing items - new_list.forEach((item) => { - if (!this.item_list.some((old_item) => - this.unique_props?.every((prop) => old_item[prop] === item[prop]) ?? - old_item === item)) { - const itemWidget = this.create_row(item); - - list.add(itemWidget); - this._item_map.set(item, itemWidget); - } - }); - - this.item_list = new_list; - - list.show_all(); - on_text_change(''); - }); - - this.window = ( - <PopupWindow - name={name} - keymode={Astal.Keymode.ON_DEMAND} - on_open={() => { - entry.set_text(''); - refreshItems(); - centerCursor(); - entry.grab_focus(); - }} - > - <box - vertical - className={`${name} sorted-list`} - > - <box className="widget search"> - - <icon icon="preferences-system-search-symbolic" /> - - {entry} - - <button - css="margin-left: 5px;" - cursor="pointer" - onButtonReleaseEvent={refreshItems} - > - <icon icon="view-refresh-symbolic" css="font-size: 26px;" /> - </button> - - </box> - - <eventbox cursor="pointer"> - <scrollable - className="widget list" - - css="min-height: 600px; min-width: 700px;" - hscroll={Gtk.PolicyType.NEVER} - vscroll={Gtk.PolicyType.AUTOMATIC} - > - <box vertical> - {list} - {placeholder} - </box> - </scrollable> - </eventbox> - </box> - </PopupWindow> - ) as PopupWindow; - - this.create_list = create_list; - this.create_row = create_row; - this.fzf_options = fzf_options; - this.unique_props = unique_props; - this.on_row_activated = on_row_activated; - this.sort_func = sort_func; - - refreshItems(); - } -}; - -/** - * @param props props for a SortedList Widget - * @returns the widget - */ -export default function<Attr>(props: SortedListProps<Attr>) { - return (new SortedList(props)).window; -} diff --git a/modules/ags/config/widgets/misc/subclasses.tsx b/modules/ags/config/widgets/misc/subclasses.tsx deleted file mode 100644 index fde7b9c7..00000000 --- a/modules/ags/config/widgets/misc/subclasses.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { astalify, Gtk, type ConstructProps } from 'astal/gtk3'; -import { register } from 'astal/gobject'; - - -@register() -export class ToggleButton extends astalify(Gtk.ToggleButton) { - constructor(props: ConstructProps< - ToggleButton, - Gtk.ToggleButton.ConstructorProps - >) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - super(props as any); - } -} - -@register() -export class RadioButton extends astalify(Gtk.RadioButton) { - constructor(props: ConstructProps< - RadioButton, - Gtk.RadioButton.ConstructorProps - > = {}) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - super(props as any); - } -} - -@register() -export class ListBox extends astalify(Gtk.ListBox) { - override get_children() { - return super.get_children() as Gtk.ListBoxRow[]; - } - - constructor(props: ConstructProps< - ListBox, - Gtk.ListBox.ConstructorProps - > = {}) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - super(props as any); - } -} - -@register() -export class ProgressBar extends astalify(Gtk.ProgressBar) { - constructor(props: ConstructProps< - ProgressBar, - Gtk.ProgressBar.ConstructorProps - > = {}) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - super(props as any); - } -} - -@register() -export class ComboBoxText extends astalify(Gtk.ComboBoxText) { - constructor(props: ConstructProps< - ComboBoxText, - Gtk.ComboBoxText.ConstructorProps - > = {}) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - super(props as any); - } -} diff --git a/modules/ags/config/widgets/network/_index.scss b/modules/ags/config/widgets/network/_index.scss deleted file mode 100644 index 01ec31e0..00000000 --- a/modules/ags/config/widgets/network/_index.scss +++ /dev/null @@ -1,32 +0,0 @@ -@use 'sass:color'; -@use '../../style/colors'; - -.network.widget { - margin-top: 0; - - * { - font-size: 20px; - } - - row { - all: unset; - } - - .toggle-button { - padding: 4px; - min-width: 30px; - min-height: 30px; - - transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out; - - box-shadow: 2px 1px 2px colors.$accent-color; - margin: 4px 4px 4px 4px; - background-color: colors.$window_bg_color; - - &.active { - box-shadow: 0 0 0 white; - margin: 6px 4px 2px 4px; - background-color: color.adjust(colors.$window_bg_color, $lightness: -3%); - } - } -} diff --git a/modules/ags/config/widgets/network/access-point.tsx b/modules/ags/config/widgets/network/access-point.tsx deleted file mode 100644 index bc3e7c14..00000000 --- a/modules/ags/config/widgets/network/access-point.tsx +++ /dev/null @@ -1,137 +0,0 @@ -import { bind, execAsync } from 'astal'; -import { Gtk, Widget } from 'astal/gtk3'; -import { register } from 'astal/gobject'; - -import AstalNetwork from 'gi://AstalNetwork'; - -import Separator from '../misc/separator'; -import { notifySend } from '../../lib'; - - -const apCommand = (ap: AstalNetwork.AccessPoint, cmd: string[]): void => { - execAsync([ - 'nmcli', - ...cmd, - ap.get_ssid()!, - ]).catch((e) => notifySend({ - title: 'Network', - iconName: ap.get_icon_name(), - body: (e as Error).message, - actions: [ - { - id: 'open', - label: 'Open network manager', - callback: () => - execAsync('nm-connection-editor'), - }, - ], - })).catch((e) => console.error(e)); -}; - -const apConnect = (ap: AstalNetwork.AccessPoint): void => { - execAsync(['nmcli', 'connection', 'show', ap.get_ssid()!]) - .catch(() => apCommand(ap, ['device', 'wifi', 'connect'])) - .then(() => apCommand(ap, ['connection', 'up'])); -}; - -const apDisconnect = (ap: AstalNetwork.AccessPoint): void => { - apCommand(ap, ['connection', 'down']); -}; - -@register() -export default class AccessPointWidget extends Widget.Box { - readonly aps: AstalNetwork.AccessPoint[]; - - getStrongest() { - return this.aps.sort((apA, apB) => apB.get_strength() - apA.get_strength())[0]; - } - - constructor({ aps }: { aps: AstalNetwork.AccessPoint[] }) { - const wifi = AstalNetwork.get_default().get_wifi(); - - if (!wifi) { - throw new Error('Could not find wifi device.'); - } - - const rev = ( - <revealer - transitionType={Gtk.RevealerTransitionType.SLIDE_DOWN} - > - <box vertical halign={Gtk.Align.FILL} hexpand> - <Separator size={8} vertical /> - - <centerbox> - <label - label="Connected" - valign={Gtk.Align.CENTER} - halign={Gtk.Align.START} - /> - - <box /> - - <switch - cursor="pointer" - valign={Gtk.Align.CENTER} - halign={Gtk.Align.END} - - state={bind(wifi, 'activeAccessPoint') - .as((activeAp) => aps.includes(activeAp))} - - onButtonReleaseEvent={(self) => { - if (self.state) { - apDisconnect(this.getStrongest()); - } - else { - apConnect(this.getStrongest()); - } - }} - - /> - </centerbox> - - <Separator size={8} vertical /> - </box> - </revealer> - ) as Widget.Revealer; - - const button = ( - <button - cursor="pointer" - onButtonReleaseEvent={() => { - rev.revealChild = !rev.revealChild; - }} - > - <box> - <icon - icon="check-active-symbolic" - - css={bind(wifi, 'activeAccessPoint').as((activeAp) => aps.includes(activeAp) ? - '' : - 'opacity: 0;')} - /> - - <Separator size={8} /> - - <icon - icon={bind(aps[0], 'iconName')} - /> - - <Separator size={8} /> - - <label label={aps[0].get_ssid()!} /> - </box> - </button> - ); - - super({ - vertical: true, - children: [ - button, - rev, - (<Separator size={8} vertical />), - ], - }); - - this.aps = aps; - }; -}; diff --git a/modules/ags/config/widgets/network/main.tsx b/modules/ags/config/widgets/network/main.tsx deleted file mode 100644 index 3ea1b602..00000000 --- a/modules/ags/config/widgets/network/main.tsx +++ /dev/null @@ -1,117 +0,0 @@ -import { bind, Variable } from 'astal'; -import { Gtk } from 'astal/gtk3'; - -import AstalNetwork from 'gi://AstalNetwork'; - -import { ToggleButton } from '../misc/subclasses'; -import Separator from '../misc/separator'; - -import AccessPointWidget from './access-point'; - - -export default () => { - const wifi = AstalNetwork.get_default().get_wifi(); - - if (!wifi) { - throw new Error('Could not find wifi device.'); - } - - const IsRefreshing = Variable<boolean>(false); - const AccessPoints = Variable<AstalNetwork.AccessPoint[]>(wifi.get_access_points()); - - wifi.connect('notify::access-points', () => { - if (IsRefreshing.get()) { - AccessPoints.set(wifi.get_access_points()); - } - }); - - IsRefreshing.subscribe(() => { - if (IsRefreshing.get()) { - AccessPoints.set(wifi.get_access_points()); - } - }); - - const apList = ( - <scrollable - className="list" - - css="min-height: 300px;" - hscroll={Gtk.PolicyType.NEVER} - vscroll={Gtk.PolicyType.AUTOMATIC} - > - <box vertical> - {bind(AccessPoints).as(() => { - const joined = new Map<string, AstalNetwork.AccessPoint[]>(); - - AccessPoints.get() - .filter((ap) => ap.get_ssid()) - .sort((apA, apB) => { - const sort = apB.get_strength() - apA.get_strength(); - - return sort !== 0 ? - sort : - apA.get_ssid()!.localeCompare(apB.get_ssid()!); - }) - .forEach((ap) => { - const arr = joined.get(ap.get_ssid()!); - - if (arr) { - arr.push(ap); - } - else { - joined.set(ap.get_ssid()!, [ap]); - } - }); - - return [...joined.values()].map((aps) => <AccessPointWidget aps={aps} />); - })} - </box> - </scrollable> - ); - - return ( - <box - className="network widget" - vertical - > - <centerbox homogeneous> - <switch - cursor="pointer" - valign={Gtk.Align.CENTER} - halign={Gtk.Align.START} - - active={bind(wifi, 'enabled')} - - setup={(self) => { - self.connect('notify::active', () => { - wifi.set_enabled(self.active); - }); - }} - /> - - <box /> - - <ToggleButton - cursor="pointer" - halign={Gtk.Align.END} - - className="toggle-button" - - sensitive={bind(wifi, 'enabled')} - active={bind(IsRefreshing)} - - onToggled={(self) => { - self.toggleClassName('active', self.active); - IsRefreshing.set(self.active); - }} - > - <icon icon="emblem-synchronizing-symbolic" css="font-size: 30px;" /> - </ToggleButton> - </centerbox> - - <Separator size={8} vertical /> - - {apList} - </box> - ); -}; diff --git a/modules/ags/config/widgets/network/wim.tsx b/modules/ags/config/widgets/network/wim.tsx deleted file mode 100644 index 589fe06e..00000000 --- a/modules/ags/config/widgets/network/wim.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { Astal } from 'astal/gtk3'; - -import PopupWindow from '../misc/popup-window'; - -import NetworkWidget from './main'; - - -export default () => ( - <PopupWindow - name="network" - anchor={Astal.WindowAnchor.RIGHT | Astal.WindowAnchor.TOP} - > - <NetworkWidget /> - </PopupWindow> -); diff --git a/modules/ags/config/widgets/notifs/_index.scss b/modules/ags/config/widgets/notifs/_index.scss deleted file mode 100644 index 526a112f..00000000 --- a/modules/ags/config/widgets/notifs/_index.scss +++ /dev/null @@ -1,133 +0,0 @@ -@use 'sass:color'; -@use '../../style/colors'; - -.notification.widget { - // urgencies - // &.urgency ... - - .icon { - margin-right: 10px; - } - - .time { - margin: 3px; - } - - .close-button { - margin: 3px; - } - - .title { - font-weight: 800; - font-size: 20px; - margin-bottom: 5px; - } - - .description { - margin-bottom: 5px; - } - - .actions { - margin: 3px; - - // .action-button {} - } - - .smooth-progress { - min-height: 7px; - margin: 3px; - - .background { - background-color: color.adjust(colors.$window_bg_color, $lightness: -3%); - border-radius: 3px; - } - - .progress { - background-color: colors.$accent-color; - border-radius: 3px; - } - } -} - -.notification-center { - margin-top: 0; - - min-height: 700px; - min-width: 580px; - - * { - font-size: 16px; - } - - .header { - padding: 10px; - margin-bottom: 9px; - - label { - font-size: 22px; - } - } - - .notification-list-box { - padding: 0 12px; - - .notification { - box-shadow: none; - } - - scrollbar { - all: unset; - border-radius: 8px; - border-top-left-radius: 0; - border-bottom-left-radius: 0; - - * { - all: unset; - } - - &:hover { - border-radius: 8px; - border-top-left-radius: 0; - border-bottom-left-radius: 0; - } - } - - scrollbar.vertical { - transition: 200ms; - background-color: rgba(23, 23, 23, 0.3); - - &:hover { - background-color: rgba(23, 23, 23, 0.7); - - slider { - background-color: rgba(238, 238, 238, 0.7); - min-width: .6em; - } - } - - slider { - background-color: rgba(238, 238, 238, 0.5); - border-radius: 9px; - min-width: .4em; - min-height: 2em; - transition: 200ms; - } - } - } - - .placeholder { - color: white; - - icon { - font-size: 7em; - text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6); - -gtk-icon-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6); - } - - label { - font-size: 1.2em; - text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6); - -gtk-icon-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6); - } - } -} diff --git a/modules/ags/config/widgets/notifs/binto.tsx b/modules/ags/config/widgets/notifs/binto.tsx deleted file mode 100644 index 9938504e..00000000 --- a/modules/ags/config/widgets/notifs/binto.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { Astal } from 'astal/gtk3'; - -import PopupWindow from '../misc/popup-window'; -import { get_gdkmonitor_from_desc } from '../../lib'; - -import Popups from './popups'; -import Center from './center'; - - -export const NotifPopups = () => ( - <window - name="notifications" - namespace="noanim-notifications" - gdkmonitor={get_gdkmonitor_from_desc('desc:Acer Technologies Acer K212HQL T3EAA0014201')} - layer={Astal.Layer.OVERLAY} - anchor={Astal.WindowAnchor.BOTTOM | Astal.WindowAnchor.LEFT} - > - <Popups /> - </window> -); - -export const NotifCenter = () => ( - <PopupWindow - name="notif-center" - gdkmonitor={get_gdkmonitor_from_desc('desc:Acer Technologies Acer K212HQL T3EAA0014201')} - anchor={Astal.WindowAnchor.BOTTOM | Astal.WindowAnchor.RIGHT} - transition="slide bottom" - > - <Center /> - </PopupWindow> -); diff --git a/modules/ags/config/widgets/notifs/center.tsx b/modules/ags/config/widgets/notifs/center.tsx deleted file mode 100644 index 7dac643c..00000000 --- a/modules/ags/config/widgets/notifs/center.tsx +++ /dev/null @@ -1,152 +0,0 @@ -import { bind, timeout } from 'astal'; -import { App, Gtk, Widget } from 'astal/gtk3'; - -import AstalNotifd from 'gi://AstalNotifd'; - -import { Notification, HasNotifs } from './notification'; -import NotifGestureWrapper from './gesture'; - - -const addNotif = (box: Widget.Box, notifObj: AstalNotifd.Notification) => { - if (notifObj) { - const NewNotif = Notification({ - id: notifObj.id, - slide_in_from: 'Right', - }); - - if (NewNotif) { - box.pack_end(NewNotif, false, false, 0); - box.show_all(); - } - } -}; - -const NotificationList = () => { - const notifications = AstalNotifd.get_default(); - - return ( - <box - vertical - vexpand - valign={Gtk.Align.START} - visible={bind(HasNotifs)} - // It needs to be bigger than the notifs to not jiggle - css="min-width: 550px;" - - setup={(self) => { - notifications.get_notifications().forEach((n) => { - addNotif(self, n); - }); - - self - .hook(notifications, 'notified', (_, id) => { - if (id) { - const notifObj = notifications.get_notification(id); - - if (notifObj) { - addNotif(self, notifObj); - } - } - }) - .hook(notifications, 'resolved', (_, id) => { - const notif = (self.get_children() as NotifGestureWrapper[]) - .find((ch) => ch.id === id); - - if (notif?.get_sensitive()) { - notif.slideAway('Right'); - } - }); - }} - /> - ); -}; - -const ClearButton = () => { - const notifications = AstalNotifd.get_default(); - - return ( - <eventbox - cursor={bind(HasNotifs).as((hasNotifs) => hasNotifs ? 'pointer' : 'not-allowed')} - > - <button - className="clear" - sensitive={bind(HasNotifs)} - - onButtonReleaseEvent={() => { - notifications.get_notifications().forEach((notif) => { - notif.dismiss(); - }); - timeout(1000, () => { - App.get_window('win-notif-center')?.set_visible(false); - }); - }} - > - <box> - <label label="Clear " /> - - <icon icon={bind(notifications, 'notifications') - .as((notifs) => notifs.length > 0 ? - 'user-trash-full-symbolic' : - 'user-trash-symbolic')} - /> - </box> - </button> - </eventbox> - ); -}; - -const Header = () => ( - <box className="header"> - <label - label="Notifications" - hexpand - xalign={0} - /> - <ClearButton /> - </box> -); - -const Placeholder = () => ( - <revealer - transitionType={Gtk.RevealerTransitionType.CROSSFADE} - revealChild={bind(HasNotifs).as((v) => !v)} - > - <box - className="placeholder" - vertical - valign={Gtk.Align.CENTER} - halign={Gtk.Align.CENTER} - vexpand - hexpand - > - <icon icon="notification-disabled-symbolic" /> - <label label="Your inbox is empty" /> - </box> - </revealer> -); - -export default () => ( - <box - className="notification-center widget" - vertical - > - <Header /> - - <box className="notification-wallpaper-box"> - <scrollable - className="notification-list-box" - hscroll={Gtk.PolicyType.NEVER} - vscroll={Gtk.PolicyType.AUTOMATIC} - > - <box - className="notification-list" - vertical - > - <NotificationList /> - - <Placeholder /> - </box> - </scrollable> - </box> - </box> -); diff --git a/modules/ags/config/widgets/notifs/gesture.tsx b/modules/ags/config/widgets/notifs/gesture.tsx deleted file mode 100644 index fa17a86c..00000000 --- a/modules/ags/config/widgets/notifs/gesture.tsx +++ /dev/null @@ -1,359 +0,0 @@ -import { Gdk, Gtk, Widget } from 'astal/gtk3'; -import { property, register } from 'astal/gobject'; -import { idle, interval, timeout } from 'astal'; - -import AstalIO from 'gi://AstalIO'; - -import AstalNotifd from 'gi://AstalNotifd'; - -import { hyprMessage } from '../../lib'; - -import { HasNotifs } from './notification'; -import { get_hyprland_monitor } from '../../lib'; - -/* Types */ -import { CursorPos, LayerResult } from '../../lib'; - - -const display = Gdk.Display.get_default(); - -const MAX_OFFSET = 200; -const OFFSCREEN = 300; -const ANIM_DURATION = 500; -const SLIDE_MIN_THRESHOLD = 10; -const TRANSITION = 'transition: margin 0.5s ease, opacity 0.5s ease;'; -const MAX_LEFT = ` - margin-left: -${Number(MAX_OFFSET + OFFSCREEN)}px; - margin-right: ${Number(MAX_OFFSET + OFFSCREEN)}px; -`; -const MAX_RIGHT = ` - margin-left: ${Number(MAX_OFFSET + OFFSCREEN)}px; - margin-right: -${Number(MAX_OFFSET + OFFSCREEN)}px; -`; - -const slideLeft = `${TRANSITION} ${MAX_LEFT} opacity: 0;`; - -const slideRight = `${TRANSITION} ${MAX_RIGHT} opacity: 0;`; - -const defaultStyle = `${TRANSITION} margin: unset; opacity: 1;`; - -type NotifGestureWrapperProps = Widget.BoxProps & { - id: number - slide_in_from?: 'Left' | 'Right' - popup_timer?: number - setup_notif?: (self: NotifGestureWrapper) => void -}; - -@register() -export class NotifGestureWrapper extends Widget.EventBox { - public static popups = new Map<number, NotifGestureWrapper>(); - public static sliding_in = 0; - public static on_sliding_in: (amount: number) => void; - - readonly id: number; - readonly slide_in_from: 'Left' | 'Right'; - readonly is_popup: boolean; - - private timer_object: AstalIO.Time | undefined; - - @property(Number) - declare popup_timer: number; - - @property(Boolean) - declare dragging: boolean; - - private _sliding_away = false; - - private async get_hovered(): Promise<boolean> { - const layers = JSON.parse(await hyprMessage('j/layers')) as LayerResult; - const cursorPos = JSON.parse(await hyprMessage('j/cursorpos')) as CursorPos; - - const win = this.get_window(); - - if (!win) { - return false; - } - - const monitor = display?.get_monitor_at_window(win); - - if (!monitor) { - return false; - } - - const plugName = get_hyprland_monitor(monitor)?.name; - - const notifLayer = layers[plugName ?? '']?.levels['3'] - ?.find((n) => n.namespace === 'notifications'); - - if (!notifLayer) { - return false; - } - - const index = [...NotifGestureWrapper.popups.keys()] - .sort((a, b) => b - a) - .indexOf(this.id); - - const popups = [...NotifGestureWrapper.popups.entries()] - .sort((a, b) => b[0] - a[0]) - .map(([key, val]) => [key, val.get_allocated_height()]); - - const thisY = notifLayer.y + popups - .map((v) => v[1]) - .slice(0, index) - .reduce((prev, curr) => prev + curr, 0); - - if (cursorPos.y >= thisY && cursorPos.y <= thisY + (popups[index]?.at(1) ?? 0)) { - if (cursorPos.x >= notifLayer.x && - cursorPos.x <= notifLayer.x + notifLayer.w) { - return true; - } - } - - return false; - } - - private setCursor(cursor: string) { - if (!display) { - return; - } - this.window.set_cursor(Gdk.Cursor.new_from_name( - display, - cursor, - )); - } - - public slideAway(side: 'Left' | 'Right', duplicate = false): void { - if (!this.sensitive || this._sliding_away) { - return; - } - - // Make it uninteractable - this.sensitive = false; - this._sliding_away = true; - - let rev = this.get_child() as Widget.Revealer | null; - - if (!rev) { - return; - } - - const revChild = rev.get_child() as Widget.Box | null; - - if (!revChild) { - return; - } - - revChild.set_css(side === 'Left' ? slideLeft : slideRight); - - timeout(ANIM_DURATION - 100, () => { - rev = this.get_child() as Widget.Revealer | null; - - if (!rev) { - return; - } - - rev.revealChild = false; - - timeout(ANIM_DURATION, () => { - if (!duplicate) { - // Kill notif if specified - if (!this.is_popup) { - const notifications = AstalNotifd.get_default(); - - notifications.get_notification(this.id)?.dismiss(); - - // Update HasNotifs - HasNotifs.set(notifications.get_notifications().length > 0); - } - else { - // Make sure we cleanup any references to this instance - NotifGestureWrapper.popups.delete(this.id); - } - } - - // Get rid of disappeared widget - this.destroy(); - }); - }); - } - - constructor({ - id, - slide_in_from = 'Left', - popup_timer = 0, - setup_notif = () => { /**/ }, - ...rest - }: NotifGestureWrapperProps) { - const notifications = AstalNotifd.get_default(); - - super({ - on_button_press_event: () => { - this.setCursor('grabbing'); - }, - - // OnRelease - on_button_release_event: () => { - this.setCursor('grab'); - }, - - // OnHover - on_enter_notify_event: () => { - this.setCursor('grab'); - }, - - // OnHoverLost - on_leave_notify_event: () => { - this.setCursor('grab'); - }, - - onDestroy: () => { - this.timer_object?.cancel(); - }, - }); - - this.id = id; - this.slide_in_from = slide_in_from; - this.dragging = false; - - this.popup_timer = popup_timer; - this.is_popup = this.popup_timer !== 0; - - // Handle timeout before sliding away if it is a popup - if (this.popup_timer !== 0) { - this.timer_object = interval(1000, async() => { - try { - if (!(await this.get_hovered())) { - if (this.popup_timer === 0) { - this.slideAway('Left'); - } - else { - --this.popup_timer; - } - } - } - catch (_e) { - this.timer_object?.cancel(); - } - }); - } - - this.hook(notifications, 'notified', (_, notifId) => { - if (notifId === this.id) { - this.slideAway(this.is_popup ? 'Left' : 'Right', true); - } - }); - - const gesture = Gtk.GestureDrag.new(this); - - this.add( - <revealer - transitionType={Gtk.RevealerTransitionType.SLIDE_DOWN} - transitionDuration={500} - revealChild={false} - > - <box - {...rest} - setup={(self) => { - self - // When dragging - .hook(gesture, 'drag-update', () => { - let offset = gesture.get_offset()[1]; - - if (!offset || offset === 0) { - return; - } - - // Slide right - if (offset > 0) { - self.set_css(` - opacity: 1; transition: none; - margin-left: ${offset}px; - margin-right: -${offset}px; - `); - } - - // Slide left - else { - offset = Math.abs(offset); - self.set_css(` - opacity: 1; transition: none; - margin-right: ${offset}px; - margin-left: -${offset}px; - `); - } - - // Put a threshold on if a click is actually dragging - this.dragging = Math.abs(offset) > SLIDE_MIN_THRESHOLD; - - this.setCursor('grabbing'); - }) - - // On drag end - .hook(gesture, 'drag-end', () => { - const offset = gesture.get_offset()[1]; - - if (!offset) { - return; - } - - // If crosses threshold after letting go, slide away - if (Math.abs(offset) > MAX_OFFSET) { - this.slideAway(offset > 0 ? 'Right' : 'Left'); - } - else { - self.set_css(defaultStyle); - this.dragging = false; - - this.setCursor('grab'); - } - }); - - if (this.is_popup) { - NotifGestureWrapper.on_sliding_in(++NotifGestureWrapper.sliding_in); - } - - // Reverse of slideAway, so it started at squeeze, then we go to slide - self.set_css(this.slide_in_from === 'Left' ? - slideLeft : - slideRight); - - idle(() => { - if (!notifications.get_notification(id)) { - return; - } - - const rev = self?.get_parent() as Widget.Revealer | null; - - if (!rev) { - return; - } - - rev.revealChild = true; - - timeout(ANIM_DURATION, () => { - if (!notifications.get_notification(id)) { - return; - } - - // Then we go to center - self.set_css(defaultStyle); - - if (this.is_popup) { - timeout(ANIM_DURATION, () => { - NotifGestureWrapper.on_sliding_in( - --NotifGestureWrapper.sliding_in, - ); - }); - } - }); - }); - }} - /> - </revealer>, - ); - - setup_notif(this); - } -} - -export default NotifGestureWrapper; diff --git a/modules/ags/config/widgets/notifs/notification.tsx b/modules/ags/config/widgets/notifs/notification.tsx deleted file mode 100644 index 47017fcc..00000000 --- a/modules/ags/config/widgets/notifs/notification.tsx +++ /dev/null @@ -1,208 +0,0 @@ -import { App, Gtk, Gdk, Widget } from 'astal/gtk3'; -import { Variable } from 'astal'; - -import GLib from 'gi://GLib'; - -import AstalApps from 'gi://AstalApps'; -const Applications = AstalApps.Apps.new(); - -import AstalNotifd from 'gi://AstalNotifd'; - -import NotifGestureWrapper from './gesture'; -// import SmoothProgress from '../misc/smooth-progress'; - - -// Make a variable to connect to for Widgets -// to know when there are notifs or not -export const HasNotifs = Variable(false); - -const setTime = (time: number): string => GLib.DateTime - .new_from_unix_local(time) - .format('%H:%M') ?? ''; - -const NotifIcon = ({ notifObj }: { - notifObj: AstalNotifd.Notification -}) => { - let icon: string | undefined; - - if (notifObj.get_image() && notifObj.get_image() !== '') { - icon = notifObj.get_image(); - App.add_icons(icon); - } - else if (notifObj.get_app_icon() !== '' && Widget.Icon.lookup_icon(notifObj.get_app_icon())) { - icon = notifObj.get_app_icon(); - } - else { - icon = Applications.fuzzy_query( - notifObj.get_app_name(), - )[0]?.get_icon_name(); - } - - return ( - <box - valign={Gtk.Align.CENTER} - className="icon" - css={` - min-width: 78px; - min-height: 78px; - `} - > - {icon && ( - <icon - icon={icon} - css="font-size: 58px;" - halign={Gtk.Align.CENTER} - hexpand - valign={Gtk.Align.CENTER} - vexpand - /> - )} - </box> - ); -}; - -const setupButton = (self: Gtk.Widget) => { - const display = Gdk.Display.get_default(); - - // OnHover - self.connect('enter-notify-event', () => { - if (!display) { - return; - } - self.get_window()?.set_cursor(Gdk.Cursor.new_from_name( - display, - 'pointer', - )); - }); - - // OnHoverLost - self.connect('leave-notify-event', () => { - if (!display) { - return; - } - self.get_window()?.set_cursor(null); - }); -}; - -const BlockedApps = [ - 'Spotify', -]; - -export const Notification = ({ - id = 0, - popup_timer = 0, - slide_in_from = 'Left' as 'Left' | 'Right', -}): NotifGestureWrapper | undefined => { - const notifications = AstalNotifd.get_default(); - - const notifObj = notifications.get_notification(id); - - if (!notifObj) { - return; - } - - if (BlockedApps.find((app) => app === notifObj.app_name)) { - notifObj.dismiss(); - - return; - } - - HasNotifs.set(notifications.get_notifications().length > 0); - - // const progress = SmoothProgress({ className: 'smooth-progress' }); - - return ( - <NotifGestureWrapper - id={id} - popup_timer={popup_timer} - slide_in_from={slide_in_from} - /* setup_notif={(self) => { - if (self.is_popup) { - self.connect('notify::popup-timer', () => { - progress.fraction = self.popup_timer / 5; - }); - } - else { - progress.destroy(); - } - }}*/ - > - <box vertical className={`notification ${notifObj.get_urgency()} widget`}> - {/* Content */} - <box> - <NotifIcon notifObj={notifObj} /> - - {/* Top of Content */} - <box vertical css="min-width: 400px"> - - <box> - {/* Title */} - <label - className="title" - halign={Gtk.Align.START} - valign={Gtk.Align.END} - xalign={0} - hexpand - max_width_chars={24} - truncate - wrap - label={notifObj.get_summary()} - use_markup={notifObj.get_summary().startsWith('<')} - /> - - {/* Time */} - <label - className="time" - valign={Gtk.Align.CENTER} - halign={Gtk.Align.END} - label={setTime(notifObj.get_time())} - /> - - {/* Close button */} - <button - className="close-button" - valign={Gtk.Align.START} - halign={Gtk.Align.END} - setup={setupButton} - - onButtonReleaseEvent={() => { - notifObj.dismiss(); - }} - > - <icon icon="window-close-symbolic" /> - </button> - - </box> - - {/* Description */} - <label - className="description" - hexpand - use_markup - xalign={0} - label={notifObj.get_body()} - wrap - /> - </box> - </box> - - {/* progress */} - - {/* Actions */} - <box className="actions"> - {notifObj.get_actions().map((action) => ( - <button - className="action-button" - hexpand - setup={setupButton} - - onButtonReleaseEvent={() => notifObj.invoke(action.id)} - > - <label label={action.label} /> - </button> - ))} - </box> - </box> - </NotifGestureWrapper> - ) as NotifGestureWrapper; -}; diff --git a/modules/ags/config/widgets/notifs/popups.tsx b/modules/ags/config/widgets/notifs/popups.tsx deleted file mode 100644 index 033b81fc..00000000 --- a/modules/ags/config/widgets/notifs/popups.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import AstalNotifd from 'gi://AstalNotifd'; - -import NotifGestureWrapper from './gesture'; -import { Notification } from './notification'; - - -export default () => { - const notifications = AstalNotifd.get_default(); - - return ( - <box - // Needed so it occupies space at the start - // It needs to be bigger than the notifs to not jiggle - css="min-width: 550px;" - vertical - - setup={(self) => { - const notifQueue: number[] = []; - - const addPopup = (id: number) => { - if (!id || !notifications.get_notification(id)) { - return; - } - - if (NotifGestureWrapper.sliding_in === 0) { - const NewNotif = Notification({ id, popup_timer: 5 }); - - if (NewNotif) { - // Use this instead of add to put it at the top - self.pack_end(NewNotif, false, false, 0); - self.show_all(); - - NotifGestureWrapper.popups.set(id, NewNotif); - } - } - else { - notifQueue.push(id); - } - }; - - NotifGestureWrapper.on_sliding_in = (n) => { - if (n === 0) { - const id = notifQueue.shift(); - - if (id) { - addPopup(id); - } - } - }; - - const handleResolved = (id: number) => { - const notif = NotifGestureWrapper.popups.get(id); - - if (!notif) { - return; - } - - notif.slideAway('Left'); - NotifGestureWrapper.popups.delete(id); - }; - - self - .hook(notifications, 'notified', (_, id) => addPopup(id)) - .hook(notifications, 'resolved', (_, id) => handleResolved(id)); - }} - /> - ); -}; diff --git a/modules/ags/config/widgets/notifs/wim.tsx b/modules/ags/config/widgets/notifs/wim.tsx deleted file mode 100644 index 61bd30a8..00000000 --- a/modules/ags/config/widgets/notifs/wim.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { Astal } from 'astal/gtk3'; - -import PopupWindow from '../misc/popup-window'; - -import Popups from './popups'; -import Center from './center'; - - -export const NotifPopups = () => ( - <window - name="notifications" - namespace="notifications" - layer={Astal.Layer.OVERLAY} - anchor={Astal.WindowAnchor.TOP | Astal.WindowAnchor.LEFT} - > - <Popups /> - </window> -); - -export const NotifCenter = () => ( - <PopupWindow - name="notif-center" - anchor={Astal.WindowAnchor.TOP | Astal.WindowAnchor.RIGHT} - > - <Center /> - </PopupWindow> -); diff --git a/modules/ags/config/widgets/on-screen-display/_index.scss b/modules/ags/config/widgets/on-screen-display/_index.scss deleted file mode 100644 index b9013177..00000000 --- a/modules/ags/config/widgets/on-screen-display/_index.scss +++ /dev/null @@ -1,21 +0,0 @@ -.osd { - .osd-item { - padding: 12px 20px; - - label { - min-width: 170px; - } - - progressbar { - min-height: 6px; - min-width: 170px; - } - - icon { - font-size: 2rem; - color: white; - margin-left: -0.4rem; - margin-right: 0.8rem; - } - } -} diff --git a/modules/ags/config/widgets/on-screen-display/index.tsx b/modules/ags/config/widgets/on-screen-display/index.tsx deleted file mode 100644 index 6fa4f97b..00000000 --- a/modules/ags/config/widgets/on-screen-display/index.tsx +++ /dev/null @@ -1,177 +0,0 @@ -import { bind, timeout } from 'astal'; -import { App, Astal, Gtk, Widget } from 'astal/gtk3'; - -import AstalWp from 'gi://AstalWp'; - -import { ProgressBar } from '../misc/subclasses'; -import PopupWindow from '../misc/popup-window'; -import Brightness from '../../services/brightness'; - -/* Types */ -declare global { - function popup_osd(osd: string): void; -} - - -const HIDE_DELAY = 2000; -const transition_duration = 300; - -export default () => { - let n_showing = 0; - let stack: Widget.Stack | undefined; - - const popup = (osd: string) => { - if (!stack) { - return; - } - - ++n_showing; - stack.shown = osd; - - App.get_window('win-osd')?.set_visible(true); - - timeout(HIDE_DELAY, () => { - --n_showing; - - if (n_showing === 0) { - App.get_window('win-osd')?.set_visible(false); - } - }); - }; - - globalThis.popup_osd = popup; - - const brightness = Brightness.get_default(); - const speaker = AstalWp.get_default()?.get_audio()?.get_default_speaker(); - const microphone = AstalWp.get_default()?.get_audio()?.get_default_microphone(); - - if (!speaker || !microphone) { - throw new Error('Could not find default audio devices.'); - } - - return ( - <PopupWindow - name="osd" - anchor={Astal.WindowAnchor.BOTTOM} - exclusivity={Astal.Exclusivity.IGNORE} - close_on_unfocus="stay" - transition="slide bottom" - > - <stack - className="osd" - transitionDuration={transition_duration} - setup={(self) => { - timeout(3 * 1000, () => { - stack = self; - }); - }} - > - - <box - name="speaker" - css="margin-bottom: 80px;" - - setup={(self) => { - self.hook(speaker, 'notify::mute', () => { - popup('speaker'); - }); - }} - > - <box className="osd-item widget"> - <icon icon={bind(speaker, 'volumeIcon')} /> - - <ProgressBar - fraction={bind(speaker, 'volume')} - sensitive={bind(speaker, 'mute').as((v) => !v)} - valign={Gtk.Align.CENTER} - /> - </box> - </box> - - <box - name="microphone" - css="margin-bottom: 80px;" - - setup={(self) => { - self.hook(microphone, 'notify::mute', () => { - popup('microphone'); - }); - }} - > - <box className="osd-item widget"> - <icon icon={bind(microphone, 'volumeIcon')} /> - - <ProgressBar - fraction={bind(microphone, 'volume')} - sensitive={bind(microphone, 'mute').as((v) => !v)} - valign={Gtk.Align.CENTER} - /> - </box> - </box> - - <box - name="brightness" - css="margin-bottom: 80px;" - - setup={(self) => { - self.hook(brightness, 'notify::screen-icon', () => { - popup('brightness'); - }); - }} - > - <box className="osd-item widget"> - <icon icon={bind(brightness, 'screenIcon')} /> - - <ProgressBar - fraction={bind(brightness, 'screen')} - valign={Gtk.Align.CENTER} - /> - </box> - </box> - - { - brightness.hasKbd && ( - <box - name="keyboard" - css="margin-bottom: 80px;" - - setup={(self) => { - self.hook(brightness, 'notify::kbd-level', () => { - popup('keyboard'); - }); - }} - > - <box className="osd-item widget"> - <icon icon="keyboard-brightness-symbolic" /> - - <ProgressBar - fraction={bind(brightness, 'kbdLevel').as((v) => (v ?? 0) / 2)} - sensitive={bind(brightness, 'kbdLevel').as((v) => v !== 0)} - valign={Gtk.Align.CENTER} - /> - </box> - </box> - ) - } - - <box - name="caps" - css="margin-bottom: 80px;" - - setup={(self) => { - self.hook(brightness, 'notify::caps-icon', () => { - popup('caps'); - }); - }} - > - <box className="osd-item widget"> - <icon icon={bind(brightness, 'capsIcon')} /> - - <label label="Caps Lock" /> - </box> - </box> - - </stack> - </PopupWindow> - ); -}; diff --git a/modules/ags/config/widgets/on-screen-keyboard/_index.scss b/modules/ags/config/widgets/on-screen-keyboard/_index.scss deleted file mode 100644 index f4d952b0..00000000 --- a/modules/ags/config/widgets/on-screen-keyboard/_index.scss +++ /dev/null @@ -1,109 +0,0 @@ -@use 'sass:color'; -@use '../../style/colors'; - -.settings { - padding: 0.5rem; - - .button { - background-color: colors.$window_bg_color; - border: 0.1rem solid color.adjust(colors.$window_bg_color, $lightness: -3%); - border-radius: 0.7rem; - padding: 0.3rem; - - &.toggled { - background-color: colors.$accent-color; - } - } -} - -.osk { - padding-top: 4px; - - &.hidden { - opacity: 0; - } - - .side { - .key { - &:active label { - background-color: colors.$accent-color; - } - - label { - background-color: colors.$window_bg_color; - border-radius: 6px; - min-height: 3rem; - - transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out; - - box-shadow: 2px 1px 2px colors.$accent-color; - - padding: 4px; - - margin: 4px 4px 4px 4px; - - &.active { - box-shadow: 0 0 0 white; - margin: 6px 4px 2px 4px; - background-color: color.adjust(colors.$window_bg_color, $lightness: -3%); - } - - &.normal, - &.Super { - min-width: 3rem; - } - - &.Tab, - &.Backspace { - min-width: 7rem; - } - - &.Enter, - &.Caps { - min-width: 8rem; - } - - &.Shift { - min-width: 9rem; - } - - &.Space { - min-width: 20rem; - } - - &.PrtSc, - &.AltGr { - min-width: 3.2rem; - } - - &.altgr { - border: 0.08rem solid blue; - } - } - } - - &.right-side { - border-radius: 0 10px 0 0; - - .key .mod { - &.Ctrl { - min-width: 2.4rem; - } - } - } - - &.left-side { - border-radius: 10px 0 0 0; - - .key .mod { - &.Alt { - min-width: 3rem; - } - - &.Ctrl { - min-width: 4rem; - } - } - } - } -} diff --git a/modules/ags/config/widgets/on-screen-keyboard/arcs.tsx b/modules/ags/config/widgets/on-screen-keyboard/arcs.tsx deleted file mode 100644 index 924ae70f..00000000 --- a/modules/ags/config/widgets/on-screen-keyboard/arcs.tsx +++ /dev/null @@ -1,151 +0,0 @@ -import { Gdk, Gtk } from 'astal/gtk3'; - -import Cairo from 'cairo'; - -import { Bezier, BezierPoints, Point } from '../../lib'; - -/* Types */ -type Side = 'top' | 'right' | 'bottom' | 'left'; - - -const SIDES: Side[] = ['top', 'right', 'bottom', 'left']; - -export default ({ - css = 'background-color: black;', - allocation = { width: 0, height: 0 }, -}) => ( - <box> - <drawingarea - css={css} - - setup={(widget) => { - widget.set_size_request(allocation.width, allocation.height); - - widget.connect('draw', (_, cairoContext: Cairo.Context) => { - widget.set_size_request(allocation.width, allocation.height); - - const styleContext = widget.get_style_context(); - - const bgColor = styleContext.get_background_color(Gtk.StateFlags.NORMAL); - - const borderWidth = styleContext.get_border(Gtk.StateFlags.NORMAL); - - const borderColor = Object.fromEntries(SIDES.map((side) => [ - side, - styleContext.get_property( - `border-${side}-color`, Gtk.StateFlags.NORMAL, - ) as Gdk.RGBA, - ])) as Record<Side, Gdk.RGBA>; - - /* - * Draws a cubic bezier curve from the current point - * of the cairo context. - * - * @param dest the destination point of the curve - * @param curve the cubic bezier's control points. this - * is the same as a CSS easing function - */ - const drawBezier = (dest: Point, curve: BezierPoints): void => { - const start = new Point(cairoContext.getCurrentPoint()); - - // Converts the ratios to absolute coordinates - curve[0] = curve[0] * (dest.x - start.x) + start.x; - curve[1] = curve[1] * (dest.y - start.y) + start.y; - curve[2] = curve[2] * (dest.x - start.x) + start.x; - curve[3] = curve[3] * (dest.y - start.y) + start.y; - - cairoContext.curveTo(...curve, dest.x, dest.y); - }; - - const colorBorder = ( - side: Side, - start: Point, - dest: Point, - curve?: BezierPoints, - ) => { - cairoContext.moveTo(...start.values); - - if (curve) { - drawBezier(dest, curve); - } - else { - cairoContext.lineTo(...dest.values); - } - - cairoContext.setLineWidth(borderWidth[side]); - cairoContext.setSourceRGBA( - borderColor[side].red, - borderColor[side].green, - borderColor[side].blue, - borderColor[side].alpha, - ); - - cairoContext.stroke(); - }; - - const bottomLeft = new Point({ - x: 0, - y: allocation.height, - }); - - const topLeft = new Point({ - x: 0, - y: 0, - }); - - const middleLeft = new Point({ - x: allocation.width / 3, - y: allocation.height * 0.8, - }); - - const middleRight = new Point({ - x: (allocation.width / 3) * 2, - y: allocation.height * 0.8, - }); - - const topRight = new Point({ - x: allocation.width, - y: 0, - }); - - const bottomRight = new Point({ - x: allocation.width, - y: allocation.height, - }); - - const bezier = new Bezier(0.76, 0, 0.24, 1); - - // bottom left to top left - cairoContext.moveTo(...bottomLeft.values); - cairoContext.lineTo(...topLeft.values); - - // top left to middle left - drawBezier(middleLeft, bezier.points); - - // middle left to middle right - cairoContext.lineTo(...middleRight.values); - - // middle right to top right - drawBezier(topRight, bezier.points); - - // top right to bottom right - cairoContext.lineTo(...bottomRight.values); - - // bottom right to bottom left - cairoContext.closePath(); - - // Add color - cairoContext.setSourceRGBA(bgColor.red, bgColor.green, bgColor.blue, bgColor.alpha); - cairoContext.fill(); - - colorBorder('left', bottomLeft, topLeft); - colorBorder('top', topLeft, middleLeft, bezier.points); - colorBorder('top', middleLeft, middleRight); - colorBorder('top', middleRight, topRight, bezier.points); - colorBorder('right', topRight, bottomRight); - colorBorder('bottom', bottomLeft, bottomRight); - }); - }} - /> - </box> -); diff --git a/modules/ags/config/widgets/on-screen-keyboard/gesture.ts b/modules/ags/config/widgets/on-screen-keyboard/gesture.ts deleted file mode 100644 index 917c2945..00000000 --- a/modules/ags/config/widgets/on-screen-keyboard/gesture.ts +++ /dev/null @@ -1,223 +0,0 @@ -import { execAsync, idle } from 'astal'; -import { Astal, Gtk } from 'astal/gtk3'; - -import Tablet from '../../services/tablet'; -import { hyprMessage } from '../../lib'; - -import OskWindow from './osk-window'; -import { Keys } from './keys'; - - -const KEY_N = 249; -const KEYCODES = Array.from(Array(KEY_N).keys()).map((keycode) => `${keycode}:0`); - -const ANIM_DURATION = 700; - -const releaseAllKeys = () => { - execAsync([ - 'ydotool', 'key', - ...KEYCODES, - ]).catch(print); -}; - -export default (window: OskWindow) => { - const tablet = Tablet.get_default(); - - let signals = [] as number[]; - let calculatedHeight = 0; - - idle(() => { - calculatedHeight = window.get_allocated_height(); - tablet.oskState = false; - - setTimeout(() => { - window.get_grandchildren()[0].toggleClassName('hidden', false); - window.set_exclusivity(Astal.Exclusivity.EXCLUSIVE); - }, ANIM_DURATION * 3); - }); - - const gesture = Gtk.GestureDrag.new(window); - - window.hook(tablet, 'notify::osk-state', () => { - if (tablet.oskState) { - window.setSlideDown(); - - window.get_child().set_css(` - transition: margin-bottom ${ANIM_DURATION}ms cubic-bezier(0.36, 0, 0.66, -0.56); - margin-bottom: 0px; - `); - } - else { - releaseAllKeys(); - - window.setSlideUp(); - - window.get_child().set_css(` - transition: margin-bottom ${ANIM_DURATION}ms cubic-bezier(0.36, 0, 0.66, -0.56); - margin-bottom: -${calculatedHeight}px; - `); - } - }); - - window.killGestureSigs = () => { - signals.forEach((id) => { - gesture.disconnect(id); - }); - signals = []; - window.startY = null; - }; - - window.setSlideUp = () => { - window.killGestureSigs(); - - // Begin drag - signals.push( - gesture.connect('drag-begin', () => { - hyprMessage('j/cursorpos').then((out) => { - window.startY = JSON.parse(out).y; - }); - }), - ); - - // Update drag - signals.push( - gesture.connect('drag-update', () => { - hyprMessage('j/cursorpos').then((out) => { - if (!window.startY) { - return; - } - - const currentY = JSON.parse(out).y; - const offset = window.startY - currentY; - - if (offset < 0) { - window.get_child().set_css(` - transition: margin-bottom 0.5s ease-in-out; - margin-bottom: -${calculatedHeight}px; - `); - - return; - } - - if (offset > calculatedHeight) { - window.get_child().set_css(` - margin-bottom: 0px; - `); - } - else { - window.get_child().set_css(` - margin-bottom: ${offset - calculatedHeight}px; - `); - } - }); - }), - ); - - // End drag - signals.push( - gesture.connect('drag-end', () => { - hyprMessage('j/cursorpos').then((out) => { - if (!window.startY) { - return; - } - - const currentY = JSON.parse(out).y; - const offset = window.startY - currentY; - - if (offset > calculatedHeight) { - window.get_child().set_css(` - transition: margin-bottom 0.5s ease-in-out; - margin-bottom: 0px; - `); - tablet.oskState = true; - } - else { - window.get_child().set_css(` - transition: margin-bottom 0.5s ease-in-out; - margin-bottom: -${calculatedHeight}px; - `); - } - - window.startY = null; - }); - }), - ); - }; - - window.setSlideDown = () => { - window.killGestureSigs(); - - // Begin drag - signals.push( - gesture.connect('drag-begin', () => { - hyprMessage('j/cursorpos').then((out) => { - const hasActiveKey = Keys.get().map((v) => v.get()).includes(true); - - if (!hasActiveKey) { - window.startY = JSON.parse(out).y; - } - }); - }), - ); - - // Update drag - signals.push( - gesture.connect('drag-update', () => { - hyprMessage('j/cursorpos').then((out) => { - if (!window.startY) { - return; - } - - const currentY = JSON.parse(out).y; - const offset = window.startY - currentY; - - if (offset > 0) { - window.get_child().set_css(` - transition: margin-bottom 0.5s ease-in-out; - margin-bottom: 0px; - `); - - return; - } - - window.get_child().set_css(` - margin-bottom: ${offset}px; - `); - }); - }), - ); - - // End drag - signals.push( - gesture.connect('drag-end', () => { - hyprMessage('j/cursorpos').then((out) => { - if (!window.startY) { - return; - } - - const currentY = JSON.parse(out).y; - const offset = window.startY - currentY; - - if (offset < -(calculatedHeight * 2 / 3)) { - window.get_child().set_css(` - transition: margin-bottom 0.5s ease-in-out; - margin-bottom: -${calculatedHeight}px; - `); - - tablet.oskState = false; - } - else { - window.get_child().set_css(` - transition: margin-bottom 0.5s ease-in-out; - margin-bottom: 0px; - `); - } - - window.startY = null; - }); - }), - ); - }; - - return window; -}; diff --git a/modules/ags/config/widgets/on-screen-keyboard/index.tsx b/modules/ags/config/widgets/on-screen-keyboard/index.tsx deleted file mode 100644 index d341e230..00000000 --- a/modules/ags/config/widgets/on-screen-keyboard/index.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { execAsync } from 'astal'; -import { Astal } from 'astal/gtk3'; - -import OskWindow from './osk-window'; -import Gesture from './gesture'; -import Keyboard from './keyboard'; - - -export default () => { - execAsync('ydotoold').catch(() => { /**/ }); - - return Gesture(( - <OskWindow - name="osk" - namespace="noanim-osk" - - layer={Astal.Layer.OVERLAY} - anchor={ - Astal.WindowAnchor.BOTTOM | - Astal.WindowAnchor.LEFT | - Astal.WindowAnchor.RIGHT - } - > - <Keyboard /> - </OskWindow> - ) as OskWindow); -}; diff --git a/modules/ags/config/widgets/on-screen-keyboard/keyboard-layouts.ts b/modules/ags/config/widgets/on-screen-keyboard/keyboard-layouts.ts deleted file mode 100644 index c81f5f67..00000000 --- a/modules/ags/config/widgets/on-screen-keyboard/keyboard-layouts.ts +++ /dev/null @@ -1,551 +0,0 @@ -// keyboard is missing right Ctrl mod https://handwiki.org/wiki/images/4/41/KB_Canadian_Multilingual_Standard.svg - -export const defaultOskLayout = 'qwerty_custom'; -export const oskLayouts = { - qwerty_custom: { - name: 'QWERTY - Custom', - name_short: 'CSA', - comment: 'Like physical keyboard', - // A normal key looks like this: {label: "a", labelShift: "A", shape: "normal", keycode: 30, type: "normal"} - // A modkey looks like this: {label: "Ctrl", shape: "control", keycode: 29, type: "modkey"} - // key types are: normal, tab, caps, shift, control, fn (normal w/ half height), space, expand - keys: [ - [ - { - keytype: 'normal', - label: 'Esc', - shape: 'fn', - keycode: 1, - }, - { - keytype: 'normal', - label: 'F1', - shape: 'fn', - keycode: 59, - }, - { - keytype: 'normal', - label: 'F2', - shape: 'fn', - keycode: 60, - }, - { - keytype: 'normal', - label: 'F3', - shape: 'fn', - keycode: 61, - }, - { - keytype: 'normal', - label: 'F4', - shape: 'fn', - keycode: 62, - }, - { - keytype: 'normal', - label: 'F5', - shape: 'fn', - keycode: 63, - }, - { - keytype: 'normal', - label: 'F6', - shape: 'fn', - keycode: 64, - }, - { - keytype: 'normal', - label: 'F7', - shape: 'fn', - keycode: 65, - }, - { - keytype: 'normal', - label: 'F8', - shape: 'fn', - keycode: 66, - }, - { - keytype: 'normal', - label: 'F9', - shape: 'fn', - keycode: 67, - }, - { - keytype: 'normal', - label: 'F10', - shape: 'fn', - keycode: 68, - }, - { - keytype: 'normal', - label: 'F11', - shape: 'fn', - keycode: 87, - }, - { - keytype: 'normal', - label: 'F12', - shape: 'fn', - keycode: 88, - }, - { - keytype: 'normal', - label: 'Home', - shape: 'fn', - keycode: 110, - }, - { - keytype: 'normal', - label: 'End', - shape: 'fn', - keycode: 115, - }, - { - keytype: 'normal', - label: 'Del', - shape: 'fn', - keycode: 111, - }, - ], - [ - { - keytype: 'normal', - label: '/', - labelShift: '\\', - labelAltGr: '|', - shape: 'normal', - keycode: 41, - }, - { - keytype: 'normal', - label: '1', - labelShift: '!', - shape: 'normal', - keycode: 2, - }, - { - keytype: 'normal', - label: '2', - labelShift: '@', - shape: 'normal', - keycode: 3, - }, - { - keytype: 'normal', - label: '3', - labelShift: '#', - labelAltGr: '¤', - shape: 'normal', - keycode: 4, - }, - { - keytype: 'normal', - label: '4', - labelShift: '$', - shape: 'normal', - keycode: 5, - }, - { - keytype: 'normal', - label: '5', - labelShift: '%', - shape: 'normal', - keycode: 6, - }, - { - keytype: 'normal', - label: '6', - labelShift: '?', - shape: 'normal', - keycode: 7, - }, - { - keytype: 'normal', - label: '7', - labelShift: '&', - labelAltGr: '{', - shape: 'normal', - keycode: 8, - }, - { - keytype: 'normal', - label: '8', - labelShift: '*', - labelAltGr: '}', - shape: 'normal', - keycode: 9, - }, - { - keytype: 'normal', - label: '9', - labelShift: '(', - labelAltGr: '[', - shape: 'normal', - keycode: 10, - }, - { - keytype: 'normal', - label: '0', - labelShift: ')', - labelAltGr: ']', - shape: 'normal', - keycode: 11, - }, - { - keytype: 'normal', - label: '-', - labelShift: '_', - shape: 'normal', - keycode: 12, - }, - { - keytype: 'normal', - label: '=', - labelShift: '+', - labelAltGr: '¬', - shape: 'normal', - keycode: 13, - }, - { - keytype: 'normal', - label: 'Backspace', - shape: 'expand', - keycode: 14, - }, - ], - [ - { - keytype: 'normal', - label: 'Tab', - shape: 'tab', - keycode: 15, - }, - { - keytype: 'normal', - label: 'q', - labelShift: 'Q', - shape: 'normal', - keycode: 16, - }, - { - keytype: 'normal', - label: 'w', - labelShift: 'W', - shape: 'normal', - keycode: 17, - }, - { - keytype: 'normal', - label: 'e', - labelShift: 'E', - labelAltGr: '€', - shape: 'normal', - keycode: 18, - }, - { - keytype: 'normal', - label: 'r', - labelShift: 'R', - shape: 'normal', - keycode: 19, - }, - { - keytype: 'normal', - label: 't', - labelShift: 'T', - shape: 'normal', - keycode: 20, - }, - { - keytype: 'normal', - label: 'y', - labelShift: 'Y', - shape: 'normal', - keycode: 21, - }, - { - keytype: 'normal', - label: 'u', - labelShift: 'U', - shape: 'normal', - keycode: 22, - }, - { - keytype: 'normal', - label: 'i', - labelShift: 'I', - shape: 'normal', - keycode: 23, - }, - { - keytype: 'normal', - label: 'o', - labelShift: 'O', - shape: 'normal', - keycode: 24, - }, - { - keytype: 'normal', - label: 'p', - labelShift: 'P', - shape: 'normal', - keycode: 25, - }, - { - keytype: 'normal', - label: '^', - labelShift: '"', - labelAltGr: '`', - shape: 'normal', - keycode: 26, - }, - { - keytype: 'normal', - label: 'ç', - labelShift: 'Ç', - labelAltGr: '~', - shape: 'normal', - keycode: 27, - }, - { - keytype: 'normal', - label: 'à', - labelShift: 'À', - shape: 'expand', - keycode: 43, - }, - ], - [ - { - keytype: 'normal', - label: 'Caps', - shape: 'caps', - keycode: 58, - }, - { - keytype: 'normal', - label: 'a', - labelShift: 'A', - shape: 'normal', - keycode: 30, - }, - { - keytype: 'normal', - label: 's', - labelShift: 'S', - shape: 'normal', - keycode: 31, - }, - { - keytype: 'normal', - label: 'd', - labelShift: 'D', - shape: 'normal', - keycode: 32, - }, - { - keytype: 'normal', - label: 'f', - labelShift: 'F', - shape: 'normal', - keycode: 33, - }, - { - keytype: 'normal', - label: 'g', - labelShift: 'G', - shape: 'normal', - keycode: 34, - }, - { - keytype: 'normal', - label: 'h', - labelShift: 'H', - shape: 'normal', - keycode: 35, - }, - { - keytype: 'normal', - label: 'j', - labelShift: 'J', - shape: 'normal', - keycode: 36, - }, - { - keytype: 'normal', - label: 'k', - labelShift: 'K', - shape: 'normal', - keycode: 37, - }, - { - keytype: 'normal', - label: 'l', - labelShift: 'L', - shape: 'normal', - keycode: 38, - }, - { - keytype: 'normal', - label: ';', - labelShift: ':', - labelAltGr: '°', - shape: 'normal', - keycode: 39, - }, - { - keytype: 'normal', - label: 'è', - labelShift: 'È', - shape: 'normal', - keycode: 40, - }, - { - keytype: 'normal', - label: 'Enter', - shape: 'expand', - keycode: 28, - }, - ], - [ - { - keytype: 'modkey', - label: 'Shift', - shape: 'shift', - keycode: 42, - }, - { - keytype: 'normal', - label: 'z', - labelShift: 'Z', - labelAltGr: '«', - shape: 'normal', - keycode: 44, - }, - { - keytype: 'normal', - label: 'x', - labelShift: 'X', - labelAltGr: '»', - shape: 'normal', - keycode: 45, - }, - { - keytype: 'normal', - label: 'c', - labelShift: 'C', - shape: 'normal', - keycode: 46, - }, - { - keytype: 'normal', - label: 'v', - labelShift: 'V', - shape: 'normal', - keycode: 47, - }, - { - keytype: 'normal', - label: 'b', - labelShift: 'B', - shape: 'normal', - keycode: 48, - }, - { - keytype: 'normal', - label: 'n', - labelShift: 'N', - shape: 'normal', - keycode: 49, - }, - { - keytype: 'normal', - label: 'm', - labelShift: 'M', - shape: 'normal', - keycode: 50, - }, - { - keytype: 'normal', - label: ',', - labelShift: "'", - labelAltGr: '<', - shape: 'normal', - keycode: 51, - }, - { - keytype: 'normal', - label: '.', - labelShift: '"', - labelAltGr: '>', - shape: 'normal', - keycode: 52, - }, - { - keytype: 'normal', - label: 'é', - labelShift: 'É', - shape: 'normal', - keycode: 53, - }, - { - keytype: 'modkey', - label: 'Shift', - shape: 'expand', - keycode: 54, - }, - ], - [ - { - keytype: 'modkey', - label: 'Ctrl', - shape: 'control', - keycode: 29, - }, - { - keytype: 'modkey', - label: 'Super', - shape: 'normal', - keycode: 125, - }, - { - keytype: 'modkey', - label: 'Alt', - shape: 'normal', - keycode: 56, - }, - { - keytype: 'normal', - label: 'Space', - shape: 'space', - keycode: 57, - }, - { - keytype: 'normal', - label: 'Space', - shape: 'space', - keycode: 57, - }, - { - keytype: 'modkey', - label: 'AltGr', - shape: 'normal', - keycode: 100, - }, - { - keytype: 'normal', - label: 'PrtSc', - shape: 'fn', - keycode: 99, - }, - { - keytype: 'modkey', - label: 'Ctrl', - shape: 'control', - keycode: 97, - }, - ], - ], - }, -}; diff --git a/modules/ags/config/widgets/on-screen-keyboard/keyboard.tsx b/modules/ags/config/widgets/on-screen-keyboard/keyboard.tsx deleted file mode 100644 index e990b26e..00000000 --- a/modules/ags/config/widgets/on-screen-keyboard/keyboard.tsx +++ /dev/null @@ -1,165 +0,0 @@ -import { bind, idle, Variable } from 'astal'; -import { Astal, Gtk, Widget } from 'astal/gtk3'; - -import { ToggleButton } from '../misc/subclasses'; -import Separator from '../misc/separator'; - -import Arc from './arcs'; -import Key from './keys'; - -import { defaultOskLayout, oskLayouts } from './keyboard-layouts'; - - -const keyboardLayout = defaultOskLayout; -const keyboardJson = oskLayouts[keyboardLayout]; - -const L_KEY_PER_ROW = [8, 7, 6, 6, 6, 4]; -const SPACING = 4; -const COLOR = 'rgba(0, 0, 0, 0.5)'; - -export default () => { - const ThirdWidth = Variable(0); - - return ( - <box - vertical - onRealize={(self) => idle(() => { - ThirdWidth.set(self.get_allocated_width() / 3); - })} - > - <centerbox - className="osk hidden" - hexpand - > - {/* LEFT */} - <box - widthRequest={bind(ThirdWidth)} - css={`background: ${COLOR};`} - className="left-side side" - halign={Gtk.Align.START} - vertical - > - {...keyboardJson.keys.map((row, rowIndex) => { - const keys = [] as Widget.Box[]; - - row.forEach((key, keyIndex) => { - if (keyIndex < L_KEY_PER_ROW[rowIndex]) { - keys.push(Key(key)); - } - }); - - return ( - <box vertical> - <box className="row"> - <Separator size={SPACING} /> - - {...keys} - </box> - - <Separator size={SPACING} vertical /> - </box> - ); - })} - </box> - - {/* MIDDLE */} - <box - widthRequest={bind(ThirdWidth)} - halign={Gtk.Align.CENTER} - valign={Gtk.Align.FILL} - vertical - > - <box - valign={Gtk.Align.START} - > - {bind(ThirdWidth).as((width) => ( - <Arc - allocation={{ width, height: 160 }} - css={`background: ${COLOR};`} - /> - - ))} - </box> - - <box - halign={Gtk.Align.FILL} - hexpand - vexpand - css={`background: ${COLOR};`} - className="settings" - > - <centerbox - halign={Gtk.Align.FILL} - hexpand - vexpand - > - <box /> - - <ToggleButton - className="button" - cursor="pointer" - active - valign={Gtk.Align.CENTER} - halign={Gtk.Align.CENTER} - - onToggled={(self) => { - self.toggleClassName( - 'toggled', - self.get_active(), - ); - - if (self.get_toplevel() === self) { - return; - } - - (self.get_toplevel() as Widget.Window | undefined) - ?.set_exclusivity( - self.get_active() ? - Astal.Exclusivity.EXCLUSIVE : - Astal.Exclusivity.NORMAL, - ); - }} - > - Exclusive - </ToggleButton> - - <box /> - </centerbox> - </box> - </box> - - {/* RIGHT */} - <box - widthRequest={bind(ThirdWidth)} - css={`background: ${COLOR};`} - className="right-side side" - halign={Gtk.Align.END} - vertical - > - {...keyboardJson.keys.map((row, rowIndex) => { - const keys = [] as Widget.Box[]; - - row.forEach((key, keyIndex) => { - if (keyIndex >= L_KEY_PER_ROW[rowIndex]) { - keys.push(Key(key)); - } - }); - - return ( - <box vertical> - <box - className="row" - halign={Gtk.Align.END} - > - {...keys} - </box> - - <Separator size={SPACING} vertical /> - </box> - ); - })} - </box> - </centerbox> - </box> - ) as Widget.Box; -}; diff --git a/modules/ags/config/widgets/on-screen-keyboard/keys.tsx b/modules/ags/config/widgets/on-screen-keyboard/keys.tsx deleted file mode 100644 index d0b09368..00000000 --- a/modules/ags/config/widgets/on-screen-keyboard/keys.tsx +++ /dev/null @@ -1,243 +0,0 @@ -import { bind, execAsync, interval, Variable } from 'astal'; -import { Gtk, Widget } from 'astal/gtk3'; - -import Brightness from '../../services/brightness'; - -import Separator from '../misc/separator'; - -/* Types */ -import AstalIO from 'gi://AstalIO'; - -interface Key { - keytype: string - label: string - labelShift?: string - labelAltGr?: string - shape: string - keycode: number -} - - -const brightness = Brightness.get_default(); - -const SPACING = 4; -const LSHIFT_CODE = 42; -const LALT_CODE = 56; -const LCTRL_CODE = 29; - -export const Keys = Variable<Variable<boolean>[]>([]); - -// Keep track of modifier statuses -const Super = Variable(false); -const LAlt = Variable(false); -const LCtrl = Variable(false); -const AltGr = Variable(false); -const RCtrl = Variable(false); - -const Caps = Variable(false); - -brightness.connect('notify::caps-level', (_, state) => { - Caps.set(state); -}); - -// Assume both shifts are the same for key.labelShift -const LShift = Variable(false); -const RShift = Variable(false); - -const Shift = Variable(false); - -LShift.subscribe(() => { - Shift.set(LShift.get() || RShift.get()); -}); -RShift.subscribe(() => { - Shift.set(LShift.get() || RShift.get()); -}); - - -const ModKey = (key: Key) => { - let Mod: Variable<boolean>; - - if (key.label === 'Super') { - Mod = Super; - } - - // Differentiate left and right mods - else if (key.label === 'Shift' && key.keycode === LSHIFT_CODE) { - Mod = LShift; - } - - else if (key.label === 'Alt' && key.keycode === LALT_CODE) { - Mod = LAlt; - } - - else if (key.label === 'Ctrl' && key.keycode === LCTRL_CODE) { - Mod = LCtrl; - } - - else if (key.label === 'Shift') { - Mod = RShift; - } - - else if (key.label === 'AltGr') { - Mod = AltGr; - } - - else if (key.label === 'Ctrl') { - Mod = RCtrl; - } - - Keys.set([...Keys.get(), Mod!]); - - const label = ( - <label - className={`mod ${key.label}`} - label={key.label} - /> - ) as Widget.Label; - - const button = ( - <eventbox - className="key" - cursor="pointer" - - onButtonPressEvent={() => { - execAsync(`ydotool key ${key.keycode}:${Mod.get() ? 0 : 1}`); - - label.toggleClassName('active', !Mod.get()); - Mod.set(!Mod.get()); - }} - > - {label} - </eventbox> - ); - - return ( - <box> - {button} - <Separator size={SPACING} /> - </box> - ) as Widget.Box; -}; - -const RegularKey = (key: Key) => { - const IsActive = Variable(false); - const IsLongPressing = Variable(false); - - Keys.set([...Keys.get(), IsActive]); - - const widget = ( - <eventbox - className="key" - cursor="pointer" - - onButtonReleaseEvent={() => { - IsLongPressing.set(false); - IsActive.set(false); - }} - > - <label - className={bind(IsActive).as((v) => [ - 'normal', - key.label, - (v ? 'active' : ''), - ].join(' '))} - - label={key.label} - - setup={(self) => { - self - .hook(Shift, () => { - if (key.labelShift) { - self.set_label(Shift.get() ? - key.labelShift : - key.label); - } - }) - .hook(Caps, () => { - if (key.label === 'Caps') { - IsActive.set(Caps.get()); - - return; - } - - if (key.labelShift && key.label.match(/[A-Za-z]/)) { - self.set_label(Caps.get() ? - key.labelShift : - key.label); - } - }) - .hook(AltGr, () => { - if (key.labelAltGr) { - self.toggleClassName('altgr', AltGr.get()); - - self.set_label(AltGr.get() ? - key.labelAltGr : - key.label); - } - }); - }} - /> - </eventbox> - ) as Widget.EventBox; - - const gesture = Gtk.GestureLongPress.new(widget); - - gesture.delay_factor = 1.0; - - const onClick = (callback: () => void) => { - const pointer = gesture.get_point(null); - const x = pointer[1]; - const y = pointer[2]; - - if ((!x || !y) || (x === 0 && y === 0)) { - return; - } - - callback(); - }; - - widget.hook(gesture, 'begin', () => { - IsActive.set(true); - }); - - widget.hook(gesture, 'cancelled', () => { - onClick(() => { - execAsync(`ydotool key ${key.keycode}:1`); - execAsync(`ydotool key ${key.keycode}:0`); - - IsActive.set(false); - }); - }); - - // Long Press - widget.hook(gesture, 'pressed', () => { - onClick(() => { - IsLongPressing.set(true); - }); - }); - - let spamClick: AstalIO.Time | undefined; - - IsLongPressing.subscribe((v) => { - if (v) { - spamClick = interval(100, () => { - execAsync(`ydotool key ${key.keycode}:1`); - execAsync(`ydotool key ${key.keycode}:0`); - }); - } - else { - spamClick?.cancel(); - } - }); - - return ( - <box> - {widget} - <Separator size={SPACING} /> - </box> - ) as Widget.Box; -}; - -export default (key: Key): Widget.Box => key.keytype === 'normal' ? - RegularKey(key) : - ModKey(key); diff --git a/modules/ags/config/widgets/on-screen-keyboard/osk-window.tsx b/modules/ags/config/widgets/on-screen-keyboard/osk-window.tsx deleted file mode 100644 index 20a598ba..00000000 --- a/modules/ags/config/widgets/on-screen-keyboard/osk-window.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { App, Widget } from 'astal/gtk3'; -import { register } from 'astal/gobject'; - - -@register() -export default class OskWindow extends Widget.Window { - public startY: number | null = null; - - declare public killGestureSigs: () => void; - declare public setSlideUp: () => void; - declare public setSlideDown: () => void; - - get_child(): Widget.Box { - return super.get_child() as Widget.Box; - } - - get_grandchildren(): (Widget.Box | Widget.CenterBox)[] { - return this.get_child().get_children() as (Widget.Box | Widget.CenterBox)[]; - } - - constructor({ ...rest }: Widget.WindowProps) { - super({ application: App, ...rest }); - } -} diff --git a/modules/ags/config/widgets/powermenu/_index.scss b/modules/ags/config/widgets/powermenu/_index.scss deleted file mode 100644 index 110b11c1..00000000 --- a/modules/ags/config/widgets/powermenu/_index.scss +++ /dev/null @@ -1,36 +0,0 @@ -@use 'sass:color'; -@use '../../style/colors'; - -.powermenu { - padding: 10px; - - icon { - font-size: 70px; - min-width: 130px; - min-height: 130px; - } - - label { - font-size: 50px; - } - - button { - margin: 5px 10px; - transition: all ease .2s; - - &:hover, - &:active { - background-color: color.adjust(colors.$window_bg_color, $lightness: 3%); - } - } - - .shutdown { - color: colors.$red_1; - } - .reboot { - color: colors.$purple_1; - } - .logout { - color: colors.$yellow_1; - } -} diff --git a/modules/ags/config/widgets/powermenu/index.tsx b/modules/ags/config/widgets/powermenu/index.tsx deleted file mode 100644 index 637c8571..00000000 --- a/modules/ags/config/widgets/powermenu/index.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { execAsync } from 'astal'; -import { Astal, Gtk } from 'astal/gtk3'; - -import { hyprMessage } from '../../lib'; - -import PopupWindow from '../misc/popup-window'; - - -const PowermenuWidget = () => { - const label = <label /> as Astal.Label; - - return ( - <centerbox className="powermenu widget"> - <stack transitionType={Gtk.StackTransitionType.SLIDE_DOWN}> - <box name="buttons"> - <button - className="shutdown button" - cursor="pointer" - onButtonReleaseEvent={(self) => { - label.set_label('Shutting down...'); - (self.get_parent()?.get_parent() as Astal.Stack).set_shown('message'); - execAsync(['systemctl', 'poweroff']).catch(print); - }} - > - <icon icon="system-shutdown-symbolic" /> - </button> - - <button - className="reboot button" - cursor="pointer" - onButtonReleaseEvent={(self) => { - label.set_label('Rebooting...'); - (self.get_parent()?.get_parent() as Astal.Stack).set_shown('message'); - execAsync(['systemctl', 'reboot']).catch(print); - }} - > - <icon icon="system-restart-symbolic" /> - </button> - - <button - className="logout button" - cursor="pointer" - onButtonReleaseEvent={(self) => { - label.set_label('Logging out...'); - (self.get_parent()?.get_parent() as Astal.Stack).set_shown('message'); - hyprMessage('dispatch exit').catch(print); - }} - > - <icon icon="system-log-out-symbolic" /> - </button> - </box> - - <box name="message" hexpand={false} halign={Gtk.Align.CENTER}> - {label} - </box> - </stack> - </centerbox> - ); -}; - -export default () => ( - <PopupWindow - name="powermenu" - transition="slide bottom" - // To put it at the center of the screen - exclusivity={Astal.Exclusivity.IGNORE} - > - <PowermenuWidget /> - </PopupWindow> -); diff --git a/modules/ags/config/widgets/screenshot/_index.scss b/modules/ags/config/widgets/screenshot/_index.scss deleted file mode 100644 index d81df32a..00000000 --- a/modules/ags/config/widgets/screenshot/_index.scss +++ /dev/null @@ -1,27 +0,0 @@ -@use '../../style/colors'; - -.screenshot { - font-size: 30px; - - .header { - .header-btn { - margin: 5px; - transition: background 400ms; - - &.active { - background: colors.$window_bg_color; - } - } - } - - scrollable { - margin: 5px; - min-height: 400px; - - box { - .item-btn { - margin: 3px; - } - } - } -} diff --git a/modules/ags/config/widgets/screenshot/capture.sh b/modules/ags/config/widgets/screenshot/capture.sh deleted file mode 100755 index d3a1e729..00000000 --- a/modules/ags/config/widgets/screenshot/capture.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash - -if [[ "$1" == "region" ]]; then - if [[ "$2" == "true" ]]; then - wayfreeze & PID=$! - sleep .1 - fi - - selection="$(slurp)" - - if [[ "$2" == "true" ]]; then - kill "$PID" - fi - - exec grim -g "$selection" - | satty -f - || true -else - exec grim "$@" - | satty -f - || true -fi diff --git a/modules/ags/config/widgets/screenshot/index.tsx b/modules/ags/config/widgets/screenshot/index.tsx deleted file mode 100644 index 7ff517c2..00000000 --- a/modules/ags/config/widgets/screenshot/index.tsx +++ /dev/null @@ -1,185 +0,0 @@ -import { bind, execAsync, Variable } from 'astal'; -import { App, Gtk, Widget } from 'astal/gtk3'; - -import AstalApps from 'gi://AstalApps'; -import AstalHyprland from 'gi://AstalHyprland'; - -import PopupWindow from '../misc/popup-window'; -import Separator from '../misc/separator'; - -import { hyprMessage } from '../../lib'; - - -const ICON_SEP = 6; -const takeScreenshot = (selector: string[], delay = 1000): void => { - App.get_window('win-screenshot')?.set_visible(false); - - setTimeout(() => { - execAsync([ - `${SRC}/widgets/screenshot/capture.sh`, - ].concat(selector)).catch(console.error); - }, delay); -}; - -export default () => { - const hyprland = AstalHyprland.get_default(); - - const windowList = <box vertical /> as Widget.Box; - - const updateWindows = async() => { - if (!App.get_window('win-screenshot')?.get_visible()) { - return; - } - - const applications = AstalApps.Apps.new(); - - windowList.children = (JSON.parse(await hyprMessage('j/clients')) as AstalHyprland.Client[]) - .filter((client) => client.workspace.id === hyprland.get_focused_workspace().get_id()) - .map((client) => ( - <button - className="item-btn" - cursor="pointer" - - onButtonReleaseEvent={() => { - takeScreenshot(['-w', client.address]); - }} - > - <box halign={Gtk.Align.CENTER}> - <icon icon={applications.fuzzy_query(client.class)[0].iconName} /> - - <Separator size={ICON_SEP} /> - - <label - label={client.title} - truncate - max_width_chars={50} - /> - </box> - </button> - )); - }; - - hyprland.connect('notify::clients', updateWindows); - hyprland.connect('notify::focused-workspace', updateWindows); - - const Shown = Variable<string>('monitors'); - - const stack = ( - <stack - shown={bind(Shown)} - transitionType={Gtk.StackTransitionType.SLIDE_LEFT_RIGHT} - > - <scrollable name="monitors"> - <box vertical> - {bind(hyprland, 'monitors').as((monitors) => monitors.map((monitor) => ( - <button - className="item-btn" - cursor="pointer" - - onButtonReleaseEvent={() => { - takeScreenshot(['-o', monitor.get_name()]); - }} - > - <label - label={`${monitor.get_name()}: ${monitor.get_description()}`} - truncate - maxWidthChars={50} - /> - </button> - )))} - </box> - </scrollable> - - <scrollable name="windows"> - {windowList} - </scrollable> - </stack> - ) as Widget.Stack; - - const StackButton = ({ label = '', iconName = '' }) => ( - <button - cursor="pointer" - className={bind(Shown).as((shown) => - `header-btn${shown === label ? ' active' : ''}`)} - - onButtonReleaseEvent={() => { - Shown.set(label); - }} - > - <box halign={Gtk.Align.CENTER}> - <icon icon={iconName} /> - - <Separator size={ICON_SEP} /> - - {label} - </box> - </button> - ) as Widget.Button; - - let frozen = false; - const freezeIcon = <icon icon="checkbox-symbolic" /> as Widget.Icon; - const freezeButton = ( - <button - cursor="pointer" - className="header-btn" - - onButtonReleaseEvent={() => { - frozen = !frozen; - freezeIcon.set_icon(frozen ? - 'checkbox-checked-symbolic' : - 'checkbox-symbolic'); - }} - > - <box halign={Gtk.Align.CENTER}> - {freezeIcon} - - <Separator size={ICON_SEP} /> - - freeze - </box> - </button> - ) as Widget.Button; - - const regionButton = ( - <button - cursor="pointer" - className="header-btn" - - onButtonReleaseEvent={() => { - takeScreenshot(['region', frozen ? 'true' : 'false'], 0); - }} - > - <box halign={Gtk.Align.CENTER}> - <icon icon="tool-crop-symbolic" /> - </box> - </button> - ) as Widget.Button; - - return ( - <PopupWindow - name="screenshot" - on_open={() => { - updateWindows(); - }} - > - <box - className="screenshot widget" - vertical - > - <box - className="header" - homogeneous - > - <StackButton label="monitors" iconName="display-symbolic" /> - <StackButton label="windows" iconName="window-symbolic" /> - <box> - {regionButton} - {freezeButton} - </box> - </box> - - {stack} - </box> - </PopupWindow> - ); -}; diff --git a/modules/ags/default.nix b/modules/ags/default.nix deleted file mode 100644 index 98fbf8fd..00000000 --- a/modules/ags/default.nix +++ /dev/null @@ -1,84 +0,0 @@ -# TODO: move everything to Gtk4 -self: { - config, - lib, - pkgs, - ... -}: let - inherit (self.inputs) ags astal virtualkeyboard-adapter; - inherit (lib) hasPrefix mkIf removePrefix; - - # Configs - cfgDesktop = config.roles.desktop; - flakeDir = config.environment.variables.FLAKE; - - agsConfigDir = "${removePrefix "/home/${cfgDesktop.user}/" flakeDir}/modules/ags/config"; - - hmOpts = {lib, ...}: { - options.programs.ags = { - package = lib.mkOption { - type = with lib.types; nullOr package; - default = null; - }; - - astalLibs = lib.mkOption { - type = with lib.types; nullOr (listOf package); - default = null; - }; - - lockPkg = lib.mkOption { - type = with lib.types; nullOr package; - default = null; - }; - - configDir = lib.mkOption { - type = lib.types.str; - default = agsConfigDir; - }; - }; - }; -in { - config = mkIf cfgDesktop.ags.enable { - assertions = [ - { - assertion = hasPrefix "/home/${cfgDesktop.user}/" flakeDir; - message = '' - Your $FLAKE environment variable needs to point to a directory in - the main users' home to use the AGS module. - ''; - } - ]; - - # Machine config - security.pam.services.astal-auth = {}; - services.upower.enable = true; - - nixpkgs.overlays = [ - ags.overlays.default - astal.overlays.default - virtualkeyboard-adapter.overlays.default - ]; - - i18n.inputMethod = mkIf cfgDesktop.isTouchscreen { - enable = true; - type = "fcitx5"; - - fcitx5 = { - waylandFrontend = true; - plasma6Support = true; - addons = [ - pkgs.virtualkeyboard-adapter - ]; - }; - }; - - home-manager.users.${cfgDesktop.user}.imports = [ - hmOpts - (import ./packages.nix self) - (import ./hyprland.nix self) - ]; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/ags/gtk4/.envrc b/modules/ags/gtk4/.envrc deleted file mode 100644 index 674cafba..00000000 --- a/modules/ags/gtk4/.envrc +++ /dev/null @@ -1 +0,0 @@ -use flake "$FLAKE#node" diff --git a/modules/ags/gtk4/.gitignore b/modules/ags/gtk4/.gitignore deleted file mode 100644 index 8dfae95e..00000000 --- a/modules/ags/gtk4/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -@girs -node_modules diff --git a/modules/ags/gtk4/app.ts b/modules/ags/gtk4/app.ts deleted file mode 100644 index 5ded45f3..00000000 --- a/modules/ags/gtk4/app.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { programArgs } from 'system'; - -import lock from './configurations/lock'; - - -switch (programArgs[0]) { - case 'lock': lock(); break; -} diff --git a/modules/ags/gtk4/configurations/lock.ts b/modules/ags/gtk4/configurations/lock.ts deleted file mode 100644 index f6f35d7f..00000000 --- a/modules/ags/gtk4/configurations/lock.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { App } from 'astal/gtk4'; - -import Lockscreen from '../widgets/lockscreen'; - -import style from '../style.scss'; - - -export default () => { - App.start({ - css: style, - instanceName: 'lock', - - requestHandler(js, res) { - App.eval(js).then(res).catch(res); - }, - - main: () => { - Lockscreen(); - }, - }); -}; diff --git a/modules/ags/gtk4/env.d.ts b/modules/ags/gtk4/env.d.ts deleted file mode 100644 index 9cdf81ce..00000000 --- a/modules/ags/gtk4/env.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -declare const SRC: string; - -declare module 'inline:*' { - const content: string; - - export default content; -} - -declare module '*.scss' { - const content: string; - - export default content; -} - -declare module '*.blp' { - const content: string; - - export default content; -} - -declare module '*.css' { - const content: string; - - export default content; -} diff --git a/modules/ags/gtk4/eslint.config.ts b/modules/ags/gtk4/eslint.config.ts deleted file mode 100644 index c8613917..00000000 --- a/modules/ags/gtk4/eslint.config.ts +++ /dev/null @@ -1,456 +0,0 @@ -import eslint from '@eslint/js'; -import jsdoc from 'eslint-plugin-jsdoc'; -import stylistic from '@stylistic/eslint-plugin'; -import tseslint from 'typescript-eslint'; - - -export default tseslint.config({ - files: ['**/*.{js,ts,tsx}'], - ignores: ['node_modules/**', 'types/**'], - - extends: [ - eslint.configs.recommended, - jsdoc.configs['flat/recommended-typescript'], - stylistic.configs['recommended-flat'], - ...tseslint.configs.recommended, - ...tseslint.configs.stylistic, - ], - - rules: { - // JSDoc settings - 'jsdoc/tag-lines': ['warn', 'any', { startLines: 1 }], - 'jsdoc/check-line-alignment': ['warn', 'always', { - tags: ['param', 'arg', 'argument', 'property', 'prop'], - }], - 'jsdoc/no-types': 'off', - - // Newer settings - '@typescript-eslint/no-extraneous-class': ['off'], - '@typescript-eslint/no-implied-eval': ['off'], - 'class-methods-use-this': 'off', - '@stylistic/no-multiple-empty-lines': 'off', - '@stylistic/jsx-indent-props': 'off', - 'no-use-before-define': 'off', - '@typescript-eslint/no-use-before-define': 'error', - '@stylistic/indent-binary-ops': 'off', - '@stylistic/max-statements-per-line': [ - 'error', - { max: 2 }, - ], - - // Pre-flat config - '@typescript-eslint/no-unused-vars': [ - 'error', - { - args: 'all', - argsIgnorePattern: '^_', - caughtErrors: 'all', - caughtErrorsIgnorePattern: '^_', - destructuredArrayIgnorePattern: '^_', - varsIgnorePattern: '^_', - ignoreRestSiblings: true, - }, - ], - - 'array-callback-return': [ - 'error', - { - allowImplicit: true, - checkForEach: true, - }, - ], - 'no-constructor-return': [ - 'error', - ], - 'no-unreachable-loop': [ - 'error', - { - ignore: [ - 'ForInStatement', - 'ForOfStatement', - ], - }, - ], - 'block-scoped-var': [ - 'error', - ], - 'curly': [ - 'warn', - ], - 'default-case-last': [ - 'warn', - ], - 'default-param-last': [ - 'error', - ], - 'eqeqeq': [ - 'error', - 'smart', - ], - 'func-names': [ - 'warn', - 'never', - ], - 'func-style': [ - 'warn', - 'expression', - ], - 'logical-assignment-operators': [ - 'warn', - 'always', - ], - 'no-array-constructor': [ - 'error', - ], - 'no-empty-function': [ - 'warn', - ], - 'no-empty-static-block': [ - 'warn', - ], - 'no-extend-native': [ - 'error', - ], - 'no-extra-bind': [ - 'warn', - ], - 'no-implicit-coercion': [ - 'warn', - ], - 'no-iterator': [ - 'error', - ], - 'no-labels': [ - 'error', - ], - 'no-lone-blocks': [ - 'error', - ], - 'no-lonely-if': [ - 'error', - ], - 'no-loop-func': [ - 'error', - ], - /* - 'no-magic-numbers': [ - 'error', - { - ignore: [ - -1, - 0.1, - 0, - 1, - 2, - 3, - 4, - 5, - 10, - 12, - 33, - 66, - 100, - 255, - 360, - 450, - 500, - 1000, - ], - ignoreDefaultValues: true, - ignoreClassFieldInitialValues: true, - }, - ], - */ - 'no-multi-assign': [ - 'error', - ], - 'no-new-wrappers': [ - 'error', - ], - 'no-object-constructor': [ - 'error', - ], - 'no-proto': [ - 'error', - ], - 'no-return-assign': [ - 'error', - ], - 'no-sequences': [ - 'error', - ], - 'no-shadow': [ - 'error', - { - builtinGlobals: true, - allow: [ - 'Window', - ], - }, - ], - 'no-undef-init': [ - 'warn', - ], - 'no-undefined': [ - 'error', - ], - 'no-useless-constructor': [ - 'warn', - ], - 'no-useless-escape': [ - 'off', - ], - 'no-useless-return': [ - 'error', - ], - 'no-var': [ - 'error', - ], - 'no-void': [ - 'off', - ], - 'no-with': [ - 'error', - ], - 'object-shorthand': [ - 'error', - 'always', - ], - 'one-var': [ - 'error', - 'never', - ], - 'operator-assignment': [ - 'warn', - 'always', - ], - 'prefer-arrow-callback': [ - 'error', - ], - 'prefer-const': [ - 'error', - ], - 'prefer-object-has-own': [ - 'error', - ], - 'prefer-regex-literals': [ - 'error', - ], - 'prefer-template': [ - 'warn', - ], - 'no-prototype-builtins': 'off', - '@typescript-eslint/no-var-requires': [ - 'off', - ], - '@stylistic/array-bracket-newline': [ - 'warn', - 'consistent', - ], - '@stylistic/array-bracket-spacing': [ - 'warn', - 'never', - ], - '@stylistic/arrow-parens': [ - 'warn', - 'always', - ], - '@stylistic/brace-style': [ - 'warn', - 'stroustrup', - { allowSingleLine: true }, - ], - '@stylistic/comma-dangle': [ - 'warn', - 'always-multiline', - ], - '@stylistic/comma-spacing': [ - 'warn', - { - before: false, - after: true, - }, - ], - '@stylistic/comma-style': [ - 'error', - 'last', - ], - '@stylistic/dot-location': [ - 'error', - 'property', - ], - '@stylistic/function-call-argument-newline': [ - 'warn', - 'consistent', - ], - '@stylistic/function-paren-newline': [ - 'warn', - 'consistent', - ], - '@stylistic/indent': [ - 'warn', - 4, - { - SwitchCase: 1, - ignoreComments: true, - ignoredNodes: ['TemplateLiteral > *'], - }, - ], - '@stylistic/key-spacing': [ - 'warn', - { - beforeColon: false, - afterColon: true, - }, - ], - '@stylistic/keyword-spacing': [ - 'warn', - { - before: true, - }, - ], - '@stylistic/linebreak-style': [ - 'error', - 'unix', - ], - '@stylistic/lines-between-class-members': [ - 'warn', - 'always', - { - exceptAfterSingleLine: true, - }, - ], - '@stylistic/max-len': [ - 'warn', - { - code: 105, - ignoreComments: true, - ignoreTrailingComments: true, - ignoreUrls: true, - }, - ], - '@stylistic/multiline-ternary': [ - 'warn', - 'always-multiline', - ], - '@stylistic/new-parens': [ - 'error', - ], - '@stylistic/no-mixed-operators': [ - 'warn', - ], - '@stylistic/no-mixed-spaces-and-tabs': [ - 'error', - ], - '@stylistic/no-multi-spaces': [ - 'error', - ], - '@stylistic/no-tabs': [ - 'error', - ], - '@stylistic/no-trailing-spaces': [ - 'error', - ], - '@stylistic/no-whitespace-before-property': [ - 'warn', - ], - '@stylistic/nonblock-statement-body-position': [ - 'error', - 'below', - ], - '@stylistic/object-curly-newline': [ - 'warn', - { - consistent: true, - }, - ], - '@stylistic/object-curly-spacing': [ - 'warn', - 'always', - ], - '@stylistic/operator-linebreak': [ - 'warn', - 'after', - ], - '@stylistic/padded-blocks': [ - 'error', - 'never', - ], - '@stylistic/padding-line-between-statements': [ - 'warn', - { - blankLine: 'always', - prev: '*', - next: 'return', - }, - { - blankLine: 'always', - prev: [ - 'const', - 'let', - 'var', - ], - next: '*', - }, - { - blankLine: 'any', - prev: [ - 'const', - 'let', - 'var', - ], - next: [ - 'const', - 'let', - 'var', - ], - }, - { - blankLine: 'always', - prev: [ - 'case', - 'default', - ], - next: '*', - }, - ], - '@stylistic/quote-props': [ - 'error', - 'consistent-as-needed', - ], - '@stylistic/quotes': [ - 'error', - 'single', - { - avoidEscape: true, - }, - ], - '@stylistic/semi': [ - 'error', - 'always', - ], - '@stylistic/semi-spacing': [ - 'warn', - ], - '@stylistic/space-before-blocks': [ - 'warn', - ], - '@stylistic/space-before-function-paren': [ - 'warn', - 'never', - ], - '@stylistic/space-infix-ops': [ - 'warn', - ], - '@stylistic/spaced-comment': [ - 'warn', - 'always', - ], - '@stylistic/switch-colon-spacing': [ - 'warn', - ], - '@stylistic/wrap-regex': [ - 'warn', - ], - }, -}); diff --git a/modules/ags/gtk4/lib/cairo.ts b/modules/ags/gtk4/lib/cairo.ts deleted file mode 100644 index b01c69b8..00000000 --- a/modules/ags/gtk4/lib/cairo.ts +++ /dev/null @@ -1,47 +0,0 @@ -type PointProps = [number, number] | { - x: number - y: number -} | number; - -export class Point { - public x = 0; - public y = 0; - - get values(): [number, number] { - return [this.x, this.y]; - } - - constructor(props?: PointProps, y?: number) { - if (typeof props === 'number') { - if (y) { - this.x = props; - this.y = y; - } - else { - throw new Error('Wrong props'); - } - } - else if (Array.isArray(props)) { - this.x = props[0]; - this.y = props[1]; - } - else if (props) { - this.x = props.x; - this.y = props.y; - } - } -} - -export type BezierPoints = [number, number, number, number]; - -export class Bezier { - private _points: BezierPoints; - - get points() { - return [...this._points] as BezierPoints; - } - - constructor(x1: number, y1: number, x2: number, y2: number) { - this._points = [x1, y1, x2, y2]; - } -} diff --git a/modules/ags/gtk4/lib/hypr.ts b/modules/ags/gtk4/lib/hypr.ts deleted file mode 100644 index 04f1bc30..00000000 --- a/modules/ags/gtk4/lib/hypr.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { Gdk } from 'astal/gtk4'; - -import AstalHyprland from 'gi://AstalHyprland'; - - -export const get_hyprland_monitor = (monitor: Gdk.Monitor): AstalHyprland.Monitor | undefined => { - const hyprland = AstalHyprland.get_default(); - - const manufacturer = monitor.get_manufacturer()?.replace(',', ''); - const model = monitor.get_model()?.replace(',', ''); - const start = `${manufacturer} ${model}`; - - return hyprland.get_monitors().find((m) => m.get_description()?.startsWith(start)); -}; - -export const get_hyprland_monitor_desc = (monitor: Gdk.Monitor): string => { - const hyprland = AstalHyprland.get_default(); - - const manufacturer = monitor.get_manufacturer()?.replace(',', ''); - const model = monitor.get_model()?.replace(',', ''); - const start = `${manufacturer} ${model}`; - - return `desc:${hyprland - .get_monitors() - .find((m) => m.get_description()?.startsWith(start))?.get_description()}`; -}; - -export const get_gdkmonitor_from_desc = (desc: string): Gdk.Monitor => { - const display = Gdk.Display.get_default(); - - for (let m = 0; m < (display?.get_monitors().get_n_items() ?? 0); m++) { - const monitor = display?.get_monitors().get_item(m) as Gdk.Monitor; - - if (monitor && desc === get_hyprland_monitor_desc(monitor)) { - return monitor; - } - } - - throw Error(`Monitor ${desc} not found`); -}; - -export const get_monitor_desc = (mon: AstalHyprland.Monitor): string => { - return `desc:${mon.get_description()}`; -}; - -export const hyprMessage = (message: string) => new Promise<string>(( - resolution = () => { /**/ }, - rejection = () => { /**/ }, -) => { - const hyprland = AstalHyprland.get_default(); - - try { - hyprland.message_async(message, (_, asyncResult) => { - const result = hyprland.message_finish(asyncResult); - - resolution(result); - }); - } - catch (e) { - rejection(e); - } -}); - -export const centerCursor = (): void => { - const hyprland = AstalHyprland.get_default(); - - let x: number; - let y: number; - const monitor = hyprland.get_focused_monitor(); - - switch (monitor.get_transform()) { - case 1: - x = monitor.get_x() - (monitor.get_height() / 2); - y = monitor.get_y() - (monitor.get_width() / 2); - break; - - case 2: - x = monitor.get_x() - (monitor.get_width() / 2); - y = monitor.get_y() - (monitor.get_height() / 2); - break; - - case 3: - x = monitor.get_x() + (monitor.get_height() / 2); - y = monitor.get_y() + (monitor.get_width() / 2); - break; - - default: - x = monitor.get_x() + (monitor.get_width() / 2); - y = monitor.get_y() + (monitor.get_height() / 2); - break; - } - - hyprMessage(`dispatch movecursor ${x} ${y}`); -}; diff --git a/modules/ags/gtk4/lib/index.ts b/modules/ags/gtk4/lib/index.ts deleted file mode 100644 index 0b00a1a5..00000000 --- a/modules/ags/gtk4/lib/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './cairo'; -export * from './hypr'; -export * from './notify'; -export * from './windows'; diff --git a/modules/ags/gtk4/lib/notify.ts b/modules/ags/gtk4/lib/notify.ts deleted file mode 100644 index 3c29275b..00000000 --- a/modules/ags/gtk4/lib/notify.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { subprocess } from 'astal'; - -/* Types */ -interface NotifyAction { - id: string - label: string - callback: () => void -} -interface NotifySendProps { - actions?: NotifyAction[] - appName?: string - body?: string - category?: string - hint?: string - iconName: string - replaceId?: number - title: string - urgency?: 'low' | 'normal' | 'critical' -} - -const escapeShellArg = (arg: string | undefined): string => `'${arg?.replace(/'/g, '\'\\\'\'') ?? ''}'`; - -export const notifySend = ({ - actions = [], - appName, - body, - category, - hint, - iconName, - replaceId, - title, - urgency = 'normal', -}: NotifySendProps) => new Promise<number>((resolve) => { - let printedId = false; - - const cmd = [ - 'notify-send', - '--print-id', - `--icon=${escapeShellArg(iconName)}`, - escapeShellArg(title), - escapeShellArg(body ?? ''), - // Optional params - appName ? `--app-name=${escapeShellArg(appName)}` : '', - category ? `--category=${escapeShellArg(category)}` : '', - hint ? `--hint=${escapeShellArg(hint)}` : '', - replaceId ? `--replace-id=${replaceId.toString()}` : '', - `--urgency=${urgency}`, - ].concat( - actions.map(({ id, label }) => `--action=${escapeShellArg(id)}=${escapeShellArg(label)}`), - ).join(' '); - - subprocess( - cmd, - (out) => { - if (!printedId) { - resolve(parseInt(out)); - printedId = true; - } - else { - actions.find((action) => action.id === out)?.callback(); - } - }, - (err) => { - console.error(`[Notify] ${err}`); - }, - ); -}); diff --git a/modules/ags/gtk4/lib/windows.ts b/modules/ags/gtk4/lib/windows.ts deleted file mode 100644 index 768e9f07..00000000 --- a/modules/ags/gtk4/lib/windows.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { idle } from 'astal'; -import { App, Gdk, Gtk } from 'astal/gtk4'; - -/* Types */ -import PopupWindow from '../widgets/misc/popup-window'; - -export interface Layer { - address: string - x: number - y: number - w: number - h: number - namespace: string -} -export interface Levels { - 0?: Layer[] | null - 1?: Layer[] | null - 2?: Layer[] | null - 3?: Layer[] | null -} -export interface Layers { - levels: Levels -} -export type LayerResult = Record<string, Layers>; -export interface CursorPos { - x: number - y: number -} - -export const closeAll = () => { - (App.get_windows() as PopupWindow[]) - .filter((w) => w && - w.close_on_unfocus && - w.close_on_unfocus !== 'stay') - .forEach((w) => { - App.get_window(w.name)?.set_visible(false); - }); -}; - -export const perMonitor = (window: (monitor: Gdk.Monitor) => Gtk.Widget) => idle(() => { - const display = Gdk.Display.get_default(); - const windows = new Map<Gdk.Monitor, Gtk.Widget>(); - - const createWindow = (monitor: Gdk.Monitor) => { - windows.set(monitor, window(monitor)); - }; - - for (let m = 0; m < (display?.get_monitors().get_n_items() ?? 0); m++) { - const monitor = display?.get_monitors().get_item(m) as Gdk.Monitor; - - if (monitor) { - createWindow(monitor); - } - } - - display?.connect('monitor-added', (_, monitor) => { - createWindow(monitor); - }); - - display?.connect('monitor-removed', (_, monitor) => { - windows.delete(monitor); - }); -}); diff --git a/modules/ags/gtk4/package-lock.json b/modules/ags/gtk4/package-lock.json deleted file mode 120000 index a908665d..00000000 --- a/modules/ags/gtk4/package-lock.json +++ /dev/null @@ -1 +0,0 @@ -../config/package-lock.json \ No newline at end of file diff --git a/modules/ags/gtk4/package.json b/modules/ags/gtk4/package.json deleted file mode 120000 index f3ea5f3b..00000000 --- a/modules/ags/gtk4/package.json +++ /dev/null @@ -1 +0,0 @@ -../config/package.json \ No newline at end of file diff --git a/modules/ags/gtk4/style.scss b/modules/ags/gtk4/style.scss deleted file mode 100644 index f22022f3..00000000 --- a/modules/ags/gtk4/style.scss +++ /dev/null @@ -1,22 +0,0 @@ -@use './widgets/lockscreen'; - -// https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gtk/theme/Adwaita/_colors-public.scss -$fg-color: #{"@theme_fg_color"}; -$bg-color: #{"@theme_bg_color"}; - -window.Bar { - background: transparent; - color: $fg-color; - font-weight: bold; - - >centerbox { - background: $bg-color; - border-radius: 10px; - margin: 8px; - } - - button { - border-radius: 8px; - margin: 2px; - } -} diff --git a/modules/ags/gtk4/tsconfig.json b/modules/ags/gtk4/tsconfig.json deleted file mode 100644 index f57c0397..00000000 --- a/modules/ags/gtk4/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "compilerOptions": { - "experimentalDecorators": true, - "lib": [ - "ES2022" - ], - "module": "ES2022", - "moduleResolution": "Bundler", - "noEmit": true, - "skipLibCheck": true, - "strict": true, - "target": "ES2022" - } -} diff --git a/modules/ags/gtk4/widgets/astalify/astalify.ts b/modules/ags/gtk4/widgets/astalify/astalify.ts deleted file mode 100644 index 5375c286..00000000 --- a/modules/ags/gtk4/widgets/astalify/astalify.ts +++ /dev/null @@ -1,179 +0,0 @@ -import { property, register } from 'astal'; -import { Gtk, hook } from 'astal/gtk4'; -import { type Connectable, type Subscribable } from 'astal/binding'; - -import construct from './construct'; -import setupControllers from './controller'; - -import { - type BindableProps, - childType, - type Cursor, - dummyBuilder, - type MixinParams, - noImplicitDestroy, - setChildren, -} from './generics'; - - -export default < - C extends new (...props: MixinParams) => Gtk.Widget, - ConstructorProps, ->( - cls: C, - clsName = cls.name, -) => { - @register({ GTypeName: `RealClass_${clsName}` }) - class Widget extends cls { - declare private _css: string | undefined; - declare private _provider: Gtk.CssProvider | undefined; - - @property(String) - get css(): string | undefined { - return this._css; - } - - set css(value: string) { - if (!this._provider) { - this._provider = new Gtk.CssProvider(); - - this.get_style_context().add_provider( - this._provider, - Gtk.STYLE_PROVIDER_PRIORITY_USER, - ); - } - - this._css = value; - this._provider.load_from_string(value); - } - - - declare private [childType]: string; - - @property(String) - get type(): string { return this[childType]; } - - set type(value: string) { this[childType] = value; } - - - @property(Object) - get children(): Gtk.Widget[] { return this.getChildren(this); } - - set children(value: Gtk.Widget[]) { this.setChildren(this, value); } - - - declare private [noImplicitDestroy]: boolean; - - @property(String) - get noImplicitDestroy(): boolean { return this[noImplicitDestroy]; } - - set noImplicitDestroy(value: boolean) { this[noImplicitDestroy] = value; } - - - protected getChildren(widget: Gtk.Widget): Gtk.Widget[] { - if ('get_child' in widget && typeof widget.get_child == 'function') { - return widget.get_child() ? [widget.get_child()] : []; - } - - const children: Gtk.Widget[] = []; - let ch = widget.get_first_child(); - - while (ch !== null) { - children.push(ch); - ch = ch.get_next_sibling(); - } - - return children; - } - - protected setChildren(widget: Gtk.Widget, children: Gtk.Widget[]) { - for (const child of children) { - widget.vfunc_add_child( - dummyBuilder, - child, - childType in widget ? widget[childType] as string : null, - ); - } - } - - [setChildren](children: Gtk.Widget[]) { - for (const child of (this.getChildren(this))) { - child?.unparent(); - - if (!children.includes(child) && noImplicitDestroy in this) { - child.run_dispose(); - } - } - - this.setChildren(this, children); - } - - - private _cursorName: Cursor = 'default'; - - @property(String) - get cursorName(): Cursor { - return this._cursorName; - } - - set cursorName(val: Cursor) { - this._cursorName = val; - this.set_cursor_from_name(val); - } - - - hook( - object: Connectable, - signal: string, - callback: (self: this, ...args: unknown[]) => void, - ): this; - - hook( - object: Subscribable, - callback: (self: this, ...args: unknown[]) => void, - ): this; - - hook( - object: Connectable | Subscribable, - signalOrCallback: string | ((self: this, ...args: unknown[]) => void), - callback?: (self: this, ...args: unknown[]) => void, - ) { - hook(this, object, signalOrCallback, callback); - - return this; - } - - - constructor(...params: MixinParams) { - const props = params[0] || {}; - - super('cssName' in props ? { cssName: props.cssName } : {}); - - if ('cssName' in props) { - delete props.cssName; - } - - if (props.noImplicitDestroy) { - this.noImplicitDestroy = true; - delete props.noImplicitDestroy; - } - - if (props.type) { - this.type = props.type; - delete props.type; - } - - construct(this, setupControllers(this, props)); - } - } - - type Constructor<Instance, Props> = new (...args: Props[]) => Instance; - - type WidgetClass = Constructor< - Widget & Gtk.Widget & InstanceType<C>, - Partial<BindableProps<ConstructorProps>> - >; - - // override the parameters of the `super` constructor - return Widget as unknown as WidgetClass; -}; diff --git a/modules/ags/gtk4/widgets/astalify/bindings.ts b/modules/ags/gtk4/widgets/astalify/bindings.ts deleted file mode 100644 index c23001cc..00000000 --- a/modules/ags/gtk4/widgets/astalify/bindings.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Variable } from 'astal'; -import { Binding } from 'astal/binding'; - - -export const mergeBindings = <Value = unknown>( - array: (Value | Binding<Value> | Binding<Value[]>)[], -): Value[] | Binding<Value[]> => { - const getValues = (args: Value[]) => { - let i = 0; - - return array.map((value) => value instanceof Binding ? - args[i++] : - value); - }; - - const bindings = array.filter((i) => i instanceof Binding); - - if (bindings.length === 0) { - return array as Value[]; - } - - if (bindings.length === 1) { - return (bindings[0] as Binding<Value[]>).as(getValues); - } - - return Variable.derive(bindings, getValues)(); -}; diff --git a/modules/ags/gtk4/widgets/astalify/construct.ts b/modules/ags/gtk4/widgets/astalify/construct.ts deleted file mode 100644 index 27d108d6..00000000 --- a/modules/ags/gtk4/widgets/astalify/construct.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { execAsync } from 'astal'; -import { type Gtk, type ConstructProps } from 'astal/gtk4'; -import { Binding, kebabify, snakeify } from 'astal/binding'; - -import { mergeBindings } from './bindings'; -import { type EventController } from './controller'; -import { type AstalifyProps, type BindableProps, type GenericWidget, setChildren } from './generics'; - - -export default < - Self extends GenericWidget, - Props extends Gtk.Widget.ConstructorProps, ->( - widget: Self, - props: Omit< - ConstructProps<Self, Props> & Partial<BindableProps<AstalifyProps>>, - keyof EventController<Self> - >, -) => { - type Key = keyof typeof props; - const keys = Object.keys(props) as Key[]; - const entries = Object.entries(props) as [Key, unknown][]; - - const setProp = (prop: Key, value: Self[keyof Self]) => { - try { - const setter = `set_${snakeify(prop.toString())}` as keyof Self; - - if (typeof widget[setter] === 'function') { - return widget[setter](value); - } - - return (widget[prop as keyof Self] = value); - } - catch (error) { - console.error(`could not set property "${prop.toString()}" on ${widget}:`, error); - } - }; - - const children = props.children ? - props.children instanceof Binding ? - [props.children] as (Binding<Gtk.Widget[]> | Binding<Gtk.Widget> | Gtk.Widget)[] : - props.children as Gtk.Widget[] : - []; - - if (props.child) { - children.unshift(props.child); - } - - // remove undefined values - for (const [key, value] of entries) { - if (typeof value === 'undefined') { - delete props[key]; - } - } - - // collect bindings - const bindings: [Key, Binding<unknown>][] = []; - - for (const key of keys) { - if (props[key] instanceof Binding) { - bindings.push([key, props[key]]); - delete props[key]; - } - } - - // collect signal handlers - const onHandlers: [string, string | (() => void)][] = []; - - for (const key of keys) { - if (key.toString().startsWith('on')) { - const sig = kebabify(key.toString()).split('-').slice(1).join('-'); - - onHandlers.push([sig, props[key] as string | (() => void)]); - delete props[key]; - } - } - - // set children - const mergedChildren = mergeBindings<Gtk.Widget>(children.flat(Infinity)); - - if (mergedChildren instanceof Binding) { - widget[setChildren](mergedChildren.get()); - - widget.connect('destroy', mergedChildren.subscribe((v) => { - widget[setChildren](v); - })); - } - else if (mergedChildren.length > 0) { - widget[setChildren](mergedChildren); - } - - // setup signal handlers - for (const [signal, callback] of onHandlers) { - const sig = signal.startsWith('notify') ? - signal.replace('-', '::') : - signal; - - if (typeof callback === 'function') { - widget.connect(sig, callback); - } - else { - widget.connect(sig, () => execAsync(callback) - .then(print).catch(console.error)); - } - } - - // setup bindings handlers - for (const [prop, binding] of bindings) { - if (prop === 'child' || prop === 'children') { - widget.connect('destroy', (binding as Binding<Gtk.Widget[]>).subscribe((v: Gtk.Widget[]) => { - widget[setChildren](v); - })); - } - widget.connect('destroy', binding.subscribe((v: unknown) => { - setProp(prop, v as Self[keyof Self]); - })); - setProp(prop, binding.get() as Self[keyof Self]); - } - - // filter undefined values - for (const [key, value] of entries) { - if (typeof value === 'undefined') { - delete props[key]; - } - } - - Object.assign(widget, props); - props.setup?.(widget); - - return widget; -}; diff --git a/modules/ags/gtk4/widgets/astalify/controller.ts b/modules/ags/gtk4/widgets/astalify/controller.ts deleted file mode 100644 index 48c0fdb0..00000000 --- a/modules/ags/gtk4/widgets/astalify/controller.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { Gdk, Gtk } from 'astal/gtk4'; - -export interface EventController<Self extends Gtk.Widget> { - onFocusEnter?: (self: Self) => void - onFocusLeave?: (self: Self) => void - - onKeyPressed?: (self: Self, keyval: number, keycode: number, state: Gdk.ModifierType) => void - onKeyReleased?: (self: Self, keyval: number, keycode: number, state: Gdk.ModifierType) => void - onKeyModifier?: (self: Self, state: Gdk.ModifierType) => void - - onLegacy?: (self: Self, event: Gdk.Event) => void - onButtonPressed?: (self: Self, state: Gdk.ButtonEvent) => void - onButtonReleased?: (self: Self, state: Gdk.ButtonEvent) => void - - onHoverEnter?: (self: Self, x: number, y: number) => void - onHoverLeave?: (self: Self) => void - onMotion?: (self: Self, x: number, y: number) => void - - onScroll?: (self: Self, dx: number, dy: number) => void - onScrollDecelerate?: (self: Self, vel_x: number, vel_y: number) => void -} - - -export default <T>(widget: Gtk.Widget, { - onFocusEnter, - onFocusLeave, - onKeyPressed, - onKeyReleased, - onKeyModifier, - onLegacy, - onButtonPressed, - onButtonReleased, - onHoverEnter, - onHoverLeave, - onMotion, - onScroll, - onScrollDecelerate, - ...props -}: EventController<Gtk.Widget> & T) => { - if (onFocusEnter || onFocusLeave) { - const focus = new Gtk.EventControllerFocus(); - - widget.add_controller(focus); - - if (onFocusEnter) { focus.connect('focus-enter', () => onFocusEnter(widget)); } - - if (onFocusLeave) { focus.connect('focus-leave', () => onFocusLeave(widget)); } - } - - if (onKeyPressed || onKeyReleased || onKeyModifier) { - const key = new Gtk.EventControllerKey(); - - widget.add_controller(key); - - if (onKeyPressed) { - key.connect('key-pressed', (_, val, code, state) => onKeyPressed(widget, val, code, state)); - } - - if (onKeyReleased) { - key.connect('key-released', (_, val, code, state) => - onKeyReleased(widget, val, code, state)); - } - - if (onKeyModifier) { - key.connect('modifiers', (_, state) => onKeyModifier(widget, state)); - } - } - - if (onLegacy || onButtonPressed || onButtonReleased) { - const legacy = new Gtk.EventControllerLegacy(); - - widget.add_controller(legacy); - - legacy.connect('event', (_, event) => { - if (event.get_event_type() === Gdk.EventType.BUTTON_PRESS) { - onButtonPressed?.(widget, event as Gdk.ButtonEvent); - } - - if (event.get_event_type() === Gdk.EventType.BUTTON_RELEASE) { - onButtonReleased?.(widget, event as Gdk.ButtonEvent); - } - - onLegacy?.(widget, event); - }); - } - - if (onMotion || onHoverEnter || onHoverLeave) { - const hover = new Gtk.EventControllerMotion(); - - widget.add_controller(hover); - - if (onHoverEnter) { - hover.connect('enter', (_, x, y) => onHoverEnter(widget, x, y)); - } - - if (onHoverLeave) { - hover.connect('leave', () => onHoverLeave(widget)); - } - - if (onMotion) { - hover.connect('motion', (_, x, y) => onMotion(widget, x, y)); - } - } - - if (onScroll || onScrollDecelerate) { - const scroll = new Gtk.EventControllerScroll(); - - widget.add_controller(scroll); - - if (onScroll) { - scroll.connect('scroll', (_, x, y) => onScroll(widget, x, y)); - } - - if (onScrollDecelerate) { - scroll.connect('decelerate', (_, x, y) => onScrollDecelerate(widget, x, y)); - } - } - - return props; -}; diff --git a/modules/ags/gtk4/widgets/astalify/generics.ts b/modules/ags/gtk4/widgets/astalify/generics.ts deleted file mode 100644 index 272c7fc4..00000000 --- a/modules/ags/gtk4/widgets/astalify/generics.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { Gtk } from 'astal/gtk4'; -import { Binding } from 'astal/binding'; - -import { EventController } from './controller'; - -// A mixin class must have a constructor with a single rest parameter of type 'any[]' -// eslint-disable-next-line "@typescript-eslint/no-explicit-any" -export type MixinParams = any[]; - -export type BindableChild = Gtk.Widget | Binding<Gtk.Widget>; - -export type BindableProps<T> = { - [K in keyof T]: Binding<T[K]> | T[K]; -}; - -export const noImplicitDestroy = Symbol('no no implicit destroy'); -export const setChildren = Symbol('children setter method'); -export const childType = Symbol('child type'); - -export const dummyBuilder = new Gtk.Builder(); - -export type GenericWidget = InstanceType<typeof Gtk.Widget> & { - [setChildren]: (children: Gtk.Widget[]) => void -}; - -export interface AstalifyProps { - css: string - child: Gtk.Widget - children: Gtk.Widget[] - cursorName: Cursor -} - -type SigHandler< - W extends InstanceType<typeof Gtk.Widget>, - Args extends unknown[], -> = ((self: W, ...args: Args) => unknown) | string | string[]; - -export type ConstructProps< - Self extends InstanceType<typeof Gtk.Widget>, - Props extends Gtk.Widget.ConstructorProps, - Signals extends Record<`on${string}`, unknown[]> = Record<`on${string}`, unknown[]>, -> = Partial<{ - // @ts-expect-error can't assign to unknown, but it works as expected though - [S in keyof Signals]: SigHandler<Self, Signals[S]> -}> & Partial<Record<`on${string}`, SigHandler<Self, unknown[]>>> & Partial<BindableProps<Omit< - Props, - 'cssName' | 'css_name' | 'cursor' ->>> & { - noImplicitDestroy?: true - type?: string - cssName?: string -} & EventController<Self> & { - onDestroy?: (self: Self) => unknown - setup?: (self: Self) => void -}; - -export type Cursor = - | 'default' - | 'help' - | 'pointer' - | 'context-menu' - | 'progress' - | 'wait' - | 'cell' - | 'crosshair' - | 'text' - | 'vertical-text' - | 'alias' - | 'copy' - | 'no-drop' - | 'move' - | 'not-allowed' - | 'grab' - | 'grabbing' - | 'all-scroll' - | 'col-resize' - | 'row-resize' - | 'n-resize' - | 'e-resize' - | 's-resize' - | 'w-resize' - | 'ne-resize' - | 'nw-resize' - | 'sw-resize' - | 'se-resize' - | 'ew-resize' - | 'ns-resize' - | 'nesw-resize' - | 'nwse-resize' - | 'zoom-in' - | 'zoom-out'; diff --git a/modules/ags/gtk4/widgets/astalify/index.ts b/modules/ags/gtk4/widgets/astalify/index.ts deleted file mode 100644 index ad46465d..00000000 --- a/modules/ags/gtk4/widgets/astalify/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import astalify from './astalify'; - -export default astalify; - -export { - type AstalifyProps, - type BindableProps, - type ConstructProps, - childType, -} from './generics'; diff --git a/modules/ags/gtk4/widgets/bar.ts b/modules/ags/gtk4/widgets/bar.ts deleted file mode 100644 index 7e91473d..00000000 --- a/modules/ags/gtk4/widgets/bar.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { App, Astal, Gdk, Gtk } from 'astal/gtk4'; -import { Variable } from 'astal'; - -import Kompass from 'gi://Kompass'; - -import { Box, Calendar, CenterBox, Label, MenuButton, Popover, Window } from './subclasses'; - -const { EXCLUSIVE } = Astal.Exclusivity; -const { TOP, LEFT, RIGHT } = Astal.WindowAnchor; -const { CENTER } = Gtk.Align; - -const time = Variable(0); - -setInterval(() => { - time.set(time.get() + 1); -}, 1000); - -export default () => { - const styledBox = Box({ - css: time().as((t) => `* { background: red; min-height: 10px; min-width: ${t}px; }`), - }); - - return Window({ - visible: true, - cssClasses: ['Bar'], - exclusivity: EXCLUSIVE, - anchor: TOP | LEFT | RIGHT, - application: App, - - child: CenterBox({ - startWidget: new Kompass.Tray({ - cursor: Gdk.Cursor.new_from_name('pointer', null), - }), - - centerWidget: styledBox, - - endWidget: MenuButton({ - cursorName: 'pointer', - hexpand: true, - halign: CENTER, - - children: [ - Label({ label: time().as(String) }), - Popover({ child: Calendar() }), - ], - }), - }), - }); -}; diff --git a/modules/ags/gtk4/widgets/lockscreen/_index.scss b/modules/ags/gtk4/widgets/lockscreen/_index.scss deleted file mode 100644 index fa2c2601..00000000 --- a/modules/ags/gtk4/widgets/lockscreen/_index.scss +++ /dev/null @@ -1,9 +0,0 @@ -window, -viewport { - all: unset; -} - -.lock-clock { - font-size: 80pt; - font-family: 'Ubuntu Mono'; -} diff --git a/modules/ags/gtk4/widgets/lockscreen/index.ts b/modules/ags/gtk4/widgets/lockscreen/index.ts deleted file mode 100644 index 4fb7a6a2..00000000 --- a/modules/ags/gtk4/widgets/lockscreen/index.ts +++ /dev/null @@ -1,246 +0,0 @@ -import { idle, timeout, Variable } from 'astal'; -import { App, Astal, Gdk, Gtk } from 'astal/gtk4'; -import { register } from 'astal/gobject'; - -import AstalAuth from 'gi://AstalAuth'; -import Gtk4SessionLock from 'gi://Gtk4SessionLock'; - -import { Box, BoxClass, Entry, Label, Window } from '../subclasses'; -import Separator from '../misc/separator'; -import { get_hyprland_monitor_desc } from '../../lib'; - -// This file is generated by Nix -import Vars from './vars'; - -/* Types */ -declare global { - function authFinger(): void; -} -@register() -class BlurredBox extends BoxClass { - geometry = {} as { w: number, h: number }; -} - - -export default () => { - const windows = new Map<Gdk.Monitor, Gtk.Window>(); - const blurBGs: BlurredBox[] = []; - - const transition_duration = 1000; - const WINDOW_MARGINS = -2; - const ENTRY_SPACING = 20; - const CLOCK_SPACING = 60; - - const bgCSS = ({ w = 1, h = 1 } = {}) => `* { - border: 2px solid rgba(189, 147, 249, 0.8); - background: rgba(0, 0, 0, 0.2); - min-height: ${h}px; - min-width: ${w}px; - transition: min-height ${transition_duration / 2}ms, - min-width ${transition_duration / 2}ms; - }`; - - const lock = Gtk4SessionLock.Instance.new(); - - const unlock = () => { - blurBGs.forEach((b) => { - b.css = bgCSS({ - w: b.geometry.w, - h: 1, - }); - - timeout(transition_duration / 2, () => { - b.css = bgCSS({ - w: 1, - h: 1, - }); - }); - }); - timeout(transition_duration, () => { - lock.unlock(); - Gdk.Display.get_default()?.sync(); - App.quit(); - }); - }; - - const Clock = () => { - const time = Variable<string>('').poll(1000, () => { - return (new Date().toLocaleString([], { - hour: 'numeric', - minute: 'numeric', - hour12: true, - }) ?? '') - .replace('a.m.', 'AM') - .replace('p.m.', 'PM'); - }); - - return Label({ - cssClasses: ['lock-clock'], - label: time(), - }); - }; - - const PasswordPrompt = (monitor: Gdk.Monitor, visible: boolean) => { - const rev = new BlurredBox({ css: bgCSS() }); - - idle(() => { - rev.geometry = { - w: monitor.get_geometry().width, - h: monitor.get_geometry().height, - }; - - rev.css = bgCSS({ - w: rev.geometry.w, - h: 1, - }); - - timeout(transition_duration / 2, () => { - rev.css = bgCSS({ - w: rev.geometry.w, - h: rev.geometry.h, - }); - }); - }); - - blurBGs.push(rev); - - Window({ - name: `blur-bg-${monitor.get_model()}`, - namespace: `blur-bg-${monitor.get_model()}`, - gdkmonitor: monitor, - layer: Astal.Layer.OVERLAY, - visible: true, - - anchor: Astal.WindowAnchor.TOP | - Astal.WindowAnchor.LEFT | - Astal.WindowAnchor.RIGHT | - Astal.WindowAnchor.BOTTOM, - - margin: WINDOW_MARGINS, - exclusivity: Astal.Exclusivity.IGNORE, - - child: Box({ - halign: Gtk.Align.CENTER, - valign: Gtk.Align.CENTER, - children: [rev], - }), - }); - - const label = Label({ label: 'Enter password:' }); - - return new Gtk.Window({ - child: visible ? - Box({ - vertical: true, - halign: Gtk.Align.CENTER, - valign: Gtk.Align.CENTER, - spacing: 16, - - children: [ - Clock(), - - Separator({ - size: CLOCK_SPACING, - vertical: true, - }), - - Box({ - halign: Gtk.Align.CENTER, - cssClasses: ['avatar'], - }), - - Box({ - cssClasses: ['entry-box'], - vertical: true, - - children: [ - label, - - Separator({ - size: ENTRY_SPACING, - vertical: true, - }), - - Entry({ - halign: Gtk.Align.CENTER, - xalign: 0.5, - visibility: false, - placeholder_text: 'password', - - onRealize: (self) => self.grab_focus(), - - onActivate: (self) => { - self.set_sensitive(false); - - AstalAuth.Pam.authenticate(self.get_text() ?? '', (_, task) => { - try { - AstalAuth.Pam.authenticate_finish(task); - unlock(); - } - catch (e) { - self.set_text(''); - label.set_label((e as Error).message); - self.set_sensitive(true); - } - }); - }, - }), - ], - }), - ], - }) : - Box(), - }); - }; - - const createWindow = (monitor: Gdk.Monitor) => { - const hyprDesc = get_hyprland_monitor_desc(monitor); - const entryVisible = Vars.mainMonitor === hyprDesc || Vars.dupeLockscreen; - const win = PasswordPrompt(monitor, entryVisible); - - windows.set(monitor, win); - }; - - const lock_screen = () => { - const display = Gdk.Display.get_default(); - - for (let m = 0; m < (display?.get_monitors().get_n_items() ?? 0); m++) { - const monitor = display?.get_monitors().get_item(m) as Gdk.Monitor; - - if (monitor) { - createWindow(monitor); - } - } - - display?.get_monitors()?.connect('items-changed', () => { - for (let m = 0; m < (display?.get_monitors().get_n_items() ?? 0); m++) { - const monitor = display?.get_monitors().get_item(m) as Gdk.Monitor; - - if (monitor && !windows.has(monitor)) { - createWindow(monitor); - } - } - }); - - lock.lock(); - - windows.forEach((win, monitor) => { - lock.assign_window_to_monitor(win, monitor); - win.show(); - }); - }; - - if (Vars.hasFprintd) { - globalThis.authFinger = () => AstalAuth.Pam.authenticate('', (_, task) => { - try { - AstalAuth.Pam.authenticate_finish(task); - unlock(); - } - catch (e) { - console.error((e as Error).message); - } - }); - globalThis.authFinger(); - } - lock_screen(); -}; diff --git a/modules/ags/gtk4/widgets/misc/popup-window.ts b/modules/ags/gtk4/widgets/misc/popup-window.ts deleted file mode 100644 index ae8edc11..00000000 --- a/modules/ags/gtk4/widgets/misc/popup-window.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { App, Astal, Gtk } from 'astal/gtk4'; -import { property, register } from 'astal/gobject'; -import { Binding, idle } from 'astal'; - -import { WindowClass, WindowProps } from '../subclasses'; -import { get_hyprland_monitor, hyprMessage } from '../../lib'; - -/* Types */ -type CloseType = 'none' | 'stay' | 'released' | 'clicked'; -type HyprTransition = 'slide' | 'slide top' | 'slide bottom' | 'slide left' | - 'slide right' | 'popin' | 'fade'; -type PopupCallback = (self?: WindowClass) => void; - -export type PopupWindowProps = WindowProps & { - transition?: HyprTransition | Binding<HyprTransition> - close_on_unfocus?: CloseType | Binding<CloseType> - on_open?: PopupCallback - on_close?: PopupCallback -}; - - -@register() -export class PopupWindow extends WindowClass { - @property(String) - declare transition: HyprTransition | Binding<HyprTransition>; - - @property(String) - declare close_on_unfocus: CloseType | Binding<CloseType>; - - on_open: PopupCallback; - on_close: PopupCallback; - - constructor({ - transition = 'slide top', - close_on_unfocus = 'released', - on_open = () => { /**/ }, - on_close = () => { /**/ }, - - name, - visible = false, - layer = Astal.Layer.OVERLAY, - ...rest - }: PopupWindowProps) { - super({ - ...rest, - name: `win-${name}`, - namespace: `win-${name}`, - visible: false, - layer, - setup: () => idle(() => { - // Add way to make window open on startup - if (visible) { - this.visible = true; - } - }), - } as WindowProps); - - App.add_window(this); - - const setTransition = (_: PopupWindow, t: HyprTransition | Binding<HyprTransition>) => { - hyprMessage(`keyword layerrule animation ${t}, ${this.name}`).catch(console.log); - }; - - this.connect('notify::transition', setTransition); - - this.close_on_unfocus = close_on_unfocus; - this.transition = transition; - this.on_open = on_open; - this.on_close = on_close; - - this.connect('notify::visible', () => { - // Make sure we have the right animation - setTransition(this, this.transition); - - if (this.visible) { - this.on_open(this); - } - else { - this.on_close(this); - } - }); - }; - - async set_x_pos( - alloc: Gtk.Allocation, - side = 'right' as 'left' | 'right', - ) { - const monitor = this.gdkmonitor ?? this.get_current_monitor(); - - const transform = get_hyprland_monitor(monitor)?.get_transform(); - - let width: number; - - if (transform && (transform === 1 || transform === 3)) { - width = monitor.get_geometry().height; - } - else { - width = monitor.get_geometry().width; - } - - this.margin_right = side === 'right' ? - (width - alloc.x - alloc.width) : - this.margin_right; - - this.margin_left = side === 'right' ? - this.margin_left : - (alloc.x - alloc.width); - } -} - -export default PopupWindow; diff --git a/modules/ags/gtk4/widgets/misc/separator.ts b/modules/ags/gtk4/widgets/misc/separator.ts deleted file mode 100644 index 59b54b1d..00000000 --- a/modules/ags/gtk4/widgets/misc/separator.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Box, BoxProps } from '../subclasses'; - - -export default ({ - size, - vertical = false, - css = '', - ...rest -}: { size: number } & BoxProps) => Box({ - css: `* { ${vertical ? 'min-height' : 'min-width'}: ${size}px; ${css} }`, - ...rest, -} as BoxProps); diff --git a/modules/ags/gtk4/widgets/subclasses/box.ts b/modules/ags/gtk4/widgets/subclasses/box.ts deleted file mode 100644 index 4f3f41d1..00000000 --- a/modules/ags/gtk4/widgets/subclasses/box.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { register } from 'astal'; -import { Astal, Gtk } from 'astal/gtk4'; - -import astalify, { type AstalifyProps, type ConstructProps } from '../astalify'; - - -export type BoxProps = ConstructProps< - BoxClass, - Astal.Box.ConstructorProps & AstalifyProps ->; - -@register({ GTypeName: 'Box' }) -export class BoxClass extends astalify(Astal.Box) { - constructor({ cssName = 'box', ...props }: BoxProps = {}) { - super({ cssName, ...props }); - } - - getChildren(self: BoxClass) { - return self.get_children(); - } - - setChildren(self: BoxClass, children: Gtk.Widget[]) { - return self.set_children(children); - } -} - -export const Box = (props?: BoxProps) => new BoxClass(props); diff --git a/modules/ags/gtk4/widgets/subclasses/button.ts b/modules/ags/gtk4/widgets/subclasses/button.ts deleted file mode 100644 index a9c1203c..00000000 --- a/modules/ags/gtk4/widgets/subclasses/button.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { register } from 'astal'; -import { Gtk } from 'astal/gtk4'; - -import astalify, { type AstalifyProps, type ConstructProps } from '../astalify'; - - -type ButtonSignals = Record<`on${string}`, unknown[]> & { - onClicked: [] -}; -export type ButtonProps = ConstructProps< - ButtonClass, - Gtk.Button.ConstructorProps & AstalifyProps, - ButtonSignals ->; - -@register({ GTypeName: 'Button' }) -export class ButtonClass extends astalify(Gtk.Button) { - constructor({ cssName = 'button', ...props }: ButtonProps = {}) { - super({ cssName, ...props }); - } -} - -export const Button = (props?: ButtonProps) => new ButtonClass(props); diff --git a/modules/ags/gtk4/widgets/subclasses/calendar.ts b/modules/ags/gtk4/widgets/subclasses/calendar.ts deleted file mode 100644 index 8888d9fd..00000000 --- a/modules/ags/gtk4/widgets/subclasses/calendar.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { register } from 'astal'; -import { Gtk } from 'astal/gtk4'; - -import astalify, { type AstalifyProps, type ConstructProps } from '../astalify'; - - -type CalendarSignals = Record<`on${string}`, unknown[]> & { - onDaySelected: [] - onNextMonth: [] - onNextYear: [] - onPrevMonth: [] - onPrevYear: [] - -}; -export type CalendarProps = ConstructProps< - CalendarClass, - Gtk.Calendar.ConstructorProps & AstalifyProps, - CalendarSignals ->; - -@register({ GTypeName: 'Calendar' }) -export class CalendarClass extends astalify(Gtk.Calendar) { - constructor({ cssName = 'calendar', ...props }: CalendarProps = {}) { - super({ cssName, ...props }); - } -} - -export const Calendar = (props?: CalendarProps) => new CalendarClass(props); diff --git a/modules/ags/gtk4/widgets/subclasses/centerbox.ts b/modules/ags/gtk4/widgets/subclasses/centerbox.ts deleted file mode 100644 index 78fa55ef..00000000 --- a/modules/ags/gtk4/widgets/subclasses/centerbox.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { register } from 'astal'; -import { Gtk } from 'astal/gtk4'; - -import astalify, { type AstalifyProps, type ConstructProps } from '../astalify'; - - -export type CenterBoxProps = ConstructProps< - CenterBoxClass, - Gtk.CenterBox.ConstructorProps & AstalifyProps ->; - -@register({ GTypeName: 'CenterBox' }) -export class CenterBoxClass extends astalify(Gtk.CenterBox) { - constructor({ cssName = 'centerbox', ...props }: CenterBoxProps = {}) { - super({ cssName, ...props }); - } - - getChildren(box: CenterBoxClass) { - return [box.startWidget, box.centerWidget, box.endWidget]; - } - - setChildren(box: CenterBoxClass, children: (Gtk.Widget | null)[]) { - if (children.length > 3) { - throw new Error('Cannot have more than 3 children in a CenterBox'); - } - - box.startWidget = children[0] || new Gtk.Box(); - box.centerWidget = children[1] || new Gtk.Box(); - box.endWidget = children[2] || new Gtk.Box(); - } -} - -export const CenterBox = (props?: CenterBoxProps) => new CenterBoxClass(props); diff --git a/modules/ags/gtk4/widgets/subclasses/entry.ts b/modules/ags/gtk4/widgets/subclasses/entry.ts deleted file mode 100644 index ed02c663..00000000 --- a/modules/ags/gtk4/widgets/subclasses/entry.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { register } from 'astal'; -import { Gtk } from 'astal/gtk4'; - -import astalify, { type AstalifyProps, type ConstructProps } from '../astalify'; - - -type EntrySignals = Record<`on${string}`, unknown[]> & { - onActivate: [] - onNotifyText: [] -}; -export type EntryProps = ConstructProps< - EntryClass, - Gtk.Entry.ConstructorProps & AstalifyProps, - EntrySignals ->; - -@register({ GTypeName: 'Entry' }) -export class EntryClass extends astalify(Gtk.Entry) { - constructor({ cssName = 'entry', ...props }: EntryProps = {}) { - super({ cssName, ...props }); - } - - getChildren() { return []; } -} - -export const Entry = (props?: EntryProps) => new EntryClass(props); diff --git a/modules/ags/gtk4/widgets/subclasses/image.ts b/modules/ags/gtk4/widgets/subclasses/image.ts deleted file mode 100644 index c614ffc3..00000000 --- a/modules/ags/gtk4/widgets/subclasses/image.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { register } from 'astal'; -import { Gtk } from 'astal/gtk4'; - -import astalify, { type AstalifyProps, type ConstructProps } from '../astalify'; - - -export type ImageProps = ConstructProps< - ImageClass, - Gtk.Image.ConstructorProps & AstalifyProps ->; - -@register({ GTypeName: 'Image' }) -export class ImageClass extends astalify(Gtk.Image) { - constructor({ cssName = 'image', ...props }: ImageProps = {}) { - super({ cssName, ...props }); - } - - getChildren() { return []; } -} - -export const Image = (props?: ImageProps) => new ImageClass(props); diff --git a/modules/ags/gtk4/widgets/subclasses/index.ts b/modules/ags/gtk4/widgets/subclasses/index.ts deleted file mode 100644 index c537722a..00000000 --- a/modules/ags/gtk4/widgets/subclasses/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -export * from './box'; -export * from './button'; -export * from './calendar'; -export * from './centerbox'; -export * from './entry'; -export * from './image'; -export * from './label'; -export * from './levelbar'; -export * from './menubutton'; -export * from './overlay'; -export * from './popover'; -export * from './revealer'; -export * from './slider'; -export * from './stack'; -export * from './switch'; -export * from './window'; diff --git a/modules/ags/gtk4/widgets/subclasses/label.ts b/modules/ags/gtk4/widgets/subclasses/label.ts deleted file mode 100644 index 4dd1cd76..00000000 --- a/modules/ags/gtk4/widgets/subclasses/label.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { register } from 'astal'; -import { Gtk } from 'astal/gtk4'; - -import astalify, { type AstalifyProps, type ConstructProps } from '../astalify'; - - -export type LabelProps = ConstructProps< - LabelClass, - Gtk.Label.ConstructorProps & AstalifyProps ->; - -@register({ GTypeName: 'Label' }) -export class LabelClass extends astalify(Gtk.Label) { - constructor({ cssName = 'label', ...props }: LabelProps = {}) { - super({ cssName, ...props }); - } - - getChildren() { return []; } -} - -export const Label = (props?: LabelProps) => new LabelClass(props); diff --git a/modules/ags/gtk4/widgets/subclasses/levelbar.ts b/modules/ags/gtk4/widgets/subclasses/levelbar.ts deleted file mode 100644 index e51894a9..00000000 --- a/modules/ags/gtk4/widgets/subclasses/levelbar.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { register } from 'astal'; -import { Gtk } from 'astal/gtk4'; - -import astalify, { type AstalifyProps, type ConstructProps } from '../astalify'; - - -export type LevelBarProps = ConstructProps< - LevelBarClass, - Gtk.LevelBar.ConstructorProps & AstalifyProps ->; - -@register({ GTypeName: 'LevelBar' }) -export class LevelBarClass extends astalify(Gtk.LevelBar) { - constructor({ cssName = 'levelbar', ...props }: LevelBarProps = {}) { - super({ cssName, ...props }); - } - - getChildren() { return []; } -} - -export const LevelBar = (props?: LevelBarProps) => new LevelBarClass(props); diff --git a/modules/ags/gtk4/widgets/subclasses/menubutton.ts b/modules/ags/gtk4/widgets/subclasses/menubutton.ts deleted file mode 100644 index 3e2c0900..00000000 --- a/modules/ags/gtk4/widgets/subclasses/menubutton.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { register } from 'astal'; -import { Gtk } from 'astal/gtk4'; - -import astalify, { type AstalifyProps, type ConstructProps } from '../astalify'; - - -export type MenuButtonProps = ConstructProps< - MenuButtonClass, - Gtk.MenuButton.ConstructorProps & AstalifyProps ->; - -@register({ GTypeName: 'MenuButton' }) -export class MenuButtonClass extends astalify(Gtk.MenuButton) { - constructor({ cssName = 'menubutton', ...props }: MenuButtonProps = {}) { - super({ cssName, ...props }); - } - - getChildren(self: MenuButtonClass) { - return [self.popover, self.child]; - } - - setChildren(self: MenuButtonClass, children: Gtk.Widget[]) { - for (const child of children) { - if (child instanceof Gtk.Popover) { - self.set_popover(child); - } - else { - self.set_child(child); - } - } - } -} - -export const MenuButton = (props?: MenuButtonProps) => new MenuButtonClass(props); diff --git a/modules/ags/gtk4/widgets/subclasses/overlay.ts b/modules/ags/gtk4/widgets/subclasses/overlay.ts deleted file mode 100644 index f4541c0d..00000000 --- a/modules/ags/gtk4/widgets/subclasses/overlay.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { register } from 'astal'; -import { Gtk } from 'astal/gtk4'; - -import astalify, { childType, type AstalifyProps, type ConstructProps } from '../astalify'; - - -export type OverlayProps = ConstructProps< - OverlayClass, - Gtk.Overlay.ConstructorProps & AstalifyProps ->; - -@register({ GTypeName: 'Overlay' }) -export class OverlayClass extends astalify(Gtk.Overlay) { - constructor({ cssName = 'overlay', ...props }: OverlayProps = {}) { - super({ cssName, ...props }); - } - - getChildren(self: OverlayClass) { - const children: Gtk.Widget[] = []; - let ch = self.get_first_child(); - - while (ch !== null) { - children.push(ch); - ch = ch.get_next_sibling(); - } - - return children.filter((child) => child !== self.child); - } - - setChildren(self: OverlayClass, children: Gtk.Widget[]) { - for (const child of children) { - const types = childType in child ? - (child[childType] as string).split(/\s+/) : - []; - - if (types.includes('overlay')) { - self.add_overlay(child); - } - else { - self.set_child(child); - } - - self.set_measure_overlay(child, types.includes('measure')); - self.set_clip_overlay(child, types.includes('clip')); - } - } -} - -export const Overlay = (props?: OverlayProps) => new OverlayClass(props); diff --git a/modules/ags/gtk4/widgets/subclasses/popover.ts b/modules/ags/gtk4/widgets/subclasses/popover.ts deleted file mode 100644 index a47c5d37..00000000 --- a/modules/ags/gtk4/widgets/subclasses/popover.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { register } from 'astal'; -import { Gtk } from 'astal/gtk4'; - -import astalify, { type AstalifyProps, type ConstructProps } from '../astalify'; - - -export type PopoverProps = ConstructProps< - PopoverClass, - Gtk.Popover.ConstructorProps & AstalifyProps ->; - -@register({ GTypeName: 'Popover' }) -export class PopoverClass extends astalify(Gtk.Popover) { - constructor({ cssName = 'popover', ...props }: PopoverProps = {}) { - super({ cssName, ...props }); - } -} - -export const Popover = (props?: PopoverProps) => new PopoverClass(props); diff --git a/modules/ags/gtk4/widgets/subclasses/revealer.ts b/modules/ags/gtk4/widgets/subclasses/revealer.ts deleted file mode 100644 index 77b241fd..00000000 --- a/modules/ags/gtk4/widgets/subclasses/revealer.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { register } from 'astal'; -import { Gtk } from 'astal/gtk4'; - -import astalify, { type AstalifyProps, type ConstructProps } from '../astalify'; - - -export type RevealerProps = ConstructProps< - RevealerClass, - Gtk.Revealer.ConstructorProps & AstalifyProps ->; - -@register({ GTypeName: 'Revealer' }) -export class RevealerClass extends astalify(Gtk.Revealer) { - constructor({ cssName = 'revealer', ...props }: RevealerProps = {}) { - super({ cssName, ...props }); - } -} - -export const Revealer = (props?: RevealerProps) => new RevealerClass(props); diff --git a/modules/ags/gtk4/widgets/subclasses/slider.ts b/modules/ags/gtk4/widgets/subclasses/slider.ts deleted file mode 100644 index 4f327f72..00000000 --- a/modules/ags/gtk4/widgets/subclasses/slider.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { register } from 'astal'; -import { Astal } from 'astal/gtk4'; - -import astalify, { type AstalifyProps, type ConstructProps } from '../astalify'; - - -type SliderSignals = Record<`on${string}`, unknown[]> & { - onClicked: [] -}; -export type SliderProps = ConstructProps< - SliderClass, - Astal.Slider.ConstructorProps & AstalifyProps, - SliderSignals ->; - -@register({ GTypeName: 'Slider' }) -export class SliderClass extends astalify(Astal.Slider) { - constructor({ cssName = 'slider', ...props }: SliderProps = {}) { - super({ cssName, ...props }); - } - - getChildren() { return []; } -} - -export const Slider = (props?: SliderProps) => new SliderClass(props); diff --git a/modules/ags/gtk4/widgets/subclasses/stack.ts b/modules/ags/gtk4/widgets/subclasses/stack.ts deleted file mode 100644 index c10ff3e5..00000000 --- a/modules/ags/gtk4/widgets/subclasses/stack.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { register } from 'astal'; -import { Gtk } from 'astal/gtk4'; - -import astalify, { type AstalifyProps, type ConstructProps } from '../astalify'; - - -export type StackProps = ConstructProps< - StackClass, - Gtk.Stack.ConstructorProps & AstalifyProps ->; - -@register({ GTypeName: 'Stack' }) -export class StackClass extends astalify(Gtk.Stack) { - constructor({ cssName = 'stack', ...props }: StackProps = {}) { - super({ cssName, ...props }); - } - - setChildren(self: StackClass, children: Gtk.Widget[]) { - for (const child of children) { - if (child.name !== '' && child.name !== null) { - self.add_named(child, child.name); - } - else { - self.add_child(child); - } - } - } -} - -export const Stack = (props?: StackProps) => new StackClass(props); diff --git a/modules/ags/gtk4/widgets/subclasses/switch.ts b/modules/ags/gtk4/widgets/subclasses/switch.ts deleted file mode 100644 index 9c075a18..00000000 --- a/modules/ags/gtk4/widgets/subclasses/switch.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { register } from 'astal'; -import { Gtk } from 'astal/gtk4'; - -import astalify, { type AstalifyProps, type ConstructProps } from '../astalify'; - - -export type SwitchProps = ConstructProps< - SwitchClass, - Gtk.Switch.ConstructorProps & AstalifyProps ->; - -@register({ GTypeName: 'Switch' }) -export class SwitchClass extends astalify(Gtk.Switch) { - constructor({ cssName = 'switch', ...props }: SwitchProps = {}) { - super({ cssName, ...props }); - } - - getChildren() { return []; } -} - -export const Switch = (props?: SwitchProps) => new SwitchClass(props); diff --git a/modules/ags/gtk4/widgets/subclasses/window.ts b/modules/ags/gtk4/widgets/subclasses/window.ts deleted file mode 100644 index e5e7e5a6..00000000 --- a/modules/ags/gtk4/widgets/subclasses/window.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { register } from 'astal'; -import { Astal } from 'astal/gtk4'; - -import astalify, { type AstalifyProps, type ConstructProps } from '../astalify'; - - -export type WindowProps = ConstructProps< - WindowClass, - Astal.Window.ConstructorProps & AstalifyProps ->; - -@register({ GTypeName: 'Window' }) -export class WindowClass extends astalify(Astal.Window) { - constructor({ cssName = 'window', ...props }: WindowProps = {}) { - super({ cssName, ...props }); - } -} - -export const Window = (props?: WindowProps) => new WindowClass(props); diff --git a/modules/ags/hyprland.nix b/modules/ags/hyprland.nix deleted file mode 100644 index 42036677..00000000 --- a/modules/ags/hyprland.nix +++ /dev/null @@ -1,208 +0,0 @@ -self: { - lib, - osConfig, - ... -}: let - inherit (self.lib.hypr) mkAnimation mkBezier mkBind mkLayerRule; - - inherit (lib) mkIf; - - cfgDesktop = osConfig.roles.desktop; -in { - config = mkIf cfgDesktop.ags.enable { - wayland.windowManager.hyprland = { - settings = { - general = { - gaps_in = 5; - gaps_out = 5; - border_size = 0; - }; - - decoration = { - rounding = 12; - - blur = { - enabled = true; - size = 3; - passes = 1; - }; - - shadow.enabled = false; - }; - - animations = { - enabled = true; - - bezier = map mkBezier [ - { - name = "easeInQuart"; - p0 = [0.895 0.030]; - p1 = [0.685 0.220]; - } - { - name = "easeOutQuart"; - p0 = [0.165 0.840]; - p1 = [0.440 1.000]; - } - { - name = "easeInOutQuart"; - p0 = [0.770 0.000]; - p1 = [0.175 1.000]; - } - - # fade out - { - name = "easeInExpo"; - p0 = [0.950 0.050]; - p1 = [0.795 0.035]; - } - ]; - - animation = map mkAnimation [ - { - name = "workspaces"; - duration = 6; - bezier = "easeOutQuart"; - style = "slide"; - } - - { - name = "windows"; - duration = 4; - bezier = "easeOutQuart"; - style = "slide"; - } - { - name = "fadeIn"; - enable = false; - } - { - name = "fadeOut"; - duration = 4; - bezier = "easeInExpo"; - } - - { - name = "fadeLayersIn"; - enable = false; - } - { - name = "fadeLayersOut"; - duration = 4; - bezier = "easeInExpo"; - } - { - name = "layers"; - duration = 4; - bezier = "easeInOutQuart"; - style = "fade"; - } - ]; - }; - - layerrule = map mkLayerRule [ - { - rule = "animation popin"; - namespace = "^(hyprpaper.*)"; - } - { - rule = "animation fade"; - namespace = "^(bg-layer.*)"; - } - { - rule = "noanim"; - namespace = "^(noanim-.*)"; - } - - { - rule = "blur"; - namespace = "^(blur-bg.*)"; - } - { - rule = "ignorealpha 0.19"; - namespace = "^(blur-bg.*)"; - } - ]; - - exec-once = [ - "ags" - "sleep 3; ags request 'open win-applauncher'" - ]; - - bind = map mkBind [ - { - modifier = "$mainMod SHIFT"; - key = "E"; - command = "ags toggle win-powermenu"; - } - { - modifier = "$mainMod"; - key = "D"; - command = "ags toggle win-applauncher"; - } - { - modifier = "$mainMod"; - key = "V"; - command = "ags toggle win-clipboard"; - } - { - key = "Print"; - command = "ags toggle win-screenshot"; - } - - { - key = "XF86AudioMute"; - command = "pactl set-sink-mute @DEFAULT_SINK@ toggle"; - } - { - key = "XF86AudioMicMute"; - command = "pactl set-source-mute @DEFAULT_SOURCE@ toggle"; - } - { - modifier = "$mainMod"; - key = "Print"; - command = "bash -c \"grim -g \\\"$(slurp)\\\" - | satty -f -\""; - } - ]; - - binde = map mkBind [ - { - key = "XF86MonBrightnessUp"; - command = "ags request 'Brightness.screen +0.05'"; - } - { - key = "XF86MonBrightnessDown"; - command = "ags request 'Brightness.screen -0.05'"; - } - - { - key = "XF86AudioRaiseVolume"; - command = "wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+ & ags request 'popup speaker' &"; - } - { - key = "XF86AudioLowerVolume"; - command = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- & ags request 'popup speaker' &"; - } - ]; - - bindn = map mkBind [ - { - key = "Escape"; - command = "ags request closeAll"; - } - ]; - - bindr = map mkBind [ - { - modifier = "CAPS"; - key = "Caps_Lock"; - command = "ags request fetchCapsState"; - } - ]; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/ags/icons.nix b/modules/ags/icons.nix deleted file mode 100644 index 56570e1e..00000000 --- a/modules/ags/icons.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ - agsConfigDir, - pkgs, - ... -}: { - "${agsConfigDir}/icons/down-large-symbolic.svg".source = pkgs.fetchurl { - url = "https://www.svgrepo.com/download/158537/down-chevron.svg"; - hash = "sha256-mOfNjgZh0rt6XosKA2kpLY22lJldSS1XCphgrnvZH1s="; - }; - - "${agsConfigDir}/icons/nixos-logo-symbolic.svg".text = - # xml - '' - <svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> - <defs> - <path id="lambda" d="M7.352 1.592l-1.364.002L5.32 2.75l1.557 2.713-3.137-.008-1.32 2.34H14.11l-1.353-2.332-3.192-.006-2.214-3.865z" fill="#000000" /> - </defs> - <use xlink:href="#lambda" /> - <use xlink:href="#lambda" transform="rotate(120 12 12)" /> - <use xlink:href="#lambda" transform="rotate(240 12 12)" /> - <g opacity=".7"> - <use xlink:href="#lambda" transform="rotate(60 12 12)" /> - <use xlink:href="#lambda" transform="rotate(180 12 12)" /> - <use xlink:href="#lambda" transform="rotate(300 12 12)" /> - </g> - </svg> - ''; -} diff --git a/modules/ags/packages.nix b/modules/ags/packages.nix deleted file mode 100644 index de415af2..00000000 --- a/modules/ags/packages.nix +++ /dev/null @@ -1,195 +0,0 @@ -self: { - config, - lib, - osConfig, - pkgs, - ... -}: let - inherit (self.inputs) kompass; - - inherit (lib) attrValues boolToString filter getExe mkIf optionalAttrs optionals; - - inherit (osConfig.networking) hostName; - - cfg = config.programs.ags; - cfgDesktop = osConfig.roles.desktop; - gtk4ConfigDir = "${cfg.configDir}/../gtk4"; - - mainPkg = pkgs.writeShellApplication { - name = "ags"; - runtimeInputs = [cfg.package]; - text = '' - if [ "$#" == 0 ]; then - exec ags run ~/${cfg.configDir} -a ${hostName} - else - exec ags "$@" - fi - ''; - }; -in { - config = mkIf cfgDesktop.ags.enable { - # Make these accessible outside these files - programs.ags = { - package = pkgs.ags.override { - extraPackages = cfg.astalLibs; - }; - - astalLibs = attrValues { - inherit - (pkgs.astal) - io - astal3 - astal4 - apps - auth - battery - bluetooth - greet - hyprland - mpris - network - notifd - powerprofiles - tray - wireplumber - ; - - # TODO: add overlays to upstream flake after ags PR is merged - libKompass = kompass.packages.${pkgs.system}.libkompass; - - # libkompass dependencies - inherit - (pkgs.astal) - cava - river - ; - - inherit - (pkgs) - libadwaita - gtk4-layer-shell - gtk4 # Needed to build types - ; - }; - - lockPkg = pkgs.writeShellApplication { - name = "lock"; - runtimeInputs = [cfg.package]; - text = '' - gsettings set org.gnome.desktop.interface cursor-size 30 - - if [ "$#" == 0 ]; then - exec ags run ~/${gtk4ConfigDir}/app.ts -a lock --gtk4 - else - exec ags "$@" -i lock - fi - ''; - }; - }; - - home = { - packages = - [ - mainPkg - (pkgs.writeShellApplication { - name = "ags4"; - runtimeInputs = [cfg.package]; - text = '' - gsettings set org.gnome.desktop.interface cursor-size 30 - - if [ "$#" == 0 ]; then - exec ags run ~/${gtk4ConfigDir}/app.ts --gtk4 -a ${hostName} - else - exec ags "$@" - fi - ''; - }) - ] - ++ (attrValues { - inherit - (pkgs) - networkmanagerapplet - playerctl - wayfreeze - ; - inherit - (pkgs.selfPackages) - coloryou - ; - }) - ++ (optionals cfgDesktop.isTouchscreen (attrValues { - inherit - (pkgs) - ydotool - ; - })); - - file = let - inherit - (self.lib.${pkgs.system}) - buildNodeModules - buildGirTypes - ; - - lockscreenVars = - # javascript - '' - export default { - mainMonitor: '${cfgDesktop.mainMonitor}', - dupeLockscreen: ${boolToString cfgDesktop.displayManager.duplicateScreen}, - hasFprintd: ${boolToString (hostName == "wim")}, - }; - ''; - in ( - (import ./icons.nix { - inherit pkgs; - agsConfigDir = cfg.configDir; - }) - // (import ./icons.nix { - inherit pkgs; - agsConfigDir = gtk4ConfigDir; - }) - // (buildGirTypes { - pname = "ags"; - configPath = "${cfg.configDir}/@girs"; - packages = filter (x: - true - && x.pname != "libadwaita" - && x.pname != "libkompass" - && x.pname != "gtk4-layer-shell" - && x.pname != "gtk4-session-lock") - cfg.astalLibs; - }) - // (buildGirTypes { - pname = "ags"; - configPath = "${gtk4ConfigDir}/@girs"; - packages = filter (x: - true) - cfg.astalLibs; - }) - // { - "${cfg.configDir}/node_modules" = { - force = true; - source = buildNodeModules ./config (import ./config).npmDepsHash; - }; - - "${gtk4ConfigDir}/node_modules" = { - force = true; - source = buildNodeModules ./config (import ./config).npmDepsHash; - }; - - "${gtk4ConfigDir}/widgets/lockscreen/vars.ts".text = lockscreenVars; - } - // optionalAttrs cfgDesktop.isTouchscreen { - ".config/fcitx5/conf/virtualkeyboardadapter.conf".text = '' - ActivateCmd="${getExe mainPkg} request 'show-osk'" - DeactivateCmd="${getExe mainPkg} request 'hide-osk'" - ''; - } - ); - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/base/common-nix/default.nix b/modules/base/common-nix/default.nix deleted file mode 100644 index 4f4db2c0..00000000 --- a/modules/base/common-nix/default.nix +++ /dev/null @@ -1,43 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (self.inputs) nixd nixpkgs; - inherit (self.lib) hasVersion throws; - - inherit (lib) attrValues filter findFirst hasAttr mkIf optionalString; - - inherit (config.sops.secrets) access-token; - - cfg = config.roles.base; - - nixdInput = - findFirst - (x: x.pname == "nix") {} - nixd.packages.x86_64-linux.nixd.buildInputs; - - nixVersions = filter (x: ! throws x && hasVersion x) (attrValues pkgs.nixVersions); -in { - config = mkIf cfg.enable { - nix = { - package = findFirst (x: x.version == nixdInput.version) {} nixVersions; - - # Minimize dowloads of indirect nixpkgs flakes - registry.nixpkgs.flake = nixpkgs; - nixPath = ["nixpkgs=${nixpkgs}"]; - - extraOptions = - optionalString (hasAttr "sops" config) - "!include ${access-token.path}"; - }; - - # Global hm settings - home-manager.useGlobalPkgs = true; - home-manager.useUserPackages = true; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/base/default-droid.nix b/modules/base/default-droid.nix deleted file mode 100644 index d6fecc50..00000000 --- a/modules/base/default-droid.nix +++ /dev/null @@ -1,22 +0,0 @@ -self: {lib, ...}: let - inherit (lib) mkOption types; -in { - imports = [ - (import ./common-nix self) - (import ./packages self) - ]; - - options.roles.base = { - enable = mkOption { - type = types.bool; - default = true; - }; - - user = mkOption { - type = types.str; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/base/default.nix b/modules/base/default.nix deleted file mode 100644 index 0725834b..00000000 --- a/modules/base/default.nix +++ /dev/null @@ -1,146 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (lib) attrValues mkDefault mkIf mkOption types; - inherit (self.inputs) home-manager; - - cfg = config.roles.base; -in { - imports = [ - ./locale - ./locate - ./substituters - (import ./common-nix self) - (import ./packages self) - - self.nixosModules.borgbackup - self.nixosModules.tmux - - home-manager.nixosModules.home-manager - ]; - - options.roles.base = { - enable = mkOption { - type = types.bool; - default = true; - }; - - user = mkOption { - type = types.str; - }; - }; - - config = mkIf cfg.enable { - environment.variables.FLAKE = mkDefault "/home/${cfg.user}/.nix"; - - programs.tmux.enableCustomConf = true; - - boot.tmp.useTmpfs = true; - - systemd.services.nix-daemon = { - environment.TMPDIR = "/home/nix-cache"; - preStart = '' - mkdir -p ${config.systemd.services.nix-daemon.environment.TMPDIR} - ''; - }; - - nix = { - # Edit nix.conf - settings = { - # Store - keep-outputs = true; - keep-derivations = true; - auto-optimise-store = true; - - # Commands - experimental-features = ["nix-command" "flakes"]; - http-connections = 0; # unlimited for local cache - warn-dirty = false; - show-trace = true; - allow-import-from-derivation = true; - fallback = true; - - # remote building - trusted-users = ["matt" "nixremote"]; - }; - }; - - programs.nh = { - enable = true; - package = pkgs.nh; - - # weekly cleanup - clean = { - enable = true; - extraArgs = "--keep-since 30d"; - }; - }; - - services = { - fwupd.enable = true; - - xserver.xkb = { - layout = "ca"; - variant = "multix"; - }; - }; - - boot.supportedFilesystems = ["ext4" "xfs" "btrfs" "vfat" "ntfs"]; - system.fsPackages = attrValues { - inherit - (pkgs) - btrfs-progs - nfs-utils - ntfs3g - xfsprogs - ; - }; - - environment.variables.NPM_CONFIG_GLOBALCONFIG = "/etc/npmrc"; - environment.etc.npmrc.text = '' - fund = false - update-notifier = false - ''; - - environment.systemPackages = attrValues { - # Peripherals - inherit - (pkgs) - hdparm - pciutils - usbutils - rar - ; - }; - - users.mutableUsers = false; - - home-manager.users = let - default = { - imports = [ - { - programs.bash = { - sessionVariables = rec { - FLAKE = config.environment.variables.FLAKE; - NH_FLAKE = FLAKE; - }; - shellAliases.nh = "env -u FLAKE nh"; - }; - } - ]; - - home.stateVersion = config.system.stateVersion; - }; - in { - root = default; - greeter = mkIf (config.services.greetd.enable) default; - ${cfg.user} = default; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/base/locale/default.nix b/modules/base/locale/default.nix deleted file mode 100644 index 74812e80..00000000 --- a/modules/base/locale/default.nix +++ /dev/null @@ -1,58 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) attrValues mkIf; - - cfg = config.roles.base; -in { - config = mkIf cfg.enable { - fonts = { - fontconfig = { - enable = true; - - defaultFonts = { - emoji = ["Noto Color Emoji"]; - monospace = ["JetBrainsMono Nerd Font Mono"]; - sansSerif = ["Noto Nerd Font"]; - serif = ["Noto Nerd Font"]; - }; - }; - - packages = attrValues { - jetbrainsMono = pkgs.jetbrains-mono; - jetbrainsMonoNF = pkgs.nerd-fonts.jetbrains-mono; - - inherit - (pkgs) - noto-fonts - noto-fonts-cjk-sans - noto-fonts-emoji - liberation_ttf - font-awesome - meslo-lgs-nf - ubuntu_font_family - ; - - inherit - (pkgs.nerd-fonts) - go-mono - iosevka - symbols-only - space-mono - ubuntu - noto - ; - }; - }; - - # Select internationalisation properties. - i18n.defaultLocale = "en_CA.UTF-8"; - console.useXkbConfig = true; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/base/locate/default.nix b/modules/base/locate/default.nix deleted file mode 100644 index 886e75f3..00000000 --- a/modules/base/locate/default.nix +++ /dev/null @@ -1,92 +0,0 @@ -{ - config, - pkgs, - lib, - ... -}: let - inherit (lib) concatStringsSep getName mkIf; - - baseCfg = config.roles.base; - cfg = config.services.locate; - - locateGroup = getName cfg.package.name; - - locate = "${cfg.package}/bin/locate"; - updatedb = "${cfg.package}/bin/updatedb"; - - database = "/var/lib/locate/locatedb"; - pruneFS = concatStringsSep " " cfg.pruneFS; - pruneNames = concatStringsSep " " cfg.pruneNames; - prunePaths = concatStringsSep " " cfg.prunePaths; - - updatedbBin = '' - ${updatedb} -o ${database} --prunefs "${pruneFS}" \ - --prunepaths "${prunePaths}" --prunenames "${pruneNames}" - ''; -in { - config = mkIf baseCfg.enable { - users.users.${baseCfg.user}.extraGroups = [ - locateGroup - ]; - - systemd.services.locate = { - wantedBy = ["default.target"]; - serviceConfig = { - User = baseCfg.user; - Group = locateGroup; - StateDirectory = "locate"; - StateDirectoryMode = "0770"; - ExecStart = updatedbBin; - }; - }; - - systemd.timers.locate = { - wantedBy = ["timers.target"]; - timerConfig = { - Unit = "locate.service"; - OnCalendar = "*-*-* *:0/10:50"; # Every 10 minutes - }; - }; - - home-manager.users.${baseCfg.user}.programs.bash.shellAliases = { - locate = "${pkgs.writeShellScriptBin "lct" '' - exec ${locate} -d ${database} "$@" 2> >(grep -v "/var/cache/locatedb") - ''}/bin/lct"; - - updatedb = updatedbBin; - }; - - services.locate = { - enable = true; - package = pkgs.mlocate; - interval = "never"; - - prunePaths = [ - "/var/lib/flatpak" - - # Defaults - "/tmp" - "/var/tmp" - "/var/cache" - "/var/lock" - "/var/run" - "/var/spool" - "/nix/var/log/nix" - ]; - - pruneNames = [ - "node_modules" - - # Defaults - ".bzr" - ".cache" - ".git" - ".hg" - ".svn" - ]; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/base/packages/default.nix b/modules/base/packages/default.nix deleted file mode 100644 index 85f35445..00000000 --- a/modules/base/packages/default.nix +++ /dev/null @@ -1,142 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (lib) attrValues makeBinPath mkIf remove; - - cfg = config.roles.base; -in { - config = mkIf cfg.enable { - nixpkgs.overlays = - (map (i: self.inputs.${i}.overlays.default) [ - "grim-hyprland" - "nixos-jellyfin" - "nh" - "nixd" - "nurl" - ]) - ++ (attrValues { - # inherit - # (self.overlays) - # ; - }); - - environment.systemPackages = remove null (attrValues { - inherit - (pkgs.selfPackages) - pokemon-colorscripts - repl - ; - - nurl = - if (cfg.user != "nixos" && cfg.user != "nix-on-droid") - then - pkgs.nurl.overrideAttrs { - postInstall = '' - wrapProgram $out/bin/nurl --prefix PATH : ${makeBinPath [ - (config.home-manager.users.${cfg.user}.programs.git.package or pkgs.gitMinimal) - (config.nix.package or pkgs.nix) - pkgs.mercurial - ]} - installManPage artifacts/nurl.1 - installShellCompletion artifacts/nurl.{bash,fish} --zsh artifacts/_nurl - ''; - } - else null; - - inherit - (pkgs.nodePackages) - undollar - ; - - inherit (pkgs) alejandra just; - - # Archiving - inherit - (pkgs) - zip - unzip - p7zip - bzip2 - gzip - gnutar - xz - ; - - # File management - inherit - (pkgs) - findutils - diffutils - util-linux - which - imagemagick - ; - - # Networking - inherit (pkgs.dig) dnsutils; - inherit - (pkgs) - arp-scan - openssh - rsync - wget - gnupg - ; - - # Misc CLI stuff - inherit - (pkgs) - hydra-check - killall - nix-output-monitor - nix-melt - nix-tree - nix-update - progress - tree - gnugrep - gnused - ; - - # Expected Stuff - inherit - (pkgs) - hostname - man - perl - tzdata - ; - - listDerivs = pkgs.writeShellApplication { - name = "listDerivs"; - text = '' - exec nix-store --query --requisites /run/current-system | cut -d- -f2- | sort -u - ''; - }; - - from = pkgs.writeShellApplication { - name = "from"; - - runtimeInputs = attrValues { - inherit - (pkgs) - coreutils - which - ; - }; - - text = '' - for var do - realpath "$(which "$var")" - done - ''; - }; - }); - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/base/substituters/default.nix b/modules/base/substituters/default.nix deleted file mode 100644 index 630efc90..00000000 --- a/modules/base/substituters/default.nix +++ /dev/null @@ -1,54 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) foldl isList mergeAttrsWithFunc mkIf optionals unique; - - cfg = config.roles.base; - - mergeAttrsList = list: - foldl (mergeAttrsWithFunc (a: b: - if isList a && isList b - then unique (a ++ b) - else b)) {} - list; -in { - config = mkIf cfg.enable { - environment.systemPackages = [ - (pkgs.writeShellApplication { - name = "rebuild-no-cache"; - runtimeInputs = [config.programs.nh.package]; - text = '' - exec nh os switch -- --option binary-caches "https://cache.nixos.org" "$@" - ''; - }) - ]; - - nix = { - settings = let - mkSubstituterConf = prio: url: key: { - substituters = ["${url}?priority=${toString prio}"]; - trusted-public-keys = optionals (key != null) [key]; - }; - in - mergeAttrsList ([ - (mkSubstituterConf 200 "https://cache.nixos.org" "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=") - (mkSubstituterConf 1000 "https://hyprland.cachix.org" "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=") - (mkSubstituterConf 1000 "https://nix-gaming.cachix.org" "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=") - (mkSubstituterConf 1000 "https://nixpkgs-wayland.cachix.org" "nixpkgs-wayland.cachix.org-1:3lwxaILxMRkVhehr5StQprHdEo4IrE8sRho9R9HOLYA=") - (mkSubstituterConf 1000 "https://nix-community.cachix.org" "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=") - (mkSubstituterConf 1000 "https://viperml.cachix.org" "viperml.cachix.org-1:qZhKBMTfmcLL+OG6fj/hzsMEedgKvZVFRRAhq7j8Vh8=") - (mkSubstituterConf 1000 "https://cuda-maintainers.cachix.org" "cuda-maintainers.cachix.org-1:0dq3bujKpuEPMCX6U4WylrUDZ9JyUG0VpVZa7CNfq5E=") - (mkSubstituterConf 1100 "https://nix-on-droid.cachix.org" "nix-on-droid.cachix.org-1:56snoMJTXmDRC1Ei24CmKoUqvHJ9XCp+nidK7qkMQrU=") - ] - ++ optionals (config.networking.hostName != "servivi") [ - (mkSubstituterConf 100 "https://cache.nelim.org" "cache.nelim.org:JmFqkUdH11EA9EZOFAGVHuRYp7EbsdJDHvTQzG2pPyY=") - ]); - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/borgbackup/default.nix b/modules/borgbackup/default.nix deleted file mode 100644 index 4242ad41..00000000 --- a/modules/borgbackup/default.nix +++ /dev/null @@ -1,44 +0,0 @@ -{ - config, - lib, - ... -}: let - inherit (lib) mkIf; - - cfg = config.services.borgbackup; -in { - imports = [./module.nix]; - - config = mkIf (cfg.configs != {}) { - services.borgbackup = { - existingRepos = [ - { - name = "docker"; - host = "nos"; - authorizedKeys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPijoxuSwH9IrS4poewzHHwe64UoX4QY7Qix5VhEdqKR root@servivi" - ]; - } - - { - name = "mc"; - host = "servivi"; - authorizedKeys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPijoxuSwH9IrS4poewzHHwe64UoX4QY7Qix5VhEdqKR root@servivi" - ]; - } - - { - name = "seven-days"; - host = "nos"; - authorizedKeys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPijoxuSwH9IrS4poewzHHwe64UoX4QY7Qix5VhEdqKR root@servivi" - ]; - } - ]; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/borgbackup/module.nix b/modules/borgbackup/module.nix deleted file mode 100644 index a22f7c2d..00000000 --- a/modules/borgbackup/module.nix +++ /dev/null @@ -1,278 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) mkIf mkOption types; - inherit (lib.lists) all any filter findSingle length; - inherit (lib.attrsets) attrValues hasAttr listToAttrs mapAttrs removeAttrs; - - inherit (config.sops) secrets; - inherit (config.networking) hostName; - - cfg = config.services.borgbackup; -in { - options.services.borgbackup = { - configs = mkOption { - # Taken from https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/backup/borgbackup.nix - type = types.attrsOf (types.submodule ( - let - globalConfig = config; - in - { - name, - config, - ... - }: { - options = { - paths = mkOption { - type = types.nullOr (types.coercedTo types.str lib.singleton (types.listOf types.str)); - default = null; - }; - dumpCommand = mkOption { - type = types.nullOr types.path; - default = null; - }; - repo = mkOption { - type = types.str; - default = name; - }; - removableDevice = mkOption { - type = types.bool; - default = false; - }; - archiveBaseName = mkOption { - type = types.nullOr (types.strMatching "[^/{}]+"); - default = "${globalConfig.networking.hostName}-${name}"; - }; - dateFormat = mkOption { - type = types.str; - default = "+%Y-%m-%dT%H:%M:%S"; - }; - startAt = mkOption { - type = with types; either str (listOf str); - # Run every 3 hours - default = "00/3:00"; - }; - persistentTimer = mkOption { - default = false; - type = types.bool; - }; - inhibitsSleep = mkOption { - default = false; - type = types.bool; - }; - user = mkOption { - type = types.str; - default = "root"; - }; - group = mkOption { - type = types.str; - default = "root"; - }; - encryption.mode = mkOption { - type = types.enum [ - "repokey" - "keyfile" - "repokey-blake2" - "keyfile-blake2" - "authenticated" - "authenticated-blake2" - "none" - ]; - default = "none"; - }; - encryption.passCommand = mkOption { - type = with types; nullOr str; - default = null; - }; - encryption.passphrase = mkOption { - type = with types; nullOr str; - default = null; - }; - compression = mkOption { - type = types.strMatching "none|(auto,)?(lz4|zstd|zlib|lzma)(,[[:digit:]]{1,2})?"; - default = "auto,lz4"; - }; - exclude = mkOption { - type = with types; listOf str; - default = []; - }; - patterns = mkOption { - type = with types; listOf str; - default = []; - }; - readWritePaths = mkOption { - type = types.listOf types.path; - default = []; - }; - privateTmp = mkOption { - type = types.bool; - default = true; - }; - doInit = mkOption { - type = types.bool; - default = true; - }; - appendFailedSuffix = mkOption { - type = types.bool; - default = true; - }; - prune.keep = mkOption { - type = with types; attrsOf (either int (strMatching "[[:digit:]]+[Hdwmy]")); - default = {}; - }; - prune.prefix = mkOption { - type = types.nullOr (types.str); - default = config.archiveBaseName; - }; - environment = mkOption { - type = with types; attrsOf str; - default = {}; - }; - preHook = mkOption { - type = types.lines; - default = ""; - }; - postInit = mkOption { - type = types.lines; - default = ""; - }; - postCreate = mkOption { - type = types.lines; - default = ""; - }; - postPrune = mkOption { - type = types.lines; - default = ""; - }; - postHook = mkOption { - type = types.lines; - default = ""; - }; - extraArgs = mkOption { - type = types.str; - default = ""; - }; - extraInitArgs = mkOption { - type = types.str; - default = ""; - }; - extraCreateArgs = mkOption { - type = types.str; - default = ""; - }; - extraPruneArgs = mkOption { - type = types.str; - default = ""; - }; - extraCompactArgs = mkOption { - type = types.str; - default = ""; - }; - }; - } - )); - default = {}; - }; - - existingRepos = mkOption { - type = types.listOf (types.submodule { - options = { - name = mkOption { - type = types.str; - }; - host = mkOption { - type = types.str; - }; - authorizedKeys = mkOption { - type = types.listOf types.str; - default = []; - }; - }; - }); - default = []; - }; - }; - - config = mkIf (cfg.configs != {}) { - assertions = [ - { - assertion = all ( - conf: - any (repo: conf.repo == repo.name) cfg.existingRepos - ) (attrValues cfg.configs); - message = '' - The repo you want to backup to needs to exist. - ''; - } - ]; - - services.borgbackup = let - backupDir = { - nos = "/data/borgbackups"; - servivi = "/home/backups"; - }; - in { - repos = - mkIf (length cfg.existingRepos > 0) - (listToAttrs (map (r: { - inherit (r) name; - value = { - authorizedKeysAppendOnly = r.authorizedKeys; - path = "${backupDir.${hostName}}/${r.name}"; - }; - }) - (filter (x: x.host == hostName) cfg.existingRepos))); - - jobs = mapAttrs (n: v: let - existingRepo = findSingle (x: x.name == v.repo) null null cfg.existingRepos; - otherAttrs = removeAttrs v [ - "environment" - "paths" - "preHook" - "postHook" - "repo" - ]; - pathPrefix = "/root/snaps"; - snapPath = "${pathPrefix}/${n}"; - in - { - environment = - v.environment - // (mkIf (hasAttr "borg-ssh" secrets) { - BORG_RSH = "ssh -o 'StrictHostKeyChecking=no' -i ${secrets.borg-ssh.path}"; - }); - - paths = map (x: snapPath + x) v.paths; - - preHook = - v.preHook - + '' - if [[ ! -d ${pathPrefix} ]]; then - mkdir -p ${pathPrefix} - fi - - ${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r / ${snapPath} - ''; - - postHook = - v.postHook - + '' - ${pkgs.btrfs-progs}/bin/btrfs subvolume delete ${snapPath} - ''; - - repo = - if (hostName != existingRepo.host) - then "ssh://borg@${existingRepo.host}${backupDir.${existingRepo.host}}/${v.repo}" - else "${backupDir.${existingRepo.host}}/${v.repo}"; - } - // otherAttrs) - cfg.configs; - }; - }; - - # For accurate stack trace - _file = ./module.nix; -} diff --git a/modules/caddy-plus/default.nix b/modules/caddy-plus/default.nix deleted file mode 100644 index 3a4262eb..00000000 --- a/modules/caddy-plus/default.nix +++ /dev/null @@ -1,104 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (self.lib) capitalise; - - inherit (lib) types; - inherit (lib.attrsets) attrValues; - inherit (lib.modules) mkIf mkOverride; - inherit (lib.options) mkOption; - inherit (lib.strings) concatMapStringsSep concatStringsSep optionalString; - - cfg = config.services.caddy; - - mkSubDirConf = subOpts: - optionalString (subOpts.reverseProxy != null) ( - if subOpts.experimental - then '' - ${subOpts.extraConfig} - - redir /${subOpts.subDirName} /${subOpts.subDirName}/ - route /${subOpts.subDirName}/* { - uri strip_prefix ${subOpts.subDirName} - reverse_proxy ${subOpts.reverseProxy} { - header_up X-Real-IP {remote} - header_up X-${capitalise subOpts.subDirName}-Base "/${subOpts.subDirName}" - } - } - '' - else '' - ${subOpts.extraConfig} - - redir /${subOpts.subDirName} /${subOpts.subDirName}/ - reverse_proxy /${subOpts.subDirName}/* { - to ${subOpts.reverseProxy} - } - '' - ); - - mkSubDomainConf = hostName: subOpts: '' - @${subOpts.subDomainName} host ${subOpts.subDomainName}.${hostName} - handle @${subOpts.subDomainName} { - ${subOpts.extraConfig} - ${optionalString (subOpts.reverseProxy != null) "reverse_proxy ${subOpts.reverseProxy}"} - - ${concatMapStringsSep "\n" mkSubDirConf (attrValues subOpts.subDirectories)} - } - ''; - - mkVHostConf = hostOpts: let - sslCertDir = config.security.acme.certs.${hostOpts.useACMEHost}.directory; - in '' - ${hostOpts.hostName} ${concatStringsSep " " hostOpts.serverAliases} { - ${optionalString (hostOpts.listenAddresses != []) "bind ${concatStringsSep " " hostOpts.listenAddresses}"} - ${optionalString (hostOpts.useACMEHost != null) "tls ${sslCertDir}/cert.pem ${sslCertDir}/key.pem"} - log { - ${hostOpts.logFormat} - } - - ${hostOpts.extraConfig} - ${optionalString (hostOpts.reverseProxy != null) "reverse_proxy ${hostOpts.reverseProxy}"} - ${concatMapStringsSep "\n" mkSubDirConf (attrValues hostOpts.subDirectories)} - ${concatMapStringsSep "\n" (mkSubDomainConf hostOpts.hostName) (attrValues hostOpts.subDomains)} - } - ''; - - settingsFormat = pkgs.formats.json {}; - - configFile = - if cfg.settings != {} - then settingsFormat.generate "caddy.json" cfg.settings - else let - Caddyfile = pkgs.writeTextDir "Caddyfile" '' - { - ${cfg.globalConfig} - } - ${cfg.extraConfig} - ${concatMapStringsSep "\n" mkVHostConf (attrValues cfg.virtualHosts)} - ''; - - Caddyfile-formatted = pkgs.runCommand "Caddyfile-formatted" {nativeBuildInputs = [cfg.package];} '' - mkdir -p $out - cp --no-preserve=mode ${Caddyfile}/Caddyfile $out/Caddyfile - caddy fmt --overwrite $out/Caddyfile - ''; - in "${ - if pkgs.stdenv.buildPlatform == pkgs.stdenv.hostPlatform - then Caddyfile-formatted - else Caddyfile - }/Caddyfile"; -in { - options.services.caddy.virtualHosts = mkOption { - type = types.attrsOf (types.submodule (import ./vhost-options.nix cfg)); - }; - - config = mkIf cfg.enable { - services.caddy.configFile = mkOverride 80 configFile; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/caddy-plus/sub-dir-options.nix b/modules/caddy-plus/sub-dir-options.nix deleted file mode 100644 index bda937e6..00000000 --- a/modules/caddy-plus/sub-dir-options.nix +++ /dev/null @@ -1,43 +0,0 @@ -cfg: { - lib, - name, - ... -}: let - inherit (lib) mkOption types; -in { - options = { - subDirName = mkOption { - type = types.str; - default = name; - description = "The sub directory name to handle."; - }; - - reverseProxy = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - Option to give the parameters to a simple "reverse_proxy" command - appended after extraConfig. - ''; - }; - - experimental = mkOption { - type = types.bool; - default = false; - description = '' - Specify if the app being proxied expects to be under a subdirectory. - If it doesn't, we can attempt to circumvent that but it is not guaranteed - to work for every app. - ''; - }; - - extraConfig = mkOption { - type = types.lines; - default = ""; - description = '' - Additional lines of configuration appended to this sub domain in the - automatically generated `Caddyfile`. - ''; - }; - }; -} diff --git a/modules/caddy-plus/sub-domain-options.nix b/modules/caddy-plus/sub-domain-options.nix deleted file mode 100644 index 3e6e3f18..00000000 --- a/modules/caddy-plus/sub-domain-options.nix +++ /dev/null @@ -1,52 +0,0 @@ -cfg: { - lib, - name, - ... -}: let - inherit (lib) literalExpression mkOption types; -in { - options = { - subDomainName = mkOption { - type = types.str; - default = name; - description = "The sub domain name to handle."; - }; - - reverseProxy = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - Option to give the parameters to a simple "reverse_proxy" command - appended after extraConfig. - ''; - }; - - subDirectories = mkOption { - type = types.attrsOf (types.submodule (import ./sub-dir-options.nix cfg)); - default = {}; - example = literalExpression '' - { - headscale = { - appSupport = false; - reverseProxy = "localhost:8080"; - extraConfig = ''' - encode gzip - '''; - }; - }; - ''; - description = '' - Declarative specification of a subdomain's subdirectories served by Caddy. - ''; - }; - - extraConfig = mkOption { - type = types.lines; - default = ""; - description = '' - Additional lines of configuration appended to this sub domain in the - automatically generated `Caddyfile`. - ''; - }; - }; -} diff --git a/modules/caddy-plus/vhost-options.nix b/modules/caddy-plus/vhost-options.nix deleted file mode 100644 index 452df7ab..00000000 --- a/modules/caddy-plus/vhost-options.nix +++ /dev/null @@ -1,51 +0,0 @@ -cfg: {lib, ...}: let - inherit (lib) literalExpression mkOption types; -in { - options = { - reverseProxy = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - Option to give the parameters to a simple "reverse_proxy" command - appended after extraConfig. - ''; - }; - - subDomains = mkOption { - type = types.attrsOf (types.submodule (import ./sub-domain-options.nix cfg)); - default = {}; - example = literalExpression '' - { - headscale = { - reverseProxy = "localhost:8080"; - extraConfig = ''' - encode gzip - '''; - } - }; - ''; - description = '' - Declarative specification of a virtual hosts subdomain served by Caddy. - ''; - }; - - subDirectories = mkOption { - type = types.attrsOf (types.submodule (import ./sub-dir-options.nix cfg)); - default = {}; - example = literalExpression '' - { - headscale = { - appSupport = false; - reverseProxy = "localhost:8080"; - extraConfig = ''' - encode gzip - '''; - }; - }; - ''; - description = '' - Declarative specification of a subdomain's subdirectories served by Caddy. - ''; - }; - }; -} diff --git a/modules/default.nix b/modules/default.nix deleted file mode 100644 index a9118149..00000000 --- a/modules/default.nix +++ /dev/null @@ -1,128 +0,0 @@ -{ - self ? {}, - description ? false, -}: let - module = mod: desc: - if description - then desc - else mod; -in { - base = - module - (import ./base self) - '' - Sets up locale, nix config, binary caches, general packages and some - miscellaneous configs I might want on every device I use. - ''; - - base-droid = - module - (import ./base/default-droid.nix self) - '' - Sets up locale, nix config, binary caches, general packages and some - miscellaneous configs I might want on every nix-on-droid device I use. - ''; - - borgbackup = - module - (import ./borgbackup) - '' - Sets up a wrapper around `services.borgbackup` to setup default behaviour - and make configuration of backups easier. - ''; - - caddy-plus = - module - (import ./caddy-plus self) - '' - Extends the caddy options to allow declaring subdirectory routes and - reverse proxy directives through nix code. - ''; - - desktop = - module - (import ./desktop self) - '' - Sets up a Display Manager, a Desktop Environment and themes for any graphical - apps to use the Dracula Theme. This module uses Hyprland as window manager and - AGS / Astal for the UI. - ''; - - docker = - module - (import ./docker self) - '' - Imports [nixos-docker-compose](https://github.com/matt1432/nixos-docker-compose), - sets default options such as BTRFS filesystem and adds an update script for images. - ''; - - esphome-plus = - module - (import ./esphome-plus) - '' - Fixes a bug with compilation of m5-atom-stack firmware and allows declaring - firmware configurations in nix code. - ''; - - ha-plus = - module - (import ./ha-plus) - '' - Extends the home-assistant options to allow declaring the content of specific - configuration files in the home-assistant configuration directory such as - custom sentences through nix code. - ''; - - kmscon = - module - (import ./kmscon) - '' - Extends the kmscon options to add more descriptive ones. - ''; - - meta = - module - (import ./meta) - '' - Adds options to declare the documentation of my devices that will be - generated to `./configurations/README.md`. - ''; - - nvidia = - module - (import ./nvidia) - '' - Abstracts NVIDIA options and miscellaneous fixes behind simpler options. - ''; - - plymouth = - module - (import ./plymouth) - '' - Sets some boot options to make the boot sequence cleaner. - ''; - - server = - module - (import ./server) - '' - Sets up sshd, tailscale and related configurations. - ''; - - tmux = - module - (import ./tmux) - '' - Uses the home-manager tmux module to declare my custom configuration and - links it to `/etc` to set it globally. - ''; - - wyoming-plus = - module - (import ./wyoming-plus) - '' - Extends the `wyoming.openwakeword` options to allow declaring flags used - by the [fork](https://github.com/rhasspy/wyoming-openwakeword/pull/17) - of `wyoming-openwakeword` exposed by this module. - ''; -} diff --git a/modules/desktop/default.nix b/modules/desktop/default.nix deleted file mode 100644 index e4290f87..00000000 --- a/modules/desktop/default.nix +++ /dev/null @@ -1,121 +0,0 @@ -self: { - config, - lib, - ... -}: let - inherit (self.inputs) home-manager; - - inherit (lib) elemAt mkIf mkOption types; - - cfg = config.roles.desktop; - flakeDir = config.environment.variables.FLAKE; -in { - imports = [ - (import ./manager self) - (import ./environment self) - - self.nixosModules.nvidia - home-manager.nixosModules.home-manager - ]; - - config = mkIf cfg.enable { - assertions = [ - { - assertion = lib.hasPrefix "/home/${cfg.user}/" flakeDir; - message = '' - Your $FLAKE environment variable needs to point to a directory in - the main users' home to use the desktop module. - ''; - } - ]; - - nixpkgs.overlays = map (i: self.inputs.${i}.overlays.default) [ - "hyprgrass" - "hyprland" - "hyprland-plugins" - "hyprpaper" - ]; - }; - - options.roles.desktop = { - enable = mkOption { - type = types.bool; - default = false; - }; - - user = mkOption { - type = types.str; - description = '' - The name of the user who is going to be using the "DE". - ''; - }; - - ags.enable = mkOption { - type = types.bool; - default = false; - description = '' - Whether we want to enable AGS for the DE shell. - ''; - }; - - mainMonitor = mkOption { - type = types.str; - description = '' - The name of the main monitor used for Hyprland - and Greetd which also uses Hyprland. - ''; - # This is to allow a bash script to know whether this value exists - default = "null"; - }; - - fontName = mkOption { - type = types.str; - default = elemAt config.fonts.fontconfig.defaultFonts.monospace 0; - }; - - fontSize = mkOption { - type = types.float; - default = 12.0; - description = '' - The size of the font in GUIs. - ''; - }; - - isLaptop = mkOption { - type = types.bool; - description = '' - If the computer is a laptop. - ''; - default = false; - }; - - isTouchscreen = mkOption { - type = types.bool; - description = '' - If the computer has a touchscreen. - ''; - default = false; - }; - - displayManager = { - enable = mkOption { - type = types.bool; - default = true; - description = '' - Whether we want to enable the Display Manager. - ''; - }; - - duplicateScreen = mkOption { - type = types.bool; - description = '' - If we should duplicate the login prompt on all monitors. - ''; - default = true; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/desktop/environment/config/mimeapps.list b/modules/desktop/environment/config/mimeapps.list deleted file mode 100644 index 513f634e..00000000 --- a/modules/desktop/environment/config/mimeapps.list +++ /dev/null @@ -1,20 +0,0 @@ -[Added Associations] -application/pdf=firefox-devedition.desktop;wine-extension-pdf.desktop;okularApplication_pdf.desktop;com.github.xournalpp.xournalpp.desktop;draw.desktop;sioyek.desktop; -application/zip=org.kde.ark.desktop;org.prismlauncher.PrismLauncher.desktop; -image/jpeg=org.photoqt.PhotoQt.desktop;wine-extension-jpe.desktop;satty.desktop;okularApplication_kimgio.desktop;wine-extension-jfif.desktop; -image/png=swayimg.desktop;okularApplication_kimgio.desktop;firefox.desktop;satty.desktop; -text/plain=nvim.desktop;writer.desktop;okularApplication_txt.desktop;wine-extension-txt.desktop; -text/x-java=nvim.desktop; - -[Default Applications] -application/pdf=firefox-devedition.desktop; -application/zip=org.kde.ark.desktop; -image/jpeg=swayimg.desktop; -image/png=swayimg.desktop; -text/plain=nvim.desktop; -text/x-java=nvim.desktop; -x-scheme-handler/discord-712465656758665259=discord-712465656758665259.desktop -x-scheme-handler/ror2mm=r2modman.desktop - -[Removed Associations] -application/pdf=firefox-3.desktop;firefox-2.desktop; diff --git a/modules/desktop/environment/default.nix b/modules/desktop/environment/default.nix deleted file mode 100644 index 50cec24e..00000000 --- a/modules/desktop/environment/default.nix +++ /dev/null @@ -1,250 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (self.lib.hypr) mkBind mkMonitor; - - inherit (lib) attrValues concatStringsSep mkIf optionals removeSuffix; - - cfg = config.roles.desktop; - - hyprCfg = - config - .home-manager - .users - .${cfg.user} - .wayland - .windowManager - .hyprland; -in { - imports = [ - (import ../../ags self) - - ./modules/dconf.nix - ./modules/printer.nix - ./modules/ratbag-mice.nix - (import ./modules/audio.nix self) - (import ./modules/packages.nix self) - (import ./modules/security.nix self) - ]; - - config = mkIf cfg.enable { - services = { - dbus.enable = true; - gvfs.enable = true; - libinput.enable = true; - xserver.wacom.enable = cfg.isTouchscreen; - }; - - programs.hyprland = { - enable = true; - package = hyprCfg.finalPackage; - portalPackage = hyprCfg.finalPortalPackage; - }; - - xdg.portal = { - enable = true; - - extraPortals = [ - pkgs.kdePackages.xdg-desktop-portal-kde - pkgs.xdg-desktop-portal-gtk - ]; - - config.hyprland = { - default = [ - "hyprland" - "gtk" - ]; - - "org.freedesktop.impl.portal.FileChooser" = [ - "kde" - ]; - }; - }; - - home-manager.users.${cfg.user} = { - imports = [ - ./home/dev.nix - - # Plugins - (import ./home/hyprexpo.nix self) - (import ./home/hyprgrass.nix self) - - (import ./home/inputs.nix self) - (import ../theme self) - ]; - - wayland.windowManager.hyprland = { - enable = true; - - # Get rid of logs shown on the TTY right before Hyprland launches - package = pkgs.hyprland.overrideAttrs (o: { - postInstall = '' - ${removeSuffix "\n\n" o.postInstall} \ - --append-flags '&>/dev/null' - ''; - }); - - systemd.variables = ["-all"]; - - settings = { - envd = let - mkGSchemas = pkg: "${pkg}/share/gsettings-schemas/${pkg.name}"; - in - [ - "GTK_USE_PORTAL, 1" - "NIXOS_OZONE_WL, 1" - "ELECTRON_OZONE_PLATFORM_HINT, auto" - - "XDG_DATA_DIRS, ${concatStringsSep ":" [ - (mkGSchemas pkgs.gsettings-desktop-schemas) - (mkGSchemas pkgs.gtk3) - "$XDG_DATA_DIRS" - ]}" - ] - ++ (optionals config.nvidia.enable [ - "LIBVA_DRIVER_NAME, nvidia" - "XDG_SESSION_TYPE, wayland" - "GBM_BACKEND, nvidia-drm" - "__GLX_VENDOR_LIBRARY_NAME, nvidia" - ]); - - xwayland.force_zero_scaling = true; - monitor = map mkMonitor [ - { - description = "Lenovo Group Limited 0x41A0"; - resolution = "1920x1200"; - refreshRate = 60; - position = "0x2920"; - } - { - description = "Samsung Electric Company C27JG5x HTOM100586"; - resolution = "2560x1440"; - refreshRate = 120; - position = "1920x120"; - } - { - description = "GIGA-BYTE TECHNOLOGY CO. LTD. G27QC 0x00000B1D"; - resolution = "2560x1440"; - refreshRate = 120; - position = "1920x1560"; - } - { - description = "Acer Technologies Acer K212HQL T3EAA0014201"; - resolution = "1920x1080"; - refreshRate = 60; - position = "840x450"; - transform = "270"; - } - { - description = "Sharp Corporation LC-40LB480U 0x00000001"; - resolution = "1680x1050"; - mirror = cfg.mainMonitor; - } - ]; - - "$mainMod" = "SUPER"; - - bind = [ - # Defaults - "$mainMod, F, fullscreen" - "$mainMod, C, killactive" - "$mainMod SHIFT, SPACE, togglefloating" - "$mainMod, J, layoutmsg, togglesplit" - - ## Move focus with arrow keys - "$mainMod, left, movefocus, l" - "$mainMod, right, movefocus, r" - "$mainMod, up, movefocus, u" - "$mainMod, down, movefocus, d" - - ## Move to specific workspaces - "$mainMod, 1, workspace, 1" - "$mainMod, 2, workspace, 2" - "$mainMod, 3, workspace, 3" - "$mainMod, 4, workspace, 4" - "$mainMod, 5, workspace, 5" - "$mainMod, 6, workspace, 6" - "$mainMod, 7, workspace, 7" - "$mainMod, 8, workspace, 8" - "$mainMod, 9, workspace, 9" - "$mainMod, 0, workspace, 10" - - # Move active window to a workspace - "$mainMod SHIFT, 1, movetoworkspace, 1" - "$mainMod SHIFT, 2, movetoworkspace, 2" - "$mainMod SHIFT, 3, movetoworkspace, 3" - "$mainMod SHIFT, 4, movetoworkspace, 4" - "$mainMod SHIFT, 5, movetoworkspace, 5" - "$mainMod SHIFT, 6, movetoworkspace, 6" - "$mainMod SHIFT, 7, movetoworkspace, 7" - "$mainMod SHIFT, 8, movetoworkspace, 8" - "$mainMod SHIFT, 9, movetoworkspace, 9" - "$mainMod SHIFT, 0, movetoworkspace, 10" - ]; - - # Mouse Binds - bindm = map mkBind [ - { - modifier = "$mainMod"; - key = "mouse:272"; - dispatcher = "movewindow"; - } - { - modifier = "$mainMod"; - key = "mouse:273"; - dispatcher = "resizewindow"; - } - ]; - - misc = { - disable_hyprland_logo = true; - disable_splash_rendering = true; - vfr = true; - }; - - ecosystem = { - no_update_news = true; - no_donation_nag = true; - }; - - dwindle = { - smart_split = true; - special_scale_factor = 0.8; - }; - }; - }; - - # libs - home.packages = attrValues { - inherit - (pkgs) - bluez-tools - brightnessctl - pulseaudio - alsa-utils - libayatana-appindicator - xdg-utils - evtest - glib - libinput - xclip - libnotify - ; - - qt5Wayland = pkgs.qt5.qtwayland; - qt6Wayland = pkgs.qt6.qtwayland; - - inherit - (pkgs.xorg) - xrandr - ; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/desktop/environment/home/dev.nix b/modules/desktop/environment/home/dev.nix deleted file mode 100644 index d0f7a93f..00000000 --- a/modules/desktop/environment/home/dev.nix +++ /dev/null @@ -1,85 +0,0 @@ -{ - lib, - osConfig, - pkgs, - ... -}: let - inherit (lib) mkIf; - inherit (pkgs.writers) writeJSON; - - cfg = osConfig.roles.desktop; - - clangdConf = writeJSON "clangd-hypr-conf" { - CompileFlags.Add = ["-D__cpp_concepts=202002L"]; - }; -in { - # https://wiki.hyprland.org/Contributing-and-Debugging/#lsp-and-formatting - config = mkIf cfg.enable { - home.packages = [ - (pkgs.writeShellApplication { - name = "setupDev"; - - runtimeInputs = [ - pkgs.cmake - osConfig.programs.direnv.nix-direnv.package - osConfig.programs.git.package - ]; - - text = '' - if [[ $# -gt 0 ]]; then - project="$1" - subproject="''${2:-"."}" - - cd "$HOME/git/$project/$subproject" || return - fi - - chmod +w -fR ./{.cache,build} || true - git clean -xdf - - if [ -e .envrc ] || [ -e ../.envrc ]; then - if [[ $# -gt 0 ]]; then - nix develop -c echo "load shellHook" - else - direnv reload - fi - fi - - if [ -e CMakeLists.txt ] || [ -e ../CMakeLists.txt ]; then - nix develop -c cmake -S . -B build/ -G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON - fi - - cat ${clangdConf} > .clangd - ''; - }) - - (pkgs.writeShellApplication { - name = "testChanges"; - - runtimeInputs = [ - pkgs.cmake - osConfig.programs.direnv.nix-direnv.package - osConfig.programs.git.package - ]; - - text = '' - project="$1" - subproject="''${2:-"."}" - - cd "$HOME/git/$project/$subproject" || return - - chmod +w -fR ./{.cache,build} || true - git clean -xdf - - cd "$FLAKE" || return - nix flake update "$1" - nh os switch - - setupDev "$project" "$subproject" - ''; - }) - ]; - }; - - # For accurate stack trace - _file = ./dev.nix; -} diff --git a/modules/desktop/environment/home/foot.nix b/modules/desktop/environment/home/foot.nix deleted file mode 100644 index e78656d6..00000000 --- a/modules/desktop/environment/home/foot.nix +++ /dev/null @@ -1,95 +0,0 @@ -{ - lib, - osConfig, - ... -}: let - inherit (lib) mkIf; - - cfg = osConfig.roles.desktop; -in { - config = mkIf cfg.enable { - programs = { - # https://codeberg.org/dnkl/foot/wiki#spawning-new-terminal-instances-in-the-current-working-directory - bash.bashrcExtra = - # bash - '' - osc7_cwd() { - local strlen=''${#PWD} - local encoded="" - local pos c o - for (( pos=0; pos<strlen; pos++ )); do - c=''${PWD:$pos:1} - case "$c" in - [-/:_.!\'\(\)~[:alnum:]] ) o="$c" ;; - * ) printf -v o '%%%02X' "'$c" ;; - esac - encoded+="''${o}" - done - printf '\e]7;file://%s%s\e\\' "''${HOSTNAME}" "''${encoded}" - } - PROMPT_COMMAND=''${PROMPT_COMMAND:+$PROMPT_COMMAND; }osc7_cwd - ''; - - foot = { - enable = true; - - settings = { - main = { - term = "xterm-256color"; - - font = "${cfg.fontName}:size=${ - lib.strings.floatToString cfg.fontSize - }"; - pad = "0x10"; - }; - - key-bindings = { - spawn-terminal = "Control+Shift+Return"; - }; - - bell = { - urgent = false; - notify = false; - visual = false; - command = null; - command-focused = false; - }; - - colors = { - # BG transparency - alpha = 0.8; - - background = "282a36"; - foreground = "f8f8f2"; - - regular0 = "21222c"; # black - regular1 = "ff5555"; # red - regular2 = "50fa7b"; # green - regular3 = "f1fa8c"; # yellow - regular4 = "bd93f9"; # blue - regular5 = "ff79c6"; # magenta - regular6 = "8be9fd"; # cyan - regular7 = "f8f8f2"; # white - - bright0 = "6272a4"; # bright black - bright1 = "ff6e6e"; # bright red - bright2 = "69ff94"; # bright green - bright3 = "ffffa5"; # bright yellow - bright4 = "d6acff"; # bright blue - bright5 = "ff92df"; # bright magenta - bright6 = "a4ffff"; # bright cyan - bright7 = "ffffff"; # bright white - - selection-foreground = "ffffff"; - selection-background = "44475a"; - - urls = "8be9fd"; - }; - }; - }; - }; - }; - - # For accurate stack trace - _file = ./foot.nix; -} diff --git a/modules/desktop/environment/home/hyprexpo.nix b/modules/desktop/environment/home/hyprexpo.nix deleted file mode 100644 index b5c67423..00000000 --- a/modules/desktop/environment/home/hyprexpo.nix +++ /dev/null @@ -1,44 +0,0 @@ -self: { - lib, - osConfig, - pkgs, - ... -}: let - inherit (self.lib.hypr) mkBind; - - inherit (lib) mkIf; - - cfg = osConfig.roles.desktop; -in { - config = mkIf cfg.enable { - wayland.windowManager.hyprland = { - plugins = [pkgs.hyprlandPlugins.hyprexpo]; - - settings = { - plugin.hyprexpo = { - columns = 3; - gap_size = 5; - bg_col = "rgb(111111)"; - workspace_method = "center current"; # [center/first] [workspace] e.g. first 1 or center m+1 - - enable_gesture = true; # laptop touchpad - gesture_fingers = 3; - gesture_distance = 300; # how far is the "max" - gesture_positive = true; # positive = swipe down. Negative = swipe up. - }; - - bind = [ - (mkBind { - modifier = "ALT"; - key = "tab"; - dispatcher = "hyprexpo:expo"; - command = "toggle"; # can be: toggle, off/disable or on/enable - }) - ]; - }; - }; - }; - - # For accurate stack trace - _file = ./hyprexpo.nix; -} diff --git a/modules/desktop/environment/home/hyprgrass.nix b/modules/desktop/environment/home/hyprgrass.nix deleted file mode 100644 index 48d830bf..00000000 --- a/modules/desktop/environment/home/hyprgrass.nix +++ /dev/null @@ -1,76 +0,0 @@ -self: { - lib, - osConfig, - pkgs, - ... -}: let - inherit (self.lib.hypr) mkBind; - - inherit (lib) mkIf; - - cfg = osConfig.roles.desktop; -in { - config = mkIf (cfg.enable && cfg.isTouchscreen) { - wayland.windowManager.hyprland = { - plugins = [pkgs.hyprlandPlugins.hyprgrass]; - - settings = { - plugin.touch_gestures = { - # The default sensitivity is probably too low on tablet screens, - # I recommend turning it up to 4.0 - sensitivity = 4.0; - - # must be >= 3 - workspace_swipe_fingers = 3; - - emulate_touchpad_swipe = true; - - # switching workspaces by swiping from an edge, this is separate from workspace_swipe_fingers - # and can be used at the same time - # possible values: l, r, u, or d - # to disable it set it to anything else - # workspace_swipe_edge = "d"; - - # in milliseconds - long_press_delay = 400; - - # resize windows by long-pressing on window borders and gaps. - # If general:resize_on_border is enabled, general:extend_border_grab_area is used for floating - # windows - resize_on_border_long_press = true; - - # in pixels, the distance from the edge that is considered an edge - edge_margin = 10; - - # send proper cancel events to windows instead of hacky touch_up events, - # NOT recommended as it crashed a few times, once it's stabilized I'll make it the default - experimental.send_cancel = 0; - - hyprgrass-bind = map mkBind [ - { - key = "edge:u:d"; - command = "ags request 'open win-applauncher'"; - } - ]; - - hyprgrass-bindm = map mkBind [ - { - key = "longpress:2"; - dispatcher = "movewindow"; - } - ]; - }; - - gestures = { - workspace_swipe = true; - workspace_swipe_fingers = 3; - workspace_swipe_touch = false; - workspace_swipe_cancel_ratio = 0.15; - }; - }; - }; - }; - - # For accurate stack trace - _file = ./hyprgrass.nix; -} diff --git a/modules/desktop/environment/home/inputs.nix b/modules/desktop/environment/home/inputs.nix deleted file mode 100644 index e2a1e733..00000000 --- a/modules/desktop/environment/home/inputs.nix +++ /dev/null @@ -1,83 +0,0 @@ -self: { - osConfig, - lib, - ... -}: let - inherit (self.lib.hypr) mkBind; - - inherit (lib) mkIf; - - cfg = osConfig.roles.desktop; - - inherit (osConfig.services.xserver) xkb; - - miceNames = [ - "logitech-g502-x" - "logitech-g502-hero-gaming-mouse" - ]; - - mkConf = name: { - inherit name; - sensitivity = 0; - accel_profile = "flat"; - }; -in { - config = mkIf cfg.enable { - wayland.windowManager.hyprland = { - settings = { - device = map mkConf miceNames; - - cursor = { - no_hardware_cursors = osConfig.nvidia.enable; - hide_on_touch = true; - }; - - exec-once = - if cfg.mainMonitor != null - then ["hyprctl dispatch focusmonitor ${cfg.mainMonitor}"] - else []; - - input = { - # Keyboard - kb_layout = xkb.layout; - kb_variant = xkb.variant; - numlock_by_default = true; - repeat_rate = 25; - - # Mouse - follow_mouse = true; - - # Touchpad - touchpad = { - natural_scroll = true; - disable_while_typing = false; - drag_lock = true; - tap-and-drag = true; - }; - }; - - bind = map mkBind [ - { - key = "XF86AudioPlay"; - command = "playerctl play-pause"; - } - { - key = "XF86AudioStop"; - command = "playerctl stop"; - } - { - key = "XF86AudioNext"; - command = "playerctl next"; - } - { - key = "XF86AudioPrev"; - command = "playerctl previous"; - } - ]; - }; - }; - }; - - # For accurate stack trace - _file = ./inputs.nix; -} diff --git a/modules/desktop/environment/home/mpv.nix b/modules/desktop/environment/home/mpv.nix deleted file mode 100644 index 2201b776..00000000 --- a/modules/desktop/environment/home/mpv.nix +++ /dev/null @@ -1,80 +0,0 @@ -self: { - lib, - osConfig, - pkgs, - ... -}: let - inherit (pkgs.scopedPackages) mpvScripts; - - inherit (lib) attrValues mkIf; - - cfg = osConfig.roles.desktop; -in { - config = mkIf cfg.enable { - # For kdialog-open-files - home.packages = [ - pkgs.kdePackages.kdialog - ]; - - programs.mpv = { - enable = true; - - # https://github.com/mpv-player/mpv/wiki/User-Scripts - scripts = attrValues { - inherit - (mpvScripts) - modernz - persist-properties - undo-redo - ; - - # touch-gestures & deps - inherit - (mpvScripts) - pointer-event - touch-gestures - ; - - # Ctrl + o - inherit (mpvScripts) kdialog-open-files; - }; - - scriptOpts = { - persist_properties = { - properties = "volume,sub-scale"; - }; - - # Touch gestures default - pointer-event = { - margin_left = 0; - margin_right = 80; - margin_top = 50; - margin_bottom = 130; - ignore_left_single_long_while_window_dragging = true; - left_single = "cycle pause"; - left_double = "script-message-to touch_gestures double"; - left_long = "script-binding uosc/menu-blurred"; - left_drag_start = "script-message-to touch_gestures drag_start"; - left_drag_end = "script-message-to touch_gestures drag_end"; - left_drag = "script-message-to touch_gestures drag"; - }; - - touch-gestures = { - # valid options are: - # 'playlist' for changing the playlist item by swiping - # 'seek' for seeking by dragging - horizontal_drag = "seek"; - - # scale seeking based on the duration of the video - proportional_seek = true; - - # scale factor for seeking - seek_scale = 1; - }; - }; - }; - }; - - # For accurate stack trace - _file = ./mpv.nix; -} diff --git a/modules/desktop/environment/home/obs.nix b/modules/desktop/environment/home/obs.nix deleted file mode 100644 index 3dee8adf..00000000 --- a/modules/desktop/environment/home/obs.nix +++ /dev/null @@ -1,25 +0,0 @@ -{ - lib, - osConfig, - pkgs, - ... -}: let - inherit (lib) attrValues mkIf; - - cfg = osConfig.roles.desktop; -in { - config = mkIf cfg.enable { - programs = { - obs-studio = { - enable = true; - plugins = attrValues { - inherit - (pkgs.obs-studio-plugins) - droidcam-obs - wlrobs - ; - }; - }; - }; - }; -} diff --git a/modules/desktop/environment/modules/audio.nix b/modules/desktop/environment/modules/audio.nix deleted file mode 100644 index aee166eb..00000000 --- a/modules/desktop/environment/modules/audio.nix +++ /dev/null @@ -1,39 +0,0 @@ -self: { - config, - lib, - ... -}: let - inherit (self.inputs) nix-gaming; - - inherit (lib) mkIf; - - cfg = config.roles.desktop; -in { - imports = [nix-gaming.nixosModules.pipewireLowLatency]; - - config = mkIf cfg.enable { - services = { - pulseaudio.enable = false; - - pipewire = { - enable = true; - alsa.enable = true; - jack.enable = true; - pulse.enable = true; - lowLatency.enable = true; - - extraConfig.pipewire-pulse.combine-sink = { - "pulse.cmd" = [ - { - cmd = "load-module"; - args = "module-combine-sink"; - } - ]; - }; - }; - }; - }; - - # For accurate stack trace - _file = ./audio.nix; -} diff --git a/modules/desktop/environment/modules/dconf.nix b/modules/desktop/environment/modules/dconf.nix deleted file mode 100644 index 4b233c29..00000000 --- a/modules/desktop/environment/modules/dconf.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ - config, - lib, - ... -}: let - inherit (lib) mkIf; - - cfg = config.roles.desktop; -in { - config = mkIf cfg.enable { - programs.dconf.enable = true; - - home-manager.users.${cfg.user} = { - dconf.settings = { - "org/virt-manager/virt-manager/connections" = { - autoconnect = ["qemu:///system"]; - uris = ["qemu:///system"]; - }; - - "apps/seahorse/listing" = { - keyrings-selected = ["gnupg://"]; - }; - - "org/gtk/settings/file-chooser" = { - show-hidden = true; - }; - - "org/gnome/desktop/interface" = { - color-scheme = "prefer-dark"; - }; - }; - }; - }; - - # For accurate stack trace - _file = ./dconf.nix; -} diff --git a/modules/desktop/environment/modules/dolphin.nix b/modules/desktop/environment/modules/dolphin.nix deleted file mode 100644 index 116e2ba5..00000000 --- a/modules/desktop/environment/modules/dolphin.nix +++ /dev/null @@ -1,98 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) attrValues mkIf; - - cfg = config.roles.desktop; -in { - # https://github.com/NixOS/nixpkgs/blob/443424323ed4ff51b4f4314af39e0f57bb103586/nixos/modules/services/desktop-managers/plasma6.nix - config = mkIf cfg.enable { - # To make it work with firefox - # https://www.reddit.com/r/NixOS/comments/xtoubc/comment/koxxr3e/?utm_source=share&utm_medium=web2x&context=3 - systemd.user.services.plasma-dolphin = { - unitConfig = { - Description = "Dolphin file manager"; - PartOf = ["graphical-session.target"]; - }; - path = ["/run/current-system/sw"]; - environment.QT_QPA_PLATFORM = "wayland"; - serviceConfig = { - Type = "dbus"; - BusName = "org.freedesktop.FileManager1"; - ExecStart = "${pkgs.kdePackages.dolphin}/bin/dolphin"; - }; - }; - - services.udisks2.enable = true; - - # Enable GTK applications to load SVG icons - programs.gdk-pixbuf.modulePackages = [pkgs.librsvg]; - - # Fix application associations - home-manager.users.${cfg.user}.xdg.configFile."menus/applications.menu" - .source = "${pkgs.kdePackages.plasma-workspace}/etc/xdg/menus/plasma-applications.menu"; - - environment.systemPackages = attrValues { - # Complete apps - inherit - (pkgs.kdePackages) - ark - dolphin - kcharselect - kmenuedit - kinfocenter - plasma-systemmonitor - ksystemstats - libksysguard - systemsettings - kcmutils - ; - - # globally loadable bits - inherit - (pkgs.kdePackages) - frameworkintegration # provides Qt plugin - kauth # provides helper service - kcoreaddons # provides extra mime type info - kded # provides helper service - kfilemetadata # provides Qt plugins - kguiaddons # provides geo URL handlers - kiconthemes # provides Qt plugins - kimageformats # provides Qt plugins - qtimageformats # provides optional image formats such as .webp and .avif - kio # provides helper service + a bunch of other stuff - kio-admin # managing files as admin - kio-extras # stuff for MTP, AFC, etc - kio-fuse # fuse interface for KIO - kpackage # provides kpackagetool tool - kservice # provides kbuildsycoca6 tool - kunifiedpush # provides a background service and a KCM - plasma-activities # provides plasma-activities-cli tool - solid # provides solid-hardware6 tool - phonon-vlc # provides Phonon plugin - ; - - inherit - (pkgs) - xdg-user-dirs - ; - - inherit - (pkgs.kdePackages) - baloo-widgets - dolphin-plugins - ffmpegthumbs - kde-cli-tools - kdegraphics-thumbnailers - kmime - qtsvg - ; - }; - }; - - # For accurate stack trace - _file = ./dolphin.nix; -} diff --git a/modules/desktop/environment/modules/packages.nix b/modules/desktop/environment/modules/packages.nix deleted file mode 100644 index cd037ef2..00000000 --- a/modules/desktop/environment/modules/packages.nix +++ /dev/null @@ -1,356 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (self.lib.hypr) mkBind; - inherit (self.inputs) nixcord; - - inherit (lib) attrValues getExe mkIf optionals; - inherit (pkgs.writers) writeTOML; - - cfg = config.roles.desktop; - - flakeDir = config.environment.variables.FLAKE; - isNvidia = config.nvidia.enable; - - restartTailscale = pkgs.writeShellScriptBin "restartTailscale" '' - sudo ${pkgs.systemd}/bin/systemctl restart tailscaled.service - ''; -in { - imports = [./dolphin.nix]; - - config = mkIf cfg.enable { - programs.kdeconnect.enable = true; - - security.sudo.extraRules = [ - { - users = [cfg.user]; - groups = [100]; - commands = [ - { - command = "${pkgs.systemd}/bin/systemctl restart tailscaled.service"; - options = ["SETENV" "NOPASSWD"]; - } - ]; - } - ]; - - home-manager.users.${cfg.user} = { - imports = [ - ../home/foot.nix - ../home/obs.nix - (import ../home/mpv.nix self) - - nixcord.homeManagerModules.nixcord - - ({config, ...}: let - inherit (config.lib.file) mkOutOfStoreSymlink; - configDir = "${flakeDir}/modules/desktop/environment/config"; - in { - xdg.configFile = { - "dolphinrc".source = mkOutOfStoreSymlink "${configDir}/dolphinrc"; - "kdeglobals".source = mkOutOfStoreSymlink "${configDir}/kdeglobals"; - "kiorc".source = mkOutOfStoreSymlink "${configDir}/kiorc"; - "mimeapps.list".source = mkOutOfStoreSymlink "${configDir}/mimeapps.list"; - - "satty/config.toml".source = writeTOML "satty.toml" { - general = { - early-exit = true; - copy-command = "wl-copy"; - initial-tool = "crop"; - output-filename = "${config.home.homeDirectory}/Pictures/Screenshots/screen-%d-%m-%Y_%H:%M:%S.png"; - }; - font.family = "Ubuntu Mono"; - }; - }; - }) - ]; - - programs = { - nixcord = { - enable = true; - - discord = { - package = - if isNvidia - then - pkgs.discord.overrideAttrs { - postFixup = '' - wrapProgramShell $out/bin/Discord \ - --set XDG_SESSION_TYPE "x11" \ - --unset NIXOS_OZONE_WL \ - --unset WAYLAND_DISPLAY - ''; - } - else pkgs.discord; - - vencord.unstable = true; - openASAR.enable = false; - - settings = { - skipHostUpdate = true; - dangerousEnableDevtoolsOnlyEnableIfYouKnowWhatYoureDoing = true; - minWidth = 940; - minHeight = 500; - isMaximized = true; - isMinimized = false; - enableHardwareAcceleration = !isNvidia; - }; - }; - - config = { - notifyAboutUpdates = false; - autoUpdate = false; - autoUpdateNotification = false; - - themeLinks = [ - "https://markchan0225.github.io/RoundedDiscord/RoundedDiscord.theme.css" - "https://raw.githubusercontent.com/dracula/BetterDiscord/master/Dracula_Official.theme.css" - ]; - - plugins = { - alwaysTrust.enable = true; - biggerStreamPreview.enable = true; - clearURLs.enable = true; - crashHandler.enable = true; - disableCallIdle.enable = true; - emoteCloner.enable = true; - imageZoom.enable = true; - memberCount.enable = true; - messageLinkEmbeds.enable = true; - - messageLogger = { - enable = true; - ignoreBots = true; - ignoreSelf = true; - }; - - mutualGroupDMs.enable = true; - onePingPerDM.enable = true; - openInApp.enable = true; - platformIndicators.enable = true; - previewMessage.enable = true; - readAllNotificationsButton.enable = true; - reverseImageSearch.enable = true; - spotifyCrack.enable = true; - themeAttributes.enable = true; - typingIndicator.enable = true; - typingTweaks.enable = true; - viewIcons.enable = true; - viewRaw.enable = true; - voiceChatDoubleClick.enable = true; - volumeBooster.enable = true; - whoReacted.enable = true; - }; - }; - }; - - sioyek = { - enable = true; - - config = { - startup_commands = "toggle_custom_color"; - ui_font = "JetBrainsMono Nerd Font Mono Regular"; - font_size = "24"; - source = toString pkgs.scopedPackages.dracula.sioyek; - }; - }; - }; - - home.packages = attrValues { - # KDE packages - inherit - (pkgs.kdePackages) - kdenlive - okular - ; - - # School - inherit (pkgs.hunspellDicts) en_CA; - inherit - (pkgs) - xournalpp - virt-manager - libreoffice-fresh - hunspell - krename - ; - - # Apps - inherit - (pkgs) - gnome-calculator - jellyfin-media-player - nextcloud-client - protonmail-desktop # run with `XDG_SESSION_TYPE=x11 proton-mail` if it crashes https://github.com/NixOS/nixpkgs/issues/365156 - spotifywm - swayimg - vesktop # screen-sharing on desktop - ; - - prismlauncher = pkgs.prismlauncher.override { - glfw3-minecraft = pkgs.glfw3-minecraft.overrideAttrs (o: { - patches = - o.patches - ++ [ - (pkgs.fetchpatch { - url = "https://aur.archlinux.org/cgit/aur.git/plain/0006-Avoid-error-on-startup.patch?h=glfw-wayland-minecraft-cursorfix"; - hash = "sha256-oF+mTNOXPq/yr+y58tTeRkLJE67QzJJSleKFZ85+Uys="; - }) - (pkgs.fetchpatch { - url = "https://aur.archlinux.org/cgit/aur.git/plain/0002-Fix-duplicate-pointer-scroll-events.patch?h=glfw-wayland-minecraft-cursorfix"; - hash = "sha256-qd92eEqXjBPf0mgD19U5H8E88idd6NC6WnRTfvm829w="; - }) - ]; - }); - }; - - # tools - inherit - (pkgs) - grim-hyprland - wl-color-picker - wl-clipboard - cliphist - slurp - satty - ; - - GParted = let - inherit - (pkgs) - # build deps - writeShellApplication - makeWrapper - symlinkJoin - # deps - gparted - psmisc - seahorse - ; - - sudoWrapper = writeShellApplication { - name = "GParted"; - runtimeInputs = [ - gparted - psmisc - "/run/wrappers" - ]; - text = '' - ( - sleep 1.5 - - while killall -r -0 ssh-askpass > /dev/null 2>&1; do - sleep 0.1 - - if [[ $(hyprctl activewindow | grep ssh-askpass) == "" ]]; then - killall -r ssh-askpass - fi - done - ) & - - export SUDO_ASKPASS="${seahorse}/libexec/seahorse/ssh-askpass" - - exec sudo -k -EA gparted "$@" - ''; - }; - in - symlinkJoin { - name = "gparted"; - paths = [gparted]; - buildInputs = [makeWrapper]; - postBuild = '' - mkdir $out/.wrapped - mv $out/bin/gparted $out/.wrapped - cp ${getExe sudoWrapper} $out/bin/gparted - - sed -i "s#Exec.*#Exec=$out/bin/gparted %f#" $out/share/applications/gparted.desktop - ''; - }; - }; - - wayland.windowManager.hyprland = { - settings = { - exec-once = - [ - "${config.programs.kdeconnect.package}/libexec/kdeconnectd" - "kdeconnect-indicator" - - "wl-paste --watch cliphist store" - - "sleep 3; nextcloud --background" - - "[workspace special:protonmail silent] sleep 10; proton-mail" - "[workspace special:spot silent] spotify" - ] - ++ optionals config.services.tailscale.enable [ - "sleep 3; ${getExe restartTailscale}" - ]; - - windowrule = - [ - "tile, class:^(libreoffice)$" - "float, class:^(org.gnome.Calculator)$" - "float, class:^(com.gabm.satty)$" - "size 1000 700, class:^(com.gabm.satty)$" - - "float, class:^(com.nextcloud.desktopclient.nextcloud)$" - "move cursor -15 -10, class:^(com.nextcloud.desktopclient.nextcloud)$" - "size 400 581, class:^(com.nextcloud.desktopclient.nextcloud)$" - - "workspace special:protonmail silent, class:^(Proton Mail)$" - "workspace special:spot silent, class:^(Spotify)$" - ] - ++ optionals isNvidia [ - "workspace 1 silent, class:^(discord)$" - "workspace 2 silent, class:^(steam)$" - "workspace 2 silent, initialTitle:^(.*Marvel Rivals.*)$" - ]; - - workspace = optionals isNvidia [ - "1, monitor:desc:Acer Technologies Acer K212HQL T3EAA0014201, default:true" - "2, monitor:${cfg.mainMonitor}, default:true" - ]; - - bind = map mkBind [ - { - modifier = "$mainMod"; - key = "Q"; - command = "foot"; - } - - { - modifier = "$mainMod SHIFT"; - key = "C"; - command = "wl-color-picker"; - } - - { - modifier = "$mainMod"; - key = "P"; - dispatcher = "togglespecialworkspace"; - command = "protonmail"; - } - { - modifier = "$mainMod"; - key = "S"; - dispatcher = "togglespecialworkspace"; - command = "spot"; - } - - { - key = "mouse:277"; - dispatcher = "pass"; - command = "class:^(discord)$"; - } - ]; - }; - }; - }; - }; - - # For accurate stack trace - _file = ./packages.nix; -} diff --git a/modules/desktop/environment/modules/printer.nix b/modules/desktop/environment/modules/printer.nix deleted file mode 100644 index 2bae944f..00000000 --- a/modules/desktop/environment/modules/printer.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) attrValues mkIf; - - cfg = config.roles.desktop; -in { - config = mkIf cfg.enable { - services = { - # Enable CUPS to print documents. - printing = { - enable = true; - - drivers = attrValues { - inherit - (pkgs) - hplip - samsung-unified-linux-driver - ; - }; - }; - }; - }; - - # For accurate stack trace - _file = ./printer.nix; -} diff --git a/modules/desktop/environment/modules/ratbag-mice.nix b/modules/desktop/environment/modules/ratbag-mice.nix deleted file mode 100644 index c788072e..00000000 --- a/modules/desktop/environment/modules/ratbag-mice.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (pkgs.selfPackages) libratbag piper; - inherit (lib) mkIf; - - cfg = config.roles.desktop; -in { - config = mkIf cfg.enable { - services.ratbagd = { - enable = true; - - package = libratbag; - }; - - environment.systemPackages = [ - piper - ]; - }; -} diff --git a/modules/desktop/environment/modules/security.nix b/modules/desktop/environment/modules/security.nix deleted file mode 100644 index b8ddfc7b..00000000 --- a/modules/desktop/environment/modules/security.nix +++ /dev/null @@ -1,105 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (self.lib.hypr) mkBind; - - inherit (lib) getExe map mkIf; - - cfg = config.roles.desktop; - - hmCfg = config.home-manager.users.${cfg.user}; - hyprPkg = hmCfg.wayland.windowManager.hyprland.finalPackage; - - # See modules/ags/packages.nix - lockPkg = hmCfg.programs.ags.lockPkg; - - runInDesktop = pkgs.writeShellApplication { - name = "runInDesktop"; - runtimeInputs = [ - pkgs.sudo - hyprPkg - ]; - - text = '' - params=( "$@" ) - user="$(id -u ${cfg.user})" - readarray -t SIGS <<< "$(ls "/run/user/$user/hypr/")" - - run() { - export HYPRLAND_INSTANCE_SIGNATURE="$1" - sudo -Eu ${cfg.user} hyprctl dispatch exec "''${params[@]}" - } - - i=0 - - while ! run "''${SIGS[$i]}"; do - ((i+=1)) - done - ''; - }; -in { - config = mkIf cfg.enable { - services.acpid = mkIf cfg.isLaptop { - enable = true; - - lidEventCommands = - # bash - '' - LID="/proc/acpi/button/lid/LID/state" - state=$(${pkgs.gawk}/bin/awk '{print $2}' "$LID") - - case "$state" in - *open*) - ${getExe runInDesktop} "${getExe lockPkg} request 'authFinger()'" - ;; - - *close*) - ${getExe runInDesktop} "${getExe lockPkg}" - ;; - - *) - logger -t lid-handler "Failed to detect lid state ($state)" - ;; - esac - ''; - }; - - home-manager.users.${cfg.user} = { - home.packages = [ - pkgs.seahorse - lockPkg - ]; - - wayland.windowManager.hyprland.settings = { - exec-once = [ - "gnome-keyring-daemon --start --components=secrets" - "${pkgs.plasma5Packages.polkit-kde-agent}/libexec/polkit-kde-authentication-agent-1" - ]; - - windowrule = [ - "float , class:^(org.kde.polkit-kde-authentication-agent-1)$" - "size 741 288, class:^(org.kde.polkit-kde-authentication-agent-1)$" - "center , class:^(org.kde.polkit-kde-authentication-agent-1)$" - - # For GParted auth - "size 741 288 , class:^(ssh-askpass)$" - "move cursor -370 -144, class:^(ssh-askpass)$" - ]; - - bind = map mkBind [ - { - modifier = "$mainMod"; - key = "L"; - command = getExe lockPkg; - } - ]; - }; - }; - }; - - # For accurate stack trace - _file = ./security.nix; -} diff --git a/modules/desktop/manager/ags/default.nix b/modules/desktop/manager/ags/default.nix deleted file mode 100644 index 80dba026..00000000 --- a/modules/desktop/manager/ags/default.nix +++ /dev/null @@ -1,64 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (lib) mkIf; - - cfg = config.roles.desktop; - agsCfg = hmCfg.programs.ags; - hmCfg = config.home-manager.users.${cfg.user}; - - hyprland = hmCfg.wayland.windowManager.hyprland.finalPackage; - - agsConfig = let - homeFiles = config.home-manager.users.${cfg.user}.home.file; - nodeModules = homeFiles."${agsCfg.configDir}/node_modules".source; - in - pkgs.runCommandLocal "agsConfig" {} '' - cp -ar ${../../../ags/config}/* ./. - chmod +w -R ./. - cp -ar ${nodeModules} ./node_modules - ${agsCfg.package}/bin/ags bundle ./app.ts $out - ''; -in { - config = mkIf cfg.enable { - assertions = [ - { - assertion = cfg.ags.enable; - message = '' - The Display Manager requires AGS to be enabled. - ''; - } - ]; - - # Add home folder for home-manager to work - users.users.greeter = { - home = "/var/lib/greeter"; - createHome = true; - }; - - home-manager.users.greeter = { - home.packages = [ - hyprland - - (pkgs.writeShellApplication { - name = "agsGreeter"; - - runtimeInputs = [ - agsCfg.package - hyprland - ]; - - text = '' - exec ags run ${agsConfig} -a greeter - ''; - }) - ]; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/desktop/manager/default.nix b/modules/desktop/manager/default.nix deleted file mode 100644 index 0a8cb915..00000000 --- a/modules/desktop/manager/default.nix +++ /dev/null @@ -1,52 +0,0 @@ -self: { - config, - lib, - ... -}: let - inherit (lib) getExe mkIf; - - cfg = config.roles.desktop; - - hyprland = - config - .home-manager - .users - .${cfg.user} - .wayland - .windowManager - .hyprland - .finalPackage; -in { - imports = [ - (import ./ags self) - (import ./hyprland self) - ]; - - config = mkIf (cfg.enable && cfg.displayManager.enable) { - services = { - displayManager.sessionPackages = [hyprland]; - - greetd = { - enable = true; - settings = { - default_session = { - command = getExe hyprland; - user = "greeter"; - }; - - initial_session = { - command = getExe hyprland; - user = cfg.user; - }; - }; - }; - }; - - # unlock GPG keyring on login - services.gnome.gnome-keyring.enable = true; - security.pam.services.greetd.enableGnomeKeyring = true; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/desktop/manager/hyprland/default.nix b/modules/desktop/manager/hyprland/default.nix deleted file mode 100644 index dd4ba5ab..00000000 --- a/modules/desktop/manager/hyprland/default.nix +++ /dev/null @@ -1,77 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (self.lib.hypr) mkAnimation; - - inherit (lib) mkIf optionals; - - inherit (import ./setupMonitors.nix {inherit config pkgs;}) setupMonitors; - - cfg = config.roles.desktop; - - cfgHypr = - config - .home-manager - .users - .${cfg.user} - .wayland - .windowManager - .hyprland; -in { - config = mkIf cfg.enable { - home-manager.users.greeter = { - imports = [ - (import ../../theme self) - ]; - - wayland.windowManager.hyprland = { - enable = true; - systemd.enable = false; - - package = cfgHypr.finalPackage; - - settings = { - inherit (cfgHypr.settings) cursor device ecosystem input misc monitor; - - envd = optionals (config.nvidia.enable) [ - "LIBVA_DRIVER_NAME, nvidia" - "NVD_BACKEND, direct" - "XDG_SESSION_TYPE, wayland" - "GBM_BACKEND, nvidia-drm" - "__GLX_VENDOR_LIBRARY_NAME, nvidia" - ]; - - general.border_size = 0; - - decoration = { - blur.enabled = false; - shadow.enabled = false; - }; - - animation = map mkAnimation [ - { - name = "fadeLayersIn"; - enable = false; - } - { - name = "layers"; - duration = 4; - style = "popin"; - } - ]; - - exec-once = [ - setupMonitors - "agsGreeter &> /tmp/ags-greetd.log; hyprctl dispatch exit" - ]; - }; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/desktop/manager/hyprland/setupMonitors.nix b/modules/desktop/manager/hyprland/setupMonitors.nix deleted file mode 100644 index 063faeaa..00000000 --- a/modules/desktop/manager/hyprland/setupMonitors.nix +++ /dev/null @@ -1,53 +0,0 @@ -{ - config, - pkgs, - ... -}: let - inherit (pkgs.lib) getExe; - - cfg = config.roles.desktop; - - hyprland = - config - .home-manager - .users - .${cfg.user} - .wayland - .windowManager - .hyprland - .finalPackage; - - # Show Regreet on all monitors - dupeMonitors = pkgs.writeShellApplication { - name = "dupeMonitors"; - runtimeInputs = [hyprland pkgs.jq]; - text = '' - main="${cfg.mainMonitor}" - names="($(hyprctl -j monitors | jq -r '.[] .description'))" - - if [[ "$main" == "null" ]]; then - main="''${names[0]}" - fi - - for (( i=0; i<''${#names[@]}; i++ )); do - - # shellcheck disable=SC2001 - name=$(echo "''${names[$i]}" | sed 's/.*(\(.*\))/\1/') - # shellcheck disable=SC2001 - desc=$(echo "''${names[$i]}" | sed 's/ (.*//') - - if [[ "$name" != "$main" && "desc:$desc" != "$main" ]]; then - hyprctl keyword monitor "$name",preferred,auto,1,mirror,"$main" - fi - done - - hyprctl dispatch focusmonitor "$main" - ''; - }; - # Check if user wants the greeter only on main monitor -in { - setupMonitors = - if (cfg.mainMonitor != "null" && !cfg.displayManager.duplicateScreen) - then "hyprctl dispatch focusmonitor ${cfg.mainMonitor}" - else getExe dupeMonitors; -} diff --git a/modules/desktop/theme/cursors/default.nix b/modules/desktop/theme/cursors/default.nix deleted file mode 100644 index cd6a973b..00000000 --- a/modules/desktop/theme/cursors/default.nix +++ /dev/null @@ -1,33 +0,0 @@ -self: { - lib, - osConfig, - pkgs, - ... -}: let - inherit (pkgs.scopedPackages) dracula; - - inherit (lib) mkIf; - - cfg = osConfig.roles.desktop; -in { - config = mkIf cfg.enable { - home.pointerCursor = { - name = "Dracula-cursors"; - package = dracula.gtk; - size = 24; - - gtk.enable = true; - hyprcursor.enable = true; - }; - - # Fixes Gtk4 apps complaining about mismatched cursor size - wayland.windowManager.hyprland.settings = { - exec-once = [ - "gsettings set org.gnome.desktop.interface cursor-size 30" - ]; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/desktop/theme/default.nix b/modules/desktop/theme/default.nix deleted file mode 100644 index 5044f7ce..00000000 --- a/modules/desktop/theme/default.nix +++ /dev/null @@ -1,39 +0,0 @@ -self: { - lib, - osConfig, - ... -}: let - inherit (lib) mkIf; - - cfg = osConfig.roles.desktop; -in { - imports = [ - ./gtk - ./hyprpaper - ./xresources - - (import ./cursors self) - (import ./qt self) - ]; - - config = mkIf cfg.enable { - wayland.windowManager.hyprland = { - settings = { - windowrule = [ - "size 1231 950, title:^(Open Folder)$" - "float , title:^(Open Folder)$" - - "size 1231 950, title:^(Open File)$" - "float , title:^(Open File)$" - ]; - - layerrule = [ - "noanim, selection" - ]; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/desktop/theme/gtk/default.nix b/modules/desktop/theme/gtk/default.nix deleted file mode 100644 index 677e1a19..00000000 --- a/modules/desktop/theme/gtk/default.nix +++ /dev/null @@ -1,66 +0,0 @@ -{ - pkgs, - lib, - osConfig, - ... -}: let - inherit (lib) mkIf; - - inherit (import ./gradience.nix {inherit pkgs lib;}) gradience; - - cfg = osConfig.roles.desktop; -in { - config = mkIf cfg.enable { - home.packages = [ - pkgs.gnomeExtensions.user-themes - ]; - - # Gtk settings - gtk = { - enable = true; - - theme = { - name = "adw-gtk3"; - package = pkgs.adw-gtk3; - }; - - iconTheme = { - name = "Flat-Remix-Violet-Dark"; - package = pkgs.flat-remix-icon-theme; - }; - - font = { - name = "Sans Serif"; - size = cfg.fontSize; - }; - - gtk3 = { - extraConfig = { - "gtk-application-prefer-dark-theme" = 1; - }; - extraCss = "@import url(\"file://${gradience.build}/gtk-3.0/gtk.css\");"; - }; - - gtk4.extraCss = "@import url(\"file://${gradience.build}/gtk-4.0/gtk.css\");"; - }; - - dconf.settings = { - "org/gnome/shell/extensions/user-theme" = { - name = gradience.shellTheme; - }; - "org/gnome/shell" = { - enabled-extensions = [pkgs.gnomeExtensions.user-themes.extensionUuid]; - }; - }; - - xdg.dataFile.shellTheme = { - enable = true; - recursive = true; - source = "${gradience.build}/gradience-shell"; - target = "themes/${gradience.shellTheme}"; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/desktop/theme/gtk/gradience.nix b/modules/desktop/theme/gtk/gradience.nix deleted file mode 100644 index 60488b4d..00000000 --- a/modules/desktop/theme/gtk/gradience.nix +++ /dev/null @@ -1,56 +0,0 @@ -{pkgs, ...}: { - gradience = rec { - # https://github.com/V-Mann-Nick/nix-home-manager/blob/main/gnome/theme.nix - package = pkgs.gradience.overrideAttrs (old: { - version = "0.8.0-beta1"; - propagatedBuildInputs = old.propagatedBuildInputs ++ [pkgs.python3Packages.libsass]; - src = pkgs.fetchgit { - url = "https://github.com/GradienceTeam/Gradience.git"; - rev = "06b83cee3b84916ab9812a47a84a28ca43c8e53f"; - sha256 = "sha256-gdY5QG0STLHY9bw5vI49rY6oNT8Gg8oxqHeEbqM4XfM="; - fetchSubmodules = true; - }; - patches = - (old.patches or []) - ++ [ - (pkgs.fetchpatch { - url = "https://github.com/V-Mann-Nick/nix-home-manager/raw/e68c661f21bf17323f8f0657f3af06c7f837cc07/gnome/gradience.patch"; - hash = "sha256-CcOd5KXjSSwYan8MwIJ4SBmmMXriBlOLYk5XFADLf6c="; - }) - ]; - }); - - # Stub the gnome-shell binary to satisfy the check without downloading Gnome - gnomeShellStub = pkgs.writeShellScriptBin "gnome-shell" '' - echo "GNOME Shell 45.2" - ''; - - presets = pkgs.fetchFromGitHub { - owner = "GradienceTeam"; - repo = "Community"; - rev = "b3628d28164d91b3be1cc4736cd77a19c5da4d74"; - hash = "sha256-tpS6LpPKedPBvI51bD/g299nYM7gY8C1+AmGza1FJ4w="; - }; - - build = pkgs.stdenv.mkDerivation { - name = "gradience-build"; - phases = ["buildPhase" "installPhase"]; - nativeBuildInputs = [gnomeShellStub]; - buildPhase = '' - export HOME=$TMPDIR - export XDG_CURRENT_DESKTOP=GNOME - mkdir -p $HOME/.config/presets - ${package}/bin/gradience-cli apply -p "${presets}/curated/dracula-dark.json" --gtk both - ${package}/bin/gradience-cli gnome-shell -p "${presets}/curated/dracula-dark.json" -v dark - ''; - installPhase = '' - mkdir -p $out - cp -r .config/gtk-4.0 $out/ - cp -r .config/gtk-3.0 $out/ - cp -r .local/share/themes/gradience-shell $out/ - ''; - }; - - shellTheme = "gradience-shell"; - }; -} diff --git a/modules/desktop/theme/hyprpaper/default.nix b/modules/desktop/theme/hyprpaper/default.nix deleted file mode 100644 index d864e309..00000000 --- a/modules/desktop/theme/hyprpaper/default.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ - lib, - osConfig, - pkgs, - ... -}: let - inherit (lib) mkIf; - - cfg = osConfig.roles.desktop; - wallpaper = toString pkgs.scopedPackages.dracula.wallpaper; -in { - config = mkIf cfg.enable { - home.packages = [pkgs.hyprpaper]; - - xdg.configFile."hypr/hyprpaper.conf" = { - text = lib.hm.generators.toHyprconf { - attrs = { - ipc = "on"; - splash = false; - - preload = [wallpaper]; - - wallpaper = [ - ",${wallpaper}" - ]; - }; - }; - }; - }; -} diff --git a/modules/desktop/theme/qt/default.nix b/modules/desktop/theme/qt/default.nix deleted file mode 100644 index e34229ee..00000000 --- a/modules/desktop/theme/qt/default.nix +++ /dev/null @@ -1,50 +0,0 @@ -self: { - lib, - osConfig, - pkgs, - ... -}: let - inherit (pkgs.scopedPackages) dracula; - - inherit (lib) mkIf; - - cfg = osConfig.roles.desktop; -in { - config = mkIf cfg.enable { - home.packages = [ - pkgs.libsForQt5.qtstyleplugin-kvantum - pkgs.kdePackages.qtstyleplugin-kvantum - ]; - - qt = { - enable = true; - style.name = "kvantum"; - platformTheme.name = "qtct"; - }; - - xdg.configFile = let - floatFont = lib.strings.floatToString cfg.fontSize; - qtconf = - # ini - '' - [Fonts] - fixed="Sans Serif,${floatFont},-1,5,50,0,0,0,0,0" - general="Sans Serif,${floatFont},-1,5,50,0,0,0,0,0" - - [Appearance] - icon_theme=Flat-Remix-Violet-Dark - style=''; - # The newline before this must be there - in { - "Kvantum/Dracula/Dracula.kvconfig".source = "${dracula.gtk}/share/Kvantum/Dracula-purple-solid/Dracula-purple-solid.kvconfig"; - "Kvantum/Dracula/Dracula.svg".source = "${dracula.gtk}/share/Kvantum/Dracula-purple-solid/Dracula-purple-solid.svg"; - "Kvantum/kvantum.kvconfig".text = "[General]\ntheme=Dracula"; - - "qt5ct/qt5ct.conf".text = qtconf + "kvantum"; - "qt6ct/qt6ct.conf".text = qtconf + "kvantum"; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/desktop/theme/xresources/default.nix b/modules/desktop/theme/xresources/default.nix deleted file mode 100644 index 7776d962..00000000 --- a/modules/desktop/theme/xresources/default.nix +++ /dev/null @@ -1,36 +0,0 @@ -{ - lib, - osConfig, - ... -}: let - inherit (lib) mkIf; - - cfg = osConfig.roles.desktop; -in { - config = mkIf cfg.enable { - xresources.extraConfig = '' - ! Dracula Xresources palette - *.foreground: #F8F8F2 - *.background: #282A36 - *.color0: #000000 - *.color8: #4D4D4D - *.color1: #FF5555 - *.color9: #FF6E67 - *.color2: #50FA7B - *.color10: #5AF78E - *.color3: #F1FA8C - *.color11: #F4F99D - *.color4: #BD93F9 - *.color12: #CAA9FA - *.color5: #FF79C6 - *.color13: #FF92D0 - *.color6: #8BE9FD - *.color14: #9AEDFE - *.color7: #BFBFBF - *.color15: #E6E6E6 - ''; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/docker/.template/compose.nix b/modules/docker/.template/compose.nix deleted file mode 100644 index b73d1b4b..00000000 --- a/modules/docker/.template/compose.nix +++ /dev/null @@ -1,12 +0,0 @@ -rwDataDir: {config, ...}: let - inherit (config.sops) secrets; - - rwPath = rwDataDir + "/projectName"; -in { - virtualisation.docker.compose."projectName" = { - services = {}; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/docker/.template/images/image.nix b/modules/docker/.template/images/image.nix deleted file mode 100644 index 152d9b12..00000000 --- a/modules/docker/.template/images/image.nix +++ /dev/null @@ -1,8 +0,0 @@ -pkgs: -pkgs.dockerTools.pullImage rec { - imageName = "some/image/name"; - imageDigest = ""; - sha256 = ""; - finalImageName = imageName; - finalImageTag = "latest"; -} diff --git a/modules/docker/default.nix b/modules/docker/default.nix deleted file mode 100644 index a527bca6..00000000 --- a/modules/docker/default.nix +++ /dev/null @@ -1,52 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (lib) mkIf mkOption types; - - cfg = config.roles.docker; -in { - imports = [self.inputs.docker-compose.nixosModules.default]; - - options.roles.docker = { - enable = mkOption { - default = cfg.compositions != {}; - type = types.bool; - description = '' - Option to enable docker even without compositions. - ''; - }; - - storageDriver = mkOption { - default = "btrfs"; # I use BTRFS on all my servers - type = types.str; - }; - }; - - config = mkIf cfg.enable { - virtualisation = { - docker = { - enable = true; - storageDriver = cfg.storageDriver; - - daemon.settings.dns = ["8.8.8.8" "1.1.1.1"]; - }; - }; - - # Script for updating the images of a compose.nix file - environment.systemPackages = [ - (pkgs.callPackage ./updateImage.nix {}) - ]; - - home-manager.users.root.home.file.".docker/config.json".text = '' - { - "psFormat": "table {{.ID}}\\t{{.Image}}\\t{{.Names}}\\t{{.Status}}" - } - ''; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/docker/updateImage.nix b/modules/docker/updateImage.nix deleted file mode 100644 index cea02e50..00000000 --- a/modules/docker/updateImage.nix +++ /dev/null @@ -1,40 +0,0 @@ -{ - nix-prefetch-docker, - skopeo, - writeShellApplication, - ... -}: -writeShellApplication { - name = "updateImages"; - - runtimeInputs = [ - (writeShellApplication { - name = "pullImage"; - runtimeInputs = [nix-prefetch-docker skopeo]; - text = '' - FILE="$1" - - IMAGE=$(sed -n 's/.*imageName = "\([^"]*\).*/\1/p' "$FILE") - TAG=$(sed -n 's/.*finalImageTag = "\([^"]*\).*/\1/p' "$FILE") - CURRENT_DIGEST=$(sed -n 's/.*imageDigest = "\([^"]*\).*/\1/p' "$FILE") - NEW_DIGEST=$(skopeo inspect "docker://$IMAGE:$TAG" | jq '.Digest' -r) - - output="$IMAGE $TAG" - - if ! grep "Locked" "$FILE"; then - if [[ "$CURRENT_DIGEST" != "$NEW_DIGEST" ]]; then - echo -e "• $output:\n $CURRENT_DIGEST\n → $NEW_DIGEST\n" - PREFETCH=$(nix-prefetch-docker "$IMAGE" "$TAG") - echo -e "pkgs:\npkgs.dockerTools.pullImage rec $PREFETCH" > "$FILE" - sed -i 's/finalImageName.*/finalImageName = imageName;/' "$FILE" - fi - fi - ''; - }) - ]; - - text = '' - DIR=''${1:-"."} - find "$DIR"/images -type f -exec pullImage {} \; - ''; -} diff --git a/modules/esphome-plus/default.nix b/modules/esphome-plus/default.nix deleted file mode 100644 index 07db3c08..00000000 --- a/modules/esphome-plus/default.nix +++ /dev/null @@ -1,132 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) converge getExe mkOption types; - inherit (lib.modules) mkForce mkIf; - inherit (lib.lists) elem; - inherit (lib.strings) concatMapStringsSep optionalString; - inherit (lib.attrsets) mapAttrsToList filterAttrsRecursive optionalAttrs; - - cfg = config.services.esphome; - - stateDir = "/var/lib/esphome"; - format = pkgs.formats.yaml {}; - - # Adapted from https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/home-automation/home-assistant.nix - mkESPConf = n: cfg: let - filteredConfig = converge (filterAttrsRecursive (_: v: ! elem v [null])) cfg; - in rec { - name = "${n}-nix.yaml"; - file = pkgs.runCommandLocal name {} '' - cp ${format.generate name filteredConfig} $out - sed -i -e "s/'\!\([a-z_]\+\) \(.*\)'/\!\1 \2/;s/^\!\!/\!/;" $out - sed -i 's/ {}//g' $out - sed -i "s/'\"/\"/g" $out - sed -i "s/\"'/\"/g" $out - ''; - }; -in { - options.services.esphome = { - firmwareConfigs = mkOption { - default = {}; - type = with types; attrsOf anything; - }; - - secretsFile = mkOption { - default = null; - type = types.nullOr types.path; - }; - }; - - config = mkIf cfg.enable { - # Fixes https://github.com/NixOS/nixpkgs/issues/339557 - users = { - users.esphome = { - isNormalUser = true; - group = "esphome"; - home = stateDir; - }; - groups.esphome = {}; - }; - - # Fixes https://github.com/NixOS/nixpkgs/issues/370611 - nixpkgs.overlays = [ - (final: prev: { - esphome = prev.esphome.overrideAttrs (o: { - patches = [ - (builtins.toFile "post-build.patch" '' - --- a/esphome/components/esp32/post_build.py.script - +++ b/esphome/components/esp32/post_build.py.script - @@ -2,10 +2,13 @@ - - # pylint: disable=E0602 - Import("env") # noqa - +#print(env.Dump()) - - import os - import shutil - - +os.environ["PATH"] = os.path.dirname(env.get("PYTHONEXE")) + os.pathsep + os.environ["PATH"] - + - if os.environ.get("ESPHOME_USE_SUBPROCESS") is None: - try: - import esptool - @@ -63,6 +66,7 @@ def esp32_create_combined_bin(source, target, env): - esptool.main(cmd) - else: - subprocess.run(["esptool.py", *cmd]) - + #subprocess.run([env.get("PYTHONEXE"), "/var/lib/esphome/.platformio/packages/tool-esptoolpy/esptool.py", *cmd]) - - - def esp32_copy_ota_bin(source, target, env): - '') - ]; - }); - }) - ]; - - systemd.services.esphome = { - serviceConfig = - (optionalAttrs (cfg.firmwareConfigs != {}) { - ExecStartPre = getExe (pkgs.writeShellApplication { - name = "esphome-exec-start-pre"; - - runtimeInputs = [ - pkgs.findutils - ]; - - text = '' - shopt -s nullglob - - for file in ${stateDir}/*-nix.yaml; do - rm "$file" - done - - ${optionalString - (cfg.secretsFile != null) - # bash - '' - cp -f "$(realpath "${cfg.secretsFile}")" ${stateDir}/secrets.yaml - ''} - - ${concatMapStringsSep - "\n" - (dev: - # bash - '' - cp -f "$(realpath "${dev.file}")" ${stateDir}/"${dev.name}" - '') - (mapAttrsToList mkESPConf cfg.firmwareConfigs)} - ''; - }); - }) - // { - # Fixes https://github.com/NixOS/nixpkgs/issues/339557 - DynamicUser = mkForce "off"; - }; - }; - }; -} diff --git a/modules/ha-plus/default.nix b/modules/ha-plus/default.nix deleted file mode 100644 index 0f8b0a9d..00000000 --- a/modules/ha-plus/default.nix +++ /dev/null @@ -1,104 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) any attrValues concatMapStringsSep getExe mapAttrs' mkDefault mkDerivedConfig mkIf mkOption nameValuePair replaceStrings types; - - cfg = config.services.home-assistant; - format = pkgs.formats.yaml {}; - configFilesList = attrValues cfg.configFiles; -in { - options.services.home-assistant = { - configFiles = mkOption { - default = {}; - description = '' - Set of files that have to be linked in the configuration directory. - ''; - - type = types.attrsOf (types.submodule ( - { - name, - config, - options, - ... - }: { - options = { - enable = mkOption { - type = types.bool; - default = true; - description = '' - Whether this file should be generated. This - option allows specific files to be disabled. - ''; - }; - - target = mkOption { - type = types.str; - description = '' - Name of symlink (relative to config directory). - Defaults to the attribute name. - ''; - }; - - text = mkOption { - default = null; - type = types.nullOr types.lines; - description = "Text of the file."; - }; - - source = mkOption { - type = types.path; - description = "Path of the source file."; - }; - }; - - config = { - target = mkDefault name; - source = mkIf (config.text != null) ( - let - name' = "haConf-" + replaceStrings ["/"] ["-"] name; - in - mkDerivedConfig options.text (pkgs.writeText name') - ); - }; - } - )); - }; - - customSentences = mkOption { - type = types.attrsOf (types.submodule { - freeformType = format.type; - options.language = mkOption { - type = types.str; - }; - }); - }; - }; - - config = mkIf cfg.enable { - systemd.services.home-assistant = - mkIf ( - cfg.configFiles != {} && any (c: c.enable) configFilesList - ) { - preStart = let - inherit (cfg) configDir; - mkLink = configFile: '' - mkdir -p ${configDir}/${dirOf configFile.target} - cp -rf ${configFile.source} ${configDir}/${configFile.target} - ''; - in - getExe (pkgs.writeShellApplication { - name = "home-assistant-pre-start"; - text = concatMapStringsSep "\n" mkLink configFilesList; - }); - }; - - services.home-assistant.configFiles = mapAttrs' (n: v: - nameValuePair "custom_sentences/${v.language}/${n}.yaml" { - source = format.generate n v; - }) - cfg.customSentences; - }; -} diff --git a/modules/kmscon/default.nix b/modules/kmscon/default.nix deleted file mode 100644 index fc20a0ff..00000000 --- a/modules/kmscon/default.nix +++ /dev/null @@ -1,42 +0,0 @@ -{ - config, - lib, - ... -}: let - inherit (lib) concatStringsSep elemAt mkIf mkOption types; - - cfg = config.services.kmscon; -in { - options.services.kmscon = { - fontName = mkOption { - type = types.str; - default = elemAt config.fonts.fontconfig.defaultFonts.monospace 0; - }; - - fontSize = mkOption { - type = types.numbers.nonnegative; - default = 12.5; - }; - - fontDpi = mkOption { - type = types.numbers.nonnegative; - default = 130; - }; - }; - - config = mkIf cfg.enable { - services.kmscon = { - useXkbConfig = true; - hwRender = false; - - extraOptions = concatStringsSep " " [ - "--font-size ${toString cfg.fontSize}" - "--font-dpi ${toString cfg.fontDpi}" - "--font-name '${cfg.fontName}'" - ]; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/meta/default.nix b/modules/meta/default.nix deleted file mode 100644 index 654e2e82..00000000 --- a/modules/meta/default.nix +++ /dev/null @@ -1,15 +0,0 @@ -{lib, ...}: let - inherit (lib) mkOption types; -in { - options.meta = { - roleDescription = mkOption { - type = types.str; - default = ""; - }; - - hardwareDescription = mkOption { - type = types.str; - default = ""; - }; - }; -} diff --git a/modules/nvidia/default.nix b/modules/nvidia/default.nix deleted file mode 100644 index b9eaa0bd..00000000 --- a/modules/nvidia/default.nix +++ /dev/null @@ -1,110 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (builtins) toJSON; - inherit (lib) attrValues mkIf mkEnableOption mkOption optionals optionalString types; - - cfg = config.nvidia; -in { - options.nvidia = { - enable = mkEnableOption "nvidia"; - - enableNvidiaSettings = mkOption { - type = types.bool; - default = false; - }; - - enableWayland = mkOption { - type = types.bool; - default = false; - }; - - enableCUDA = mkOption { - type = types.bool; - default = false; - }; - }; - - config = mkIf cfg.enable { - hardware.graphics = { - enable = true; - enable32Bit = true; - - extraPackages = attrValues { - inherit - (pkgs) - vaapiVdpau - libvdpau-va-gl - nvidia-vaapi-driver - ; - }; - extraPackages32 = attrValues { - inherit - (pkgs) - vaapiVdpau - ; - }; - }; - - services.xserver.videoDrivers = ["nvidia"]; - - hardware.nvidia = { - open = true; - - package = config.boot.kernelPackages.nvidiaPackages.latest; - - # Whether to enable nvidia-settings, NVIDIA's GUI configuration tool - nvidiaSettings = cfg.enableNvidiaSettings; - }; - - environment.systemPackages = - optionals cfg.enableCUDA [pkgs.cudaPackages.cudatoolkit] - ++ (attrValues { - inherit (pkgs.nvtopPackages) nvidia; - inherit - (pkgs) - libva-utils - nvidia-vaapi-driver - pciutils - vdpauinfo - ; - }); - - boot.kernelModules = - optionals cfg.enableCUDA ["nvidia-uvm"] - ++ ["nvidia" "nvidia-drm"]; - - # Fixes egl-wayland issues with beta drivers - # https://github.com/hyprwm/Hyprland/issues/7202 - environment.etc = let - mkEglFile = n: library: let - suffix = optionalString (library != "wayland") ".1"; - pkg = - if library != "wayland" - then config.hardware.nvidia.package - else pkgs.egl-wayland; - - fileName = "${toString n}_nvidia_${library}.json"; - library_path = "${pkg}/lib/libnvidia-egl-${library}.so${suffix}"; - in { - "egl/egl_external_platform.d/${fileName}".source = pkgs.writeText fileName (toJSON { - file_format_version = "1.0.0"; - ICD = {inherit library_path;}; - }); - }; - in - mkIf cfg.enableWayland ( - {"egl/egl_external_platform.d".enable = false;} - // mkEglFile 10 "wayland" - // mkEglFile 15 "gbm" - // mkEglFile 20 "xcb" - // mkEglFile 20 "xlib" - ); - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/plymouth/default.nix b/modules/plymouth/default.nix deleted file mode 100644 index 7a3f9e52..00000000 --- a/modules/plymouth/default.nix +++ /dev/null @@ -1,36 +0,0 @@ -{ - config, - lib, - ... -}: let - inherit (lib) mkIf; - - cfg = config.boot.plymouth; -in { - config = mkIf cfg.enable { - boot = { - initrd = { - verbose = false; - systemd.enable = true; - }; - - consoleLogLevel = 0; - - kernelParams = [ - "quiet" - "splash" - "boot.shell_on_fail" - "i915.fastboot=1" - "loglevel=3" - "rd.systemd.show_status=false" - "rd.udev.log_level=3" - "udev.log_priority=3" - ]; - - loader.timeout = 0; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/server/default.nix b/modules/server/default.nix deleted file mode 100644 index 3d7446a2..00000000 --- a/modules/server/default.nix +++ /dev/null @@ -1,35 +0,0 @@ -{lib, ...}: let - inherit (lib) mkOption types; -in { - imports = [ - ./sshd - ./tailscale - ]; - - options.roles.server = { - enable = mkOption { - type = types.bool; - default = false; - }; - - user = mkOption { - type = types.str; - description = '' - The name of the machine's main user. - ''; - }; - - sshd.enable = mkOption { - type = types.bool; - default = false; - }; - - tailscale.enable = mkOption { - type = types.bool; - default = false; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/server/sshd/default.nix b/modules/server/sshd/default.nix deleted file mode 100644 index efdc8041..00000000 --- a/modules/server/sshd/default.nix +++ /dev/null @@ -1,33 +0,0 @@ -{ - config, - lib, - ... -}: let - inherit (lib) mkForce mkIf; - - cfg = config.roles.server; -in { - config = mkIf (cfg.enable && cfg.sshd.enable) { - services = { - openssh = { - enable = true; - settings = { - PasswordAuthentication = false; - PermitRootLogin = mkForce "no"; - }; - }; - }; - - users.users.${cfg.user} = { - openssh.authorizedKeys.keys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPE39uk52+NIDLdHeoSHIEsOUUFRzj06AGn09z4TUOYm matt@OP9" - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICr2+CpqXNMLsjgbrYyIwTKhlVSiIYol1ghBPzLmUpKl matt@binto" - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJGbLu+Gb7PiyNgNXMHemaQLnKixebx1/4cdJGna9OQp matt@wim" - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII1bYbOemBJHjm5onaRE52YvGiTAr+bS0l4tCjXSXud9 matt@servivi" - ]; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/server/tailscale/default.nix b/modules/server/tailscale/default.nix deleted file mode 100644 index 429f8e4c..00000000 --- a/modules/server/tailscale/default.nix +++ /dev/null @@ -1,48 +0,0 @@ -{ - config, - lib, - ... -}: let - inherit (lib) mkIf; - inherit (config.networking) hostName; - - cfg = config.roles.server; -in { - config = mkIf (cfg.enable && cfg.tailscale.enable) { - services = { - tailscale = { - enable = true; - - extraSetFlags = [ - "--operator=${cfg.user}" - ]; - }; - }; - - home-manager.users.${cfg.user} = { - programs.bash.shellAliases = { - # Connect to headscale - tup = "tailscale up --login-server https://headscale.nelim.org"; - - # Desktop - pc = "ssh -t matt@binto 'tmux -2u new -At ${hostName}'"; - - # NAS - nos = "ssh -t matt@nos 'tmux -2u new -At ${hostName}'"; - - # Experimenting server - servivi = "ssh -t matt@servivi 'tmux -2u new -At ${hostName}'"; - - # Home-assistant - homie = "ssh -t matt@homie 'tmux -2u new -At ${hostName}'"; - - # Cluster nodes - thingone = "ssh -t matt@thingone 'tmux -2u new -At ${hostName}'"; - thingtwo = "ssh -t matt@thingtwo 'tmux -2u new -At ${hostName}'"; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/modules/tmux/default.nix b/modules/tmux/default.nix deleted file mode 100644 index fbb0ab67..00000000 --- a/modules/tmux/default.nix +++ /dev/null @@ -1,62 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) attrValues hasAttr head mkIf mkOption types; - - cfg = config.programs.tmux; - - # Support NixOnDroid - firstUser = - if hasAttr "users" config.home-manager - then head (attrValues config.home-manager.users) - else config.home-manager.config; -in { - options.programs.tmux = { - enableCustomConf = mkOption { - type = types.bool; - default = false; - }; - }; - - config = mkIf cfg.enableCustomConf { - environment.etc."tmux.conf".source = firstUser.xdg.configFile."tmux/tmux.conf".source; - - home-manager.sharedModules = [ - { - programs = { - # Make sure we have color support - bash.shellAliases.tmux = "tmux -2"; - - tmux = { - enable = true; - mouse = true; - keyMode = "vi"; - terminal = "tmux-256color"; - newSession = true; - historyLimit = 30000; - - plugins = attrValues { - inherit (pkgs.tmuxPlugins) dracula; - }; - - extraConfig = - # bash - '' - bind-key -n Home send Escape "OH" - bind-key -n End send Escape "OF" - - bind -T root WheelUpPane if-shell -F -t = "#{alternate_on}" "send-keys -M" "select-pane -t =; copy-mode -e; send-keys -M" - bind -T root WheelDownPane if-shell -F -t = "#{alternate_on}" "send-keys -M" "select-pane -t =; send-keys -M" - - set -ga terminal-overrides ',xterm*:smcup@:rmcup@' - set -ga terminal-overrides ",*256col*:Tc" - ''; - }; - }; - } - ]; - }; -} diff --git a/modules/wyoming-plus/default.nix b/modules/wyoming-plus/default.nix deleted file mode 100644 index 6d47b806..00000000 --- a/modules/wyoming-plus/default.nix +++ /dev/null @@ -1,85 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) getExe mkOption types; - inherit (lib.modules) mkForce mkIf mkOverride; - inherit (lib.strings) concatMapStringsSep concatStringsSep escapeShellArgs; - - cfg = config.services.wyoming; - - forkedPkg = pkgs.callPackage ./pkgs {}; -in { - options.services.wyoming.openwakeword.vadThreshold = mkOption { - type = types.float; - default = 0.0; - apply = toString; - }; - - config = { - systemd.services = mkIf (cfg.openwakeword.enable) { - # For some reason I can't just override `ExecStart` anymore. - wyoming-openwakeword.serviceConfig = mkForce { - DynamicUser = true; - User = "wyoming-openwakeword"; - - MemoryDenyWriteExecute = cfg.openwakeword.package != forkedPkg; - - # changes according to https://github.com/rhasspy/wyoming-openwakeword/pull/27 - ExecStart = concatStringsSep " " [ - (getExe cfg.openwakeword.package) - - "--uri ${cfg.openwakeword.uri}" - "--threshold ${cfg.openwakeword.threshold}" - "--vad-threshold ${cfg.openwakeword.vadThreshold}" - "--trigger-level ${cfg.openwakeword.triggerLevel}" - - (concatMapStringsSep " " - (dir: "--custom-model-dir ${toString dir}") - cfg.openwakeword.customModelsDirectories) - - (concatMapStringsSep " " - (model: "--preload-model ${model}") - cfg.openwakeword.preloadModels) - - (escapeShellArgs cfg.openwakeword.extraArgs) - ]; - - CapabilityBoundingSet = ""; - DeviceAllow = ""; - DevicePolicy = "closed"; - LockPersonality = true; - PrivateDevices = true; - PrivateUsers = true; - ProtectHome = true; - ProtectHostname = true; - ProtectKernelLogs = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; - ProtectControlGroups = true; - ProtectProc = "invisible"; - ProcSubset = "all"; # reads /proc/cpuinfo - RestrictAddressFamilies = [ - "AF_INET" - "AF_INET6" - "AF_UNIX" - ]; - RestrictNamespaces = true; - RestrictRealtime = true; - RuntimeDirectory = "wyoming-openwakeword"; - SystemCallArchitectures = "native"; - SystemCallFilter = [ - "@system-service" - "~@privileged" - ]; - UMask = "0077"; - }; - }; - - services.wyoming.openwakeword = mkIf (cfg.openwakeword.enable) { - package = mkOverride 900 forkedPkg; - }; - }; -} diff --git a/modules/wyoming-plus/pkgs/default.nix b/modules/wyoming-plus/pkgs/default.nix deleted file mode 100644 index 9713d4c9..00000000 --- a/modules/wyoming-plus/pkgs/default.nix +++ /dev/null @@ -1,38 +0,0 @@ -{ - lib, - fetchFromGitHub, - onnxruntime, - python3Packages, - wyoming-openwakeword, - ... -}: let - inherit (lib) makeLibraryPath; -in - wyoming-openwakeword.overridePythonAttrs (o: { - version = o.version + "-vad"; - - # https://github.com/rhasspy/wyoming-openwakeword/pull/17 - src = fetchFromGitHub { - owner = "rhasspy"; - repo = "wyoming-openwakeword"; - rev = "8e679a592f5862d67a7b688d3f711b468e4b1f93"; - hash = "sha256-sP0i2ghcTpuuZbVTsAFw527y2oaJIH9OolQtKjkYC2E="; - }; - - buildInputs = - (o.buildInputs or []) - ++ [onnxruntime]; - - propagatedBuildInputs = - (o.propagatedBuildInputs or []) - ++ [python3Packages.onnxruntime]; - - # Native onnxruntime lib used by Python module onnxruntime can't find its other libs without this - makeWrapperArgs = [ - ''--prefix LD_LIBRARY_PATH : "${makeLibraryPath [onnxruntime]}"'' - ]; - - postFixup = '' - cp -ar ./wyoming_openwakeword/models/silero_vad.onnx $out/lib/python*/site-packages/wyoming_openwakeword/models - ''; - }) diff --git a/nixFastChecks/apps/default.nix b/nixFastChecks/apps/default.nix deleted file mode 100644 index 9b171d08..00000000 --- a/nixFastChecks/apps/default.nix +++ /dev/null @@ -1,7 +0,0 @@ -pkgs: let - inherit (pkgs.lib) mapAttrs' nameValuePair; -in - mapAttrs' - (name: app: - nameValuePair "app_${name}" app) - pkgs.appsPackages diff --git a/nixFastChecks/default.nix b/nixFastChecks/default.nix deleted file mode 100644 index 8793f4eb..00000000 --- a/nixFastChecks/default.nix +++ /dev/null @@ -1,18 +0,0 @@ -# Inspired by : -# https://github.com/Mic92/dotfiles/blob/c2f538934d67417941f83d8bb65b8263c43d32ca/flake.nix#L168 -{ - perSystem, - self, - ... -}: let - inherit (self.lib.attrs) recursiveUpdateList; - - apps = perSystem (import ./apps); - devices = perSystem (pkgs: import ./devices {inherit pkgs self;}); - devShells = perSystem (pkgs: import ./devShells {inherit pkgs self;}); - packages = perSystem (import ./packages); -in { - inherit apps devices devShells packages; - - all = recursiveUpdateList [apps devices devShells packages]; -} diff --git a/nixFastChecks/devShells/default.nix b/nixFastChecks/devShells/default.nix deleted file mode 100644 index ae3c1743..00000000 --- a/nixFastChecks/devShells/default.nix +++ /dev/null @@ -1,10 +0,0 @@ -{ - pkgs, - self, -}: let - inherit (pkgs.lib) mapAttrs' nameValuePair; -in - mapAttrs' - (name: shell: - nameValuePair "devShell_${name}" shell) - self.devShells.${pkgs.system} diff --git a/nixFastChecks/devices/default.nix b/nixFastChecks/devices/default.nix deleted file mode 100644 index 9f65666c..00000000 --- a/nixFastChecks/devices/default.nix +++ /dev/null @@ -1,15 +0,0 @@ -{ - pkgs, - self, -}: let - inherit (pkgs.lib) filterAttrs mapAttrs' nameValuePair; - - devices = - filterAttrs - (n: config: config.pkgs.system == pkgs.system) - self.nixosConfigurations; -in - mapAttrs' - (name: config: - nameValuePair "device_${name}" config.config.system.build.toplevel) - devices diff --git a/nixFastChecks/packages/default.nix b/nixFastChecks/packages/default.nix deleted file mode 100644 index 6476bf31..00000000 --- a/nixFastChecks/packages/default.nix +++ /dev/null @@ -1,15 +0,0 @@ -pkgs: let - inherit (pkgs.lib) elem filterAttrs hasAttr mapAttrs' nameValuePair; - - packages = - filterAttrs ( - _: v: - !(hasAttr "platforms" v.meta) - || elem pkgs.system v.meta.platforms - ) - pkgs.selfPackages; -in - mapAttrs' - (name: pkg: - nameValuePair "pkg_${name}" pkg) - packages diff --git a/nixos/cfg/boot.nix b/nixos/cfg/boot.nix new file mode 100644 index 00000000..ee0b95e3 --- /dev/null +++ b/nixos/cfg/boot.nix @@ -0,0 +1,53 @@ +{ config, pkgs, ... }: + +{ + boot = { + kernelPackages = pkgs.linuxPackages_latest; + consoleLogLevel = 0; + initrd.verbose = false; + initrd.systemd.enable = true; + + loader = { + efi.canTouchEfiVariables = true; + grub = { + enable = true; + device = "nodev"; + efiSupport = true; + extraConfig = '' + set timeout_style=hidden + ''; + # Because it still draws that image otherwise + splashImage = null; + }; + timeout = 2; + }; + + extraModulePackages = with config.boot.kernelPackages; [ + v4l2loopback + ]; + + kernelModules = [ "kvm-amd" ]; + + kernelParams = [ + "quiet" + "splash" + "boot.shell_on_fail" + "i915.fastboot=1" + "loglevel=3" + "rd.systemd.show_status=false" + "rd.udev.log_level=3" + "udev.log_priority=3" + "cryptdevice=UUID=ab82b477-2477-453f-b95f-28e5553ad10d:root" + "root=/dev/mapper/root" + ]; + + plymouth = { + enable = true; + themePackages = [ pkgs.dracula-plymouth ]; + theme = "dracula"; + }; + + # https://github.com/NixOS/nixpkgs/issues/254807#issuecomment-1722351771 + swraid.enable = false; + }; +} diff --git a/nixos/cfg/extra-hardware.nix b/nixos/cfg/extra-hardware.nix new file mode 100644 index 00000000..6c5b45e0 --- /dev/null +++ b/nixos/cfg/extra-hardware.nix @@ -0,0 +1,49 @@ +{ config, pkgs, ... }: + +{ + hardware.bluetooth = { + enable = true; + powerOnBoot = true; + }; + + # enable brightness control for swayosd + programs.light.enable = true; + + services = { + + udev.extraRules = '' + # give permanent path to keyboard XF86* binds + SUBSYSTEMS=="input", ATTRS{id/product}=="0006", ATTRS{id/vendor}=="0000", SYMLINK += "video-bus" + ''; + + fwupd.enable = true; + + # Enable CUPS to print documents. + printing.enable = true; + printing.drivers = with pkgs; [ + hplip + ]; + + pipewire = { + enable = true; + alsa.enable = true; + jack.enable = true; + pulse.enable = true; + }; + + upower.enable = true; + }; + + hardware = { + pulseaudio.enable = false; + sensor.iio.enable = true; + opengl.enable = true; + opengl.driSupport32Bit = true; + uinput.enable = true; + }; + + virtualisation = { + libvirtd.enable = true; + waydroid.enable = true; + }; +} diff --git a/nixos/cfg/main.nix b/nixos/cfg/main.nix new file mode 100644 index 00000000..b0b860a9 --- /dev/null +++ b/nixos/cfg/main.nix @@ -0,0 +1,10 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./boot.nix + ./extra-hardware.nix + ./security.nix + ./packages.nix + ]; +} diff --git a/nixos/cfg/packages.nix b/nixos/cfg/packages.nix new file mode 100644 index 00000000..46ae3eac --- /dev/null +++ b/nixos/cfg/packages.nix @@ -0,0 +1,202 @@ +{config, pkgs, lib, ...}: + +{ + systemd.user.services.protonmail-bridge = { + description = "Protonmail Bridge"; + enable = true; + script = "${pkgs.protonmail-bridge}/bin/protonmail-bridge --noninteractive --log-level info"; + path = [ pkgs.gnome.gnome-keyring ]; # HACK: https://github.com/ProtonMail/proton-bridge/issues/176 + wantedBy = [ "graphical-session.target" ]; + partOf = [ "graphical-session.target" ]; + }; + + services = { + xserver = { + enable = true; + layout = "ca"; + displayManager = { + sddm = { + enable = true; + settings = { + General = { + DisplayServer = "wayland"; + InputMethod = ""; + }; + Wayland.CompositorCommand = "${pkgs.weston}/bin/weston --shell=fullscreen-shell.so"; + Theme = { + Current = "Dracula"; + ThemeDir = "${pkgs.dracula-theme}/share/sddm/themes"; + }; + }; + }; + sessionPackages = [ + (builtins.getFlake "github:hyprwm/Hyprland").packages.x86_64-linux.default + ]; + defaultSession = "hyprland"; + autoLogin = { # logs out after a minute + enable = true; + user = "matt"; + }; + }; + libinput.enable = true; + }; + dbus.enable = true; + gvfs.enable = true; + flatpak.enable = true; + tlp.enable = true; + + locate = { + enable = true; + interval = "hourly"; + prunePaths = [ + "/tmp" + "/var/tmp" + "/var/cache" + "/var/lock" + "/var/run" + "/var/spool" + "/nix/var/log/nix" + "/proc" + "/run/user/1000" + "${pkgs.findutils}/" # doesn't work? + ]; + }; + }; + + xdg.portal = { + enable = true; + wlr.enable = true; + extraPortals = [ + pkgs.xdg-desktop-portal-gtk + ]; + }; + + programs = { + + # TODO: install plugins through nix + tmux = { + enable = true; + keyMode = "vi"; + terminal = "screen-256color"; + newSession = true; + historyLimit = 30000; + extraConfig = '' + bind-key -n Home send Escape "OH" + bind-key -n End send Escape "OF" + set -g mouse on + set -ga terminal-overrides ',xterm*:smcup@:rmcup@' + bind -T root WheelUpPane if-shell -F -t = "#{alternate_on}" "send-keys -M" "select-pane -t =; copy-mode -e; send-keys -M" + bind -T root WheelDownPane if-shell -F -t = "#{alternate_on}" "send-keys -M" "select-pane -t =; send-keys -M" + + set -g @plugin 'dracula/tmux' + run 'bash -c "$HOME/.tmux/plugins/tpm/tpm || + ${pkgs.git}/bin/git clone https://github.com/tmux-plugins/tpm $HOME/.tmux/plugins/tpm && + $HOME/.tmux/plugins/tpm/tpm"' + ''; + }; + + git = { # TODO: make better config + enable = true; + lfs.enable = true; + config = { + # Dracula Dark Theme + color = { + ui = "auto"; + branch = { + current = "cyan bold reverse"; + local = "white"; + plain = ""; + remote = "cyan"; + }; + diff = { + commit = ""; + func = "cyan"; + plain = ""; + whitespace = "magenta reverse"; + meta = "white"; + frag = "cyan bold reverse"; + old = "red"; + new = "green"; + }; + grep = { + context = ""; + filename = ""; + function = ""; + linenumber = "white"; + match = ""; + selected = ""; + separator = ""; + }; + interactive = { + error = ""; + header = ""; + help = ""; + prompt = ""; + }; + status = { + added = "green"; + changed = "yellow"; + header = ""; + localBranch = ""; + nobranch = ""; + remoteBranch = "cyan bold"; + unmerged = "magenta bold reverse"; + untracked = "red"; + updated = "green bold"; + }; + }; + }; + }; + + htop = { + enable = true; + }; + + fzf = { + fuzzyCompletion = true; + keybindings = true; + }; + }; + + # List packages in root user PATH + environment.systemPackages = with pkgs; [ + qemu + wl-clipboard + alsa-utils + wget + tree + rsync + killall + imagemagick + usbutils + evtest + plasma5Packages.kio-admin + plasma5Packages.ksshaskpass + plasma5Packages.plasma-framework + plasma5Packages.plasma-workspace + ]; + + fonts = { + fontconfig = { + enable = true; + /*defaultFonts = { + emoji = [ "Noto Color Emoji" ]; + monospace = [ "MesloLGS Nerd Font" ]; + sansSerif = [ "MesloLGS Nerd Font" ]; + serif = [ "MesloLGS Nerd Font" ]; + };*/ + }; + + packages = with pkgs; [ + (nerdfonts.override { fonts = [ "JetBrainsMono" "Go-Mono" "Iosevka" "NerdFontsSymbolsOnly" "SpaceMono" "Ubuntu" ]; }) + noto-fonts + noto-fonts-cjk + noto-fonts-emoji + liberation_ttf + font-awesome + meslo-lgs-nf + jetbrains-mono + ubuntu_font_family + ]; + }; +} diff --git a/nixos/cfg/security.nix b/nixos/cfg/security.nix new file mode 100644 index 00000000..fe493895 --- /dev/null +++ b/nixos/cfg/security.nix @@ -0,0 +1,93 @@ +{ config, pkgs, lib, ... }: + +{ + services.fprintd.enable = true; + + # https://www.reddit.com/r/NixOS/comments/z7i83r/fingertip_tip_start_fprintd_at_boot_for_a_quick/ + systemd.services.fprintd = { + wantedBy = [ "multi-user.target" ]; + serviceConfig.Type = "simple"; + }; + + services.logind.lidSwitch = "lock"; + services.gnome.gnome-keyring.enable = true; + + # Open ports in the firewall. + # networking.firewall.allowedTCPPorts = [ ... ]; + # networking.firewall.allowedUDPPorts = [ ... ]; + # Or disable the firewall altogether. + networking.firewall.enable = false; + + security.sudo.extraConfig = '' + Defaults timestamp_timeout=600 + ''; + + security.pam.services = { + + gtklock = {}; + + # all the changes in /etc/pam.d/* + sddm.text = lib.mkBefore '' + auth [success=1 new_authtok_reqd=1 default=ignore] pam_unix.so try_first_pass likeauth nullok + auth sufficient ${pkgs.fprintd}/lib/security/pam_fprintd.so + ''; + + sudo.text = '' + # Account management. + auth sufficient ${pkgs.pam-fprint-grosshack}/lib/security/pam_fprintd_grosshack.so + auth sufficient pam_unix.so try_first_pass nullok + account required pam_unix.so + + # Authentication management. + auth required pam_deny.so + + # Password management. + password sufficient pam_unix.so nullok yescrypt + + # Session management. + session required pam_env.so conffile=/etc/pam/environment readenv=0 + session required pam_unix.so + ''; + + login.text = '' + # Account management. + account required pam_unix.so + + # Authentication management. + auth sufficient ${pkgs.pam-fprint-grosshack}/lib/security/pam_fprintd_grosshack.so + auth optional pam_unix.so nullok likeauth + auth optional ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so + auth sufficient pam_unix.so try_first_pass nullok + auth required pam_deny.so + + # Password management. + password sufficient pam_unix.so nullok yescrypt + password optional ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so use_authtok + + # Session management. + session required pam_env.so conffile=/etc/pam/environment readenv=0 + session required pam_unix.so + session required pam_loginuid.so + session required ${pkgs.pam}/lib/security/pam_lastlog.so silent + session optional ${pkgs.systemd}/lib/security/pam_systemd.so + session optional ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so auto_start + ''; + + polkit-1.text = '' + # Account management. + account required pam_unix.so + + # Authentication management. + auth sufficient ${pkgs.pam-fprint-grosshack}/lib/security/pam_fprintd_grosshack.so + auth sufficient pam_unix.so try_first_pass nullok + auth required pam_deny.so + + # Password management. + password sufficient pam_unix.so nullok yescrypt + + # Session management. + session required pam_env.so conffile=/etc/pam/environment readenv=0 + session required pam_unix.so + ''; + }; +} diff --git a/nixos/configuration.nix b/nixos/configuration.nix new file mode 100644 index 00000000..1ea9d660 --- /dev/null +++ b/nixos/configuration.nix @@ -0,0 +1,50 @@ +{ config, pkgs, ... }: + +{ + imports = + [ # Include the results of the hardware scan. + ./hardware-configuration.nix + ./overlays/list.nix + ./cfg/main.nix + ./home/main.nix + ]; + + networking = { + hostName = "wim"; + networkmanager.enable = true; + networkmanager.wifi.backend = "wpa_supplicant"; + }; + + # Set your time zone. + time.timeZone = "America/Montreal"; + + # Select internationalisation properties. + i18n.defaultLocale = "en_CA.UTF-8"; + console = { + #font = "Lat2-Terminus16"; + keyMap = "ca"; + #useXkbConfig = true; # use xkbOptions in tty. + }; + + nix.settings.experimental-features = [ "nix-command" "flakes" ]; + nixpkgs.config.allowUnfree = true; + + + environment.sessionVariables = { + NIXPKGS_ALLOW_UNFREE = "1"; + GTK_THEME = "Dracula"; + QT_QPA_PLATFORMTHEME = "qt5ct"; + QT_FONT_DPI = "125"; + }; + + system.autoUpgrade.channel = "https://nixos.org/channels/nixos-unstable"; + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It's perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "23.05"; # Did you read the comment? + +} diff --git a/nixos/hardware-configuration.nix b/nixos/hardware-configuration.nix new file mode 100644 index 00000000..4c61ab25 --- /dev/null +++ b/nixos/hardware-configuration.nix @@ -0,0 +1,40 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "usb_storage" "sd_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-amd" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/6ae4d722-dacf-485a-8d29-b276f540dc91"; + fsType = "btrfs"; + }; + + boot.initrd.luks.devices."root".device = "/dev/disk/by-uuid/ab82b477-2477-453f-b95f-28e5553ad10d"; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/F6E1-006D"; + fsType = "vfat"; + }; + + swapDevices = [ ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.enp7s0f4u2.useDHCP = lib.mkDefault true; + # networking.interfaces.wlp6s0.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/nixos/home/bashdots.nix b/nixos/home/bashdots.nix new file mode 100644 index 00000000..bcdef390 --- /dev/null +++ b/nixos/home/bashdots.nix @@ -0,0 +1,148 @@ +{ pkgs, ... }: + +{ + programs.bash = { # TODO: deal with root dotfiles + enable = true; + enableCompletion = true; + #enableVteIntegration = false; what is this? + + historyFile = "\$HOME/.cache/.bash_history"; + historyFileSize = 100000; # default + historySize = 10000; # default + historyControl = [ + "erasedups" + "ignorespace" + ]; + historyIgnore = [ + "ls" + "exit" + "logout" + ]; + + shellOptions = [ + "histappend" + "checkwinsize" + "extglob" + "globstar" + "checkjobs" + "autocd" + "cdspell" + "dirspell" + "dotglob" + ] + ; + shellAliases = { + sudo = "sudo "; + frick = "sudo $(fc -ln -1)"; + + tmux = "tmux -2"; + ls = "ls -lah --color=auto"; + cp = "cp -r"; + + ags = "XDG_DATA_DIRS=/home/matt/.config/share ags"; + + tup = "tailscale up --login-server https://headscale.nelim.org"; + + pc = "mosh matt@10.0.0.248 -- tmux -2u new -At laptop"; + oksys = "mosh matt@10.0.0.213 -- tmux -2u new -At laptop"; + pve = "mosh matt@10.0.0.121 -- tmux -2u new -At laptop"; + + mc = "mosh mc@10.0.0.124 -- tmux -2u new -At laptop"; + pod = "mosh matt@10.0.0.121 -- ssh -t -p 6768 matt@10.0.0.122 'tmux -2u new -At laptop'"; + jelly = "mosh matt@10.0.0.121 -- ssh -t matt@10.0.0.123 'tmux -2u new -At laptop'"; + qbit = "mosh matt@10.0.0.121 -- ssh -t matt@10.0.0.128 'tmux -2u new -At laptop'"; + }; + sessionVariables = { # see configuration.nix + }; + + profileExtra = '' + export POKE=true + [[ -f ~/.bashrc ]] && . ~/.bashrc + ''; + bashrcExtra = '' + PROMPT_COMMAND="history -a; $PROMPT_COMMAND" + [[ -d ~/.local/bin ]] && PATH+=":$HOME/.local/bin" + + USER_COLOR="01;32m" + HOST_COLOR="183m" + PS1="\[\033[$USER_COLOR\]\u\[\033[01;38;5;$HOST_COLOR\]@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]$ " + + # source: https://stackoverflow.com/a/44232192 + PATH="$(perl -e 'print join(":", grep { not $seen{$_}++ } split(/:/, $ENV{PATH}))')" + + [ -x "$(command -v pokemon-colorscripts)" ] && + [ "$POKE" == "true" ] && + pokemon-colorscripts -r 1-5 + + function colorgrid() { + iter=16 + while [ $iter -lt 52 ] + do + second=$[$iter+36] + third=$[$second+36] + four=$[$third+36] + five=$[$four+36] + six=$[$five+36] + seven=$[$six+36] + if [ $seven -gt 250 ];then seven=$[$seven-251]; fi + + echo -en "\033[38;5;$(echo $iter)m█ " + printf "%03d" $iter + echo -en " \033[38;5;$(echo $second)m█ " + printf "%03d" $second + echo -en " \033[38;5;$(echo $third)m█ " + printf "%03d" $third + echo -en " \033[38;5;$(echo $four)m█ " + printf "%03d" $four + echo -en " \033[38;5;$(echo $five)m█ " + printf "%03d" $five + echo -en " \033[38;5;$(echo $six)m█ " + printf "%03d" $six + echo -en " \033[38;5;$(echo $seven)m█ " + printf "%03d" $seven + + iter=$[$iter+1] + printf '\r\n' + done + } + + ### DRACULA + + export FZF_DEFAULT_OPTS='--color=fg:#f8f8f2,hl:#bd93f9 --color=fg+:#f8f8f2,hl+:#bd93f9 --color=info:#ffb86c,prompt:#50fa7b,pointer:#ff79c6 --color=marker:#ff79c6,spinner:#ffb86c,header:#6272a4' + + #man-page colors + export LESS_TERMCAP_mb=$'\e[1;31m' # begin bold + export LESS_TERMCAP_md=$'\e[1;34m' # begin blink + export LESS_TERMCAP_so=$'\e[01;45;37m' # begin reverse video + export LESS_TERMCAP_us=$'\e[01;36m' # begin underline + export LESS_TERMCAP_me=$'\e[0m' # reset bold/blink + export LESS_TERMCAP_se=$'\e[0m' # reset reverse video + export LESS_TERMCAP_ue=$'\e[0m' # reset underline + + if [ "$TERM" = "linux" ]; then + printf %b '\e[40m' '\e[8]' # set default background to color 0 'dracula-bg' + printf %b '\e[37m' '\e[8]' # set default foreground to color 7 'dracula-fg' + printf %b '\e]P0282a36' # redefine 'black' as 'dracula-bg' + printf %b '\e]P86272a4' # redefine 'bright-black' as 'dracula-comment' + printf %b '\e]P1ff5555' # redefine 'red' as 'dracula-red' + printf %b '\e]P9ff7777' # redefine 'bright-red' as '#ff7777' + printf %b '\e]P250fa7b' # redefine 'green' as 'dracula-green' + printf %b '\e]PA70fa9b' # redefine 'bright-green' as '#70fa9b' + printf %b '\e]P3f1fa8c' # redefine 'brown' as 'dracula-yellow' + printf %b '\e]PBffb86c' # redefine 'bright-brown' as 'dracula-orange' + printf %b '\e]P4bd93f9' # redefine 'blue' as 'dracula-purple' + printf %b '\e]PCcfa9ff' # redefine 'bright-blue' as '#cfa9ff' + printf %b '\e]P5ff79c6' # redefine 'magenta' as 'dracula-pink' + printf %b '\e]PDff88e8' # redefine 'bright-magenta' as '#ff88e8' + printf %b '\e]P68be9fd' # redefine 'cyan' as 'dracula-cyan' + printf %b '\e]PE97e2ff' # redefine 'bright-cyan' as '#97e2ff' + printf %b '\e]P7f8f8f2' # redefine 'white' as 'dracula-fg' + printf %b '\e]PFffffff' # redefine 'bright-white' as '#ffffff' + fi + ''; + #initExtra = '' + #''; + #logoutExtra = '' + #''; + }; +} diff --git a/nixos/home/dotfiles.nix b/nixos/home/dotfiles.nix new file mode 100644 index 00000000..7d3ec604 --- /dev/null +++ b/nixos/home/dotfiles.nix @@ -0,0 +1,182 @@ +{ config, ... }: + +let + configDir = "/home/matt/.nix/config"; +in + +{ + xdg.configFile = { + "swayosd/style.css".source = config.lib.file.mkOutOfStoreSymlink "${configDir}/swayosd/style.css"; + + "gtklock/config.ini".source = config.lib.file.mkOutOfStoreSymlink "${configDir}/gtklock/config.ini"; + "gtklock/style.css".source = config.lib.file.mkOutOfStoreSymlink "${configDir}/gtklock/style.css"; + + "ripgrep".source = config.lib.file.mkOutOfStoreSymlink "${configDir}/ripgrep"; + + "discord/settings.json".source = config.lib.file.mkOutOfStoreSymlink "${configDir}/discord/settings.json"; + + "dolphinrc".source = config.lib.file.mkOutOfStoreSymlink "${configDir}/dolphinrc"; + "kdeglobals".source = config.lib.file.mkOutOfStoreSymlink "${configDir}/kdeglobals"; + "kiorc".source = config.lib.file.mkOutOfStoreSymlink "${configDir}/kiorc"; + "mimeapps.list".source = config.lib.file.mkOutOfStoreSymlink "${configDir}/mimeapps.list"; + "neofetch".source = config.lib.file.mkOutOfStoreSymlink "${configDir}/neofetch"; + "swappy".source = config.lib.file.mkOutOfStoreSymlink "${configDir}/swappy"; + }; + + programs = { + fzf = { + enable = true; + enableBashIntegration = true; + }; + + wofi = { + enable = true; + settings = { + prompt = ""; + allow_images = true; + image_size = "48"; + matching = "fuzzy"; + insensitive = true; + normal_window = true; + height = "620"; + }; + style = '' + /* https://github.com/dracula/wofi/blob/master/style.css */ + window { + margin: 0px; + border: 1px solid #bd93f9; + border-bottom: none; + border-radius: 30px; + background-color: #282a36; + } + + #input { + margin: 5px; + border: none; + color: #f8f8f2; + background-color: #44475a; + } + + #inner-box { + margin: 5px; + border: none; + background-color: #282a36; + } + + #outer-box { + margin: 5px; + padding: 10px 10px 0px 10px; + border: none; + border-radius: 30px; + background-color: #282a36; + } + + #scroll { + margin: -4px 0px -7px 0px; + border: none; + } + + #text { + margin: 5px; + border: none; + color: #f8f8f2; + } + + #entry.activatable #text { + color: #282a36; + } + + #entry > * { + color: #f8f8f2; + padding: 4px 0px 0px 0px; + } + + #entry:selected { + background-color: #44475a; + outline: none; + } + + #entry:selected #text { + font-weight: bold; + } + ''; + }; + + alacritty = { + enable = true; + settings = { + env = { + POKE = "true"; + }; + + window = { + padding = { + x = 0; + y = 10; + }; + + opacity = 0.8; + }; + + # https://github.com/dracula/alacritty/blob/05faff15c0158712be87d200081633d9f4850a7d/dracula.yml + colors = { + primary = { + background = "#282a36"; + foreground = "#f8f8f2"; + bright_foreground = "#ffffff"; + }; + cursor = { + text = "CellBackground"; + cursor = "CellForeground"; + }; + vi_mode_cursor = { + text = "CellBackground"; + cursor = "CellForeground"; + }; + search = { + matches = { + foreground = "#44475a"; + background = "#50fa7b"; + }; + focused_match = { + foreground = "#44475a"; + background = "#ffb86c"; + }; + footer_bar = { + background = "#282a36"; + foreground = "#f8f8f2"; + }; + }; + hints = { + start = { + foreground = "#282a36"; + background = "#f1fa8c"; + }; + end = { + foreground = "#f1fa8c"; + background = "#282a36"; + }; + }; + line_indicator = { + foreground = "None"; + background = "None"; + }; + selection = { + text = "CellForeground"; + background = "#44475a"; + }; + normal = { + black = "#21222c"; + red = "#ff5555"; + green = "#50fa7b"; + yellow = "#f1fa8c"; + blue = "#bd93f9"; + magenta = "#ff79c6"; + cyan = "#8be9fd"; + white = "#f8f8f2"; + }; + }; + }; + }; + }; +} diff --git a/nixos/home/hyprland.nix b/nixos/home/hyprland.nix new file mode 100644 index 00000000..6ab214b8 --- /dev/null +++ b/nixos/home/hyprland.nix @@ -0,0 +1,65 @@ +{ pkgs, config, ... }: let + + configDir = "/home/matt/.nix/config"; + + flake-compat = builtins.fetchTarball "https://github.com/edolstra/flake-compat/archive/master.tar.gz"; + + hyprland = (import flake-compat { + src = builtins.fetchTarball "https://github.com/hyprwm/Hyprland/archive/master.tar.gz"; + }).defaultNix; + + ags = (builtins.getFlake "github:Aylur/ags"); + +in +{ + home.packages = [ + pkgs.sassc + pkgs.kora-icon-theme + pkgs.coloryou + ]; + + imports = [ + hyprland.homeManagerModules.default + ags.homeManagerModules.default + ]; + + programs.ags = { + enable = true; + configDir = config.lib.file.mkOutOfStoreSymlink "${configDir}/ags"; + }; + + wayland.windowManager.hyprland = { + enable = true; + package = (builtins.getFlake "github:horriblename/hyprgrass").inputs.hyprland.packages.x86_64-linux.default; + + plugins = [ + "${(builtins.getFlake "github:horriblename/hyprgrass").packages.x86_64-linux.default}/lib/libhyprgrass.so" + ]; + + extraConfig = '' + env = XDG_DATA_DIRS, ${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}:${pkgs.gtk3}/share/gsettings-schemas/${pkgs.gtk3.name}:$XDG_DATA_DIRS + $kora = "$HOME/.config/share" + + env = AGS_PATH, ${configDir}/ags/bin + env = HYPR_PATH, ${configDir}/hypr/scripts + env = LOCK_PATH, ${configDir}/gtklock/scripts + + exec-once = ${pkgs.plasma5Packages.polkit-kde-agent}/libexec/polkit-kde-authentication-agent-1 + source = ~/.config/hypr/main.conf + ''; + }; + + # https://www.reddit.com/r/NixOS/comments/vc3srj/comment/iccqxw1/?utm_source=share&utm_medium=web2x&context=3 + xdg.configFile = { + "share/icons/hicolor".source = "${pkgs.kora-icon-theme}/share/icons/kora-pgrey"; + "../.themes/Dracula".source = "${pkgs.dracula-theme}/share/themes/Dracula"; + + "Kvantum/Dracula".source = "${pkgs.dracula-theme}/share/Kvantum/Dracula"; + "Kvantum/Dracula-Solid".source = "${pkgs.dracula-theme}/share/Kvantum/Dracula-Solid"; + "Kvantum/Dracula-purple".source = "${pkgs.dracula-theme}/share/Kvantum/Dracula-purple"; + "Kvantum/Dracula-purple-solid".source = "${pkgs.dracula-theme}/share/Kvantum/Dracula-purple-solid"; + + "hypr/main.conf".source = config.lib.file.mkOutOfStoreSymlink "${configDir}/hypr/main.conf"; + "hypr/hyprpaper.conf".source = config.lib.file.mkOutOfStoreSymlink "${configDir}/hypr/hyprpaper.conf"; + }; +} diff --git a/nixos/home/main.nix b/nixos/home/main.nix new file mode 100644 index 00000000..9d463825 --- /dev/null +++ b/nixos/home/main.nix @@ -0,0 +1,37 @@ +{ config, pkgs, ... }: +let + home-manager = builtins.fetchTarball "https://github.com/nix-community/home-manager/archive/master.tar.gz"; +in +{ +## Global config to add home-manager module +############################################################################# + imports = + [ + (import "${home-manager}/nixos") + ]; + + # Define a user account. Don't forget to set a password with 'passwd'. + users.users.matt = { + isNormalUser = true; + extraGroups = [ "wheel" "input" "uinput" "adm" "mlocate" "video" "libvirtd" ]; + }; + + home-manager.useUserPackages = true; + home-manager.useGlobalPkgs = true; + programs.dconf.enable = true; +############################################################################# + + home-manager.users.matt = { + + imports = [ + ./hyprland.nix + ./bashdots.nix + ./dotfiles.nix + ./packages.nix + ./misc.nix + ./nvim.nix + ]; + + home.stateVersion = "23.05"; + }; +} diff --git a/nixos/home/misc.nix b/nixos/home/misc.nix new file mode 100644 index 00000000..2d59ab2e --- /dev/null +++ b/nixos/home/misc.nix @@ -0,0 +1,19 @@ +{ ... }: + +{ + xdg.desktopEntries.gparted = { + name = "GParted"; + genericName = "Partition Editor"; + comment = "Create, reorganize, and delete partitions"; + exec = "Gparted"; + icon = "gparted"; + terminal = false; + type = "Application"; + categories = [ "GNOME" "System" "Filesystem" ]; + startupNotify = true; + settings = { + Keywords = "Partition"; + X-GNOME-FullName = "GParted Partition Editor"; + }; + }; +} diff --git a/nixos/home/nvim.nix b/nixos/home/nvim.nix new file mode 100644 index 00000000..9606cdf1 --- /dev/null +++ b/nixos/home/nvim.nix @@ -0,0 +1,117 @@ +# https://breuer.dev/blog/nixos-home-manager-neovim +{ config, pkgs, lib, ... }: +let + configDir = "/home/matt/.nix/config"; + + # installs a vim plugin from git with a given tag / branch + pluginGit = ref: repo: pkgs.vimUtils.buildVimPluginFrom2Nix { + pname = "${lib.strings.sanitizeDerivationName repo}"; + version = ref; + src = builtins.fetchGit { + url = "https://github.com/${repo}.git"; + ref = ref; + }; + }; + + # always installs latest version + plugin = pluginGit "HEAD"; +in { + xdg.configFile = { + "../.gradle/gradle.properties".source = pkgs.writeText "gradle.properties" '' + org.gradle.java.home = ${pkgs.temurin-bin-17} + ''; + }; + programs.neovim = { + enable = true; + package = pkgs.neovim-nightly; + + # read in the vim config from filesystem + # this enables syntaxhighlighting when editing those + extraConfig = builtins.concatStringsSep "\n" [ + (lib.strings.fileContents "${configDir}/nvim/base.vim") + # (lib.strings.fileContents ./.nvim/plugins.vim) + # (lib.strings.fileContents ./.nvim/lsp.vim) + '' + lua << EOF + ${lib.strings.fileContents "${configDir}/nvim/config.lua"} + ${lib.strings.fileContents "${configDir}/nvim/lsp.lua"} + EOF + '' + ]; + + extraPackages = with pkgs; [ + tree-sitter + nodejs_latest + gradle + bat + + python311Packages.pylint + nil + ]; + + coc = { + enable = true; + settings = { + "colors.enable" = true; + "coc.preferences.formatOnType" = true; + "Lua.misc.parameters" = [ + "--metapath" + "~/.cache/sumneko_lua/meta" + "--logpath" + "~/.cache/sumneko_lua/log" + ]; + "sumneko-lua.serverDir" = "${pkgs.lua-language-server}/share/lua-language-server"; + "java.jdt.ls.java.home" = "${pkgs.temurin-bin-17}"; + "bashIde.shellcheckPath" = "${pkgs.shellcheck}/bin/shellcheck"; + languageserver = { + nix = { + command = "nil"; + filetypes = [ "nix" ]; + rootPatterns = [ "flake.nix" ]; + }; + }; + }; + }; + plugins = with pkgs.vimPlugins; [ + vim-which-key + + coc-java + coc-css + coc-sumneko-lua + coc-highlight + coc-json + coc-pyright + coc-sh + coc-snippets + coc-vimlsp + coc-yaml + coc-toml + coc-markdownlint + coc-tsserver + + coc-fzf + (plugin "junegunn/fzf.vim") + (plugin "junegunn/fzf") + + nvim-treesitter.withAllGrammars + nvim-treesitter + nvim-autopairs + + (plugin "Mofiqul/dracula.nvim") + (plugin "lukas-reineke/indent-blankline.nvim") + (plugin "lewis6991/gitsigns.nvim") + (plugin "nvim-lualine/lualine.nvim") + + # neo-tree and deps + (plugin "nvim-neo-tree/neo-tree.nvim") + (plugin "nvim-lua/plenary.nvim") + (plugin "nvim-tree/nvim-web-devicons") + (plugin "MunifTanjim/nui.nvim") + + # to explore more + fugitive + (plugin "folke/todo-comments.nvim") + (plugin "petertriho/nvim-scrollbar") + ]; + }; +} diff --git a/nixos/home/packages.nix b/nixos/home/packages.nix new file mode 100644 index 00000000..f04031fe --- /dev/null +++ b/nixos/home/packages.nix @@ -0,0 +1,154 @@ +{ pkgs, ... }: + +{ + dconf.settings = { + "org/virt-manager/virt-manager/connections" = { + autoconnect = ["qemu:///system"]; + uris = ["qemu:///system"]; + }; + }; + + programs = { + + obs-studio = { + enable = true; + plugins = with pkgs.obs-studio-plugins; [ + wlrobs + ]; + }; + + btop.enable = true; + + jq.enable = true; + + ripgrep = { + enable = true; + }; + }; + + home.packages = with pkgs; + (with python311Packages; [ + python + pyclip + gdown + + ]) ++ + (with nodePackages; [ + undollar + + ]) ++ + (with plasma5Packages; [ + polkit-kde-agent + qtstyleplugin-kvantum + dolphin + dolphin-plugins + kdegraphics-thumbnailers + ffmpegthumbs + kio + kio-admin # needs to be both here and in system pkgs + kio-extras + ark + kcharselect + kdenlive + kmime + okular + + ]) ++ + (with gnome; [ + gnome-calculator + seahorse + adwaita-icon-theme + + ]) ++ + [ + (writeShellScriptBin "Gparted" '' + ( + sleep 1.5 + while killall -r -0 ksshaskpass > /dev/null 2>&1 + do + sleep 0.1 + if [[ $(hyprctl activewindow | grep Ksshaskpass) == "" ]]; then + killall -r ksshaskpass + fi + done + ) & + + exec env SUDO_ASKPASS=${pkgs.plasma5Packages.ksshaskpass}/bin/${pkgs.plasma5Packages.ksshaskpass.pname} sudo -k -EA "${gparted}/bin/${gparted.pname}" "$@" + '') + + # School + virt-manager + gradle + gradle-completion + #camunda-modeler + # + protonmail-bridge + thunderbird + input-emulator + bc + spotifywm + swayosd + blueberry + libayatana-appindicator + libnotify + libinput + playerctl + dracula-theme + dracula-icon-theme + steam-run + wineWowPackages.stable + cabextract + qt5.qtwayland + qt6.qtwayland + bottles-unwrapped + zscroll + httrack + lisgd + zeal + acpi + libreoffice-fresh # TODO: add spelling stuff + neofetch + photoqt + progress + wl-color-picker # add bind for this in hyprland + xclip + xdg-utils + pavucontrol # TODO: open on left click + gimp-with-plugins + jdk19_headless + bluez-tools + vlc + discord + brightnessctl + pulseaudio + alsa-utils + wget + firefox + tree + mosh + rsync + killall + hyprpaper + networkmanagerapplet + nextcloud-client + swayidle + wl-clipboard + cliphist + gtklock + gtklock-playerctl-module + gtklock-powerbar-module + grim + slurp + swappy + fontfor + qt5ct + lxappearance + imagemagick + usbutils + evtest + squeekboard + glib + appimage-run + gparted # doesn't open without sudo + ]; +} diff --git a/nixos/overlays/blueberry.nix b/nixos/overlays/blueberry.nix new file mode 100644 index 00000000..a6dfd3a0 --- /dev/null +++ b/nixos/overlays/blueberry.nix @@ -0,0 +1,10 @@ +final: prev: { + blueberry = prev.blueberry.overrideAttrs (o: { + patches = (o.patches or [ ]) ++ [ + ./patches/wayland.patch + ]; + buildInputs = (o.buildInputs or [ ]) ++ [ + prev.libappindicator + ]; + }); +} diff --git a/nixos/overlays/list.nix b/nixos/overlays/list.nix new file mode 100644 index 00000000..31768d4e --- /dev/null +++ b/nixos/overlays/list.nix @@ -0,0 +1,32 @@ +{ config, pkgs, ... }: + +{ + nixpkgs.overlays = [ + (import ./swayosd.nix) + (import ./blueberry.nix) + + (final: prev: { + input-emulator = final.callPackage ./pkgs/input-emulator.nix {}; + }) + + (final: prev: { + pam-fprint-grosshack = final.callPackage ./pkgs/pam-fprint-grosshack.nix {}; + }) + + (final: prev: { + dracula-plymouth = final.callPackage ./pkgs/dracula-plymouth.nix {}; + }) + + (final: prev: { + lavanda-sddm = final.callPackage ./pkgs/lavanda-sddm.nix {}; + }) + + (final: prev: { + coloryou = final.callPackage ./pkgs/coloryou/default.nix {}; + }) + + (import (builtins.fetchTarball { + url = "https://github.com/nix-community/neovim-nightly-overlay/archive/master.tar.gz"; + })) + ]; +} diff --git a/nixos/overlays/patches/swayosd.patch b/nixos/overlays/patches/swayosd.patch new file mode 100644 index 00000000..cf5f893c --- /dev/null +++ b/nixos/overlays/patches/swayosd.patch @@ -0,0 +1,21 @@ +diff --git a/data/meson.build b/data/meson.build +index 1ceaa11..68decdf 100644 +--- a/data/meson.build ++++ b/data/meson.build +@@ -42,11 +42,7 @@ + configure_file( + + # Systemd service unit + systemd = dependency('systemd', required: false) +-if systemd.found() +- systemd_service_install_dir = systemd.get_variable(pkgconfig :'systemdsystemunitdir') +-else +- systemd_service_install_dir = join_paths(libdir, 'systemd', 'system') +-endif ++systemd_service_install_dir = join_paths(libdir, 'systemd', 'system') + + configure_file( + configuration: conf_data, +-- +2.41.0 + diff --git a/nixos/overlays/patches/wayland.patch b/nixos/overlays/patches/wayland.patch new file mode 100644 index 00000000..54a27cfc --- /dev/null +++ b/nixos/overlays/patches/wayland.patch @@ -0,0 +1,95 @@ +# https://github.com/linuxmint/blueberry/issues/120 +--- /usr/lib/blueberry/blueberry-tray.py.org 2021-12-13 01:02:56.923349069 -0800 ++++ /usr/lib/blueberry/blueberry-tray.py 2021-12-13 02:21:23.253300141 -0800 +@@ -5,8 +5,8 @@ + import gi + gi.require_version('Gtk', '3.0') + gi.require_version('GnomeBluetooth', '1.0') +-gi.require_version('XApp', '1.0') +-from gi.repository import Gtk, Gdk, GnomeBluetooth, Gio, XApp ++gi.require_version('AppIndicator3', '0.1') ++from gi.repository import AppIndicator3, Gtk, Gdk, GnomeBluetooth, Gio + import rfkillMagic + import setproctitle + import subprocess +@@ -53,12 +53,16 @@ + self.model.connect('row-deleted', self.update_icon_callback) + self.model.connect('row-inserted', self.update_icon_callback) + +- self.icon = XApp.StatusIcon() +- self.icon.set_name("blueberry") +- self.icon.set_tooltip_text(_("Bluetooth")) +- self.icon.connect("activate", self.on_statusicon_activated) +- self.icon.connect("button-release-event", self.on_statusicon_released) +- ++ self.paired_devices = {} ++ ++ self.icon = AppIndicator3.Indicator.new( ++ 'BlueBerry', ++ 'blueberry', ++ AppIndicator3.IndicatorCategory.SYSTEM_SERVICES ++ ) ++ self.icon.set_status(AppIndicator3.IndicatorStatus.ACTIVE) ++ self.icon.set_menu(self.build_menu()) ++ + self.update_icon_callback(None, None, None) + + def on_settings_changed_cb(self, setting, key, data=None): +@@ -71,21 +75,23 @@ + return + + if self.rfkill.hard_block or self.rfkill.soft_block: +- self.icon.set_icon_name(self.tray_disabled_icon) +- self.icon.set_tooltip_text(_("Bluetooth is disabled")) ++ self.icon.set_title(_("Bluetooth is disabled")) ++ self.icon.set_icon(self.tray_disabled_icon) ++ self.icon.set_menu(self.build_menu()) + else: +- self.icon.set_icon_name(self.tray_icon) ++ self.icon.set_icon(self.tray_icon) ++ self.icon.set_menu(self.build_menu()) + self.update_connected_state() + + def update_connected_state(self): + self.get_devices() + + if len(self.connected_devices) > 0: +- self.icon.set_icon_name(self.tray_active_icon) +- self.icon.set_tooltip_text(_("Bluetooth: Connected to %s") % (", ".join(self.connected_devices))) ++ self.icon.set_title(_("Bluetooth: Connected to %s") % (", ".join(self.connected_devices))) ++ self.icon.set_icon(self.tray_active_icon) + else: +- self.icon.set_icon_name(self.tray_icon) +- self.icon.set_tooltip_text(_("Bluetooth")) ++ self.icon.set_title(_("Bluetooth")) ++ self.icon.set_icon(self.tray_icon) + + def get_devices(self): + self.connected_devices = [] +@@ -117,13 +118,11 @@ + + iter = self.model.iter_next(iter) + +- def on_statusicon_activated(self, icon, button, time): +- if button == Gdk.BUTTON_PRIMARY: +- subprocess.Popen(["blueberry"]) ++ def start_blueberry(self, _ignored): ++ subprocess.Popen(["blueberry"]) + +- def on_statusicon_released(self, icon, x, y, button, time, position): +- if button == 3: ++ def build_menu(self): + menu = Gtk.Menu() + + if not self.rfkill.hard_block: + if self.rfkill.soft_block: +@@ -168,7 +170,7 @@ + menu.append(item) + + menu.show_all() +- icon.popup_menu(menu, x, y, button, time, position) ++ return menu + + def toggle_connect_cb(self, item, data = None): + proxy = self.paired_devices[data] + diff --git a/packages/coloryou/LICENSE b/nixos/overlays/pkgs/coloryou/LICENSE similarity index 100% rename from packages/coloryou/LICENSE rename to nixos/overlays/pkgs/coloryou/LICENSE diff --git a/packages/coloryou/coloryou.py b/nixos/overlays/pkgs/coloryou/coloryou.py similarity index 98% rename from packages/coloryou/coloryou.py rename to nixos/overlays/pkgs/coloryou/coloryou.py index e796fde7..66c8efbb 100755 --- a/packages/coloryou/coloryou.py +++ b/nixos/overlays/pkgs/coloryou/coloryou.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python + """ The original script: https://github.com/dharmx/vile/blob/7d486c128c7e553912673755f97b118aaab0193d/src/shell/playerctl.py#L2 diff --git a/nixos/overlays/pkgs/coloryou/default.nix b/nixos/overlays/pkgs/coloryou/default.nix new file mode 100644 index 00000000..ff82bb9f --- /dev/null +++ b/nixos/overlays/pkgs/coloryou/default.nix @@ -0,0 +1,48 @@ +# https://blog.hackeriet.no/packaging-python-script-for-nixos/ + +# Below, we can supply defaults for the function arguments to make the script +# runnable with `nix-build` without having to supply arguments manually. +# Also, this lets me build with Python 3.11 by default, but makes it easy +# to change the python version for customised builds (e.g. testing). +{ nixpkgs ? import <nixpkgs> {}, pythonPkgs ? nixpkgs.pkgs.python311Packages }: + +let + # This takes all Nix packages into this scope + inherit (nixpkgs) pkgs; + # This takes all Python packages from the selected version into this scope. + inherit pythonPkgs; + + # Inject dependencies into the build function + f = { buildPythonPackage, utils, material-color-utilities }: + buildPythonPackage rec { + pname = "coloryou"; + version = "0.2.0"; + + # If you have your sources locally, you can specify a path + src = ./.; + + # Pull source from a Git server. + #src = builtins.fetchGit { + #url = "git://github.com/stigok/ruterstop.git"; + #ref = "master"; + #rev = "a9a4cd60e609ed3471b4b8fac8958d009053260d"; + #}; + + # Specify runtime dependencies for the package + propagatedBuildInputs = [ utils material-color-utilities ]; + + postInstall = '' + mv -v $out/bin/coloryou.py $out/bin/coloryou + ''; + + meta = { + description = '' + Get Material You colors from an image. + ''; + }; + }; + + drv = pythonPkgs.callPackage f {}; +in + if pkgs.lib.inNixShell then drv.env else drv + diff --git a/packages/coloryou/requirements.txt b/nixos/overlays/pkgs/coloryou/requirements.txt similarity index 100% rename from packages/coloryou/requirements.txt rename to nixos/overlays/pkgs/coloryou/requirements.txt diff --git a/nixos/overlays/pkgs/coloryou/setup.py b/nixos/overlays/pkgs/coloryou/setup.py new file mode 100644 index 00000000..24704abc --- /dev/null +++ b/nixos/overlays/pkgs/coloryou/setup.py @@ -0,0 +1,7 @@ +from distutils.core import setup + +setup( + name='coloryou', + version='0.0.1', + scripts=['coloryou.py',], +) diff --git a/nixos/overlays/pkgs/coloryou/shell.nix b/nixos/overlays/pkgs/coloryou/shell.nix new file mode 100644 index 00000000..9cb68ec6 --- /dev/null +++ b/nixos/overlays/pkgs/coloryou/shell.nix @@ -0,0 +1,8 @@ +with import <nixpkgs> {}; +with pkgs.python311Packages; + +buildPythonPackage rec { + name = "coloryou"; + src = ./.; + propagatedBuildInputs = [ material-color-utilities utils ]; +} diff --git a/nixos/overlays/pkgs/dracula-plymouth.nix b/nixos/overlays/pkgs/dracula-plymouth.nix new file mode 100644 index 00000000..4b1eb30e --- /dev/null +++ b/nixos/overlays/pkgs/dracula-plymouth.nix @@ -0,0 +1,39 @@ +{ lib +, stdenv +, fetchFromGitHub +, pkgs +}: + +stdenv.mkDerivation { + name = "dracula-plymouth"; + version = "unstable-2023-01-13"; + + src = fetchFromGitHub { + repo = "plymouth"; + owner = "dracula"; + rev = "37aa09b27ecee4a825b43d2c1d20b502e8f19c96"; + hash = "sha256-7YwkBzkAND9lfH2ewuwna1zUkQStBBx4JHGw3/+svhA="; + }; + + dontConfigure = true; + dontBuild = true; + + installPhase = '' + runHook preInstall + + mkdir -p $out/share/plymouth/themes + mv ./dracula $out/share/plymouth/themes/ + + sed -i "s@\/usr\/@$out\/@" $out/share/plymouth/themes/dracula/dracula.plymouth + + runHook postInstall + ''; + + meta = with lib; { + description = "A dark theme for Plymouth"; + homepage = "https://github.com/dracula/plymouth/tree/main"; + license = licenses.mit; + maintainers = with maintainers; [ matt1432 ]; + platforms = platforms.all; + }; +} diff --git a/nixos/overlays/pkgs/input-emulator.nix b/nixos/overlays/pkgs/input-emulator.nix new file mode 100644 index 00000000..0d42c59d --- /dev/null +++ b/nixos/overlays/pkgs/input-emulator.nix @@ -0,0 +1,29 @@ +{ lib +, stdenv +, meson +, ninja +, pkg-config +, cmake +, bash-completion +, fetchFromGitHub +}: + +stdenv.mkDerivation rec { + pname = "input-emulator"; + version = "6c35040e6fc4f65ce0519ee76d00d60490bcb987"; + + src = fetchFromGitHub { + owner = "tio"; + repo = pname; + rev = version; + sha256 = "sha256-Im0RADqRwlZ/RiZFSVp+HwnWoLdcpRp0Ej6RP0GY0+c="; + }; + + nativeBuildInputs = [ + meson + ninja + pkg-config + cmake + bash-completion + ]; +} diff --git a/nixos/overlays/pkgs/lavanda-sddm.nix b/nixos/overlays/pkgs/lavanda-sddm.nix new file mode 100644 index 00000000..59b0f371 --- /dev/null +++ b/nixos/overlays/pkgs/lavanda-sddm.nix @@ -0,0 +1,30 @@ +### test package +{ lib +, stdenv +, fetchFromGitHub +, pkgs +}: + +stdenv.mkDerivation { + name = "lavanda-kde"; + version = "unstable-2022-08-24"; + + src = fetchFromGitHub { + repo = "Lavanda-kde"; + owner = "vinceliuice"; + rev = "f247e5c0078df64fdee2c74d27baf479f025001e"; + hash = "sha256-hLP4Ye3lRKSCk9I+PguAWhlHUDvIqRlRazXyOccPerQ="; + }; + + dontConfigure = true; + dontBuild = true; + + installPhase = '' + runHook preInstall + + mkdir -p $out/share/sddm/themes/ + mv ./sddm/* $out/share/sddm/themes/ + + runHook postInstall + ''; +} diff --git a/nixos/overlays/pkgs/pam-fprint-grosshack.nix b/nixos/overlays/pkgs/pam-fprint-grosshack.nix new file mode 100644 index 00000000..e256c4fc --- /dev/null +++ b/nixos/overlays/pkgs/pam-fprint-grosshack.nix @@ -0,0 +1,46 @@ +{ lib +, stdenv +, meson +, ninja +, pkg-config +, glib +, libfprint +, polkit +, dbus +, systemd +, pam +, libpam-wrapper +, fetchFromGitLab +}: + +stdenv.mkDerivation rec { + pname = "pam-fprint-grosshack"; + version = "v0.3.0"; + + src = fetchFromGitLab { + owner = "mishakmak"; + repo = pname; + rev = version; + sha256 = "sha256-obczZbf/oH4xGaVvp3y3ZyDdYhZnxlCWvL0irgEYIi0="; + }; + + nativeBuildInputs = [ + meson + ninja + pkg-config + glib + libfprint + polkit + dbus + systemd + pam + libpam-wrapper + ]; + + mesonFlags = [ + "-Dpam_modules_dir=${placeholder "out"}/lib/security" + "-Dsysconfdir=${placeholder "out"}/etc" + "-Ddbus_service_dir=${placeholder "out"}/share/dbus-1/system-services" + "-Dsystemd_system_unit_dir=${placeholder "out"}/lib/systemd/system" + ]; +} diff --git a/nixos/overlays/swayosd.nix b/nixos/overlays/swayosd.nix new file mode 100644 index 00000000..b6b3c5f2 --- /dev/null +++ b/nixos/overlays/swayosd.nix @@ -0,0 +1,27 @@ +final: prev: { + swayosd = prev.swayosd.overrideAttrs (oldAttrs: rec { + + src = prev.fetchFromGitHub { + owner = "ErikReider"; + repo = "SwayOSD"; + rev = "8159c9e9962ce19f6fb78201d4d34e5817f53b45"; + hash = "sha256-kGd4/eQkhvxEL3/LToBDjE/JIR8m6w9vdFUrRTyylCE="; + }; + + cargoDeps = oldAttrs.cargoDeps.overrideAttrs (prev.lib.const { + name = "swayosd-vendor.tar.gz"; + inherit src; + outputHash = "sha256-gRhhPDUFPcDS1xo7JzCpZtd1Al1kEkx2dXf92cc2bUo="; + #outputHash = prev.lib.fakeHash; + }); + + buildInputs = (oldAttrs.buildInputs or [ ]) ++ [ + prev.systemd + ]; + + patches = [ + ./patches/swayosd.patch + ]; + }); +} + diff --git a/overlays/README.md b/overlays/README.md deleted file mode 100644 index 1720a73d..00000000 --- a/overlays/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Overlays - -This directory contains every overlay exposed by this flake. - -## List of my overlays found in `self.overlays` - -| Name | Description | -| ---- | ----------- | -| `appsPackages` | This overlay puts every derivations for apps exposed by this flake under pkgs.appsPackages. | -| `misc-fixes` | Fixes build failures, missing meta attributes, evaluation failures, etc. of the current `nixpkgs` revision of this flake. | -| `nix-version` | Overrides the nix package for everything so I don't need multiple versions. | -| `scopedPackages` | This overlay puts every package scopes exposed by this flake under pkgs.scopedPackages. | -| `selfPackages` | This overlay puts every derivations for packages exposed by this flake under pkgs.selfPackages. | -| `xdg-desktop-portal-kde` | Fixes this issue: https://invent.kde.org/plasma/xdg-desktop-portal-kde/-/issues/15 | diff --git a/overlays/default.nix b/overlays/default.nix deleted file mode 100644 index fe6307c3..00000000 --- a/overlays/default.nix +++ /dev/null @@ -1,65 +0,0 @@ -{ - self ? {}, - description ? false, -}: let - inputs = self.inputs // {inherit self;}; - - overlay = mod: desc: - if description - then desc - else mod; -in { - appsPackages = - overlay - (import ../apps/packages.nix { - inherit inputs; - }) - '' - This overlay puts every derivations for apps exposed by this flake - under pkgs.appsPackages. - ''; - - misc-fixes = - overlay - (import ./misc-fixes) - '' - Fixes build failures, missing meta attributes, evaluation failures, etc. - of the current `nixpkgs` revision of this flake. - ''; - - nix-version = - overlay - (import ./nix-version self) - '' - Overrides the nix package for everything so I don't need multiple versions. - ''; - - scopedPackages = - overlay - (import ../scopedPackages { - inherit (self.lib) mkVersion; - inherit inputs; - }) - '' - This overlay puts every package scopes exposed by this flake - under pkgs.scopedPackages. - ''; - - selfPackages = - overlay - (import ../packages { - inherit (self.lib) mkVersion; - inherit inputs; - }) - '' - This overlay puts every derivations for packages exposed by this flake - under pkgs.selfPackages. - ''; - - xdg-desktop-portal-kde = - overlay - (import ./xdg-desktop-portal-kde) - '' - Fixes this issue: https://invent.kde.org/plasma/xdg-desktop-portal-kde/-/issues/15 - ''; -} diff --git a/overlays/misc-fixes/default.nix b/overlays/misc-fixes/default.nix deleted file mode 100644 index aef36d5b..00000000 --- a/overlays/misc-fixes/default.nix +++ /dev/null @@ -1,21 +0,0 @@ -final: prev: { - # FIXME: wait for next version of nix-update to reach nixpkgs (after 1.11.0) - # https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/ni/nix-update/package.nix - nix-update = prev.nix-update.overrideAttrs (o: let - inherit (builtins) fromTOML readFile substring; - - rev = "3d5866d1a8bc2f8197222e4814a8406298c36428"; - - src = prev.fetchFromGitHub { - owner = "Mic92"; - repo = "nix-update"; - inherit rev; - hash = "sha256-y3LY2tWDQUDjraAOjQ60tgegAws1gpb+I5u06XmQnoA="; - }; - - pyproject = fromTOML (readFile "${src}/pyproject.toml"); - in { - version = "${pyproject.project.version}+${substring 0 7 rev}"; - inherit src; - }); -} diff --git a/overlays/nix-version/default.nix b/overlays/nix-version/default.nix deleted file mode 100644 index 6ec8bc03..00000000 --- a/overlays/nix-version/default.nix +++ /dev/null @@ -1,56 +0,0 @@ -self: {nix ? null}: final: prev: let - inherit (builtins) functionArgs mapAttrs replaceStrings; - inherit (final.lib) generateSplicesForMkScope head splitString versions; - inherit (self.inputs) nix-eval-jobs nix-fast-build; - - nullCheck = n: v: - if nix == null - then prev.${n} - else v; - - # This is for packages from flakes that don't offer overlays - overrideAll = pkg: extraArgs: let - pkgFile = head (splitString [":"] pkg.meta.position); - args = functionArgs (import pkgFile); - in - pkg.override (mapAttrs (n: v: final.${n} or v) (args // extraArgs)); -in - mapAttrs nullCheck { - inherit nix; - - nix-serve = prev.nix-serve-ng.override { - inherit nix; - }; - - nix-output-monitor = prev.nix-output-monitor.overrideAttrs (o: { - postPatch = '' - ${o.postPatch} - - sed -i 's/.*" nom hasn‘t detected any input. Have you redirected nix-build stderr into nom? (See -h and the README for details.)".*//' ./lib/NOM/Print.hs - ''; - }); - - nix-eval-jobs = - (overrideAll nix-eval-jobs.packages.${final.system}.default { - srcDir = null; - - nixComponents = let - generateSplicesForNixComponents = nixComponentsAttributeName: - generateSplicesForMkScope [ - "nixVersions" - nixComponentsAttributeName - ]; - in - final.nixDependencies.callPackage "${final.path}/pkgs/tools/package-management/nix/modular/packages.nix" { - inherit (nix) src version; - inherit (nix.meta) maintainers; - - otherSplices = generateSplicesForNixComponents "nixComponents_${ - replaceStrings ["."] ["_"] (versions.majorMinor nix.version) - }"; - }; - }) - // {inherit nix;}; - - nix-fast-build = overrideAll nix-fast-build.packages.${final.system}.nix-fast-build {}; - } diff --git a/overlays/xdg-desktop-portal-kde/6-1-3.patch b/overlays/xdg-desktop-portal-kde/6-1-3.patch deleted file mode 100644 index de73d233..00000000 --- a/overlays/xdg-desktop-portal-kde/6-1-3.patch +++ /dev/null @@ -1,41 +0,0 @@ -diff --git a/src/remotedesktop.cpp b/src/remotedesktop.cpp -index 99ce57f..af64eff 100644 ---- a/src/remotedesktop.cpp -+++ b/src/remotedesktop.cpp -@@ -19,6 +19,8 @@ - #include <KNotification> - #include <QGuiApplication> - #include <QRegion> -+#include <KSharedConfig> -+#include <KConfigGroup> - #include <QScreen> - - RemoteDesktopPortal::RemoteDesktopPortal(QObject *parent) -@@ -152,14 +154,19 @@ uint RemoteDesktopPortal::Start(const QDBusObjectPath &handle, - notification->setIconName(QStringLiteral("krfb")); - notification->sendEvent(); - } else { -- QScopedPointer<RemoteDesktopDialog, QScopedPointerDeleteLater> remoteDesktopDialog( -- new RemoteDesktopDialog(app_id, session->deviceTypes(), session->screenSharingEnabled())); -- Utils::setParentWindow(remoteDesktopDialog->windowHandle(), parent_window); -- Request::makeClosableDialogRequest(handle, remoteDesktopDialog.get()); -- connect(session, &Session::closed, remoteDesktopDialog.data(), &RemoteDesktopDialog::reject); -- -- if (!remoteDesktopDialog->exec()) { -- return 1; -+ auto cfg = KSharedConfig::openConfig(QStringLiteral("plasmaremotedesktoprc")); -+ const auto unattendedAccess = cfg->group("Sharing").readEntry("Unattended", false); -+ if (!unattendedAccess) -+ { -+ QScopedPointer<RemoteDesktopDialog, QScopedPointerDeleteLater> remoteDesktopDialog( -+ new RemoteDesktopDialog(app_id, session->deviceTypes(), session->screenSharingEnabled())); -+ Utils::setParentWindow(remoteDesktopDialog->windowHandle(), parent_window); -+ Request::makeClosableDialogRequest(handle, remoteDesktopDialog.get()); -+ connect(session, &Session::closed, remoteDesktopDialog.data(), &RemoteDesktopDialog::reject); -+ -+ if (!remoteDesktopDialog->exec()) { -+ return 1; -+ } - } - } - diff --git a/overlays/xdg-desktop-portal-kde/6-2.patch b/overlays/xdg-desktop-portal-kde/6-2.patch deleted file mode 100644 index 89ce03b2..00000000 --- a/overlays/xdg-desktop-portal-kde/6-2.patch +++ /dev/null @@ -1,41 +0,0 @@ -diff --git a/src/remotedesktop.cpp b/src/remotedesktop.cpp -index 02a32a7..6b9b687 100644 ---- a/src/remotedesktop.cpp -+++ b/src/remotedesktop.cpp -@@ -22,6 +22,8 @@ - #include <QDBusReply> - #include <QGuiApplication> - #include <QRegion> -+#include <KSharedConfig> -+#include <KConfigGroup> - #include <QScreen> - - using namespace Qt::StringLiterals; -@@ -178,14 +180,19 @@ uint RemoteDesktopPortal::Start(const QDBusObjectPath &handle, - notification->setIconName(QStringLiteral("krfb")); - notification->sendEvent(); - } else { -- QScopedPointer<RemoteDesktopDialog, QScopedPointerDeleteLater> remoteDesktopDialog( -- new RemoteDesktopDialog(app_id, session->deviceTypes(), session->screenSharingEnabled(), session->persistMode())); -- Utils::setParentWindow(remoteDesktopDialog->windowHandle(), parent_window); -- Request::makeClosableDialogRequest(handle, remoteDesktopDialog.get()); -- connect(session, &Session::closed, remoteDesktopDialog.data(), &RemoteDesktopDialog::reject); -- -- if (!remoteDesktopDialog->exec()) { -- return 1; -+ auto cfg = KSharedConfig::openConfig(QStringLiteral("plasmaremotedesktoprc")); -+ const auto unattendedAccess = cfg->group("Sharing").readEntry("Unattended", false); -+ if (!unattendedAccess) -+ { -+ QScopedPointer<RemoteDesktopDialog, QScopedPointerDeleteLater> remoteDesktopDialog( -+ new RemoteDesktopDialog(app_id, session->deviceTypes(), session->screenSharingEnabled(), session->persistMode())); -+ Utils::setParentWindow(remoteDesktopDialog->windowHandle(), parent_window); -+ Request::makeClosableDialogRequest(handle, remoteDesktopDialog.get()); -+ connect(session, &Session::closed, remoteDesktopDialog.data(), &RemoteDesktopDialog::reject); -+ -+ if (!remoteDesktopDialog->exec()) { -+ return 1; -+ } - } - } - diff --git a/overlays/xdg-desktop-portal-kde/default.nix b/overlays/xdg-desktop-portal-kde/default.nix deleted file mode 100644 index 0cf4862f..00000000 --- a/overlays/xdg-desktop-portal-kde/default.nix +++ /dev/null @@ -1,19 +0,0 @@ -(final: prev: { - kdePackages = prev.kdePackages.overrideScope (kfinal: kprev: { - xdg-desktop-portal-kde = kprev.xdg-desktop-portal-kde.overrideAttrs (o: { - patches = let - rdpPatch = - if o.version == "6.1.3" - then ./6-1-3.patch - else if builtins.compareVersions o.version "6.3.0" == -1 - then ./6-2.patch - else throw "This patch is not working or needed anymore. Please see https://develop.kde.org/docs/administration/portal-permissions/"; - in - (o.patches or []) - ++ [ - # https://invent.kde.org/plasma/xdg-desktop-portal-kde/-/issues/15#note_906047 - rdpPatch - ]; - }); - }); -}) diff --git a/packages/README.md b/packages/README.md deleted file mode 100644 index 58df94db..00000000 --- a/packages/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# Packages - -This directory contains every derivations for packages exposed by this flake. - -## List of my packages found in `self.packages` - -| Name | Description | Homepage | -| ---- | ----------- | -------- | -| `coloryou` | Get Material You colors from an image. | https://git.nelim.org/matt1432/nixos-configs/src/branch/master/packages/coloryou | -| `gpu-screen-recorder` | Screen recorder that has minimal impact on system performance by recording a window using the GPU only. | https://git.dec05eba.com/gpu-screen-recorder/about | -| `gsr-kms-server` | Small program giving safe KMS access to gpu-screen-recorder when recording a monitor. This is the only part of gpu-screen-recorder that could require root permissions. | https://git.dec05eba.com/gpu-screen-recorder/about | -| `homepage` | Highly customisable dashboard with Docker and service API integrations. | https://gethomepage.dev | -| `jdownloader-cli` | Command line interface to JDownloader based on jdownloader-go library. | https://github.com/rkosegi/jdownloader-cli | -| `jmusicbot` | Discord music bot that's easy to set up and run yourself | https://github.com/jagrosh/MusicBot | -| `kapowarr` | Kapowarr is a software to build and manage a comic book library, fitting in the \*arr suite of software. | https://casvt.github.io/Kapowarr | -| `komf` | Komf is a tool that fetches metadata and thumbnails for your digital comic book library. | https://github.com/Snd-R/komf | -| `libratbag` | Configuration library for gaming mice | https://github.com/libratbag/libratbag | -| `librespot-auth` | A simple program for populating a credentials.json via Spotify's zeroconf authentication. | https://github.com/dspearson/librespot-auth | -| `nbted` | Command-line NBT editor written in Rust. It does precisely one thing: convert NBT files to a pretty text format, and reverse the pretty text format back into NBT. | https://github.com/C4K3/nbted | -| `pam-fprint-grosshack` | This is a fork of the pam module which implements the simultaneous password and fingerprint behaviour present in pam_thinkfinger. | https://gitlab.com/mishakmak/pam-fprint-grosshack | -| `piper` | GTK frontend for ratbagd mouse config daemon | https://github.com/libratbag/piper | -| `pokemon-colorscripts` | A script to print out images of pokemon to the terminal. | https://gitlab.com/phoneybadger/pokemon-colorscripts | -| `proton-ge-latest` | Compatibility tool for Steam Play based on Wine and additional components. (This is intended for use in the `programs.steam.extraCompatPackages` option only.) This derivation overrides the Proton version in Steam so that games using the Proton from nix keep using it after every version change. | https://github.com/GloriousEggroll/proton-ge-custom | -| `protonhax` | Tool to help running other programs (i.e. Cheat Engine) inside Steam's proton. | https://github.com/jcnils/protonhax | -| `repl` | A wrapper of `nix repl` with the flake located at `$FLAKE` loaded in. It also attempts to load the current system's derivation for both `nixosConfigurations` and `nixOnDroidConfigurations`. | fork of https://github.com/fufexan/dotfiles/blob/main/pkgs/repl/default.nix | -| `some-sass-language-server` | Some Sass is a language server extension for Visual Studio Code and other editors with a language server protocol (LSP) client. It brings improved code suggestions, documentation and code navigation for both SCSS and indented syntaxes. | https://github.com/wkillerud/some-sass | -| `subscleaner` | Subscleaner is a Python script that removes advertisements from subtitle files. It's designed to help you enjoy your favorite shows and movies without the distraction of unwanted ads in the subtitles. | https://gitlab.com/rogs/subscleaner | -| `trash-d` | A near drop-in replacement for `rm` that uses the [FreeDesktop trash bin](https://specifications.freedesktop.org/trash-spec/trashspec-latest.html). | https://github.com/rushsteve1/trash-d | -| `urllib3` | Powerful, sanity-friendly HTTP client for Python. | https://github.com/shazow/urllib3 | diff --git a/packages/coloryou/default.nix b/packages/coloryou/default.nix deleted file mode 100644 index 72051b64..00000000 --- a/packages/coloryou/default.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ - # nix build inputs - lib, - buildPythonApplication, - # deps - hatchling, - material-color-utilities, - ... -}: let - inherit (builtins) fromTOML readFile; - - inherit (fromTOML (readFile ./pyproject.toml)) project; -in - buildPythonApplication rec { - pname = project.name; - inherit (project) version; - format = "pyproject"; - - src = ./.; - - build-system = [hatchling]; - dependencies = [material-color-utilities]; - - meta = { - mainProgram = pname; - license = lib.licenses.mit; - homepage = "https://git.nelim.org/matt1432/nixos-configs/src/branch/master/packages/coloryou"; - inherit (project) description; - }; - } diff --git a/packages/coloryou/pyproject.toml b/packages/coloryou/pyproject.toml deleted file mode 100644 index 8e304d00..00000000 --- a/packages/coloryou/pyproject.toml +++ /dev/null @@ -1,15 +0,0 @@ -[project] -name = "coloryou" -description="Get Material You colors from an image." -version = "0.1.0" - -dependencies = [ - "material_color_utilities_python", -] - -[build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" - -[project.scripts] -coloryou = "coloryou:main" diff --git a/packages/default.nix b/packages/default.nix deleted file mode 100644 index 30c46572..00000000 --- a/packages/default.nix +++ /dev/null @@ -1,63 +0,0 @@ -{ - inputs, - mkVersion, - ... -}: (final: prev: { - selfPackages = { - coloryou = final.python3Packages.callPackage ./coloryou {}; - - gpu-screen-recorder = final.callPackage ./gpu-screen-recorder/gpu-screen-recorder.nix { - inherit (inputs) gpu-screen-recorder-src; - }; - gsr-kms-server = final.callPackage ./gpu-screen-recorder/gsr-kms-server.nix { - inherit (inputs) gpu-screen-recorder-src; - }; - - homepage = final.callPackage ./homepage {}; - - jdownloader-cli = final.callPackage ./jdownloader-cli {}; - - jmusicbot = final.callPackage ./jmusicbot {}; - - kapowarr = import ./kapowarr (final // inputs); - - komf = final.callPackage ./komf {}; - - libratbag = final.callPackage ./libratbag { - inherit (inputs) libratbag-src; - }; - - librespot-auth = final.callPackage ./librespot-auth {}; - - nbted = final.callPackage ./nbted {}; - - pam-fprint-grosshack = final.callPackage ./pam-fprint-grosshack {}; - - piper = final.callPackage ./piper { - inherit (inputs) piper-src; - }; - - pokemon-colorscripts = final.callPackage ./pokemon-colorscripts { - inherit (inputs) pokemon-colorscripts-src; - inherit mkVersion; - }; - - proton-ge-latest = final.callPackage ./proton-ge-latest {}; - - protonhax = final.callPackage ./protonhax {}; - - repl = final.callPackage ./repl {}; - - some-sass-language-server = final.callPackage ./some-sass-language-server {}; - - subscleaner = final.python3Packages.callPackage ./subscleaner { - inherit (inputs) subscleaner-src; - }; - - trash-d = final.callPackage ./trash-d { - inherit (inputs) trash-d-src; - }; - - urllib3 = final.callPackage ./urllib3 {}; - }; -}) diff --git a/packages/gpu-screen-recorder/generic.nix b/packages/gpu-screen-recorder/generic.nix deleted file mode 100644 index 745cefb7..00000000 --- a/packages/gpu-screen-recorder/generic.nix +++ /dev/null @@ -1,116 +0,0 @@ -{ - # params - pname, - description, - isKmsServer ? false, - # nix build inputs - lib, - stdenv, - addDriverRunpath, - makeWrapper, - gpu-screen-recorder-src, - # deps - dbus, - ffmpeg, - libdrm, - libglvnd, - libpulseaudio, - libva, - meson, - ninja, - pipewire, - pkg-config, - vulkan-headers, - wayland, - wayland-scanner, - xorg, - ... -}: let - inherit (lib) makeLibraryPath optionalString; - inherit (builtins) fromTOML readFile; - - tag = - (fromTOML (readFile "${gpu-screen-recorder-src}/project.conf")) - .package - .version; -in - stdenv.mkDerivation { - inherit pname; - version = "${tag}+${gpu-screen-recorder-src.shortRev}"; - - src = gpu-screen-recorder-src; - - # Get rid of useless warning due to how I install the package - postPatch = '' - sed -i 's/.*gsr-kms-server is not installed in the same directory.*//' ./kms/client/kms_client.c - ''; - - nativeBuildInputs = [ - makeWrapper - meson - ninja - pkg-config - ]; - - buildInputs = [ - dbus - ffmpeg - libdrm - libpulseaudio - libva - pipewire - vulkan-headers - wayland - wayland-scanner - xorg.libXcomposite - xorg.libXdamage - xorg.libXi - xorg.libXrandr - ]; - - mesonFlags = [ - "-Dcapabilities=false" - "-Dnvidia_suspend_fix=false" - "-Dsystemd=false" - ]; - - fixupPhase = - optionalString (!isKmsServer) - # bash - '' - runHook preFixup - - wrapProgram $out/bin/gpu-screen-recorder \ - --prefix LD_LIBRARY_PATH : "${ - makeLibraryPath [ - addDriverRunpath.driverLink - libglvnd - ] - }" - - runHook postFixup - ''; - - # This is needed to force gsr to lookup kms in PATH - # to get the security wrapper - postFixup = - if isKmsServer - then - # bash - '' - rm $out/bin/gpu-screen-recorder - '' - else - # bash - '' - rm $out/bin/gsr-kms-server - ''; - - meta = { - mainProgram = pname; - license = lib.licenses.gpl3Only; - platforms = ["x86_64-linux"]; - homepage = "https://git.dec05eba.com/gpu-screen-recorder/about"; - inherit description; - }; - } diff --git a/packages/gpu-screen-recorder/gpu-screen-recorder.nix b/packages/gpu-screen-recorder/gpu-screen-recorder.nix deleted file mode 100644 index 59e85d88..00000000 --- a/packages/gpu-screen-recorder/gpu-screen-recorder.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ - callPackage, - gpu-screen-recorder-src, - ... -}: -callPackage ./generic.nix { - pname = "gpu-screen-recorder"; - inherit gpu-screen-recorder-src; - - description = '' - Screen recorder that has minimal impact on system performance by recording - a window using the GPU only. - ''; -} diff --git a/packages/gpu-screen-recorder/gsr-kms-server.nix b/packages/gpu-screen-recorder/gsr-kms-server.nix deleted file mode 100644 index 9496cda7..00000000 --- a/packages/gpu-screen-recorder/gsr-kms-server.nix +++ /dev/null @@ -1,15 +0,0 @@ -{ - callPackage, - gpu-screen-recorder-src, - ... -}: -callPackage ./generic.nix { - pname = "gsr-kms-server"; - isKmsServer = true; - inherit gpu-screen-recorder-src; - - description = '' - Small program giving safe KMS access to gpu-screen-recorder when recording a monitor. - This is the only part of gpu-screen-recorder that could require root permissions. - ''; -} diff --git a/packages/homepage/default.nix b/packages/homepage/default.nix deleted file mode 100644 index 5dc4aab2..00000000 --- a/packages/homepage/default.nix +++ /dev/null @@ -1,93 +0,0 @@ -{ - # nix build inputs - lib, - stdenv, - fetchFromGitHub, - makeWrapper, - # deps - nodejs, - pnpm, - # params - enableLocalIcons ? true, - ... -}: let - inherit (lib) getExe optionalString; - - installLocalIcons = import ./icons.nix {inherit fetchFromGitHub;}; -in - stdenv.mkDerivation (finalAttrs: { - pname = "homepage-dashboard"; - version = "1.1.1"; - - src = fetchFromGitHub { - owner = "gethomepage"; - repo = "homepage"; - rev = "v${finalAttrs.version}"; - hash = "sha256-gYFJ/coLQ/iBuMIF3+MaGfhA8J4S8TOi5sbd3ZaYeXU="; - }; - - pnpmDepsHash = "sha256-qLRtkQjwHH0JK+u+fJnYfJDhZDEasAzprSY+cogNrNg="; - - pnpmDeps = pnpm.fetchDeps { - inherit (finalAttrs) pname version src; - hash = finalAttrs.pnpmDepsHash; - }; - - nativeBuildInputs = [ - makeWrapper - nodejs - pnpm.configHook - ]; - - buildPhase = '' - pnpm build - - # Add a shebang to the server js file - sed -i '1s|^|#!${getExe nodejs}\n|' .next/standalone/server.js - ''; - - installPhase = '' - runHook preInstall - - mkdir -p $out/{share,bin} - - # Without this, homepage-dashboard errors when trying to - # write its prerender cache. - # - # This ensures that the cache implementation respects the env - # variable `HOMEPAGE_CACHE_DIR`, which is set by default in the - # wrapper below. - substituteInPlace .next/standalone/node_modules/next/dist/server/lib/incremental-cache/file-system-cache.js --replace-fail \ - "this.serverDistDir = ctx.serverDistDir;" \ - "this.serverDistDir = require('node:path').join(process.env.HOMEPAGE_CACHE_DIR, \"homepage\");" - - cp -r .next/standalone $out/share/homepage/ - cp -r public $out/share/homepage/public - - mkdir -p $out/share/homepage/.next - cp -r .next/static $out/share/homepage/.next/static - - chmod +x $out/share/homepage/server.js - - makeWrapper $out/share/homepage/server.js $out/bin/homepage \ - --set-default PORT 3000 \ - --set-default HOMEPAGE_CONFIG_DIR /var/lib/homepage-dashboard \ - --set-default HOMEPAGE_CACHE_DIR /var/cache/homepage-dashboard - - ${optionalString enableLocalIcons installLocalIcons} - - runHook postInstall - ''; - - passthru.updateScript = ./update.sh; - - meta = { - mainProgram = "homepage"; - license = lib.licenses.gpl3; - homepage = "https://gethomepage.dev"; - changelog = "https://github.com/gethomepage/homepage/releases/tag/v${finalAttrs.version}"; - description = '' - Highly customisable dashboard with Docker and service API integrations. - ''; - }; - }) diff --git a/packages/homepage/icons.nix b/packages/homepage/icons.nix deleted file mode 100644 index ee9961e8..00000000 --- a/packages/homepage/icons.nix +++ /dev/null @@ -1,13 +0,0 @@ -{fetchFromGitHub, ...}: let - dashboardIcons = fetchFromGitHub { - owner = "walkxcode"; - repo = "dashboard-icons"; - rev = "be82e22c418f5980ee2a13064d50f1483df39c8c"; # Until 2024-07-21 - hash = "sha256-z69DKzKhCVNnNHjRM3dX/DD+WJOL9wm1Im1nImhBc9Y="; - }; -in '' - mkdir -p $out/share/homepage/public/icons - cp ${dashboardIcons}/png/* $out/share/homepage/public/icons - cp ${dashboardIcons}/svg/* $out/share/homepage/public/icons - cp ${dashboardIcons}/LICENSE $out/share/homepage/public/icons/ -'' diff --git a/packages/homepage/update.sh b/packages/homepage/update.sh deleted file mode 100755 index bb249883..00000000 --- a/packages/homepage/update.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -nix-update --flake homepage - -file="$FLAKE/packages/homepage/default.nix" -old_hash="$(sed -n 's/.*pnpmDepsHash = "\(.*\)";/\1/p' "$file")" - -sed -i "s/pnpmDepsHash = .*/pnpmDepsHash = \"\";/" "$file" -npm_hash="$(nix build "$FLAKE#homepage" |& sed -n 's/.*got: *//p')" - -if [[ "$npm_hash" != "$old_hash" ]]; then - sed -i "s#pnpmDepsHash = .*#pnpmDepsHash = \"$npm_hash\";#" "$file" -else - sed -i "s#pnpmDepsHash = .*#pnpmDepsHash = \"$old_hash\";#" "$file" -fi diff --git a/packages/jdownloader-cli/default.nix b/packages/jdownloader-cli/default.nix deleted file mode 100644 index 57aad6b6..00000000 --- a/packages/jdownloader-cli/default.nix +++ /dev/null @@ -1,46 +0,0 @@ -{ - lib, - buildGoModule, - fetchFromGitHub, - installShellFiles, - ... -}: let - pname = "jdownloader-cli"; - rev = "0f32237df32dfddc4a577404ba93c7c9d79284c3"; - version = "1.0.2+${builtins.substring 0 7 rev}"; - mainProgram = "jdcli"; -in - buildGoModule { - inherit pname version; - - src = fetchFromGitHub { - owner = "matt1432"; - repo = pname; - inherit rev; - hash = "sha256-EZyXgd184NjK+eUKB4+Awc+aFrG6goyLfwZ0zVRyGLA="; - }; - - vendorHash = "sha256-lBxddgaW1s3xjGODZhlvYBmK1vC+IdmpztTgagOy7J4="; - - nativeBuildInputs = [ - installShellFiles - ]; - - postInstall = '' - mv $out/bin/cmd $out/bin/${mainProgram} - - for shell in bash fish zsh; do - $out/bin/${mainProgram} completion $shell > ${mainProgram}.$shell - installShellCompletion ${mainProgram}.$shell - done - ''; - - meta = { - inherit mainProgram; - license = lib.licenses.asl20; - homepage = "https://github.com/rkosegi/jdownloader-cli"; - description = '' - Command line interface to JDownloader based on jdownloader-go library. - ''; - }; - } diff --git a/packages/jmusicbot/default.nix b/packages/jmusicbot/default.nix deleted file mode 100644 index ed02dd0f..00000000 --- a/packages/jmusicbot/default.nix +++ /dev/null @@ -1,41 +0,0 @@ -{ - # nix build inputs - lib, - fetchurl, - # deps - jmusicbot, - jdk21_headless, - jre_minimal, - ... -}: let - inherit (lib) concatStringsSep; - - jre_modules = [ - "java.se" - "jdk.crypto.cryptoki" - ]; - - jre = (jre_minimal.override {jdk = jdk21_headless;}).overrideAttrs (o: { - buildPhase = '' - runHook preBuild - - # further optimizations for image size https://github.com/NixOS/nixpkgs/issues/169775 - jlink \ - --module-path ${jdk21_headless}/lib/openjdk/jmods \ - --add-modules ${concatStringsSep "," jre_modules} \ - --no-header-files \ - --no-man-pages \ - --output $out - - runHook postBuild - ''; - }); -in - (jmusicbot.override {jre_headless = jre;}).overrideAttrs (o: rec { - version = "0.4.3.5"; - src = fetchurl { - url = "https://github.com/xPrinny/MusicBot/releases/download/${version}/JMusicBot-${version}.jar"; - sha256 = "sha256-3hGqm6Ey4CHLSTEPvKmaPTwsoG5+jHS6W3zwjF3km8Q="; - }; - meta = o.meta // {platforms = ["x86_64-linux"];}; - }) diff --git a/packages/kapowarr/bencoding/default.nix b/packages/kapowarr/bencoding/default.nix deleted file mode 100644 index 31f8f3a3..00000000 --- a/packages/kapowarr/bencoding/default.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ - # nix build inputs - buildPythonPackage, - fetchPypi, - ... -}: let - pname = "bencoding"; - version = "0.2.6"; -in - buildPythonPackage { - inherit pname version; - - src = fetchPypi { - inherit pname version; - hash = "sha256-Q8zjHUhj4p1rxhFVHU6fJlK+KZXp1eFbRtg4PxgNREA="; - }; - } diff --git a/packages/kapowarr/default.nix b/packages/kapowarr/default.nix deleted file mode 100644 index 7a698db9..00000000 --- a/packages/kapowarr/default.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ - # nix build inputs - python3Packages, - Kapowarr-src, - ... -}: let - pyPkgs = python3Packages.override { - overrides = pyFinal: pyPrev: { - bencoding = pyFinal.callPackage ./bencoding {}; - typing-extensions = pyFinal.callPackage ./typing-extensions {}; - }; - }; -in - pyPkgs.callPackage ./kapowarr {inherit Kapowarr-src;} diff --git a/packages/kapowarr/kapowarr/default.nix b/packages/kapowarr/kapowarr/default.nix deleted file mode 100644 index 97bc4f08..00000000 --- a/packages/kapowarr/kapowarr/default.nix +++ /dev/null @@ -1,89 +0,0 @@ -{ - # nix build inputs - lib, - stdenv, - python, - makeWrapper, - Kapowarr-src, - # deps - rar, - # python deps - aiohttp, - beautifulsoup4, - bencoding, # from overrides - cryptography, - flask, - flask-socketio, - requests, - typing-extensions, # from overrides - waitress, - websocket-client, - ... -}: let - inherit (lib) getExe; - inherit (builtins) fromTOML readFile; - - pyproject = fromTOML (readFile "${Kapowarr-src}/pyproject.toml"); - - dependencies = [ - typing-extensions - requests - beautifulsoup4 - flask - waitress - cryptography - bencoding - aiohttp - flask-socketio - websocket-client - ]; - - pythonExe = getExe (python.withPackages (ps: dependencies)); - - pname = "kapowarr"; - version = "${pyproject.project.version}+${Kapowarr-src.shortRev or "dirty"}"; -in - stdenv.mkDerivation { - inherit pname version; - - src = Kapowarr-src; - - nativeBuildInputs = [makeWrapper]; - - postPatch = '' - # Remove shebang - sed -i 1d ./Kapowarr.py - - # Disable PWA for now - substituteInPlace ./backend/internals/settings.py \ - --replace-fail "with open(filename, 'w') as f:" "" \ - --replace-fail "dump(manifest, f, indent=4)" "" - - # TODO: makes sure this works - substituteInPlace ./backend/implementations/converters.py \ - --replace-fail \ - "exe = folder_path('backend', 'lib', Constants.RAR_EXECUTABLES[platform])" \ - "exe = '${getExe rar}'" - ''; - - buildPhase = '' - mkdir -p $out/${python.sitePackages} - cp -r ./. $out/${python.sitePackages} - ''; - - installPhase = '' - makeWrapper ${pythonExe} $out/bin/kapowarr \ - --add-flags "$out/${python.sitePackages}/Kapowarr.py" - ''; - - meta = { - inherit (rar.meta) platforms; - mainProgram = pname; - license = lib.licenses.gpl3Only; - homepage = "https://casvt.github.io/Kapowarr"; - description = '' - Kapowarr is a software to build and manage a comic book library, - fitting in the *arr suite of software. - ''; - }; - } diff --git a/packages/kapowarr/typing-extensions/default.nix b/packages/kapowarr/typing-extensions/default.nix deleted file mode 100644 index dbd15b3b..00000000 --- a/packages/kapowarr/typing-extensions/default.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ - # nix build inputs - buildPythonPackage, - fetchPypi, - # deps - flit-core, - ... -}: let - pname = "typing_extensions"; - version = "4.12.2"; -in - buildPythonPackage { - inherit pname version; - format = "pyproject"; - - build-system = [flit-core]; - dependencies = [flit-core]; - - src = fetchPypi { - inherit pname version; - hash = "sha256-Gn6tVcflWd1N7ohW46iLQSJav+HOjfV7fBORX+Eh/7g="; - }; - } diff --git a/packages/komf/default.nix b/packages/komf/default.nix deleted file mode 100644 index 963865a9..00000000 --- a/packages/komf/default.nix +++ /dev/null @@ -1,51 +0,0 @@ -{ - # nix build inputs - lib, - stdenv, - fetchurl, - makeWrapper, - # deps - jre, - ... -}: let - pname = "komf"; - version = "1.3.0"; -in - stdenv.mkDerivation { - inherit pname version; - - src = fetchurl { - url = "https://github.com/Snd-R/${pname}/releases/download/${version}/${pname}-${version}.jar"; - hash = "sha256-6TR6NQnms/iqieRUSniEk2iLaQo/1mC1e1OWe8skNf8="; - name = "${pname}-${version}.jar"; - }; - - nativeBuildInputs = [makeWrapper]; - buildInputs = [ - jre - ]; - - dontUnpack = true; - - installPhase = '' - runHook preInstall - - mkdir -p "$prefix/bin" - - makeWrapper ${jre}/bin/java $out/bin/${pname} \ - --add-flags "-jar $src" \ - --prefix PATH : "$PATH" - - runHook postInstall - ''; - - meta = { - mainProgram = pname; - license = lib.licenses.mit; - homepage = "https://github.com/Snd-R/komf"; - sourceProvenance = with lib.sourceTypes; [binaryBytecode]; - description = '' - Komf is a tool that fetches metadata and thumbnails for your digital comic book library. - ''; - }; - } diff --git a/packages/libratbag/default.nix b/packages/libratbag/default.nix deleted file mode 100644 index d1ee5706..00000000 --- a/packages/libratbag/default.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ - # nix build inputs - lib, - libratbag-src, - # deps - libratbag, - ... -}: let - inherit (lib) elemAt match readFile splitString; - - releaseVer = elemAt (match "^([^']*).*" (elemAt (splitString "version : '" (readFile "${libratbag-src}/meson.build")) 1)) 0; -in - libratbag.overrideAttrs { - pname = "libratbag"; - version = "${releaseVer}+${libratbag-src.shortRev}"; - src = libratbag-src; - } diff --git a/packages/librespot-auth/default.nix b/packages/librespot-auth/default.nix deleted file mode 100644 index 57c47d28..00000000 --- a/packages/librespot-auth/default.nix +++ /dev/null @@ -1,49 +0,0 @@ -{ - # nix build inputs - lib, - fetchFromGitHub, - makeWrapper, - rustPlatform, - # deps - openssl, - pkg-config, - ... -}: -rustPlatform.buildRustPackage rec { - pname = "librespot-auth"; - version = "0.1.1"; - - # deprecated https://github.com/dspearson/librespot-auth - src = fetchFromGitHub { - owner = "dspearson"; - repo = pname; - rev = "v${version}"; - sha256 = "sha256-IbbArRSKpnljhZSgL0b3EjVzKWN7bk6t0Bv7TkYr8FI="; - }; - - cargoLock = { - lockFile = "${src}/Cargo.lock"; - outputHashes = { - "librespot-core-0.5.0-dev" = "sha256-7HrA1hWEy5lliwgJ9amJy+Kd8lB50b3q2niaFWWwcYE="; - }; - }; - - nativeBuildInputs = [ - pkg-config - makeWrapper - ]; - - buildInputs = [ - openssl - ]; - - meta = { - mainProgram = pname; - license = with lib.licenses; [isc]; - homepage = "https://github.com/dspearson/librespot-auth"; - description = '' - A simple program for populating a credentials.json via Spotify's - zeroconf authentication. - ''; - }; -} diff --git a/packages/nbted/default.nix b/packages/nbted/default.nix deleted file mode 100644 index 924ff9a2..00000000 --- a/packages/nbted/default.nix +++ /dev/null @@ -1,42 +0,0 @@ -{ - # nix build inputs - lib, - rustPlatform, - fetchFromGitHub, - ... -}: let - pname = "nbted"; - version = "1.5.0"; - - src = fetchFromGitHub { - owner = "C4K3"; - repo = pname; - tag = version; - hash = "sha256-5gCxTFjI3WDC9+F9i4I2g17+wHWnQHjC4Hurj5CMhB4="; - }; -in - rustPlatform.buildRustPackage { - inherit pname src version; - - cargoLock.lockFile = "${src}/Cargo.lock"; - - env.OUT_DIR = "$out"; - - patchPhase = '' - export OUT_DIR=$(mktemp -d) - - rm ./build.rs - echo '"${version}"' > $OUT_DIR/git-revision.txt - substituteInPlace ./Cargo.toml --replace-fail "build = \"build.rs\"" "" - ''; - - meta = { - mainProgram = pname; - license = lib.licenses.cc0; - homepage = "https://github.com/C4K3/nbted"; - description = '' - Command-line NBT editor written in Rust. It does precisely one thing: convert NBT files to - a pretty text format, and reverse the pretty text format back into NBT. - ''; - }; - } diff --git a/packages/pam-fprint-grosshack/default.nix b/packages/pam-fprint-grosshack/default.nix deleted file mode 100644 index e515fc9f..00000000 --- a/packages/pam-fprint-grosshack/default.nix +++ /dev/null @@ -1,89 +0,0 @@ -{ - # nix build inputs - lib, - stdenv, - fetchFromGitLab, - nix-update-script, - # deps - dbus, - glib, - libfprint, - libpam-wrapper, - libxml2, - libxslt, - meson, - ninja, - pam, - perl, - pkg-config, - polkit, - python3Packages, - systemd, - ... -}: let - pname = "pam-fprint-grosshack"; - version = "0.3.0"; -in - stdenv.mkDerivation { - inherit pname version; - - src = fetchFromGitLab { - owner = "mishakmak"; - repo = pname; - rev = "v${version}"; - hash = "sha256-obczZbf/oH4xGaVvp3y3ZyDdYhZnxlCWvL0irgEYIi0="; - }; - - # Tests aren't actually ran for some reason so I get rid of the warning - postPatch = '' - substituteInPlace ./meson.build --replace-fail \ - "'gi.repository.FPrint': true," "'gi.repository.FPrint': false," - ''; - - nativeBuildInputs = [ - dbus - glib - libfprint - libpam-wrapper - libxml2 - libxslt - meson - ninja - pam - perl - pkg-config - polkit - systemd - - python3Packages.python - python3Packages.dbus-python - python3Packages.pydbus - python3Packages.pypamtest - python3Packages.python-dbusmock - ]; - - mesonFlags = [ - "-Dgtk_doc=true" - "-Dman=true" - "-Dpam_modules_dir=${placeholder "out"}/lib/security" - "-Dsysconfdir=${placeholder "out"}/etc" - "-Ddbus_service_dir=${placeholder "out"}/share/dbus-1/system-services" - "-Dsystemd_system_unit_dir=${placeholder "out"}/lib/systemd/system" - ]; - - passthru.updateScript = nix-update-script { - extraArgs = [ - "--flake" - ''--version=$(curl -s https://gitlab.com/api/v4/projects/mishakmak%2Fpam-fprint-grosshack/repository/tags | jq -r .[0].name)'' - ]; - }; - - meta = { - license = with lib.licenses; [gpl2Plus]; - homepage = "https://gitlab.com/mishakmak/pam-fprint-grosshack"; - description = '' - This is a fork of the pam module which implements the simultaneous password and - fingerprint behaviour present in pam_thinkfinger. - ''; - }; - } diff --git a/packages/piper/default.nix b/packages/piper/default.nix deleted file mode 100644 index deb075d1..00000000 --- a/packages/piper/default.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ - # nix build inputs - lib, - piper-src, - # deps - piper, - ... -}: let - inherit (lib) elemAt match readFile splitString; - - releaseVer = elemAt (match "^([^']*).*" (elemAt (splitString "version: '" (readFile "${piper-src}/meson.build")) 1)) 0; -in - piper.overridePythonAttrs { - pname = "piper"; - version = "${releaseVer}+${piper-src.shortRev}"; - - src = piper-src; - - mesonFlags = [ - "-Druntime-dependency-checks=false" - ]; - } diff --git a/packages/pokemon-colorscripts/default.nix b/packages/pokemon-colorscripts/default.nix deleted file mode 100644 index b0025068..00000000 --- a/packages/pokemon-colorscripts/default.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ - # nix build inputs - mkVersion, - stdenv, - pokemon-colorscripts-src, - # deps - python3Packages, - ... -}: -stdenv.mkDerivation { - pname = "pokemon-colorscripts"; - version = mkVersion pokemon-colorscripts-src; - - src = pokemon-colorscripts-src; - - propagatedBuildInputs = with python3Packages; [ - python - ]; - - installPhase = '' - mkdir -p $out/pokemon-colorscripts $out/bin - - cp -rf colorscripts $out/pokemon-colorscripts - cp pokemon.json $out/pokemon-colorscripts - - cp pokemon-colorscripts.py $out/pokemon-colorscripts - - ln -s $out/pokemon-colorscripts/pokemon-colorscripts.py $out/bin/pokemon-colorscripts - ''; - - meta = { - homepage = "https://gitlab.com/phoneybadger/pokemon-colorscripts"; - description = '' - A script to print out images of pokemon to the terminal. - ''; - }; -} diff --git a/packages/proton-ge-latest/default.nix b/packages/proton-ge-latest/default.nix deleted file mode 100644 index 8087abd5..00000000 --- a/packages/proton-ge-latest/default.nix +++ /dev/null @@ -1,42 +0,0 @@ -{ - # nix build inputs - lib, - # deps - proton-ge-bin, - rsync, - ... -}: let - inherit (lib) elemAt match replaceStrings; -in - proton-ge-bin.overrideAttrs (o: { - version = replaceStrings ["-"] ["."] (elemAt (match "^[^0-9]*(.*)" o.version) 0); - - buildInputs = [rsync]; - - buildCommand = - # bash - '' - runHook preBuild - - echo "Proton should not be installed into environments. Please use programs.steam.extraCompatPackages instead." > $out - - cat $src/compatibilitytool.vdf > ./compatibilitytool.vdf - sed -i 's/"GE-Proton[^"]*"/"GE-Proton-Latest"/g' ./compatibilitytool.vdf - - mkdir $steamcompattool - cp -a ./compatibilitytool.vdf $steamcompattool/ - rsync -ar --exclude='compatibilitytool.vdf' $src/* $steamcompattool/ - - runHook postBuild - ''; - - meta = - o.meta - // { - description = '' - ${o.meta.description} - This derivation overrides the Proton version in Steam so that games using the Proton - from nix keep using it after every version change. - ''; - }; - }) diff --git a/packages/protonhax/default.nix b/packages/protonhax/default.nix deleted file mode 100644 index 981cf2bd..00000000 --- a/packages/protonhax/default.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ - # nix build inputs - lib, - stdenv, - fetchFromGitHub, - ... -}: let - pname = "protonhax"; - version = "1.0.5"; -in - stdenv.mkDerivation { - inherit pname version; - - src = fetchFromGitHub { - owner = "jcnils"; - repo = pname; - rev = version; - hash = "sha256-5G4MCWuaF/adSc9kpW/4oDWFFRpviTKMXYAuT2sFf9w="; - }; - - installPhase = '' - install -Dt $out/bin -m755 protonhax - ''; - - meta = { - license = with lib.licenses; [bsd3]; - homepage = "https://github.com/jcnils/protonhax"; - description = '' - Tool to help running other programs (i.e. Cheat Engine) inside Steam's proton. - ''; - }; - } diff --git a/packages/repl/default.nix b/packages/repl/default.nix deleted file mode 100644 index fd10c0cb..00000000 --- a/packages/repl/default.nix +++ /dev/null @@ -1,52 +0,0 @@ -{ - # nix build inputs - writeShellApplication, - # deps - coreutils, - gnused, - ncurses, - ... -}: let - repl = ./repl.nix; - - example = command: desc: ''\n$(tput setaf 3) ${command}$(tput sgr0) - ${desc}''; -in - writeShellApplication { - name = "repl"; - - runtimeInputs = [coreutils gnused ncurses]; - - text = '' - arg=''${1:-""} - - case "$arg" in - "-h"|"--help"|"help") - # shellcheck disable=SC2059 - printf "\n\e[4mUsage\e[0m: \ - ${example "repl " "Loads system flake present at $(tput setaf 4)\\$FLAKE$(tput sgr0)."} \ - ${example "repl <flake path>" "Loads specified flake."}\n" - ;; - - *) - if [ -z "$arg" ]; then - nix repl \ - --arg flakePath "$(realpath "$FLAKE")" \ - --file ${repl} - else - nix repl \ - --arg flakePath "$(realpath "$arg" | sed 's|/flake.nix||')" \ - --file ${repl} - fi - ;; - esac - ''; - - meta = { - homepage = "fork of https://github.com/fufexan/dotfiles/blob/main/pkgs/repl/default.nix"; - description = '' - A wrapper of `nix repl` with the flake located at `$FLAKE` loaded in. It also attempts - to load the current system's derivation for both `nixosConfigurations` and - `nixOnDroidConfigurations`. - ''; - }; - } diff --git a/packages/repl/repl.nix b/packages/repl/repl.nix deleted file mode 100644 index 74c4234d..00000000 --- a/packages/repl/repl.nix +++ /dev/null @@ -1,31 +0,0 @@ -{ - flakePath, - hostnamePath ? "/etc/hostname", -}: let - inherit (builtins) currentSystem getFlake head match pathExists readFile removeAttrs; - - hostname = - if pathExists hostnamePath - then head (match "([a-zA-Z0-9\\-]+)\n" (readFile hostnamePath)) - else ""; - - self = - if pathExists flakePath - then - removeAttrs (getFlake (toString flakePath)) [ - # If you use flakegen, these take a lot of space - "nextFlake" - "nextFlakeSource" - ] - else {}; - - pkgs = self.inputs.nixpkgs.legacyPackages.${currentSystem} or {}; - lib = - if pkgs != {} - then pkgs.lib - else {}; -in - {inherit lib pkgs self;} - // self.nixosConfigurations.${hostname} - or self.nixOnDroidConfigurations.default - or {} diff --git a/packages/some-sass-language-server/default.nix b/packages/some-sass-language-server/default.nix deleted file mode 100644 index 8d359762..00000000 --- a/packages/some-sass-language-server/default.nix +++ /dev/null @@ -1,57 +0,0 @@ -{ - # nix build inputs - lib, - buildNpmPackage, - makeWrapper, - writeShellApplication, - # update script deps - nodejs_latest, - prefetch-npm-deps, - jq, - ... -}: let - inherit (lib) getExe; - inherit (builtins) fromJSON readFile; - package = fromJSON (readFile ./package.json); - - pname = "some-sass-language-server"; - version = package.dependencies.some-sass-language-server; -in - buildNpmPackage { - inherit pname version; - - src = ./.; - dontNpmBuild = true; - - nativeBuildInputs = [makeWrapper]; - - installPhase = '' - mkdir -p $out/bin - cp -r node_modules $out - makeWrapper $out/node_modules/.bin/some-sass-language-server $out/bin/some-sass-language-server - ''; - - npmDepsHash = "sha256-/LWkQwDqU8ISY9v72sn6DmJTro8j18opW75n9ck0jGk="; - - passthru.updateScript = getExe (writeShellApplication { - name = "update"; - runtimeInputs = [ - nodejs_latest - prefetch-npm-deps - jq - ]; - text = import ./update.nix; - }); - - meta = { - mainProgram = pname; - license = with lib.licenses; [isc]; - homepage = "https://github.com/wkillerud/some-sass"; - description = '' - Some Sass is a language server extension for Visual Studio Code and - other editors with a language server protocol (LSP) client. It brings - improved code suggestions, documentation and code navigation for both - SCSS and indented syntaxes. - ''; - }; - } diff --git a/packages/some-sass-language-server/package-lock.json b/packages/some-sass-language-server/package-lock.json deleted file mode 100644 index 2bee5070..00000000 --- a/packages/some-sass-language-server/package-lock.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "some-sass-language-server", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "some-sass-language-server": "2.1.2" - } - }, - "node_modules/some-sass-language-server": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/some-sass-language-server/-/some-sass-language-server-2.1.2.tgz", - "integrity": "sha512-BmqN2Ejua1PLfnk3z+PN84BqZwA4dCjPb4NoH/8zjB5aTBDvbt/PPmfteO18MgKB5+uuhtsz0b2/rzw/TIlBPQ==", - "license": "MIT", - "bin": { - "some-sass-language-server": "bin/some-sass-language-server" - }, - "engines": { - "node": ">=20" - } - } - } -} diff --git a/packages/some-sass-language-server/package.json b/packages/some-sass-language-server/package.json deleted file mode 100644 index f9da39db..00000000 --- a/packages/some-sass-language-server/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "some-sass-language-server": "2.1.2" - } -} diff --git a/packages/some-sass-language-server/update.nix b/packages/some-sass-language-server/update.nix deleted file mode 100644 index 9417a958..00000000 --- a/packages/some-sass-language-server/update.nix +++ /dev/null @@ -1,16 +0,0 @@ -#bash -'' - cd "$FLAKE/packages/some-sass-language-server" || return - - latest=$(npm outdated --json | jq -r '.["some-sass-language-server"]["latest"]' || true) - - if [[ "$latest" != "null" ]]; then - sed -i "s#\"some-sass-language-server\": \"[^\"]*\"#\"some-sass-language-server\": \"$latest\"#" ./package.json - - npm update - - npm_hash="$(prefetch-npm-deps ./package-lock.json)" - - sed -i "s#npmDepsHash = .*#npmDepsHash = \"$npm_hash\";#" ./default.nix - fi -'' diff --git a/packages/subscleaner/default.nix b/packages/subscleaner/default.nix deleted file mode 100644 index 1be84ccb..00000000 --- a/packages/subscleaner/default.nix +++ /dev/null @@ -1,44 +0,0 @@ -{ - # nix build inputs - lib, - buildPythonApplication, - subscleaner-src, - # deps - appdirs, - chardet, - hatch, - pysrt, - ... -}: let - inherit (builtins) fromTOML readFile; - - pyproject = fromTOML (readFile "${subscleaner-src}/pyproject.toml"); - - pname = pyproject.project.name; - version = "${pyproject.project.version}+${subscleaner-src.shortRev}"; -in - buildPythonApplication { - inherit pname version; - format = "pyproject"; - - src = subscleaner-src; - - build-system = [hatch]; - - dependencies = [ - pysrt - chardet - appdirs - ]; - - meta = { - mainProgram = "subscleaner"; - license = lib.licenses.gpl3Only; - homepage = "https://gitlab.com/rogs/subscleaner"; - description = '' - Subscleaner is a Python script that removes advertisements from subtitle files. - It's designed to help you enjoy your favorite shows and movies without the - distraction of unwanted ads in the subtitles. - ''; - }; - } diff --git a/packages/trash-d/default.nix b/packages/trash-d/default.nix deleted file mode 100644 index d4cbc68e..00000000 --- a/packages/trash-d/default.nix +++ /dev/null @@ -1,64 +0,0 @@ -{ - # nix build inputs - lib, - stdenv, - fetchFromGitHub, - # deps - dmd, - dub, - just, - scdoc, - ... -}: let - pname = "trash"; - version = "20"; -in - stdenv.mkDerivation { - inherit pname version; - - src = fetchFromGitHub { - owner = "rushsteve1"; - repo = "trash-d"; - rev = version; - hash = "sha256-x76kEqgwJGW4wmEyr3XzEXZ2AvRsm9ewrfjRjIsOphw="; - }; - - nativeBuildInputs = [ - just - ]; - - buildInputs = [ - dmd - dub - scdoc - ]; - - buildPhase = '' - # https://github.com/svanderburg/node2nix/issues/217#issuecomment-751311272 - export HOME=$(mktemp -d) - - just release manpage - ''; - - installPhase = '' - mkdir -p $out/{bin,man/man1} - - cp -a ./build/trash $out/bin - cp -a ./build/trash.1 $out/man/man1 - ''; - - meta = { - mainProgram = "trash"; - license = with lib.licenses; [mit]; - platforms = [ - "x86_64-linux" - "i686-linux" - "x86_64-darwin" - ]; - homepage = "https://github.com/rushsteve1/trash-d"; - description = '' - A near drop-in replacement for `rm` that uses the - [FreeDesktop trash bin](https://specifications.freedesktop.org/trash-spec/trashspec-latest.html). - ''; - }; - } diff --git a/packages/urllib3/default.nix b/packages/urllib3/default.nix deleted file mode 100644 index cb7d8289..00000000 --- a/packages/urllib3/default.nix +++ /dev/null @@ -1,71 +0,0 @@ -# From nixpkgs 4c0061c983a2bcb888f5c478cfb7631ec1090c22 -{ - # nix build inputs - lib, - python3Packages, - fetchPypi, - ... -}: -python3Packages.buildPythonPackage rec { - pname = "urllib3"; - version = "1.26.16"; - format = "setuptools"; - - src = fetchPypi { - inherit pname version; - hash = "sha256-jxNfZQJ1a95rKpsomJ31++h8mXDOyqaQQe3M5/BYmxQ="; - }; - - propagatedBuildInputs = - passthru.optional-dependencies.brotli - ++ passthru.optional-dependencies.socks; - - nativeCheckInputs = with python3Packages; [ - python-dateutil - mock - pytest-freezegun - pytest-timeout - pytestCheckHook - tornado - trustme - ]; - - doCheck = false; - - preCheck = '' - export CI # Increases LONG_TIMEOUT - ''; - - pythonImportsCheck = [ - "urllib3" - ]; - - passthru.optional-dependencies = with python3Packages; { - brotli = - if isPyPy - then [ - brotlicffi - ] - else [ - brotli - ]; - secure = [ - certifi - cryptography - idna - pyopenssl - ]; - socks = [ - pysocks - ]; - }; - - meta = { - license = lib.licenses.mit; - homepage = "https://github.com/shazow/urllib3"; - changelog = "https://github.com/urllib3/urllib3/blob/${version}/CHANGES.rst"; - description = '' - Powerful, sanity-friendly HTTP client for Python. - ''; - }; -} diff --git a/results/.gitkeep b/results/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/scopedPackages/README.md b/scopedPackages/README.md deleted file mode 100644 index 59ed2973..00000000 --- a/scopedPackages/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# ScopedPackages - -This directory contains every package scopes exposed by this flake. - -## List of my package scopes found in `self.scopedPackages` - -### dracula - -Custom derivations that each represent an app's Dracula Theme. - -| Name | Description | Homepage | -| ---- | ----------- | -------- | -| `bat` | Dark theme for bat based on the Dracula Sublime theme. | https://github.com/matt1432/bat | -| `git` | Dark theme for Git. | https://github.com/dracula/git | -| `gtk` | Dracula variant of the Ant theme | https://github.com/dracula/gtk | -| `plymouth` | Dark theme for Plymouth. Forked by me to add a password prompt and black background for more seemless boot sequence. | https://github.com/matt1432/dracula-plymouth | -| `sioyek` | Dark theme for Sioyek. | https://github.com/dracula/sioyek | -| `wallpaper` | Wallpaper based on the Dracula Theme. | https://github.com/aynp/dracula-wallpapers | - -### firefoxAddons - -Every extensions I use in my firefox module. - -| Name | Description | Homepage | -| ---- | ----------- | -------- | -| `auto-refresh-page` | Refresh web pages automatically. Auto-refresh and page monitor with specified time intervals. | https://www.hashtap.com/@refresh | -| `bitwarden` | At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. | https://bitwarden.com | -| `darkreader` | Dark mode for every website. Take care of your eyes, use dark theme for night and daily browsing. | https://darkreader.org/ | -| `floccus` | Sync your bookmarks and tabs across browsers via Nextcloud, any WebDAV service, any Git service, via a local file, via Google Drive. | https://floccus.org | -| `google-container` | THIS IS NOT AN OFFICIAL ADDON FROM MOZILLA! It is a fork of the Facebook Container addon. Prevent Google from tracking you around the web. The Google Container extension helps you take control and isolate your web activity from Google. | https://github.com/containers-everywhere/contain-google | -| `image-search-options` | A customizable reverse image search tool that conveniently presents a variety of top image search engines. | http://saucenao.com/ | -| `istilldontcareaboutcookies` | Community version of the popular extension "I don't care about cookies" https://github.com/OhMyGuus/I-Dont-Care-About-Cookies | https://github.com/OhMyGuus/I-Dont-Care-About-Cookies | -| `return-youtube-dislikes` | Returns ability to see dislike statistics on youtube | | -| `sound-volume` | Up to 600% volume boost | | -| `sponsorblock` | Easily skip YouTube video sponsors. When you visit a YouTube video, the extension will check the database for reported sponsors and automatically skip known sponsors. You can also report sponsors in videos. Other browsers: https://sponsor.ajay.app | https://sponsor.ajay.app | -| `stylus` | Redesign your favorite websites with Stylus, an actively developed and community driven userstyles manager. Easily install custom themes from popular online repositories, or create, edit, and manage your own personalized CSS stylesheets. | https://add0n.com/stylus.html | -| `tampermonkey` | Tampermonkey is the world's most popular userscript manager. | https://tampermonkey.net | -| `ttv-lol-pro` | TTV LOL PRO removes most livestream ads from Twitch. | https://github.com/younesaassila/ttv-lol-pro | -| `ublock-origin` | Finally, an efficient wide-spectrum content blocker. Easy on CPU and memory. | https://github.com/gorhill/uBlock#ublock-origin | -| `undoclosetabbutton` | Allows you to restore the tab you just closed with a single click---plus it can offer a list of recently closed tabs within a convenient context menu. | https://github.com/M-Reimer/undoclosetab | - -### hass-components - -Components I use for Home-Assistant that aren't in nixpkgs. - -| Name | Description | Homepage | -| ---- | ----------- | -------- | -| `extended-ollama-conversation` | Home Assistant custom component of conversation agent. It uses Ollama to control your devices. | https://github.com/TheNimaj/extended_ollama_conversation | -| `material-symbols` | Material Symbols for Home Assistant is a collection of 13,803 Google Material Symbols for use within Home Assistant. It uses the icon-set produced and maintained by iconify. | https://github.com/beecho01/material-symbols | -| `netdaemon` | An application daemon for Home Assistant written in .NET. | https://github.com/net-daemon/netdaemon | -| `spotifyplus` | Home Assistant integration for Spotify Player control, services, and soundtouchplus integration support. | https://github.com/thlucas1/homeassistantcomponent_spotifyplus | -| `tuya-local` | Local support for Tuya devices in Home Assistant. | https://github.com/make-all/tuya-local | -| `yamaha-soundbar` | Yamaha soundbar integration for Home Assistant. | https://github.com/osk2/yamaha-soundbar | - -### lovelace-components - -Lovelace components I use for Home-Assistant that aren't in nixpkgs. - -| Name | Description | Homepage | -| ---- | ----------- | -------- | -| `big-slider-card` | A card with a big slider for light entities in Home Assistant. | https://github.com/nicufarmache/lovelace-big-slider-card | -| `custom-sidebar` | Custom HACS plugin that allows you to personalise the Home Assistant's sidebar per user or device basis. | https://github.com/elchininet/custom-sidebar | -| `material-rounded-theme` | Material Design 3 Colors and Components in Home Assistant. | https://github.com/Nerwyn/material-rounded-theme | -| `material-you-utilities` | Material You color theme generation and Home Assistant component modification. | https://github.com/Nerwyn/ha-material-you-utilities | - -### mpvScripts - -MPV scripts I use that aren't in nixpkgs. - -| Name | Description | Homepage | -| ---- | ----------- | -------- | -| `kdialog-open-files` | Use KDE KDialog to add files to playlist, subtitles to playing video or open URLs. Based on 'mpv-open-file-dialog' <https://github.com/rossy/mpv-open-file-dialog>. | https://gist.github.com/ntasos/d1d846abd7d25e4e83a78d22ee067a22 | -| `modernz` | A sleek and modern OSC for mpv designed to enhance functionality by adding more features, all while preserving the core standards of mpv's OSC. | https://github.com/Samillion/ModernZ | -| `persist-properties` | Keeps selected property values (like volume) between player sessions. | https://github.com/d87/mpv-persist-properties | -| `pointer-event` | Mouse/Touch input event detection for mpv. | https://github.com/christoph-heinrich/mpv-pointer-event | -| `touch-gestures` | Touch gestures for mpv. | https://github.com/christoph-heinrich/mpv-touch-gestures | -| `undo-redo` | Accidentally seeked? No worries, simply undo.. Undo is not enough to fix your accidental seek? Well now you can redo as well.. | https://github.com/Eisa01/mpv-scripts?tab=readme-ov-file#undoredo | diff --git a/scopedPackages/default.nix b/scopedPackages/default.nix deleted file mode 100644 index 947980c1..00000000 --- a/scopedPackages/default.nix +++ /dev/null @@ -1,36 +0,0 @@ -{ - inputs ? {}, - mkVersion ? {}, - description ? false, -}: (final: prev: let - inherit (final.lib) recurseIntoAttrs; - - mkScope = file: desc: - if description - then desc - else - recurseIntoAttrs - (final.callPackage file ({inherit mkVersion;} // inputs)); -in { - scopedPackages = { - dracula = mkScope ./dracula '' - Custom derivations that each represent an app's Dracula Theme. - ''; - - firefoxAddons = mkScope ./firefox-addons '' - Every extensions I use in my firefox module. - ''; - - hass-components = mkScope ./hass-components '' - Components I use for Home-Assistant that aren't in nixpkgs. - ''; - - lovelace-components = mkScope ./lovelace-components '' - Lovelace components I use for Home-Assistant that aren't in nixpkgs. - ''; - - mpvScripts = mkScope ./mpv-scripts '' - MPV scripts I use that aren't in nixpkgs. - ''; - }; -}) diff --git a/scopedPackages/dracula/bat/default.nix b/scopedPackages/dracula/bat/default.nix deleted file mode 100644 index d4430a8c..00000000 --- a/scopedPackages/dracula/bat/default.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ - # nix build inputs - lib, - stdenv, - mkVersion, - bat-theme-src, - ... -}: -stdenv.mkDerivation { - pname = "dracula-bat"; - version = mkVersion bat-theme-src; - - src = bat-theme-src; - - installPhase = '' - cat ./Dracula.tmTheme > $out - ''; - - meta = { - license = lib.licenses.mit; - homepage = "https://github.com/matt1432/bat"; - description = '' - Dark theme for bat based on the Dracula Sublime theme. - ''; - }; -} diff --git a/scopedPackages/dracula/default.nix b/scopedPackages/dracula/default.nix deleted file mode 100644 index 8c798f0f..00000000 --- a/scopedPackages/dracula/default.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ - lib, - pkgs, - ... -} @ inputs: -lib.makeScope pkgs.newScope (drac: { - bat = drac.callPackage ./bat { - inherit (inputs) bat-theme-src mkVersion; - }; - - git = drac.callPackage ./git { - inherit (inputs) git-theme-src mkVersion; - }; - - gtk = import ./gtk {inherit (inputs) gtk-theme-src pkgs;}; - - plymouth = drac.callPackage ./plymouth { - inherit (inputs) dracula-plymouth-src mkVersion; - }; - - sioyek = drac.callPackage ./sioyek { - inherit (inputs) sioyek-theme-src mkVersion; - }; - - wallpaper = drac.callPackage ./wallpaper {}; -}) diff --git a/scopedPackages/dracula/git/default.nix b/scopedPackages/dracula/git/default.nix deleted file mode 100644 index 26c4ba90..00000000 --- a/scopedPackages/dracula/git/default.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ - # nix build inputs - lib, - stdenv, - mkVersion, - git-theme-src, - ... -}: -stdenv.mkDerivation { - pname = "dracula-git"; - version = mkVersion git-theme-src; - - src = git-theme-src; - - installPhase = '' - chmod 777 ./config/gitconfig - - # Remove every line above 'Dracula Dark Theme' - line=$(grep -n 'Dracula Dark Theme' ./config/gitconfig | cut -d: -f1) - sed -i "1,$((line-1))d" ./config/gitconfig - - cat ./config/gitconfig > $out - ''; - - meta = { - license = lib.licenses.mit; - homepage = "https://github.com/dracula/git"; - description = '' - Dark theme for Git. - ''; - }; -} diff --git a/scopedPackages/dracula/gtk/default.nix b/scopedPackages/dracula/gtk/default.nix deleted file mode 100644 index 18b00083..00000000 --- a/scopedPackages/dracula/gtk/default.nix +++ /dev/null @@ -1,44 +0,0 @@ -{ - pkgs, - gtk-theme-src, - ... -}: -pkgs.dracula-theme.overrideAttrs (o: { - version = o.version + "+" + gtk-theme-src.shortRev; - src = gtk-theme-src; - - # Generate hyprcursor theme - buildInputs = - (o.buildInputs or []) - ++ (builtins.attrValues { - inherit - (pkgs) - hyprcursor - xcur2png - ; - }); - - preInstall = '' - ${o.preInstall or ""} - - mkdir -p $out/share/icons/Dracula-cursors - - cd ./kde/cursors - - hyprcursor-util --extract ./Dracula-cursors - - # this creates a symlink to 'theme_Extracted Theme' for some reason - hyprcursor-util --create ./extracted_Dracula-cursors - mv 'theme_Extracted Theme' ./extracted - - cat <<EOF > ./extracted/manifest.hl - name = Dracula-cursors - description = Automatically extracted with hyprcursor-util - version = 0.1 - cursors_directory = hyprcursors - EOF - - mv ./extracted/* $out/share/icons/Dracula-cursors/ - cd ../.. - ''; -}) diff --git a/scopedPackages/dracula/plymouth/default.nix b/scopedPackages/dracula/plymouth/default.nix deleted file mode 100644 index 606772c1..00000000 --- a/scopedPackages/dracula/plymouth/default.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ - # nix build inputs - lib, - stdenv, - mkVersion, - dracula-plymouth-src, - ... -}: -stdenv.mkDerivation { - pname = "dracula-plymouth"; - version = mkVersion dracula-plymouth-src; - - src = dracula-plymouth-src; - - installPhase = '' - chmod 777 ./dracula - - sed -i "s@\/usr\/@$out\/@" ./dracula/dracula.plymouth - - mkdir -p $out/share/plymouth/themes - cp -a ./dracula $out/share/plymouth/themes/ - ''; - - meta = { - license = lib.licenses.mit; - homepage = "https://github.com/matt1432/dracula-plymouth"; - description = '' - Dark theme for Plymouth. Forked by me to add a password prompt and - black background for more seemless boot sequence. - ''; - }; -} diff --git a/scopedPackages/dracula/sioyek/default.nix b/scopedPackages/dracula/sioyek/default.nix deleted file mode 100644 index 14e978e5..00000000 --- a/scopedPackages/dracula/sioyek/default.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ - # nix build inputs - lib, - stdenv, - mkVersion, - sioyek-theme-src, - ... -}: -stdenv.mkDerivation { - pname = "dracula-sioyek"; - version = mkVersion sioyek-theme-src; - - src = sioyek-theme-src; - - installPhase = '' - cat ./dracula.config > $out - ''; - - meta = { - license = lib.licenses.mit; - homepage = "https://github.com/dracula/sioyek"; - description = '' - Dark theme for Sioyek. - ''; - }; -} diff --git a/scopedPackages/dracula/wallpaper/default.nix b/scopedPackages/dracula/wallpaper/default.nix deleted file mode 100644 index 6c842709..00000000 --- a/scopedPackages/dracula/wallpaper/default.nix +++ /dev/null @@ -1,29 +0,0 @@ -{ - # nix build inputs - lib, - stdenv, - fetchurl, - ... -}: -stdenv.mkDerivation { - name = "dracula-wallpaper.png"; - - src = fetchurl { - url = "https://raw.githubusercontent.com/aynp/dracula-wallpapers/main/Art/4k/Waves%201.png"; - hash = "sha256-f9FwSOSvqTeDj4bOjYUQ6TM+/carCD9o5dhg/MnP/lk="; - }; - - phases = ["installPhase"]; - - installPhase = '' - cp -a $src $out - ''; - - meta = { - license = lib.licenses.cc-by-sa-40; - homepage = "https://github.com/aynp/dracula-wallpapers"; - description = '' - Wallpaper based on the Dracula Theme. - ''; - }; -} diff --git a/scopedPackages/firefox-addons/addons.json b/scopedPackages/firefox-addons/addons.json deleted file mode 100644 index afb3b561..00000000 --- a/scopedPackages/firefox-addons/addons.json +++ /dev/null @@ -1,54 +0,0 @@ -[ - { - "slug": "auto-refresh-page" - }, - { - "pname": "bitwarden", - "slug": "bitwarden-password-manager" - }, - { - "slug": "darkreader" - }, - { - "slug": "floccus" - }, - { - "slug": "google-container" - }, - { - "slug": "istilldontcareaboutcookies" - }, - { - "slug": "image-search-options", - "license": { - "tag": "predefined", - "shortName": "mpl11" - } - }, - { - "slug": "return-youtube-dislikes" - }, - { - "pname": "sound-volume", - "slug": "600-sound-volume" - }, - { - "slug": "sponsorblock" - }, - { - "pname": "stylus", - "slug": "styl-us" - }, - { - "slug": "tampermonkey" - }, - { - "slug": "ttv-lol-pro" - }, - { - "slug": "ublock-origin" - }, - { - "slug": "undoclosetabbutton" - } -] diff --git a/scopedPackages/firefox-addons/default.nix b/scopedPackages/firefox-addons/default.nix deleted file mode 100644 index b1d78836..00000000 --- a/scopedPackages/firefox-addons/default.nix +++ /dev/null @@ -1,42 +0,0 @@ -{ - fetchurl, - lib, - pkgs, - stdenv, - ... -} @ args: let - buildFirefoxXpiAddon = lib.makeOverridable ({ - stdenv ? args.stdenv, - fetchurl ? args.fetchurl, - pname, - version, - addonId, - url, - sha256, - meta, - ... - }: - stdenv.mkDerivation { - name = "${pname}-${version}"; - - inherit meta; - - src = fetchurl {inherit url sha256;}; - - preferLocalBuild = true; - allowSubstitutes = true; - - buildCommand = - # bash - '' - dst="$out/share/mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}" - mkdir -p "$dst" - install -v -m644 "$src" "$dst/${addonId}.xpi" - ''; - }); - - packages = import ./generated-firefox-addons.nix { - inherit buildFirefoxXpiAddon fetchurl lib stdenv; - }; -in - lib.makeScope pkgs.newScope (_: packages // {inherit buildFirefoxXpiAddon;}) diff --git a/scopedPackages/firefox-addons/generated-firefox-addons.nix b/scopedPackages/firefox-addons/generated-firefox-addons.nix deleted file mode 100644 index 92131534..00000000 --- a/scopedPackages/firefox-addons/generated-firefox-addons.nix +++ /dev/null @@ -1,355 +0,0 @@ -{ - buildFirefoxXpiAddon, - fetchurl, - lib, - stdenv, -}: { - "auto-refresh-page" = buildFirefoxXpiAddon { - pname = "auto-refresh-page"; - version = "3.2"; - addonId = "{da35dad8-f912-4c74-8f64-c4e6e6d62610}"; - url = "https://addons.mozilla.org/firefox/downloads/file/4064190/auto_refresh_page-3.2.xpi"; - sha256 = "e703d1031107bb440e3081b210e58ebf5a05a620683e42ce6255b66994475f8d"; - meta = with lib; { - homepage = "https://www.hashtap.com/@refresh"; - description = "Refresh web pages automatically. Auto-refresh and page monitor with specified time intervals."; - license = licenses.mit; - mozPermissions = [ - "tabs" - "storage" - "contextMenus" - "browsingData" - "notifications" - "webRequest" - "webRequestBlocking" - "<all_urls>" - ]; - platforms = platforms.all; - }; - }; - "bitwarden" = buildFirefoxXpiAddon { - pname = "bitwarden"; - version = "2025.3.2"; - addonId = "{446900e4-71c2-419f-a6a7-df9c091e268b}"; - url = "https://addons.mozilla.org/firefox/downloads/file/4467426/bitwarden_password_manager-2025.3.2.xpi"; - sha256 = "30f9384a46f6ef2ba6c9d273fc7c77a9afeef120dc4b3cbc5c28f171f4e8aeab"; - meta = with lib; { - homepage = "https://bitwarden.com"; - description = "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information."; - license = licenses.gpl3; - mozPermissions = [ - "<all_urls>" - "*://*/*" - "alarms" - "clipboardRead" - "clipboardWrite" - "contextMenus" - "idle" - "storage" - "tabs" - "unlimitedStorage" - "webNavigation" - "webRequest" - "webRequestBlocking" - "file:///*" - ]; - platforms = platforms.all; - }; - }; - "darkreader" = buildFirefoxXpiAddon { - pname = "darkreader"; - version = "4.9.103"; - addonId = "addon@darkreader.org"; - url = "https://addons.mozilla.org/firefox/downloads/file/4439735/darkreader-4.9.103.xpi"; - sha256 = "f565b2263a71626a0310380915b7aef90be8cc6fe16ea43ac1a0846efedc2e4c"; - meta = with lib; { - homepage = "https://darkreader.org/"; - description = "Dark mode for every website. Take care of your eyes, use dark theme for night and daily browsing."; - license = licenses.mit; - mozPermissions = [ - "alarms" - "contextMenus" - "storage" - "tabs" - "theme" - "<all_urls>" - ]; - platforms = platforms.all; - }; - }; - "floccus" = buildFirefoxXpiAddon { - pname = "floccus"; - version = "5.5.2"; - addonId = "floccus@handmadeideas.org"; - url = "https://addons.mozilla.org/firefox/downloads/file/4475378/floccus-5.5.2.xpi"; - sha256 = "204300ace8d68440cb6c3eee85f0f200a3964624deb2e16f3cc880cca1b510da"; - meta = with lib; { - homepage = "https://floccus.org"; - description = "Sync your bookmarks and tabs across browsers via Nextcloud, any WebDAV service, any Git service, via a local file, via Google Drive."; - license = licenses.mpl20; - mozPermissions = [ - "*://*/*" - "alarms" - "bookmarks" - "storage" - "unlimitedStorage" - "tabs" - "identity" - ]; - platforms = platforms.all; - }; - }; - "google-container" = buildFirefoxXpiAddon { - pname = "google-container"; - version = "1.5.4"; - addonId = "@contain-google"; - url = "https://addons.mozilla.org/firefox/downloads/file/3736912/google_container-1.5.4.xpi"; - sha256 = "47a7c0e85468332a0d949928d8b74376192cde4abaa14280002b3aca4ec814d0"; - meta = with lib; { - homepage = "https://github.com/containers-everywhere/contain-google"; - description = "THIS IS NOT AN OFFICIAL ADDON FROM MOZILLA!\nIt is a fork of the Facebook Container addon.\n\nPrevent Google from tracking you around the web. The Google Container extension helps you take control and isolate your web activity from Google."; - license = licenses.mpl20; - mozPermissions = [ - "<all_urls>" - "contextualIdentities" - "cookies" - "management" - "tabs" - "webRequestBlocking" - "webRequest" - "storage" - ]; - platforms = platforms.all; - }; - }; - "image-search-options" = buildFirefoxXpiAddon { - pname = "image-search-options"; - version = "3.0.12"; - addonId = "{4a313247-8330-4a81-948e-b79936516f78}"; - url = "https://addons.mozilla.org/firefox/downloads/file/3059971/image_search_options-3.0.12.xpi"; - sha256 = "1fbdd8597fc32b1be11302a958ea3ba2b010edcfeb432c299637b2c58c6fd068"; - meta = with lib; { - homepage = "http://saucenao.com/"; - description = "A customizable reverse image search tool that conveniently presents a variety of top image search engines."; - license = licenses.mpl11; - mozPermissions = [ - "storage" - "contextMenus" - "activeTab" - "tabs" - "<all_urls>" - ]; - platforms = platforms.all; - }; - }; - "istilldontcareaboutcookies" = buildFirefoxXpiAddon { - pname = "istilldontcareaboutcookies"; - version = "1.1.4"; - addonId = "idcac-pub@guus.ninja"; - url = "https://addons.mozilla.org/firefox/downloads/file/4216095/istilldontcareaboutcookies-1.1.4.xpi"; - sha256 = "cadeb24622d3b9a2b82bf4308242fd802546b126bb9dd14e1ea66f2aa2066795"; - meta = with lib; { - homepage = "https://github.com/OhMyGuus/I-Dont-Care-About-Cookies"; - description = "Community version of the popular extension \"I don't care about cookies\" \n\nhttps://github.com/OhMyGuus/I-Dont-Care-About-Cookies"; - license = licenses.gpl3; - mozPermissions = [ - "tabs" - "storage" - "http://*/*" - "https://*/*" - "notifications" - "webRequest" - "webRequestBlocking" - "webNavigation" - ]; - platforms = platforms.all; - }; - }; - "return-youtube-dislikes" = buildFirefoxXpiAddon { - pname = "return-youtube-dislikes"; - version = "3.0.0.18"; - addonId = "{762f9885-5a13-4abd-9c77-433dcd38b8fd}"; - url = "https://addons.mozilla.org/firefox/downloads/file/4371820/return_youtube_dislikes-3.0.0.18.xpi"; - sha256 = "2d33977ce93276537543161f8e05c3612f71556840ae1eb98239284b8f8ba19e"; - meta = with lib; { - description = "Returns ability to see dislike statistics on youtube"; - license = licenses.gpl3; - mozPermissions = [ - "activeTab" - "*://*.youtube.com/*" - "storage" - "*://returnyoutubedislikeapi.com/*" - ]; - platforms = platforms.all; - }; - }; - "sound-volume" = buildFirefoxXpiAddon { - pname = "sound-volume"; - version = "2.0.4"; - addonId = "{c4b582ec-4343-438c-bda2-2f691c16c262}"; - url = "https://addons.mozilla.org/firefox/downloads/file/4462455/600_sound_volume-2.0.4.xpi"; - sha256 = "72e3b7ea83cefc4c72f4c22cb2875b77c4e0f2c0db743445b5aa70f09d0291ac"; - meta = with lib; { - description = "Up to 600% volume boost"; - license = licenses.mpl20; - mozPermissions = [ - "<all_urls>" - "tabs" - "storage" - "webRequest" - "webRequestBlocking" - ]; - platforms = platforms.all; - }; - }; - "sponsorblock" = buildFirefoxXpiAddon { - pname = "sponsorblock"; - version = "5.11.10"; - addonId = "sponsorBlocker@ajay.app"; - url = "https://addons.mozilla.org/firefox/downloads/file/4465727/sponsorblock-5.11.10.xpi"; - sha256 = "07e8f50f01a7be1d7b35233a26f599d1471a5b601acd8dfa07dc023c86cac83d"; - meta = with lib; { - homepage = "https://sponsor.ajay.app"; - description = "Easily skip YouTube video sponsors. When you visit a YouTube video, the extension will check the database for reported sponsors and automatically skip known sponsors. You can also report sponsors in videos. Other browsers: https://sponsor.ajay.app"; - license = licenses.lgpl3; - mozPermissions = [ - "storage" - "scripting" - "https://sponsor.ajay.app/*" - "https://*.youtube.com/*" - "https://www.youtube-nocookie.com/embed/*" - ]; - platforms = platforms.all; - }; - }; - "stylus" = buildFirefoxXpiAddon { - pname = "stylus"; - version = "2.3.14"; - addonId = "{7a7a4a92-a2a0-41d1-9fd7-1e92480d612d}"; - url = "https://addons.mozilla.org/firefox/downloads/file/4451438/styl_us-2.3.14.xpi"; - sha256 = "02861b4256d7001a091ce1fbeaaf5ddcf670c3df9db55be3af2bd703a11315d8"; - meta = with lib; { - homepage = "https://add0n.com/stylus.html"; - description = "Redesign your favorite websites with Stylus, an actively developed and community driven userstyles manager. Easily install custom themes from popular online repositories, or create, edit, and manage your own personalized CSS stylesheets."; - license = licenses.gpl3; - mozPermissions = [ - "alarms" - "contextMenus" - "storage" - "tabs" - "unlimitedStorage" - "webNavigation" - "webRequest" - "webRequestBlocking" - "<all_urls>" - "https://userstyles.org/*" - ]; - platforms = platforms.all; - }; - }; - "tampermonkey" = buildFirefoxXpiAddon { - pname = "tampermonkey"; - version = "5.3.3"; - addonId = "firefox@tampermonkey.net"; - url = "https://addons.mozilla.org/firefox/downloads/file/4405733/tampermonkey-5.3.3.xpi"; - sha256 = "1eb5ddffb3b93c0258ef0458658436563772d21bf5dffa334bb8a49cca8f0fff"; - meta = with lib; { - homepage = "https://tampermonkey.net"; - description = "Tampermonkey is the world's most popular userscript manager."; - mozPermissions = [ - "alarms" - "notifications" - "tabs" - "idle" - "webNavigation" - "webRequest" - "webRequestBlocking" - "unlimitedStorage" - "storage" - "contextMenus" - "clipboardWrite" - "cookies" - "downloads" - "<all_urls>" - ]; - platforms = platforms.all; - }; - }; - "ttv-lol-pro" = buildFirefoxXpiAddon { - pname = "ttv-lol-pro"; - version = "2.4.0"; - addonId = "{76ef94a4-e3d0-4c6f-961a-d38a429a332b}"; - url = "https://addons.mozilla.org/firefox/downloads/file/4436505/ttv_lol_pro-2.4.0.xpi"; - sha256 = "78b42faab860a527c36822b34b16e5b12618aa387ea63deb822852d3065bf3f8"; - meta = with lib; { - homepage = "https://github.com/younesaassila/ttv-lol-pro"; - description = "TTV LOL PRO removes most livestream ads from Twitch."; - license = licenses.gpl3; - mozPermissions = [ - "proxy" - "storage" - "webRequest" - "webRequestBlocking" - "https://*.live-video.net/*" - "https://*.ttvnw.net/*" - "https://*.twitch.tv/*" - "https://perfprod.com/ttvlolpro/telemetry" - "https://www.twitch.tv/*" - "https://m.twitch.tv/*" - ]; - platforms = platforms.all; - }; - }; - "ublock-origin" = buildFirefoxXpiAddon { - pname = "ublock-origin"; - version = "1.63.2"; - addonId = "uBlock0@raymondhill.net"; - url = "https://addons.mozilla.org/firefox/downloads/file/4458450/ublock_origin-1.63.2.xpi"; - sha256 = "d93176cef4dc042e41ba500aa2a90e5d57b5be77449cbd522111585e3a0cd158"; - meta = with lib; { - homepage = "https://github.com/gorhill/uBlock#ublock-origin"; - description = "Finally, an efficient wide-spectrum content blocker. Easy on CPU and memory."; - license = licenses.gpl3; - mozPermissions = [ - "alarms" - "dns" - "menus" - "privacy" - "storage" - "tabs" - "unlimitedStorage" - "webNavigation" - "webRequest" - "webRequestBlocking" - "<all_urls>" - "http://*/*" - "https://*/*" - "file://*/*" - "https://easylist.to/*" - "https://*.fanboy.co.nz/*" - "https://filterlists.com/*" - "https://forums.lanik.us/*" - "https://github.com/*" - "https://*.github.io/*" - "https://github.com/uBlockOrigin/*" - "https://ublockorigin.github.io/*" - "https://*.reddit.com/r/uBlockOrigin/*" - ]; - platforms = platforms.all; - }; - }; - "undoclosetabbutton" = buildFirefoxXpiAddon { - pname = "undoclosetabbutton"; - version = "8.0.0"; - addonId = "{4853d046-c5a3-436b-bc36-220fd935ee1d}"; - url = "https://addons.mozilla.org/firefox/downloads/file/4212173/undoclosetabbutton-8.0.0.xpi"; - sha256 = "c83a058c417f98d75e62ab310e2995971bf79c99cd83cf1dcbd8a44797aa60c4"; - meta = with lib; { - homepage = "https://github.com/M-Reimer/undoclosetab"; - description = "Allows you to restore the tab you just closed with a single click—plus it can offer a list of recently closed tabs within a convenient context menu."; - license = licenses.gpl3; - mozPermissions = ["menus" "tabs" "sessions" "storage" "theme"]; - platforms = platforms.all; - }; - }; -} diff --git a/scopedPackages/hass-components/default.nix b/scopedPackages/hass-components/default.nix deleted file mode 100644 index 390a8b4f..00000000 --- a/scopedPackages/hass-components/default.nix +++ /dev/null @@ -1,31 +0,0 @@ -{ - lib, - pkgs, - self, - ... -} @ inputs: -lib.makeScope pkgs.newScope (hass: let - inherit (self.lib) mergeAttrsList; - - python3Packages = pkgs.python313Packages.override { - overrides = final: prev: (mergeAttrsList (map (fn: fn python3Packages final prev) [ - (import ./spotifyplus/overrides.nix ({inherit pkgs;} // inputs)) - (import ./tuya-local/overrides.nix {inherit pkgs;}) - ])); - }; - - buildHassComponent = file: extraArgs: - python3Packages.callPackage file (inputs // extraArgs // {}); -in { - extended-ollama-conversation = buildHassComponent ./extended-ollama-conversation {}; - - material-symbols = buildHassComponent ./material-symbols {}; - - netdaemon = buildHassComponent ./netdaemon {}; - - spotifyplus = buildHassComponent ./spotifyplus {}; - - tuya-local = buildHassComponent ./tuya-local {}; - - yamaha-soundbar = buildHassComponent ./yamaha-soundbar {}; -}) diff --git a/scopedPackages/hass-components/extended-ollama-conversation/default.nix b/scopedPackages/hass-components/extended-ollama-conversation/default.nix deleted file mode 100644 index d6392b7d..00000000 --- a/scopedPackages/hass-components/extended-ollama-conversation/default.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ - # nix build inputs - buildHomeAssistantComponent, - extended-ollama-conversation-src, - # deps - ollama, - openai, - ... -}: let - inherit (builtins) fromJSON readFile; - manifest = fromJSON (readFile "${extended-ollama-conversation-src}/custom_components/extended_ollama_conversation/manifest.json"); -in - buildHomeAssistantComponent { - owner = "TheNimaj"; - - inherit (manifest) domain version; - src = extended-ollama-conversation-src; - - dependencies = [ - ollama - openai - ]; - - ignoreVersionRequirement = ["ollama"]; - - meta = { - homepage = "https://github.com/TheNimaj/extended_ollama_conversation"; - description = '' - Home Assistant custom component of conversation agent. It uses Ollama to control your devices. - ''; - }; - } diff --git a/scopedPackages/hass-components/material-symbols/default.nix b/scopedPackages/hass-components/material-symbols/default.nix deleted file mode 100644 index a68ff450..00000000 --- a/scopedPackages/hass-components/material-symbols/default.nix +++ /dev/null @@ -1,25 +0,0 @@ -{ - # nix build inputs - lib, - buildHomeAssistantComponent, - material-symbols-src, - ... -}: let - inherit (builtins) fromJSON readFile; - manifest = fromJSON (readFile "${material-symbols-src}/custom_components/material_symbols/manifest.json"); -in - buildHomeAssistantComponent { - owner = "beecho01"; - - inherit (manifest) domain version; - src = material-symbols-src; - - meta = { - license = lib.licenses.cc-by-nc-sa-40; - homepage = "https://github.com/beecho01/material-symbols"; - description = '' - Material Symbols for Home Assistant is a collection of 13,803 Google Material Symbols - for use within Home Assistant. It uses the icon-set produced and maintained by iconify. - ''; - }; - } diff --git a/scopedPackages/hass-components/netdaemon/default.nix b/scopedPackages/hass-components/netdaemon/default.nix deleted file mode 100644 index 109cae74..00000000 --- a/scopedPackages/hass-components/netdaemon/default.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ - # nix build inputs - lib, - buildHomeAssistantComponent, - netdaemon-src, - # deps - awesomeversion, - ... -}: let - inherit (builtins) fromJSON readFile; - manifest = fromJSON (readFile "${netdaemon-src}/custom_components/netdaemon/manifest.json"); -in - buildHomeAssistantComponent { - owner = "net-daemon"; - - inherit (manifest) domain version; - src = netdaemon-src; - - dependencies = [ - awesomeversion - ]; - - meta = { - license = lib.licenses.mit; - homepage = "https://github.com/net-daemon/netdaemon"; - description = '' - An application daemon for Home Assistant written in .NET. - ''; - }; - } diff --git a/scopedPackages/hass-components/spotifyplus/default.nix b/scopedPackages/hass-components/spotifyplus/default.nix deleted file mode 100644 index cde6e845..00000000 --- a/scopedPackages/hass-components/spotifyplus/default.nix +++ /dev/null @@ -1,51 +0,0 @@ -{ - # nix build inputs - lib, - buildHomeAssistantComponent, - spotifyplus-src, - # deps - oauthlib, - platformdirs, - requests, - requests_oauthlib, - soco, - urllib3, - zeroconf, - smartinspect, # overridden in python3Packages - spotifywebapi, # overridden in python3Packages - ... -}: let - inherit (builtins) fromJSON readFile; - manifest = fromJSON (readFile "${spotifyplus-src}/custom_components/spotifyplus/manifest.json"); -in - buildHomeAssistantComponent { - owner = "thlucas1"; - - inherit (manifest) domain version; - src = spotifyplus-src; - - dependencies = [ - oauthlib - platformdirs - requests - requests_oauthlib - soco - urllib3 - zeroconf - smartinspect - spotifywebapi - ]; - - # Upstream sometimes forgets to bump version number. - # Since we're guaranteed to have lastest git, this is safe - ignoreVersionRequirement = ["spotifywebapipython"]; - - meta = { - license = lib.licenses.mit; - homepage = "https://github.com/thlucas1/homeassistantcomponent_spotifyplus"; - description = '' - Home Assistant integration for Spotify Player control, services, - and soundtouchplus integration support. - ''; - }; - } diff --git a/scopedPackages/hass-components/spotifyplus/overrides.nix b/scopedPackages/hass-components/spotifyplus/overrides.nix deleted file mode 100644 index 65242857..00000000 --- a/scopedPackages/hass-components/spotifyplus/overrides.nix +++ /dev/null @@ -1,16 +0,0 @@ -{ - smartinspect-src, - spotifywebapi-src, - pkgs, - ... -}: python3Packages: final: prev: rec { - smartinspect = python3Packages.callPackage ./smartinspect.nix { - inherit smartinspect-src; - }; - spotifywebapi = python3Packages.callPackage ./spotifywebapi.nix { - inherit smartinspect spotifywebapi-src; - }; - urllib3 = pkgs.selfPackages.urllib3.override { - inherit python3Packages; - }; -} diff --git a/scopedPackages/hass-components/spotifyplus/smartinspect.nix b/scopedPackages/hass-components/spotifyplus/smartinspect.nix deleted file mode 100644 index c7a1bf05..00000000 --- a/scopedPackages/hass-components/spotifyplus/smartinspect.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ - # nix build inputs - lib, - buildPythonPackage, - smartinspect-src, - # deps - pycryptodome, - watchdog, - ... -}: let - inherit (builtins) elemAt head readFile split; - tag = head (split "\"" (elemAt (split "VERSION:str = \"" (readFile "${smartinspect-src}/smartinspectpython/siconst.py")) 2)); -in - buildPythonPackage { - pname = "smartinspectPython"; - version = "${tag}+${smartinspect-src.shortRev}"; - - src = smartinspect-src; - - dependencies = [ - pycryptodome - watchdog - ]; - - pythonImportsCheck = [ - "smartinspectpython" - ]; - - meta = { - license = lib.licenses.bsd2; - homepage = "https://github.com/thlucas1/SmartInspectPython"; - description = '' - Provides Python code execution tracing and diagnostics support via the - SmartInspect Console Viewer. - ''; - }; - } diff --git a/scopedPackages/hass-components/spotifyplus/spotifywebapi.nix b/scopedPackages/hass-components/spotifyplus/spotifywebapi.nix deleted file mode 100644 index f08f0c02..00000000 --- a/scopedPackages/hass-components/spotifyplus/spotifywebapi.nix +++ /dev/null @@ -1,59 +0,0 @@ -{ - # nix build inputs - lib, - buildPythonPackage, - spotifywebapi-src, - # deps - lxml, - oauthlib, - pillow, - platformdirs, - pychromecast, - pyotp, - requests, - requests_oauthlib, - setuptools, - soco, - urllib3, - zeroconf, - smartinspect, # overridden in python3Packages - ... -}: let - inherit (builtins) elemAt head readFile split; - tag = head (split "\"" (elemAt (split "VERSION:str = \"" (readFile "${spotifywebapi-src}/spotifywebapipython/const.py")) 2)); -in - buildPythonPackage { - pname = "spotifywebapiPython"; - version = "${tag}+${spotifywebapi-src.shortRev}"; - pyproject = true; - - src = spotifywebapi-src; - - dependencies = [ - lxml - oauthlib - pillow - platformdirs - pychromecast - pyotp - requests - requests_oauthlib - setuptools - soco - urllib3 - zeroconf - smartinspect - ]; - - pythonImportsCheck = [ - "spotifywebapipython" - ]; - - meta = { - license = lib.licenses.mit; - homepage = "https://github.com/thlucas1/SpotifyWebApiPython"; - description = '' - A Spotify Web Api Client for Python. - ''; - }; - } diff --git a/scopedPackages/hass-components/tuya-local/default.nix b/scopedPackages/hass-components/tuya-local/default.nix deleted file mode 100644 index 4ecff85e..00000000 --- a/scopedPackages/hass-components/tuya-local/default.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ - # nix build inputs - lib, - buildHomeAssistantComponent, - tuya-local-src, - # deps - tinytuya, - tuya-device-sharing-sdk, - ... -}: let - inherit (builtins) fromJSON readFile; - manifest = fromJSON (readFile "${tuya-local-src}/custom_components/tuya_local/manifest.json"); -in - buildHomeAssistantComponent { - owner = "make-all"; - - inherit (manifest) domain version; - src = tuya-local-src; - - dependencies = [ - tinytuya - tuya-device-sharing-sdk - ]; - - meta = { - license = lib.licenses.mit; - homepage = "https://github.com/make-all/tuya-local"; - description = '' - Local support for Tuya devices in Home Assistant. - ''; - }; - } diff --git a/scopedPackages/hass-components/tuya-local/overrides.nix b/scopedPackages/hass-components/tuya-local/overrides.nix deleted file mode 100644 index 2f0a2de8..00000000 --- a/scopedPackages/hass-components/tuya-local/overrides.nix +++ /dev/null @@ -1,14 +0,0 @@ -{...}: python3Packages: final: prev: { - /* - Keep this here to make it easier to always have the right version - tinytuya = prev.tinytuya.overridePythonAttrs (o: rec { - version = "1.16.1"; - src = pkgs.fetchFromGitHub { - owner = "jasonacox"; - repo = "tinytuya"; - rev = "v${version}"; - hash = "sha256-+ReTNPKMYUXNA5tu7kZM8/7Bh4XjHSjZTiW8ROHkk5M="; - }; - }); - */ -} diff --git a/scopedPackages/hass-components/yamaha-soundbar/default.nix b/scopedPackages/hass-components/yamaha-soundbar/default.nix deleted file mode 100644 index f95616d7..00000000 --- a/scopedPackages/hass-components/yamaha-soundbar/default.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ - # nix build inputs - buildHomeAssistantComponent, - yamaha-soundbar-src, - # deps - async-upnp-client, - chardet, - validators, - ... -}: let - inherit (builtins) fromJSON readFile; - manifest = fromJSON (readFile "${yamaha-soundbar-src}/custom_components/yamaha_soundbar/manifest.json"); -in - buildHomeAssistantComponent { - owner = "osk2"; - - inherit (manifest) domain version; - src = yamaha-soundbar-src; - - dependencies = [ - async-upnp-client - chardet - validators - ]; - - meta = { - homepage = "https://github.com/osk2/yamaha-soundbar"; - description = '' - Yamaha soundbar integration for Home Assistant. - ''; - }; - } diff --git a/scopedPackages/lovelace-components/big-slider-card/default.nix b/scopedPackages/lovelace-components/big-slider-card/default.nix deleted file mode 100644 index 631d49b8..00000000 --- a/scopedPackages/lovelace-components/big-slider-card/default.nix +++ /dev/null @@ -1,33 +0,0 @@ -{ - # nix build inputs - lib, - stdenv, - fetchurl, - ... -}: let - pname = "big-slider-card"; - version = "1.1.5"; -in - stdenv.mkDerivation { - inherit pname version; - - src = fetchurl { - url = "https://github.com/nicufarmache/lovelace-big-slider-card/releases/download/${version}/${pname}.js"; - hash = "sha256-uNlgsiubLXG1VzhNCSeKo/5TmQF1fzFHjTYfutEXn1M="; - }; - - phases = ["installPhase"]; - - installPhase = '' - mkdir $out - cp $src $out/${pname}.js - ''; - - meta = { - license = lib.licenses.mit; - homepage = "https://github.com/nicufarmache/lovelace-big-slider-card"; - description = '' - A card with a big slider for light entities in Home Assistant. - ''; - }; - } diff --git a/scopedPackages/lovelace-components/custom-sidebar/default.nix b/scopedPackages/lovelace-components/custom-sidebar/default.nix deleted file mode 100644 index 1eb783fb..00000000 --- a/scopedPackages/lovelace-components/custom-sidebar/default.nix +++ /dev/null @@ -1,50 +0,0 @@ -{ - # nix build inputs - lib, - stdenv, - custom-sidebar-src, - # deps - nodejs, - pnpm, - ... -}: let - inherit (builtins) fromJSON readFile; - - package = fromJSON (readFile "${custom-sidebar-src}/package.json"); -in - stdenv.mkDerivation (finalAttrs: { - pname = "custom-sidebar"; - version = "${package.version}+${custom-sidebar-src.shortRev}"; - - src = custom-sidebar-src; - - nativeBuildInputs = [ - nodejs - pnpm.configHook - ]; - - buildPhase = '' - npm run build - ''; - - installPhase = '' - mkdir $out - cp ./dist/* $out - ''; - - pnpmDeps = pnpm.fetchDeps { - inherit (finalAttrs) pname version src; - hash = "sha256-qyzizhPQfhK7rpCWO4d5iyhIZZ5vl3RphvsHO2Wm2IU="; - }; - - passthru.updateScript = ./update.sh; - - meta = { - license = lib.licenses.asl20; - homepage = "https://github.com/elchininet/custom-sidebar"; - description = '' - Custom HACS plugin that allows you to personalise the - Home Assistant's sidebar per user or device basis. - ''; - }; - }) diff --git a/scopedPackages/lovelace-components/custom-sidebar/update.sh b/scopedPackages/lovelace-components/custom-sidebar/update.sh deleted file mode 100755 index b20acd59..00000000 --- a/scopedPackages/lovelace-components/custom-sidebar/update.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -file="$FLAKE/scopedPackages/lovelace-components/custom-sidebar/default.nix" -old_hash="$(sed -n 's/.*hash = "\(.*\)";/\1/p' "$file")" - -sed -i "s/hash = .*/hash = \"\";/" "$file" -npm_hash="$(nix build "$FLAKE#scopedPackages.x86_64-linux.lovelace-components.custom-sidebar" |& sed -n 's/.*got: *//p')" - -if [[ "$npm_hash" != "$old_hash" ]]; then - sed -i "s#hash = .*#hash = \"$npm_hash\";#" "$file" -else - sed -i "s#hash = .*#hash = \"$old_hash\";#" "$file" -fi diff --git a/scopedPackages/lovelace-components/default.nix b/scopedPackages/lovelace-components/default.nix deleted file mode 100644 index c32ccadc..00000000 --- a/scopedPackages/lovelace-components/default.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ - lib, - pkgs, - ... -} @ inputs: -lib.makeScope pkgs.newScope (lovelace: let - callPackage = file: lovelace.callPackage file ({} // inputs); -in { - big-slider-card = callPackage ./big-slider-card; - custom-sidebar = callPackage ./custom-sidebar; - material-rounded-theme = callPackage ./material-rounded-theme; - material-you-utilities = callPackage ./material-you-utilities; -}) diff --git a/scopedPackages/lovelace-components/material-rounded-theme/default.nix b/scopedPackages/lovelace-components/material-rounded-theme/default.nix deleted file mode 100644 index cc4be4d3..00000000 --- a/scopedPackages/lovelace-components/material-rounded-theme/default.nix +++ /dev/null @@ -1,33 +0,0 @@ -{ - # nix build inputs - lib, - stdenv, - fetchFromGitHub, - ... -}: let - pname = "material-rounded-theme"; - version = "4.0.2"; -in - stdenv.mkDerivation { - inherit pname version; - - src = fetchFromGitHub { - owner = "Nerwyn"; - repo = pname; - rev = version; - hash = "sha256-ZsajvWYUbrOUVTmzSIyNiEUsCgURuYdah5Ra5NSmep8="; - }; - - installPhase = '' - mkdir -p $out/share - cp ./src/material_you.yaml $out/share - ''; - - meta = { - license = lib.licenses.asl20; - homepage = "https://github.com/Nerwyn/material-rounded-theme"; - description = '' - Material Design 3 Colors and Components in Home Assistant. - ''; - }; - } diff --git a/scopedPackages/lovelace-components/material-you-utilities/default.nix b/scopedPackages/lovelace-components/material-you-utilities/default.nix deleted file mode 100644 index b665e3ee..00000000 --- a/scopedPackages/lovelace-components/material-you-utilities/default.nix +++ /dev/null @@ -1,39 +0,0 @@ -{ - lib, - buildNpmPackage, - fetchFromGitHub, - ... -}: let - pname = "material-you-utilities"; - version = "1.0.4"; -in - buildNpmPackage { - inherit pname version; - - src = fetchFromGitHub { - owner = "Nerwyn"; - repo = "ha-${pname}"; - rev = version; - hash = "sha256-iyGy6dpHZMtU2ap+smZUlLYnFKs6s8SaGAC9Y3jdoiA="; - }; - - postPatch = '' - substituteInPlace ./webpack.config.js --replace-fail \ - "git branch --show-current" "echo main" - ''; - - installPhase = '' - mkdir $out - cp ./dist/material-you-utilities.min.js $out/material-you-utilities.js - ''; - - npmDepsHash = "sha256-5cc610/BhX19k2iREYVoE3c43yDmRJsE0Nvrq/gAVjY="; - - meta = { - license = lib.licenses.asl20; - homepage = "https://github.com/Nerwyn/ha-material-you-utilities"; - description = '' - Material You color theme generation and Home Assistant component modification. - ''; - }; - } diff --git a/scopedPackages/mpv-scripts/default.nix b/scopedPackages/mpv-scripts/default.nix deleted file mode 100644 index 1fe86f5c..00000000 --- a/scopedPackages/mpv-scripts/default.nix +++ /dev/null @@ -1,16 +0,0 @@ -{pkgs, ...} @ inputs: -pkgs.lib.makeScope pkgs.newScope (mpv: let - buildLua = - mpv.callPackage - "${pkgs.path}/pkgs/applications/video/mpv/scripts/buildLua.nix" {}; - - buildLuaScript = file: - mpv.callPackage file (inputs // {inherit buildLua;}); -in { - modernz = buildLuaScript ./modernz; - pointer-event = buildLuaScript ./pointer-event; - touch-gestures = buildLuaScript ./touch-gestures; - kdialog-open-files = buildLuaScript ./kdialog-open-files; - persist-properties = buildLuaScript ./persist-properties; - undo-redo = buildLuaScript ./undo-redo; -}) diff --git a/scopedPackages/mpv-scripts/kdialog-open-files/default.nix b/scopedPackages/mpv-scripts/kdialog-open-files/default.nix deleted file mode 100644 index ebc51853..00000000 --- a/scopedPackages/mpv-scripts/kdialog-open-files/default.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ - # nix build inputs - lib, - buildLua, - fetchurl, - ... -}: -buildLua rec { - pname = "zenity-open-files"; - version = "0.0.0"; - - unpackPhase = ":"; - src = fetchurl { - url = "https://gist.githubusercontent.com/ntasos/d1d846abd7d25e4e83a78d22ee067a22/raw/b23b20e830bba024836f8b09412000658edee95c/kdialog-open-files.lua"; - hash = "sha256-qJ/Myx0mdaRsWWd+4Mk1/SUSSI/uqQdg/vLZo2pkEwA="; - }; - scriptPath = "${src}"; - - meta = { - license = lib.licenses.unlicense; - homepage = "https://gist.github.com/ntasos/d1d846abd7d25e4e83a78d22ee067a22"; - description = '' - Use KDE KDialog to add files to playlist, subtitles to playing video or open URLs. - Based on 'mpv-open-file-dialog' <https://github.com/rossy/mpv-open-file-dialog>. - ''; - }; -} diff --git a/scopedPackages/mpv-scripts/modernz/default.nix b/scopedPackages/mpv-scripts/modernz/default.nix deleted file mode 100644 index 0184d45b..00000000 --- a/scopedPackages/mpv-scripts/modernz/default.nix +++ /dev/null @@ -1,39 +0,0 @@ -{ - # nix build inputs - lib, - buildLua, - mkVersion, - makeFontsConf, - modernz-src, - ... -}: -buildLua (finalAttrs: { - pname = "modernz"; - version = mkVersion modernz-src; - - src = modernz-src; - - # Make font available to script - postInstall = '' - mkdir -p $out/share/fonts - cp -r ./fluent-system-icons.ttf $out/share/fonts - ''; - - passthru.extraWrapperArgs = [ - "--set" - "FONTCONFIG_FILE" - (toString (makeFontsConf { - fontDirectories = ["${finalAttrs.finalPackage}/share/fonts"]; - })) - ]; - - meta = { - license = lib.licenses.lgpl21; - homepage = "https://github.com/Samillion/ModernZ"; - description = '' - A sleek and modern OSC for mpv designed to enhance functionality - by adding more features, all while preserving the core standards - of mpv's OSC. - ''; - }; -}) diff --git a/scopedPackages/mpv-scripts/persist-properties/default.nix b/scopedPackages/mpv-scripts/persist-properties/default.nix deleted file mode 100644 index 0ac2a161..00000000 --- a/scopedPackages/mpv-scripts/persist-properties/default.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ - # nix build inputs - lib, - buildLua, - mkVersion, - mpv-persist-properties-src, - ... -}: -buildLua { - pname = "persist-properties"; - version = mkVersion mpv-persist-properties-src; - - src = mpv-persist-properties-src; - - meta = { - license = lib.licenses.mit; - homepage = "https://github.com/d87/mpv-persist-properties"; - description = '' - Keeps selected property values (like volume) between player sessions. - ''; - }; -} diff --git a/scopedPackages/mpv-scripts/pointer-event/default.nix b/scopedPackages/mpv-scripts/pointer-event/default.nix deleted file mode 100644 index add8a174..00000000 --- a/scopedPackages/mpv-scripts/pointer-event/default.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ - # nix build inputs - lib, - buildLua, - mkVersion, - mpv-pointer-event-src, - ... -}: -buildLua { - pname = "pointer-event"; - version = mkVersion mpv-pointer-event-src; - - src = mpv-pointer-event-src; - - meta = { - license = lib.licenses.gpl2; - homepage = "https://github.com/christoph-heinrich/mpv-pointer-event"; - description = '' - Mouse/Touch input event detection for mpv. - ''; - }; -} diff --git a/scopedPackages/mpv-scripts/touch-gestures/default.nix b/scopedPackages/mpv-scripts/touch-gestures/default.nix deleted file mode 100644 index eddf70e8..00000000 --- a/scopedPackages/mpv-scripts/touch-gestures/default.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ - # nix build inputs - lib, - buildLua, - mkVersion, - mpv-touch-gestures-src, - ... -}: -buildLua { - pname = "touch-gestures"; - version = mkVersion mpv-touch-gestures-src; - - src = mpv-touch-gestures-src; - - meta = { - license = lib.licenses.gpl2; - homepage = "https://github.com/christoph-heinrich/mpv-touch-gestures"; - description = '' - Touch gestures for mpv. - ''; - }; -} diff --git a/scopedPackages/mpv-scripts/undo-redo/default.nix b/scopedPackages/mpv-scripts/undo-redo/default.nix deleted file mode 100644 index c57020d5..00000000 --- a/scopedPackages/mpv-scripts/undo-redo/default.nix +++ /dev/null @@ -1,24 +0,0 @@ -{ - # nix build inputs - lib, - buildLua, - mkVersion, - eisa-scripts-src, - ... -}: -buildLua rec { - pname = "undo-redo"; - version = mkVersion eisa-scripts-src; - - src = eisa-scripts-src; - scriptPath = "${src}/scripts/UndoRedo.lua"; - - meta = { - license = lib.licenses.bsd2; - homepage = "https://github.com/Eisa01/mpv-scripts?tab=readme-ov-file#undoredo"; - description = '' - Accidentally seeked? No worries, simply undo.. - Undo is not enough to fix your accidental seek? Well now you can redo as well.. - ''; - }; -}