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..58de4ce5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,9 @@ -# 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 +*node_modules/ +*types +*build/ +result* +*config.js +*icons +*.direnv/ diff --git a/README.md b/README.md index 51065103..e264e820 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # My NixOS configs -## AGS +## Ags You might find it weird that most of my config is written in TypeScript. That's because all my desktops run @@ -16,21 +16,11 @@ in TypeScript because it's the scripting language I am most comfortable with. ### General -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`) +This repo is the complete configuration of machines I own, +running NixOS or Nix. I tend to mix Home-Manager and NixOS +a lot to make my custom modules by using my global vars system +explained +[here](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/devices) ### Flake Location @@ -48,40 +38,58 @@ echo "$FLAKE" # /home/matt/.nix sudo ln -sf /home/matt/.nix /etc/nixos ``` -### Subdirectories +### Flake Outputs -| 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) | +| Output | Description | +| ---------------------------------- | ----------- | +| `nixosConfigurations` | [devices](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/devices)' + ISO's configurations | +| `nixOnDroidConfigurations.default` | [Nix-On-Droid](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/devices/android)'s configuration | +| `formatter` | I have yet to know if this has any uses but I format with [alejandra](https://github.com/kamadorueda/alejandra) | +| `devShells.default` | A dev shell to build an ISO from the live-image nixosConfiguration | + +### Flake Inputs + +I 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 + +I also have a long list of inputs with `flake = false;` because +it makes it easier to update non-flake custom packages or overlays +to have the latest git. I make sure to end the names of these inputs +with `src` to make it clear what they are. ### 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`: +I only use secrets stored in `JSON` and generate `.sops.yaml` +from `.sops.nix`: ```nix let wim = "somekey"; - binto = "somekey2"; + oksys = "somekey2"; in { creation_rules = [ { path_regex = "secrets/[^/]+\\.(yaml|json|env|ini)$"; key_groups = [ { - age = [wim binto]; + age = [wim oksys]; } ]; } @@ -97,4 +105,6 @@ and this shell command: 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 +TLDR: I +**[hate](https://ruudvanasseldonk.com/2023/01/11/the-yaml-document-from-hell)** +YAML 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 ddb6a023..00000000 --- a/apps/config/package-lock.json +++ /dev/null @@ -1,2591 +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.26.0", - "@stylistic/eslint-plugin": "4.2.0", - "eslint": "9.26.0", - "eslint-plugin-jsdoc": "50.6.17", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3", - "typescript-eslint": "8.32.1" - } - }, - "node_modules/@es-joy/jsdoccomment": { - "version": "0.50.1", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.50.1.tgz", - "integrity": "sha512-fas3qe1hw38JJgU/0m5sDpcrbZGysBeZcMwW5Ws9brYxY64MJyWLXRZCj18keTycT1LFTrFXdSNMS+GRVaU6Hw==", - "license": "MIT", - "dependencies": { - "@types/eslint": "^9.6.1", - "@types/estree": "^1.0.6", - "@typescript-eslint/types": "^8.11.0", - "comment-parser": "1.4.1", - "esquery": "^1.6.0", - "jsdoc-type-pratt-parser": "~4.1.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", - "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.26.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.26.0.tgz", - "integrity": "sha512-I9XlJawFdSMvWjDt6wksMCrgns5ggLNfFwFvnShsleWruvXM514Qxk8V246efTw+eo9JABvVz+u3q2RiAowKxQ==", - "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/@modelcontextprotocol/sdk": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.11.0.tgz", - "integrity": "sha512-k/1pb70eD638anoi0e8wUGAlbMJXyvdV4p62Ko+EZ7eBe1xMx8Uhak1R5DgfoofsK5IBBnRwsYGTaLZl+6/+RQ==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "cors": "^2.8.5", - "cross-spawn": "^7.0.3", - "eventsource": "^3.0.2", - "express": "^5.0.1", - "express-rate-limit": "^7.5.0", - "pkce-challenge": "^5.0.0", - "raw-body": "^3.0.0", - "zod": "^3.23.8", - "zod-to-json-schema": "^3.24.1" - }, - "engines": { - "node": ">=18" - } - }, - "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/@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/eslint": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", - "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "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.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.32.1.tgz", - "integrity": "sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg==", - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.32.1", - "@typescript-eslint/type-utils": "8.32.1", - "@typescript-eslint/utils": "8.32.1", - "@typescript-eslint/visitor-keys": "8.32.1", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" - }, - "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/eslint-plugin/node_modules/ignore": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.4.tgz", - "integrity": "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "8.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.32.1.tgz", - "integrity": "sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "8.32.1", - "@typescript-eslint/types": "8.32.1", - "@typescript-eslint/typescript-estree": "8.32.1", - "@typescript-eslint/visitor-keys": "8.32.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.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.32.1.tgz", - "integrity": "sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.32.1", - "@typescript-eslint/visitor-keys": "8.32.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.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.32.1.tgz", - "integrity": "sha512-mv9YpQGA8iIsl5KyUPi+FGLm7+bA4fgXaeRcFKRDRwDMu4iwrSHeDPipwueNXhdIIZltwCJv+NkxftECbIZWfA==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "8.32.1", - "@typescript-eslint/utils": "8.32.1", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" - }, - "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.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.32.1.tgz", - "integrity": "sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==", - "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.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.32.1.tgz", - "integrity": "sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.32.1", - "@typescript-eslint/visitor-keys": "8.32.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.1.0" - }, - "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.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.32.1.tgz", - "integrity": "sha512-DsSFNIgLSrc89gpq1LJB7Hm1YpuhK086DRDJSNrewcGvYloWW1vZLHBTIvarKZDcAORIy/uWNx8Gad+4oMpkSA==", - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.32.1", - "@typescript-eslint/types": "8.32.1", - "@typescript-eslint/typescript-estree": "8.32.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.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.32.1.tgz", - "integrity": "sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.32.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/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", - "license": "MIT", - "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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/body-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", - "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", - "license": "MIT", - "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.0", - "http-errors": "^2.0.0", - "iconv-lite": "^0.6.3", - "on-finished": "^2.4.1", - "qs": "^6.14.0", - "raw-body": "^3.0.0", - "type-is": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "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/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/content-disposition": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", - "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "license": "MIT", - "engines": { - "node": ">=6.6.0" - } - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "license": "MIT", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "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.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.26.0.tgz", - "integrity": "sha512-Hx0MOjPh6uK9oq9nVsATZKE/Wlbai7KFjfCuw9UHaguDW3x+HF0O5nIi3ud39TWgrTjTO5nHxmL3R1eANinWHQ==", - "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.26.0", - "@eslint/plugin-kit": "^0.2.8", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@modelcontextprotocol/sdk": "^1.8.0", - "@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", - "zod": "^3.24.2" - }, - "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.17", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.6.17.tgz", - "integrity": "sha512-hq+VQylhd12l8qjexyriDsejZhqiP33WgMTy2AmaGZ9+MrMWVqPECsM87GPxgHfQn0zw+YTuhqjUfk1f+q67aQ==", - "license": "BSD-3-Clause", - "dependencies": { - "@es-joy/jsdoccomment": "~0.50.1", - "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-exports": "^0.2.4", - "semver": "^7.6.3", - "spdx-expression-parse": "^4.0.0" - }, - "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/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventsource": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.6.tgz", - "integrity": "sha512-l19WpE2m9hSuyP06+FbuUUf1G+R0SFLrtQfbRb9PRr+oimOfxQhgGCbVaXg5IvZyyTThJsxh6L/srkMiCeBPDA==", - "license": "MIT", - "dependencies": { - "eventsource-parser": "^3.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/eventsource-parser": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.1.tgz", - "integrity": "sha512-VARTJ9CYeuQYb0pZEPbzi740OWFgpHe7AYJ2WFZVnUDUQp5Dk2yJUgF36YsZ81cOyxT0QxmXD2EQpapAouzWVA==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/express": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", - "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", - "license": "MIT", - "dependencies": { - "accepts": "^2.0.0", - "body-parser": "^2.2.0", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "finalhandler": "^2.1.0", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "merge-descriptors": "^2.0.0", - "mime-types": "^3.0.0", - "on-finished": "^2.4.1", - "once": "^1.4.0", - "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", - "range-parser": "^1.2.1", - "router": "^2.2.0", - "send": "^1.1.0", - "serve-static": "^2.2.0", - "statuses": "^2.0.1", - "type-is": "^2.0.1", - "vary": "^1.1.2" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express-rate-limit": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", - "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/express-rate-limit" - }, - "peerDependencies": { - "express": "^4.11 || 5 || ^5.0.0-beta.1" - } - }, - "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/finalhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", - "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 0.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/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/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/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/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/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "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/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "license": "MIT" - }, - "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/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/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "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-exports": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/parse-imports-exports/-/parse-imports-exports-0.2.4.tgz", - "integrity": "sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==", - "license": "MIT", - "dependencies": { - "parse-statements": "1.0.11" - } - }, - "node_modules/parse-statements": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/parse-statements/-/parse-statements-1.0.11.tgz", - "integrity": "sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==", - "license": "MIT" - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/path-to-regexp": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", - "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", - "license": "MIT", - "engines": { - "node": ">=16" - } - }, - "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/pkce-challenge": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz", - "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==", - "license": "MIT", - "engines": { - "node": ">=16.20.0" - } - }, - "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-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", - "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.6.3", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "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/router": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "depd": "^2.0.0", - "is-promise": "^4.0.0", - "parseurl": "^1.3.3", - "path-to-regexp": "^8.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "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/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "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/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/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/send": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", - "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.5", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "mime-types": "^3.0.1", - "ms": "^2.1.3", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", - "license": "MIT", - "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "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/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "engines": { - "node": ">= 0.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/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/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "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/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/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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.32.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.32.1.tgz", - "integrity": "sha512-D7el+eaDHAmXvrZBy1zpzSNIRqnCOrkwTgZxTu3MUqRWk8k0q9m9Ho4+vPf7iHtgUfrK/o8IZaEApsxPlHTFCg==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/eslint-plugin": "8.32.1", - "@typescript-eslint/parser": "8.32.1", - "@typescript-eslint/utils": "8.32.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/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "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" - } - }, - "node_modules/zod": { - "version": "3.24.3", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.3.tgz", - "integrity": "sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-to-json-schema": { - "version": "3.24.5", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", - "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==", - "license": "ISC", - "peerDependencies": { - "zod": "^3.24.1" - } - } - } -} diff --git a/apps/config/package.json b/apps/config/package.json deleted file mode 100644 index 942eba20..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.26.0", - "@stylistic/eslint-plugin": "4.2.0", - "eslint": "9.26.0", - "eslint-plugin-jsdoc": "50.6.17", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3", - "typescript-eslint": "8.32.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 bffba22a..00000000 --- a/apps/extract-subs/default.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ - buildApp, - ffmpeg-full, - ... -}: -buildApp { - src = ./.; - npmDepsHash = "sha256-WZmO6vccAk0LjoyuWI/utrd9ccQFkTi+pDUSqo9xy3o="; - - 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 21637169..00000000 --- a/apps/extract-subs/package-lock.json +++ /dev/null @@ -1,2429 +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.15.18", - "esbuild": "0.25.4", - "eslint": "9.26.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.26.0", - "@stylistic/eslint-plugin": "4.2.0", - "eslint": "9.26.0", - "eslint-plugin-jsdoc": "50.6.14", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3", - "typescript-eslint": "8.32.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", - "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", - "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", - "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", - "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", - "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", - "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", - "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", - "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", - "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", - "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", - "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", - "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", - "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", - "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", - "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", - "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", - "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", - "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", - "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", - "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", - "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", - "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", - "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", - "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", - "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", - "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.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.2.tgz", - "integrity": "sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==", - "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.26.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.26.0.tgz", - "integrity": "sha512-I9XlJawFdSMvWjDt6wksMCrgns5ggLNfFwFvnShsleWruvXM514Qxk8V246efTw+eo9JABvVz+u3q2RiAowKxQ==", - "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.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@modelcontextprotocol/sdk": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.11.3.tgz", - "integrity": "sha512-rmOWVRUbUJD7iSvJugjUbFZshTAuJ48MXoZ80Osx1GM0K/H1w7rSEvmw8m6vdWxNASgtaHIhAgre4H/E9GJiYQ==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "cors": "^2.8.5", - "cross-spawn": "^7.0.5", - "eventsource": "^3.0.2", - "express": "^5.0.1", - "express-rate-limit": "^7.5.0", - "pkce-challenge": "^5.0.0", - "raw-body": "^3.0.0", - "zod": "^3.23.8", - "zod-to-json-schema": "^3.24.1" - }, - "engines": { - "node": ">=18" - } - }, - "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.15.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.18.tgz", - "integrity": "sha512-v1DKRfUdyW+jJhZNEI1PYy29S2YRxMV5AOO/x/SjKmW0acCIOqmbj6Haf9eHAhsPmrhlHSxEhv/1WszcLWV4cg==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", - "license": "MIT", - "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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/body-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", - "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", - "license": "MIT", - "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.0", - "http-errors": "^2.0.0", - "iconv-lite": "^0.6.3", - "on-finished": "^2.4.1", - "qs": "^6.14.0", - "raw-body": "^3.0.0", - "type-is": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "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/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/content-disposition": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", - "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "license": "MIT", - "engines": { - "node": ">=6.6.0" - } - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "license": "MIT", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "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/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/esbuild": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", - "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.4", - "@esbuild/android-arm": "0.25.4", - "@esbuild/android-arm64": "0.25.4", - "@esbuild/android-x64": "0.25.4", - "@esbuild/darwin-arm64": "0.25.4", - "@esbuild/darwin-x64": "0.25.4", - "@esbuild/freebsd-arm64": "0.25.4", - "@esbuild/freebsd-x64": "0.25.4", - "@esbuild/linux-arm": "0.25.4", - "@esbuild/linux-arm64": "0.25.4", - "@esbuild/linux-ia32": "0.25.4", - "@esbuild/linux-loong64": "0.25.4", - "@esbuild/linux-mips64el": "0.25.4", - "@esbuild/linux-ppc64": "0.25.4", - "@esbuild/linux-riscv64": "0.25.4", - "@esbuild/linux-s390x": "0.25.4", - "@esbuild/linux-x64": "0.25.4", - "@esbuild/netbsd-arm64": "0.25.4", - "@esbuild/netbsd-x64": "0.25.4", - "@esbuild/openbsd-arm64": "0.25.4", - "@esbuild/openbsd-x64": "0.25.4", - "@esbuild/sunos-x64": "0.25.4", - "@esbuild/win32-arm64": "0.25.4", - "@esbuild/win32-ia32": "0.25.4", - "@esbuild/win32-x64": "0.25.4" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "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.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.26.0.tgz", - "integrity": "sha512-Hx0MOjPh6uK9oq9nVsATZKE/Wlbai7KFjfCuw9UHaguDW3x+HF0O5nIi3ud39TWgrTjTO5nHxmL3R1eANinWHQ==", - "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.26.0", - "@eslint/plugin-kit": "^0.2.8", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@modelcontextprotocol/sdk": "^1.8.0", - "@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", - "zod": "^3.24.2" - }, - "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/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventsource": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", - "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", - "license": "MIT", - "dependencies": { - "eventsource-parser": "^3.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/eventsource-parser": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.2.tgz", - "integrity": "sha512-6RxOBZ/cYgd8usLwsEl+EC09Au/9BcmCKYF2/xbml6DNczf7nv0MQb+7BA2F+li6//I+28VNlQR37XfQtcAJuA==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/express": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", - "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", - "license": "MIT", - "dependencies": { - "accepts": "^2.0.0", - "body-parser": "^2.2.0", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "finalhandler": "^2.1.0", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "merge-descriptors": "^2.0.0", - "mime-types": "^3.0.0", - "on-finished": "^2.4.1", - "once": "^1.4.0", - "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", - "range-parser": "^1.2.1", - "router": "^2.2.0", - "send": "^1.1.0", - "serve-static": "^2.2.0", - "statuses": "^2.0.1", - "type-is": "^2.0.1", - "vary": "^1.1.2" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express-rate-limit": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", - "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/express-rate-limit" - }, - "peerDependencies": { - "express": "^4.11 || 5 || ^5.0.0-beta.1" - } - }, - "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/finalhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", - "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 0.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/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/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/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/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "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-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "license": "MIT" - }, - "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/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.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/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "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/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/path-to-regexp": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", - "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", - "license": "MIT", - "engines": { - "node": ">=16" - } - }, - "node_modules/pkce-challenge": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz", - "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==", - "license": "MIT", - "engines": { - "node": ">=16.20.0" - } - }, - "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-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", - "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.6.3", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "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/router": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "depd": "^2.0.0", - "is-promise": "^4.0.0", - "parseurl": "^1.3.3", - "path-to-regexp": "^8.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "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/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/send": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", - "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.5", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "mime-types": "^3.0.1", - "ms": "^2.1.3", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", - "license": "MIT", - "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "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/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "engines": { - "node": ">= 0.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/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "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/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "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" - } - }, - "node_modules/zod": { - "version": "3.24.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.4.tgz", - "integrity": "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-to-json-schema": { - "version": "3.24.5", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", - "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==", - "license": "ISC", - "peerDependencies": { - "zod": "^3.24.1" - } - } - } -} diff --git a/apps/extract-subs/package.json b/apps/extract-subs/package.json deleted file mode 100644 index 91b75e11..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.15.18", - "esbuild": "0.25.4", - "eslint": "9.26.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/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 7153c23e..00000000 --- a/apps/list2series/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -{buildApp, ...}: -buildApp { - src = ./.; - npmDepsHash = "sha256-XnVlRAyfDkR/LT4SY0uTQlrQARwGGpLbTxgecaBygi0="; - - 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 1df23e87..00000000 --- a/apps/list2series/package-lock.json +++ /dev/null @@ -1,2549 +0,0 @@ -{ - "name": "list2series", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "list2series", - "version": "0.0.0", - "dependencies": { - "@types/node": "22.15.18", - "axios": "1.9.0", - "esbuild": "0.25.4", - "eslint": "9.26.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.26.0", - "@stylistic/eslint-plugin": "4.2.0", - "eslint": "9.26.0", - "eslint-plugin-jsdoc": "50.6.17", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3", - "typescript-eslint": "8.32.1" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", - "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", - "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", - "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", - "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", - "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", - "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", - "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", - "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", - "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", - "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", - "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", - "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", - "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", - "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", - "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", - "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", - "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", - "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", - "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", - "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", - "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", - "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", - "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", - "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", - "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", - "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.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.2.tgz", - "integrity": "sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==", - "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.26.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.26.0.tgz", - "integrity": "sha512-I9XlJawFdSMvWjDt6wksMCrgns5ggLNfFwFvnShsleWruvXM514Qxk8V246efTw+eo9JABvVz+u3q2RiAowKxQ==", - "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.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@modelcontextprotocol/sdk": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.11.3.tgz", - "integrity": "sha512-rmOWVRUbUJD7iSvJugjUbFZshTAuJ48MXoZ80Osx1GM0K/H1w7rSEvmw8m6vdWxNASgtaHIhAgre4H/E9GJiYQ==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "cors": "^2.8.5", - "cross-spawn": "^7.0.5", - "eventsource": "^3.0.2", - "express": "^5.0.1", - "express-rate-limit": "^7.5.0", - "pkce-challenge": "^5.0.0", - "raw-body": "^3.0.0", - "zod": "^3.23.8", - "zod-to-json-schema": "^3.24.1" - }, - "engines": { - "node": ">=18" - } - }, - "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.15.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.18.tgz", - "integrity": "sha512-v1DKRfUdyW+jJhZNEI1PYy29S2YRxMV5AOO/x/SjKmW0acCIOqmbj6Haf9eHAhsPmrhlHSxEhv/1WszcLWV4cg==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", - "license": "MIT", - "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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.9.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", - "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", - "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/body-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", - "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", - "license": "MIT", - "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.0", - "http-errors": "^2.0.0", - "iconv-lite": "^0.6.3", - "on-finished": "^2.4.1", - "qs": "^6.14.0", - "raw-body": "^3.0.0", - "type-is": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "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/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/content-disposition": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", - "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "license": "MIT", - "engines": { - "node": ">=6.6.0" - } - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "license": "MIT", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "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/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", - "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.4", - "@esbuild/android-arm": "0.25.4", - "@esbuild/android-arm64": "0.25.4", - "@esbuild/android-x64": "0.25.4", - "@esbuild/darwin-arm64": "0.25.4", - "@esbuild/darwin-x64": "0.25.4", - "@esbuild/freebsd-arm64": "0.25.4", - "@esbuild/freebsd-x64": "0.25.4", - "@esbuild/linux-arm": "0.25.4", - "@esbuild/linux-arm64": "0.25.4", - "@esbuild/linux-ia32": "0.25.4", - "@esbuild/linux-loong64": "0.25.4", - "@esbuild/linux-mips64el": "0.25.4", - "@esbuild/linux-ppc64": "0.25.4", - "@esbuild/linux-riscv64": "0.25.4", - "@esbuild/linux-s390x": "0.25.4", - "@esbuild/linux-x64": "0.25.4", - "@esbuild/netbsd-arm64": "0.25.4", - "@esbuild/netbsd-x64": "0.25.4", - "@esbuild/openbsd-arm64": "0.25.4", - "@esbuild/openbsd-x64": "0.25.4", - "@esbuild/sunos-x64": "0.25.4", - "@esbuild/win32-arm64": "0.25.4", - "@esbuild/win32-ia32": "0.25.4", - "@esbuild/win32-x64": "0.25.4" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "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.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.26.0.tgz", - "integrity": "sha512-Hx0MOjPh6uK9oq9nVsATZKE/Wlbai7KFjfCuw9UHaguDW3x+HF0O5nIi3ud39TWgrTjTO5nHxmL3R1eANinWHQ==", - "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.26.0", - "@eslint/plugin-kit": "^0.2.8", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@modelcontextprotocol/sdk": "^1.8.0", - "@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", - "zod": "^3.24.2" - }, - "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/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventsource": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", - "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", - "license": "MIT", - "dependencies": { - "eventsource-parser": "^3.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/eventsource-parser": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.2.tgz", - "integrity": "sha512-6RxOBZ/cYgd8usLwsEl+EC09Au/9BcmCKYF2/xbml6DNczf7nv0MQb+7BA2F+li6//I+28VNlQR37XfQtcAJuA==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/express": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", - "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", - "license": "MIT", - "dependencies": { - "accepts": "^2.0.0", - "body-parser": "^2.2.0", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "finalhandler": "^2.1.0", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "merge-descriptors": "^2.0.0", - "mime-types": "^3.0.0", - "on-finished": "^2.4.1", - "once": "^1.4.0", - "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", - "range-parser": "^1.2.1", - "router": "^2.2.0", - "send": "^1.1.0", - "serve-static": "^2.2.0", - "statuses": "^2.0.1", - "type-is": "^2.0.1", - "vary": "^1.1.2" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express-rate-limit": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", - "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/express-rate-limit" - }, - "peerDependencies": { - "express": "^4.11 || 5 || ^5.0.0-beta.1" - } - }, - "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/finalhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", - "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 0.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/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/form-data/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/form-data/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/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "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-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "license": "MIT" - }, - "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/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.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/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "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/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/path-to-regexp": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", - "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", - "license": "MIT", - "engines": { - "node": ">=16" - } - }, - "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/pkce-challenge": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz", - "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==", - "license": "MIT", - "engines": { - "node": ">=16.20.0" - } - }, - "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-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", - "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.6.3", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "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/router": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "depd": "^2.0.0", - "is-promise": "^4.0.0", - "parseurl": "^1.3.3", - "path-to-regexp": "^8.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "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/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/send": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", - "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.5", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "mime-types": "^3.0.1", - "ms": "^2.1.3", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", - "license": "MIT", - "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "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/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "engines": { - "node": ">= 0.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/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "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/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "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" - } - }, - "node_modules/zod": { - "version": "3.24.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.4.tgz", - "integrity": "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-to-json-schema": { - "version": "3.24.5", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", - "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==", - "license": "ISC", - "peerDependencies": { - "zod": "^3.24.1" - } - } - } -} diff --git a/apps/list2series/package.json b/apps/list2series/package.json deleted file mode 100644 index 0346f613..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.15.18", - "axios": "1.9.0", - "esbuild": "0.25.4", - "eslint": "9.26.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 b249d477..00000000 --- a/apps/mc-mods/default.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ - buildApp, - nodejs_latest, - ... -}: -buildApp { - src = ./.; - npmDepsHash = "sha256-uXkOVnS6c70V04BT0RBWpoVpjrdAa4NydaFl2+9ygXA="; - - 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 31ad676f..00000000 --- a/apps/mc-mods/package-lock.json +++ /dev/null @@ -1,2418 +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.15.18", - "esbuild": "0.25.4", - "eslint": "9.26.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.26.0", - "@stylistic/eslint-plugin": "4.2.0", - "eslint": "9.26.0", - "eslint-plugin-jsdoc": "50.6.17", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3", - "typescript-eslint": "8.32.1" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", - "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", - "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", - "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", - "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", - "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", - "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", - "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", - "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", - "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", - "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", - "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", - "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", - "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", - "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", - "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", - "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", - "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", - "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", - "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", - "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", - "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", - "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", - "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", - "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", - "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", - "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.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.2.tgz", - "integrity": "sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==", - "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.26.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.26.0.tgz", - "integrity": "sha512-I9XlJawFdSMvWjDt6wksMCrgns5ggLNfFwFvnShsleWruvXM514Qxk8V246efTw+eo9JABvVz+u3q2RiAowKxQ==", - "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.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@modelcontextprotocol/sdk": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.11.3.tgz", - "integrity": "sha512-rmOWVRUbUJD7iSvJugjUbFZshTAuJ48MXoZ80Osx1GM0K/H1w7rSEvmw8m6vdWxNASgtaHIhAgre4H/E9GJiYQ==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "cors": "^2.8.5", - "cross-spawn": "^7.0.5", - "eventsource": "^3.0.2", - "express": "^5.0.1", - "express-rate-limit": "^7.5.0", - "pkce-challenge": "^5.0.0", - "raw-body": "^3.0.0", - "zod": "^3.23.8", - "zod-to-json-schema": "^3.24.1" - }, - "engines": { - "node": ">=18" - } - }, - "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.15.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.18.tgz", - "integrity": "sha512-v1DKRfUdyW+jJhZNEI1PYy29S2YRxMV5AOO/x/SjKmW0acCIOqmbj6Haf9eHAhsPmrhlHSxEhv/1WszcLWV4cg==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", - "license": "MIT", - "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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/body-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", - "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", - "license": "MIT", - "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.0", - "http-errors": "^2.0.0", - "iconv-lite": "^0.6.3", - "on-finished": "^2.4.1", - "qs": "^6.14.0", - "raw-body": "^3.0.0", - "type-is": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "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/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/content-disposition": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", - "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "license": "MIT", - "engines": { - "node": ">=6.6.0" - } - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "license": "MIT", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "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/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/esbuild": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", - "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.4", - "@esbuild/android-arm": "0.25.4", - "@esbuild/android-arm64": "0.25.4", - "@esbuild/android-x64": "0.25.4", - "@esbuild/darwin-arm64": "0.25.4", - "@esbuild/darwin-x64": "0.25.4", - "@esbuild/freebsd-arm64": "0.25.4", - "@esbuild/freebsd-x64": "0.25.4", - "@esbuild/linux-arm": "0.25.4", - "@esbuild/linux-arm64": "0.25.4", - "@esbuild/linux-ia32": "0.25.4", - "@esbuild/linux-loong64": "0.25.4", - "@esbuild/linux-mips64el": "0.25.4", - "@esbuild/linux-ppc64": "0.25.4", - "@esbuild/linux-riscv64": "0.25.4", - "@esbuild/linux-s390x": "0.25.4", - "@esbuild/linux-x64": "0.25.4", - "@esbuild/netbsd-arm64": "0.25.4", - "@esbuild/netbsd-x64": "0.25.4", - "@esbuild/openbsd-arm64": "0.25.4", - "@esbuild/openbsd-x64": "0.25.4", - "@esbuild/sunos-x64": "0.25.4", - "@esbuild/win32-arm64": "0.25.4", - "@esbuild/win32-ia32": "0.25.4", - "@esbuild/win32-x64": "0.25.4" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "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.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.26.0.tgz", - "integrity": "sha512-Hx0MOjPh6uK9oq9nVsATZKE/Wlbai7KFjfCuw9UHaguDW3x+HF0O5nIi3ud39TWgrTjTO5nHxmL3R1eANinWHQ==", - "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.26.0", - "@eslint/plugin-kit": "^0.2.8", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@modelcontextprotocol/sdk": "^1.8.0", - "@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", - "zod": "^3.24.2" - }, - "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/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventsource": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", - "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", - "license": "MIT", - "dependencies": { - "eventsource-parser": "^3.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/eventsource-parser": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.2.tgz", - "integrity": "sha512-6RxOBZ/cYgd8usLwsEl+EC09Au/9BcmCKYF2/xbml6DNczf7nv0MQb+7BA2F+li6//I+28VNlQR37XfQtcAJuA==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/express": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", - "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", - "license": "MIT", - "dependencies": { - "accepts": "^2.0.0", - "body-parser": "^2.2.0", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "finalhandler": "^2.1.0", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "merge-descriptors": "^2.0.0", - "mime-types": "^3.0.0", - "on-finished": "^2.4.1", - "once": "^1.4.0", - "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", - "range-parser": "^1.2.1", - "router": "^2.2.0", - "send": "^1.1.0", - "serve-static": "^2.2.0", - "statuses": "^2.0.1", - "type-is": "^2.0.1", - "vary": "^1.1.2" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express-rate-limit": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", - "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/express-rate-limit" - }, - "peerDependencies": { - "express": "^4.11 || 5 || ^5.0.0-beta.1" - } - }, - "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/finalhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", - "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 0.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/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/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/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "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-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "license": "MIT" - }, - "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/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.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/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "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/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/path-to-regexp": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", - "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", - "license": "MIT", - "engines": { - "node": ">=16" - } - }, - "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/pkce-challenge": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz", - "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==", - "license": "MIT", - "engines": { - "node": ">=16.20.0" - } - }, - "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-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", - "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.6.3", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "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/router": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "depd": "^2.0.0", - "is-promise": "^4.0.0", - "parseurl": "^1.3.3", - "path-to-regexp": "^8.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "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/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/send": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", - "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.5", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "mime-types": "^3.0.1", - "ms": "^2.1.3", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", - "license": "MIT", - "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "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/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "engines": { - "node": ">= 0.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/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "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/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "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" - } - }, - "node_modules/zod": { - "version": "3.24.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.4.tgz", - "integrity": "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-to-json-schema": { - "version": "3.24.5", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", - "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==", - "license": "ISC", - "peerDependencies": { - "zod": "^3.24.1" - } - } - } -} diff --git a/apps/mc-mods/package.json b/apps/mc-mods/package.json deleted file mode 100644 index 1654bbc0..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.15.18", - "esbuild": "0.25.4", - "eslint": "9.26.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 03762393..00000000 --- a/apps/pin-inputs/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -{buildApp, ...}: -buildApp { - src = ./.; - npmDepsHash = "sha256-nAPV9iO+sc3oy0ApmuvU/EECumPC8etHcxwCQAR5Xzk="; - - 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 19bdff89..00000000 --- a/apps/pin-inputs/package-lock.json +++ /dev/null @@ -1,2418 +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.15.18", - "esbuild": "0.25.4", - "eslint": "9.26.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.26.0", - "@stylistic/eslint-plugin": "4.2.0", - "eslint": "9.26.0", - "eslint-plugin-jsdoc": "50.6.17", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3", - "typescript-eslint": "8.32.1" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", - "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", - "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", - "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", - "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", - "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", - "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", - "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", - "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", - "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", - "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", - "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", - "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", - "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", - "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", - "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", - "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", - "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", - "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", - "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", - "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", - "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", - "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", - "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", - "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", - "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", - "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.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.2.tgz", - "integrity": "sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==", - "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.26.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.26.0.tgz", - "integrity": "sha512-I9XlJawFdSMvWjDt6wksMCrgns5ggLNfFwFvnShsleWruvXM514Qxk8V246efTw+eo9JABvVz+u3q2RiAowKxQ==", - "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.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@modelcontextprotocol/sdk": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.11.3.tgz", - "integrity": "sha512-rmOWVRUbUJD7iSvJugjUbFZshTAuJ48MXoZ80Osx1GM0K/H1w7rSEvmw8m6vdWxNASgtaHIhAgre4H/E9GJiYQ==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "cors": "^2.8.5", - "cross-spawn": "^7.0.5", - "eventsource": "^3.0.2", - "express": "^5.0.1", - "express-rate-limit": "^7.5.0", - "pkce-challenge": "^5.0.0", - "raw-body": "^3.0.0", - "zod": "^3.23.8", - "zod-to-json-schema": "^3.24.1" - }, - "engines": { - "node": ">=18" - } - }, - "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.15.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.18.tgz", - "integrity": "sha512-v1DKRfUdyW+jJhZNEI1PYy29S2YRxMV5AOO/x/SjKmW0acCIOqmbj6Haf9eHAhsPmrhlHSxEhv/1WszcLWV4cg==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", - "license": "MIT", - "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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/body-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", - "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", - "license": "MIT", - "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.0", - "http-errors": "^2.0.0", - "iconv-lite": "^0.6.3", - "on-finished": "^2.4.1", - "qs": "^6.14.0", - "raw-body": "^3.0.0", - "type-is": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "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/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/content-disposition": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", - "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "license": "MIT", - "engines": { - "node": ">=6.6.0" - } - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "license": "MIT", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "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/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/esbuild": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", - "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.4", - "@esbuild/android-arm": "0.25.4", - "@esbuild/android-arm64": "0.25.4", - "@esbuild/android-x64": "0.25.4", - "@esbuild/darwin-arm64": "0.25.4", - "@esbuild/darwin-x64": "0.25.4", - "@esbuild/freebsd-arm64": "0.25.4", - "@esbuild/freebsd-x64": "0.25.4", - "@esbuild/linux-arm": "0.25.4", - "@esbuild/linux-arm64": "0.25.4", - "@esbuild/linux-ia32": "0.25.4", - "@esbuild/linux-loong64": "0.25.4", - "@esbuild/linux-mips64el": "0.25.4", - "@esbuild/linux-ppc64": "0.25.4", - "@esbuild/linux-riscv64": "0.25.4", - "@esbuild/linux-s390x": "0.25.4", - "@esbuild/linux-x64": "0.25.4", - "@esbuild/netbsd-arm64": "0.25.4", - "@esbuild/netbsd-x64": "0.25.4", - "@esbuild/openbsd-arm64": "0.25.4", - "@esbuild/openbsd-x64": "0.25.4", - "@esbuild/sunos-x64": "0.25.4", - "@esbuild/win32-arm64": "0.25.4", - "@esbuild/win32-ia32": "0.25.4", - "@esbuild/win32-x64": "0.25.4" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "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.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.26.0.tgz", - "integrity": "sha512-Hx0MOjPh6uK9oq9nVsATZKE/Wlbai7KFjfCuw9UHaguDW3x+HF0O5nIi3ud39TWgrTjTO5nHxmL3R1eANinWHQ==", - "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.26.0", - "@eslint/plugin-kit": "^0.2.8", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@modelcontextprotocol/sdk": "^1.8.0", - "@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", - "zod": "^3.24.2" - }, - "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/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventsource": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", - "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", - "license": "MIT", - "dependencies": { - "eventsource-parser": "^3.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/eventsource-parser": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.2.tgz", - "integrity": "sha512-6RxOBZ/cYgd8usLwsEl+EC09Au/9BcmCKYF2/xbml6DNczf7nv0MQb+7BA2F+li6//I+28VNlQR37XfQtcAJuA==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/express": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", - "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", - "license": "MIT", - "dependencies": { - "accepts": "^2.0.0", - "body-parser": "^2.2.0", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "finalhandler": "^2.1.0", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "merge-descriptors": "^2.0.0", - "mime-types": "^3.0.0", - "on-finished": "^2.4.1", - "once": "^1.4.0", - "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", - "range-parser": "^1.2.1", - "router": "^2.2.0", - "send": "^1.1.0", - "serve-static": "^2.2.0", - "statuses": "^2.0.1", - "type-is": "^2.0.1", - "vary": "^1.1.2" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express-rate-limit": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", - "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/express-rate-limit" - }, - "peerDependencies": { - "express": "^4.11 || 5 || ^5.0.0-beta.1" - } - }, - "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/finalhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", - "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 0.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/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/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/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "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-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "license": "MIT" - }, - "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/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.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/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "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/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/path-to-regexp": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", - "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", - "license": "MIT", - "engines": { - "node": ">=16" - } - }, - "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/pkce-challenge": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz", - "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==", - "license": "MIT", - "engines": { - "node": ">=16.20.0" - } - }, - "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-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", - "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.6.3", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "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/router": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "depd": "^2.0.0", - "is-promise": "^4.0.0", - "parseurl": "^1.3.3", - "path-to-regexp": "^8.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "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/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/send": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", - "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.5", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "mime-types": "^3.0.1", - "ms": "^2.1.3", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", - "license": "MIT", - "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "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/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "engines": { - "node": ">= 0.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/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "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/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "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" - } - }, - "node_modules/zod": { - "version": "3.24.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.4.tgz", - "integrity": "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-to-json-schema": { - "version": "3.24.5", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", - "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==", - "license": "ISC", - "peerDependencies": { - "zod": "^3.24.1" - } - } - } -} diff --git a/apps/pin-inputs/package.json b/apps/pin-inputs/package.json deleted file mode 100644 index 4c4e51a7..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.15.18", - "esbuild": "0.25.4", - "eslint": "9.26.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 11c7f5c4..00000000 --- a/apps/update-sources/default.nix +++ /dev/null @@ -1,34 +0,0 @@ -{ - buildApp, - callPackage, - curl, - findutils, - go, - jq, - nix-update, - nodejs_latest, - prefetch-npm-deps, - ... -}: -buildApp { - src = ./.; - npmDepsHash = "sha256-9D/XgW81Zcb1rZ3YKxa/cJH+1h7eYB3PSwYsUHq2T4M="; - - runtimeInputs = [ - curl - findutils - go - jq - nix-update - nodejs_latest - prefetch-npm-deps - # We want to use the one from my config with authfile - # (callPackage ../../modules/docker/updateImage.nix {}) - (callPackage ../../configurations/homie/modules/home-assistant/netdaemon/update.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 bb0b5606..00000000 --- a/apps/update-sources/package-lock.json +++ /dev/null @@ -1,2418 +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.15.18", - "esbuild": "0.25.4", - "eslint": "9.26.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.26.0", - "@stylistic/eslint-plugin": "4.2.0", - "eslint": "9.26.0", - "eslint-plugin-jsdoc": "50.6.14", - "jiti": "2.4.2", - "pkg-types": "2.1.0", - "typescript": "5.8.3", - "typescript-eslint": "8.32.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", - "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", - "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", - "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", - "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", - "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", - "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", - "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", - "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", - "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", - "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", - "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", - "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", - "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", - "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", - "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", - "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", - "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", - "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", - "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", - "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", - "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", - "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", - "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", - "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", - "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", - "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.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.2.tgz", - "integrity": "sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==", - "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.26.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.26.0.tgz", - "integrity": "sha512-I9XlJawFdSMvWjDt6wksMCrgns5ggLNfFwFvnShsleWruvXM514Qxk8V246efTw+eo9JABvVz+u3q2RiAowKxQ==", - "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.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@modelcontextprotocol/sdk": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.11.3.tgz", - "integrity": "sha512-rmOWVRUbUJD7iSvJugjUbFZshTAuJ48MXoZ80Osx1GM0K/H1w7rSEvmw8m6vdWxNASgtaHIhAgre4H/E9GJiYQ==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "cors": "^2.8.5", - "cross-spawn": "^7.0.5", - "eventsource": "^3.0.2", - "express": "^5.0.1", - "express-rate-limit": "^7.5.0", - "pkce-challenge": "^5.0.0", - "raw-body": "^3.0.0", - "zod": "^3.23.8", - "zod-to-json-schema": "^3.24.1" - }, - "engines": { - "node": ">=18" - } - }, - "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.15.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.18.tgz", - "integrity": "sha512-v1DKRfUdyW+jJhZNEI1PYy29S2YRxMV5AOO/x/SjKmW0acCIOqmbj6Haf9eHAhsPmrhlHSxEhv/1WszcLWV4cg==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", - "license": "MIT", - "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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/body-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", - "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", - "license": "MIT", - "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.0", - "http-errors": "^2.0.0", - "iconv-lite": "^0.6.3", - "on-finished": "^2.4.1", - "qs": "^6.14.0", - "raw-body": "^3.0.0", - "type-is": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "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/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/content-disposition": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", - "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "license": "MIT", - "engines": { - "node": ">=6.6.0" - } - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "license": "MIT", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "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/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/esbuild": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", - "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.4", - "@esbuild/android-arm": "0.25.4", - "@esbuild/android-arm64": "0.25.4", - "@esbuild/android-x64": "0.25.4", - "@esbuild/darwin-arm64": "0.25.4", - "@esbuild/darwin-x64": "0.25.4", - "@esbuild/freebsd-arm64": "0.25.4", - "@esbuild/freebsd-x64": "0.25.4", - "@esbuild/linux-arm": "0.25.4", - "@esbuild/linux-arm64": "0.25.4", - "@esbuild/linux-ia32": "0.25.4", - "@esbuild/linux-loong64": "0.25.4", - "@esbuild/linux-mips64el": "0.25.4", - "@esbuild/linux-ppc64": "0.25.4", - "@esbuild/linux-riscv64": "0.25.4", - "@esbuild/linux-s390x": "0.25.4", - "@esbuild/linux-x64": "0.25.4", - "@esbuild/netbsd-arm64": "0.25.4", - "@esbuild/netbsd-x64": "0.25.4", - "@esbuild/openbsd-arm64": "0.25.4", - "@esbuild/openbsd-x64": "0.25.4", - "@esbuild/sunos-x64": "0.25.4", - "@esbuild/win32-arm64": "0.25.4", - "@esbuild/win32-ia32": "0.25.4", - "@esbuild/win32-x64": "0.25.4" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "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.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.26.0.tgz", - "integrity": "sha512-Hx0MOjPh6uK9oq9nVsATZKE/Wlbai7KFjfCuw9UHaguDW3x+HF0O5nIi3ud39TWgrTjTO5nHxmL3R1eANinWHQ==", - "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.26.0", - "@eslint/plugin-kit": "^0.2.8", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@modelcontextprotocol/sdk": "^1.8.0", - "@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", - "zod": "^3.24.2" - }, - "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/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventsource": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", - "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", - "license": "MIT", - "dependencies": { - "eventsource-parser": "^3.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/eventsource-parser": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.2.tgz", - "integrity": "sha512-6RxOBZ/cYgd8usLwsEl+EC09Au/9BcmCKYF2/xbml6DNczf7nv0MQb+7BA2F+li6//I+28VNlQR37XfQtcAJuA==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/express": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", - "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", - "license": "MIT", - "dependencies": { - "accepts": "^2.0.0", - "body-parser": "^2.2.0", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "finalhandler": "^2.1.0", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "merge-descriptors": "^2.0.0", - "mime-types": "^3.0.0", - "on-finished": "^2.4.1", - "once": "^1.4.0", - "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", - "range-parser": "^1.2.1", - "router": "^2.2.0", - "send": "^1.1.0", - "serve-static": "^2.2.0", - "statuses": "^2.0.1", - "type-is": "^2.0.1", - "vary": "^1.1.2" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express-rate-limit": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", - "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/express-rate-limit" - }, - "peerDependencies": { - "express": "^4.11 || 5 || ^5.0.0-beta.1" - } - }, - "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/finalhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", - "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 0.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/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/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/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "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-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "license": "MIT" - }, - "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/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.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/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "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/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/path-to-regexp": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", - "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", - "license": "MIT", - "engines": { - "node": ">=16" - } - }, - "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/pkce-challenge": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz", - "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==", - "license": "MIT", - "engines": { - "node": ">=16.20.0" - } - }, - "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-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", - "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.6.3", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "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/router": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "depd": "^2.0.0", - "is-promise": "^4.0.0", - "parseurl": "^1.3.3", - "path-to-regexp": "^8.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "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/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/send": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", - "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.5", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "mime-types": "^3.0.1", - "ms": "^2.1.3", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", - "license": "MIT", - "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "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/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "engines": { - "node": ">= 0.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/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "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/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "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" - } - }, - "node_modules/zod": { - "version": "3.24.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.4.tgz", - "integrity": "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-to-json-schema": { - "version": "3.24.5", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", - "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==", - "license": "ISC", - "peerDependencies": { - "zod": "^3.24.1" - } - } - } -} diff --git a/apps/update-sources/package.json b/apps/update-sources/package.json deleted file mode 100644 index 9291395d..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.15.18", - "esbuild": "0.25.4", - "eslint": "9.26.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 3357d297..00000000 --- a/apps/update-sources/src/app.ts +++ /dev/null @@ -1,209 +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 updateNetDaemon from './netdaemon'; -import runNixUpdate from './nix-update'; -import updateNodeModules from './node-modules'; -import updateVuetorrent from './vuetorrent'; - - -/* Constants */ -const FLAKE = process.env.FLAKE; - -if (!FLAKE) { - console.error('Environment variable FLAKE was not found.\n'); - process.exit(1); -} - -const args = parseArgs(); - -const main = async() => { - if (args['custom-sidebar']) { - console.log( - runNixUpdate('scopedPackages', 'lovelace-components', 'custom-sidebar') ?? 'No updates', - ); - } - - if (args['caddy'] || args['caddy-plugins']) { - console.log(updateCaddyPlugins() ?? 'No updates'); - } - - if (args['docker']) { - console.log(updateDocker() ?? 'No updates'); - } - - if (args['firefox']) { - console.log(updateFirefoxAddons() ?? 'No updates'); - } - - if (args['homepage']) { - console.log(runNixUpdate('homepage') ?? 'No updates'); - } - - if (args['flake'] || args['inputs']) { - console.log(updateFlakeInputs() ?? 'No updates'); - } - - if (args['jmusicbot']) { - console.log(runNixUpdate('jmusicbot') ?? 'No updates'); - } - - if (args['material-rounded-theme']) { - console.log( - runNixUpdate('scopedPackages', 'lovelace-components', 'material-rounded-theme') ?? - 'No updates', - ); - } - - if (args['netdaemon']) { - console.log(updateNetDaemon() ?? 'No updates'); - } - - if (args['node'] || args['node_modules']) { - console.log((await updateNodeModules()) ?? 'No updates'); - } - - if (args['pam-fprint-grosshack']) { - console.log(runNixUpdate('pam-fprint-grosshack') ?? 'No updates'); - } - - if (args['protonhax']) { - console.log(runNixUpdate('protonhax') ?? 'No updates'); - } - - if (args['some-sass-language-server']) { - console.log(runNixUpdate('some-sass-language-server') ?? 'No updates'); - } - - if (args['trash'] || args['trash-d']) { - console.log(runNixUpdate('trash-d') ?? 'No updates'); - } - - if (args['vuetorrent']) { - console.log(updateVuetorrent() ?? 'No updates'); - } - - 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 netdaemonOutput = updateNetDaemon(); - - console.log(netdaemonOutput ?? '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) { - nixUpdateOutputs.push(execution); - } - }; - - 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: 'inherit', - }); - - 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 (netdaemonOutput) { - output.push(`NetDaemon:\n${indentOutput(netdaemonOutput)}\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')); - } - } - else { - spawnSync(`alejandra -q ${FLAKE}`, [], { shell: true }); - } -}; - -main(); diff --git a/apps/update-sources/src/caddy.ts b/apps/update-sources/src/caddy.ts deleted file mode 100644 index d6ed6078..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'].join(' '), [], { 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 d0dfe091..00000000 --- a/apps/update-sources/src/docker.ts +++ /dev/null @@ -1,57 +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.length > 1) { - return out; - } -}; - -export default (): string | null => { - console.log(styleText(['magenta'], '\nUpdating docker images:\n')); - - const updates: string[] = []; - - const jdownloaderUpdates = updateImages(`${FLAKE}/configurations/nos/modules/comics/jdownloader2`); - - if (jdownloaderUpdates) { - updates.push(jdownloaderUpdates); - } - - 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 1f4137c7..00000000 --- a/apps/update-sources/src/firefox.ts +++ /dev/null @@ -1,63 +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', - ].join(' '), [], { 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, - ].join(' '), [], { 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 cbc97c5a..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"'].join(' '), [], { 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/netdaemon.ts b/apps/update-sources/src/netdaemon.ts deleted file mode 100644 index 231a1e99..00000000 --- a/apps/update-sources/src/netdaemon.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { readFileSync, writeFileSync } from 'node:fs'; -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 NetDaemon:\n')); - - const FOLDER = `${FLAKE}/configurations/homie/modules/home-assistant/netdaemon`; - - const OLD_VERSION = readFileSync(`${FOLDER}/.version`).toString().replace('\n', ''); - - const VERSION = JSON.parse(spawnSync([ - 'curl', '-s', 'https://api.github.com/repos/net-daemon/netdaemon/releases/latest', - ].join(' '), [], { shell: true }).stdout.toString()).tag_name.replace('v', ''); - - if (OLD_VERSION !== VERSION) { - writeFileSync(`${FOLDER}/.version`, `${VERSION}\n`); - - spawnSync('bumpNetdaemonDeps', [], { - cwd: FOLDER, - stdio: 'inherit', - }); - - return `NetDaemon: ${OLD_VERSION} -> ${VERSION}\n`; - } - - return null; -}; diff --git a/apps/update-sources/src/nix-update.ts b/apps/update-sources/src/nix-update.ts deleted file mode 100644 index 6b9cce61..00000000 --- a/apps/update-sources/src/nix-update.ts +++ /dev/null @@ -1,31 +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`].join(' '), [], { shell: true }, -).stdout.toString(); - -export default ( - attr: string, - scope?: string, - scopeAttr?: string, -): string | null => { - const realAttr = scope ? `${attr}.x86_64-linux.${scope}.${scopeAttr}` : attr; - const cleanAttr = scope ? `${attr}.${scope}.${scopeAttr}` : attr; - - console.log(styleText(['magenta'], `\nUpdating ${cleanAttr}:\n`)); - - const OLD_VERSION = getAttrVersion(realAttr); - - spawnSync('nix-update', ['--flake', realAttr, '-u'], { cwd: FLAKE, stdio: 'inherit' }); - - const NEW_VERSION = getAttrVersion(realAttr); - - return OLD_VERSION !== NEW_VERSION ? - `${cleanAttr}: ${OLD_VERSION} -> ${NEW_VERSION}` : - null; -}; diff --git a/apps/update-sources/src/node-modules.ts b/apps/update-sources/src/node-modules.ts deleted file mode 100644 index a5af6b7c..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'].join(' '), [], { 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 48241150..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'].join(' '), [], { shell: true }, - ).stdout.toString()).version; - - const VERSION = JSON.parse(spawnSync( - ['curl', '-s', 'https://api.github.com/repos/VueTorrent/VueTorrent/releases/latest'].join(' '), [], { 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/common/default.nix b/common/default.nix new file mode 100644 index 00000000..1b778371 --- /dev/null +++ b/common/default.nix @@ -0,0 +1,126 @@ +{ + config, + home-manager, + lib, + nh, + nix-melt, + nur, + nurl, + pkgs, + ... +} @ inputs: { + imports = [ + ./vars + + ./modules + ./pkgs + + nur.nixosModules.nur + nh.nixosModules.default + home-manager.nixosModules.home-manager + + ../modules/arion + ../modules/borgbackup + ../modules/nvidia.nix + ]; + + nixpkgs = { + config.allowUnfree = true; + overlays = import ./overlays inputs; + }; + boot.tmp.cleanOnBoot = true; + + nix = { + # Allow deleting store files with '.' in the name + package = pkgs.nix.overrideAttrs (o: { + patches = + (o.patches or []) + ++ [ + ./overlays/nix/patch + ]; + }); + # 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; + + # remote building + trusted-users = ["matt" "nixremote"]; + }; + }; + + nh = { + enable = true; + # weekly cleanup + clean = { + enable = true; + extraArgs = "--keep-since 30d"; + }; + }; + + services = { + fwupd.enable = true; + + xserver.xkb = { + layout = "ca"; + variant = "multix"; + }; + }; + + home-manager = let + inherit (config.vars) mainUser; + mainUserConf = config.home-manager.users.${mainUser}; + + default = { + imports = [ + # Make the vars be the same on Nix and HM + { + options.vars = lib.mkOption { + type = lib.types.attrs; + readOnly = true; + default = config.vars; + }; + } + + nur.hmModules.nur + + ./home + ./home/trash-d + ./pkgs + ]; + + home.packages = + [ + nix-melt.packages.${pkgs.system}.default + nurl.packages.${pkgs.system}.default + ] + ++ (with config.nur.repos.rycee; [ + mozilla-addons-to-nix + ]); + }; + in { + users = { + root = + default + // { + home.stateVersion = mainUserConf.home.stateVersion; + }; + greeter = + lib.mkIf (config.services.greetd.enable) + (default + // { + home.stateVersion = mainUserConf.home.stateVersion; + }); + + ${mainUser} = default; + }; + }; +} diff --git a/homeManagerModules/shell/config/bashrc b/common/home/bash/config/bashrc similarity index 100% rename from homeManagerModules/shell/config/bashrc rename to common/home/bash/config/bashrc diff --git a/homeManagerModules/shell/config/colorgrid.sh b/common/home/bash/config/colorgrid.sh similarity index 100% rename from homeManagerModules/shell/config/colorgrid.sh rename to common/home/bash/config/colorgrid.sh diff --git a/homeManagerModules/shell/config/dracula/fzf.sh b/common/home/bash/config/dracula/fzf.sh similarity index 100% rename from homeManagerModules/shell/config/dracula/fzf.sh rename to common/home/bash/config/dracula/fzf.sh diff --git a/homeManagerModules/shell/config/dracula/less.sh b/common/home/bash/config/dracula/less.sh similarity index 100% rename from homeManagerModules/shell/config/dracula/less.sh rename to common/home/bash/config/dracula/less.sh diff --git a/common/home/bash/default.nix b/common/home/bash/default.nix new file mode 100644 index 00000000..4850b168 --- /dev/null +++ b/common/home/bash/default.nix @@ -0,0 +1,145 @@ +{ + config, + lib, + ... +}: let + inherit (lib) concatStrings fileContents; + inherit (config.vars) promptColors; +in { + imports = [./programs.nix]; + + programs = { + starship = { + enable = true; + enableBashIntegration = true; + + settings = { + format = concatStrings [ + "╭╴" + "[](fg:${promptColors.firstColor})" + "[ ](bg:${promptColors.firstColor} fg:#090c0c)" + "[](bg:${promptColors.secondColor} fg:${promptColors.firstColor})" + "$username$hostname" + "[](fg:${promptColors.secondColor} bg:${promptColors.thirdColor})" + "$directory" + "[](fg:${promptColors.thirdColor} bg:${promptColors.fourthColor})" + "$git_branch" + "[](fg:${promptColors.fourthColor})$shlvl$nix_shell" + "\n╰╴$character" + ]; + + username = { + show_always = true; + style_user = "fg:${promptColors.textColor} bg:${promptColors.secondColor}"; + style_root = "fg:red bg:${promptColors.secondColor} blink"; + format = "[ $user]($style)"; + }; + + hostname = { + ssh_only = false; + style = "fg:${promptColors.textColor} bg:${promptColors.secondColor}"; + format = "[@$hostname ]($style)"; + }; + + directory = { + style = "fg:${promptColors.firstColor} bg:${promptColors.thirdColor}"; + format = "[ $path ]($style)"; + truncate_to_repo = false; + truncation_length = 0; + + substitutions = { + "Documents" = " "; + "Downloads" = " "; + "Music" = " "; + "Pictures" = " "; + }; + }; + + git_branch = { + style = "fg:${promptColors.secondColor} bg:${promptColors.fourthColor}"; + symbol = ""; + format = "[ $symbol $branch ]($style)"; + }; + + shlvl = { + disabled = false; + repeat = true; + symbol = " "; + format = "[ $symbol]($style)"; + threshold = 1; + }; + + nix_shell = { + symbol = "❄️ "; + format = "[ $symbol]($style)"; + }; + + character = { + success_symbol = "[\\$](bold green)"; + error_symbol = "[\\$](bold red)"; + }; + }; + }; + + bash = { + enable = true; + 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"; + 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 = '' + #''; + }; + }; +} diff --git a/homeManagerModules/shell/misc/default.nix b/common/home/bash/programs.nix similarity index 66% rename from homeManagerModules/shell/misc/default.nix rename to common/home/bash/programs.nix index 61221c25..76dab742 100644 --- a/homeManagerModules/shell/misc/default.nix +++ b/common/home/bash/programs.nix @@ -1,14 +1,9 @@ -self: { - config, - lib, +{ pkgs, + config, ... -}: let - inherit (lib) attrValues mkIf; - - cfg = config.programs.bash; -in { - config.programs = mkIf cfg.enable { +}: { + programs = { fzf = { enable = true; enableBashIntegration = true; @@ -46,16 +41,18 @@ in { bat = { enable = true; - - config.theme = "dracula-bat"; - themes.dracula-bat.src = pkgs.scopedPackages.dracula.bat; - - extraPackages = attrValues { - inherit (pkgs.bat-extras) batman; + config = { + theme = "dracula-bat"; }; + themes = { + dracula-bat = { + src = pkgs.dracula-theme; + file = "bat"; + }; + }; + extraPackages = with pkgs.bat-extras; [ + batman + ]; }; }; - - # For accurate stack trace - _file = ./default.nix; } diff --git a/common/home/default.nix b/common/home/default.nix new file mode 100644 index 00000000..b86d8a13 --- /dev/null +++ b/common/home/default.nix @@ -0,0 +1,11 @@ +{...}: { + imports = [ + ./bash + ./direnv + ./git + ./neovim + ./nix-index + ./tmux + ./packages.nix + ]; +} diff --git a/common/home/direnv/default.nix b/common/home/direnv/default.nix new file mode 100644 index 00000000..f4152f1a --- /dev/null +++ b/common/home/direnv/default.nix @@ -0,0 +1,10 @@ +{pkgs, ...}: { + programs.direnv = { + enable = true; + enableBashIntegration = true; + nix-direnv = { + enable = true; + package = pkgs.nix-direnv-flakes; + }; + }; +} diff --git a/common/home/git/default.nix b/common/home/git/default.nix new file mode 100644 index 00000000..eacbc0cc --- /dev/null +++ b/common/home/git/default.nix @@ -0,0 +1,82 @@ +{pkgs, ...}: { + programs = { + git = { + enable = true; + lfs.enable = true; + + includes = [ + {path = "${pkgs.dracula-theme}/git-colors";} + + { + condition = "hasconfig:remote.*.url:git@github.com:*/**"; + contents = { + user = { + email = "matt@nelim.org"; + name = "matt1432"; + }; + }; + } + + { + condition = "hasconfig:remote.*.url:git@git.nelim.org:*/**"; + contents = { + user = { + email = "matt@nelim.org"; + name = "matt1432"; + }; + }; + } + + { + condition = "hasconfig:remote.*.url:git@gitlab.info.uqam.ca:*/**"; + contents = { + user = { + email = "gj591944@ens.uqam.ca"; + name = "Mathis Hurtubise"; + }; + }; + } + ]; + + delta = { + enable = true; + options = { + side-by-side = true; + line-numbers-zero-style = "#E6EDF3"; #BD93F9"; + }; + }; + + extraConfig = { + diff.sopsdiffer.textconv = "sops --config /dev/null -d"; + + # https://github.com/dandavison/delta/issues/630#issuecomment-860046929 + pager = let + cmd = "LESS='LRc --mouse' ${pkgs.delta}/bin/delta"; + in { + diff = cmd; + show = cmd; + stash = cmd; + log = cmd; + reflog = cmd; + }; + }; + }; + }; + + home.packages = with pkgs; [ + (writeShellApplication { + name = "chore"; + runtimeInputs = [git]; + + text = '' + DIR=''${1:-"$FLAKE"} + + cd "$DIR" || exit 1 + + git add flake.lock + git commit -m 'chore: update flake.lock' + git push + ''; + }) + ]; +} diff --git a/common/home/neovim/base.lua b/common/home/neovim/base.lua new file mode 100644 index 00000000..28bb7406 --- /dev/null +++ b/common/home/neovim/base.lua @@ -0,0 +1,2 @@ +-- Add `:Format` command to format current buffer +vim.api.nvim_create_user_command("Format", "call CocAction('format')", {}) diff --git a/common/home/neovim/base.vim b/common/home/neovim/base.vim new file mode 100644 index 00000000..1afcffb7 --- /dev/null +++ b/common/home/neovim/base.vim @@ -0,0 +1,34 @@ +" by default, the indent is 2 spaces. +set smartindent +set expandtab +set shiftwidth=2 +set softtabstop=2 +set tabstop=2 + +" for html/rb files, 2 spaces +autocmd Filetype html setlocal ts=2 sw=2 expandtab +autocmd Filetype ruby setlocal ts=2 sw=2 expandtab + +" for js/coffee/jade files, 4 spaces +autocmd Filetype javascript setlocal ts=4 sw=4 sts=0 expandtab +autocmd Filetype typescript setlocal ts=4 sw=4 sts=0 expandtab +autocmd Filetype java setlocal ts=4 sw=4 sts=0 expandtab +autocmd Filetype sh setlocal ts=4 sw=4 sts=0 expandtab +autocmd Filetype hyprlang setlocal ts=4 sw=4 sts=0 expandtab + +" support scss @ +autocmd FileType scss setl iskeyword+=@-@ + +set number +set relativenumber + +" TODO: make this work for nix-on-droid +set undofile +set undodir=/home/matt/.cache/nvim/ + +" remove highlight on words +nnoremap <silent> <esc> :noh<cr><esc> + +" Always show the signcolumn, otherwise it would shift the text each time +" diagnostics appear/become resolved +set signcolumn=yes diff --git a/common/home/neovim/default.nix b/common/home/neovim/default.nix new file mode 100644 index 00000000..cf2cc0b0 --- /dev/null +++ b/common/home/neovim/default.nix @@ -0,0 +1,340 @@ +{ + config, + pkgs, + lib, + nvim-theme-src, + coc-stylelintplus, + vimplugin-riscv-src, + ... +}: let + inherit (config.vars) neovimIde; + inherit (lib) fileContents hasAttr optionalAttrs optionals; + + javaSdk = pkgs.temurin-bin-17; + coc-stylelintplus-flake = coc-stylelintplus.packages.${pkgs.system}.default; +in { + home = optionalAttrs neovimIde { + packages = with pkgs; [ + gradle + maven + alejandra + ]; + }; + + xdg.dataFile = optionalAttrs neovimIde { + ".gradle/gradle.properties".text = '' + org.gradle.java.home = ${javaSdk} + ''; + }; + + programs = { + java = optionalAttrs neovimIde { + enable = true; + package = javaSdk; + }; + + # I love doing typos + bash.shellAliases = { + nivm = "nvim"; + nivim = "nvim"; + }; + + neovim = { + enable = true; + withNodeJs = true; + withPython3 = true; + withRuby = false; + + defaultEditor = true; + viAlias = true; + vimAlias = true; + + extraPackages = with pkgs; ([ + bat + gcc + ] + ++ optionals neovimIde [ + nodejs_latest + nodePackages.npm + nodePackages.neovim + gradle + nil + ]); + + extraPython3Packages = ps: + optionals neovimIde [ + ps.pylint + ]; + + coc = optionalAttrs neovimIde { + enable = true; + settings = { + # General + colors.enable = true; + coc.preferences.formatOnType = true; + diagnostic.checkCurrentLine = true; + inlayHint.enable = false; + + # ESLint + eslint = { + format.enable = true; + autoFixOnSave = true; + }; + + # Stylelint + stylelintplus = { + enable = true; + cssInJs = true; + autoFixOnSave = true; + autoFixOnFormat = true; + }; + css.validate = false; + less.validate = false; + scss.validate = false; + wxss.validate = false; + + # Lua + Lua = { + misc.parameters = [ + "--metapath" + "~/.cache/sumneko_lua/meta" + "--logpath" + "~/.cache/sumneko_lua/log" + ]; + workspace.library = [ + "$\{3rd\}/luv/library" + ]; + }; + sumneko-lua = { + serverDir = "${pkgs.lua-language-server}/share/lua-language-server"; + enableNvimLuaDev = true; + }; + + languageserver = { + # Nix + nix = { + command = "nil"; + filetypes = ["nix"]; + rootPatterns = ["flake.nix"]; + settings = { + nil = { + formatting.command = ["alejandra"]; + + nix = { + maxMemoryMB = 2560; + flake.autoArchive = hasAttr "sops" config; + }; + }; + }; + }; + }; + + # Java + java = { + maven.downloadSources = true; + eclipse.downloadSources = true; + + format.settings.url = "eclipse-formatter.xml"; + + jdt.ls = { + java.home = "${javaSdk}"; + statusIcons = { + "busy" = "Busy"; + "ready" = "OK"; + "warning" = "Warning"; + "error" = "Error"; + }; + }; + }; + + # Bash + bashIde.shellcheckPath = "${pkgs.shellcheck}/bin/shellcheck"; + + markdownlint.config = { + no-trailing-spaces = true; + no-multiple-blanks = false; + no-duplicate-heading = false; + }; + }; + }; + + extraConfig = fileContents ./base.vim; + extraLuaConfig = fileContents ./base.lua; + + plugins = with pkgs.vimPlugins; + ([ + fzfWrapper + fzf-vim + fugitive + + { + plugin = dracula-nvim.overrideAttrs { + src = nvim-theme-src; + }; + type = "viml"; + config = fileContents ./plugins/dracula.vim; + } + { + plugin = todo-comments-nvim; + type = "lua"; + config = + /* + lua + */ + ''require('todo-comments').setup()''; + } + { + plugin = gitsigns-nvim; + type = "lua"; + config = fileContents ./plugins/gitsigns.lua; + } + { + plugin = indent-blankline-nvim; + type = "lua"; + config = fileContents ./plugins/indent.lua; + } + { + plugin = mini-nvim; + type = "lua"; + config = fileContents ./plugins/mini.lua; + } + ] + ++ optionals neovimIde [ + markdown-preview-nvim + + # Coc configured + coc-css + coc-eslint + coc-java + coc-sh + coc-stylelintplus-flake + { + plugin = coc-snippets; + type = "viml"; + config = fileContents ./plugins/snippets.vim; + } + + ## Lua + coc-sumneko-lua + neodev-nvim + + ## Fzf + coc-fzf + + coc-highlight + coc-json + coc-pyright + coc-vimlsp + coc-yaml + coc-toml + coc-markdownlint + coc-tsserver + + { + plugin = nvim-autopairs; + type = "lua"; + config = fileContents ./plugins/autopairs.lua; + } + { + plugin = lualine-nvim; + type = "lua"; + config = fileContents ./plugins/lualine.lua; + } + { + plugin = neo-tree-nvim; + type = "viml"; + config = '' + ${fileContents ./plugins/neotree.vim} + + lua << EOF + ${fileContents ./plugins/neotree.lua} + EOF + ''; + } + (pkgs.vimUtils.buildVimPlugin { + name = "riscv-asm"; + src = vimplugin-riscv-src; + }) + ]) + # Treesitter + ++ (with pkgs.vimPlugins; [ + nvim-treesitter-context + nvim-treesitter-textobjects + { + type = "viml"; + config = fileContents ./plugins/treesitter.vim; + plugin = nvim-treesitter.withPlugins (p: [ + p.awk + p.bash + p.c + p.c_sharp + p.cairo + p.cmake + p.comment + p.cpp + p.css + p.csv + p.cuda + p.diff + p.dockerfile + p.dot + p.git_config + p.git_rebase + p.gitattributes + p.gitcommit + p.gitignore + p.go + p.gomod + p.gosum + p.groovy + p.haskell + p.haskell_persistent + p.hyprlang + p.html + p.ini + p.java + p.javascript + p.jq + p.jsdoc + p.json + p.json5 + p.jsonc + p.jsonnet + p.kotlin + p.latex + p.lua + p.luadoc + p.make + p.markdown + p.meson + p.ninja + p.nix + p.passwd + p.perl + p.php + p.phpdoc + p.properties + p.python + p.rasi + p.regex + p.requirements + p.ruby + p.rust + p.scss + p.sql + p.ssh_config + p.toml + p.todotxt + p.typescript + p.udev + p.vim + p.vimdoc + p.vue + p.xml + p.yaml + ]); + } + ]); + }; + }; +} diff --git a/common/home/neovim/plugins/autopairs.lua b/common/home/neovim/plugins/autopairs.lua new file mode 100644 index 00000000..89604963 --- /dev/null +++ b/common/home/neovim/plugins/autopairs.lua @@ -0,0 +1,16 @@ +-- 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/common/home/neovim/plugins/dracula.vim b/common/home/neovim/plugins/dracula.vim new file mode 100644 index 00000000..255b9182 --- /dev/null +++ b/common/home/neovim/plugins/dracula.vim @@ -0,0 +1,10 @@ +" set dot icon in place of trailing whitespaces +set list listchars=tab:\ \ ,nbsp:␣,trail:•,extends:⟩,precedes:⟨ + + +lua << EOF +-- Add visual indicator for trailing whitespaces +vim.opt.fillchars = {eob = " "} + +vim.cmd[[colorscheme dracula]] +EOF diff --git a/common/home/neovim/plugins/gitsigns.lua b/common/home/neovim/plugins/gitsigns.lua new file mode 100644 index 00000000..762cbc6f --- /dev/null +++ b/common/home/neovim/plugins/gitsigns.lua @@ -0,0 +1,13 @@ +local gitsigns = require("gitsigns") + +local function visual_stage() + local first_line = vim.fn.line('v') + local last_line = vim.fn.getpos('.')[2] + gitsigns.stage_hunk({ first_line, last_line }) +end + +vim.keymap.set("v", "gs", function() + visual_stage() +end) + +gitsigns.setup(); diff --git a/common/home/neovim/plugins/indent.lua b/common/home/neovim/plugins/indent.lua new file mode 100644 index 00000000..61494fd3 --- /dev/null +++ b/common/home/neovim/plugins/indent.lua @@ -0,0 +1,26 @@ +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 = "▏", + }, +}) diff --git a/common/home/neovim/plugins/lualine.lua b/common/home/neovim/plugins/lualine.lua new file mode 100644 index 00000000..d9a4ad93 --- /dev/null +++ b/common/home/neovim/plugins/lualine.lua @@ -0,0 +1,9 @@ +require('lualine').setup({ + options = { + theme = 'dracula', + globalstatus = true, + }, + sections = { + lualine_x = {'g:coc_status', 'bo:filetype'}, + } +}) diff --git a/common/home/neovim/plugins/mini.lua b/common/home/neovim/plugins/mini.lua new file mode 100644 index 00000000..e3a6e38a --- /dev/null +++ b/common/home/neovim/plugins/mini.lua @@ -0,0 +1,23 @@ +local map = require('mini.map') +map.setup({ + integrations = { + map.gen_integration.builtin_search(), + map.gen_integration.gitsigns(), + map.gen_integration.diagnostic(), + }, + window = { + focusable = false, + width = 7, + winblend = 75, + }, +}) + +local ts_input = require('mini.surround').gen_spec.input.treesitter +require('mini.surround').setup({ + custom_surroundings = { + -- Use tree-sitter to search for function call + f = { + input = ts_input({ outer = '@call.outer', inner = '@call.inner' }) + }, + } +}) diff --git a/common/home/neovim/plugins/neotree.lua b/common/home/neovim/plugins/neotree.lua new file mode 100644 index 00000000..ad420ba1 --- /dev/null +++ b/common/home/neovim/plugins/neotree.lua @@ -0,0 +1,38 @@ +-- 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 = true, + 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, + } +}) diff --git a/common/home/neovim/plugins/neotree.vim b/common/home/neovim/plugins/neotree.vim new file mode 100644 index 00000000..a02474b7 --- /dev/null +++ b/common/home/neovim/plugins/neotree.vim @@ -0,0 +1,11 @@ +" Auto open Neo-Tree on big enough window +function! OpenTree() abort + if &columns > 100 + Neotree show + Neotree close + Neotree show + endif + lua MiniMap.open() +endfunction + +autocmd VimEnter * call OpenTree() diff --git a/common/home/neovim/plugins/snippets.vim b/common/home/neovim/plugins/snippets.vim new file mode 100644 index 00000000..3df084b6 --- /dev/null +++ b/common/home/neovim/plugins/snippets.vim @@ -0,0 +1,13 @@ +" 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>' diff --git a/common/home/neovim/plugins/treesitter.vim b/common/home/neovim/plugins/treesitter.vim new file mode 100644 index 00000000..fbabedbc --- /dev/null +++ b/common/home/neovim/plugins/treesitter.vim @@ -0,0 +1,21 @@ +lua << EOF + +require('nvim-treesitter.configs').setup({ + highlight = { enable = true }, + indent = { enable = true }, +}) + +require('treesitter-context').setup({ + enable = true, + max_lines = 3, + min_window_height = 20, +}) + +vim.filetype.add({ + pattern = { [".*/hypr/.*%.conf"] = "hyprlang" }, +}) + +EOF + +" Add line under context +hi TreesitterContextBottom gui=underline guisp=Grey diff --git a/common/home/nix-index/default.nix b/common/home/nix-index/default.nix new file mode 100644 index 00000000..c8d1e1b8 --- /dev/null +++ b/common/home/nix-index/default.nix @@ -0,0 +1,11 @@ +{nix-index-db, ...}: { + imports = [nix-index-db.hmModules.nix-index]; + + programs = { + nix-index-database.comma.enable = true; + nix-index = { + enable = true; + enableBashIntegration = true; + }; + }; +} diff --git a/common/home/packages.nix b/common/home/packages.nix new file mode 100644 index 00000000..00f68387 --- /dev/null +++ b/common/home/packages.nix @@ -0,0 +1,30 @@ +{ + config, + pkgs, + ... +}: { + home.packages = + (with config.customPkgs; [ + pokemon-colorscripts + repl + ]) + ++ (with pkgs.nodePackages; [ + undollar + ]) + ++ (with pkgs; [ + dracula-theme + neofetch + progress + wget + tree + openssh + mosh + rsync + killall + imagemagick + usbutils + zip + unzip + dig.dnsutils + ]); +} diff --git a/common/home/tmux/default.nix b/common/home/tmux/default.nix new file mode 100644 index 00000000..88378c06 --- /dev/null +++ b/common/home/tmux/default.nix @@ -0,0 +1,31 @@ +{pkgs, ...}: { + 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 = with 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/common/home/trash-d/default.nix b/common/home/trash-d/default.nix new file mode 100644 index 00000000..5a867455 --- /dev/null +++ b/common/home/trash-d/default.nix @@ -0,0 +1,7 @@ +{pkgs, ...} @ inputs: let + trash = pkgs.callPackage ./trash-d.nix inputs; +in { + home.packages = [trash]; + + programs.bash.shellAliases.rm = "trash"; +} diff --git a/common/home/trash-d/trash-d.nix b/common/home/trash-d/trash-d.nix new file mode 100644 index 00000000..4c99ce09 --- /dev/null +++ b/common/home/trash-d/trash-d.nix @@ -0,0 +1,31 @@ +{ + trash-d-src, + stdenv, + dmd, + dub, + ronn, + ... +}: +stdenv.mkDerivation { + name = "trash"; + version = trash-d-src.shortRev; + + src = trash-d-src; + + buildInputs = [dub dmd ronn]; + + buildPhase = '' + # https://github.com/svanderburg/node2nix/issues/217#issuecomment-751311272 + export HOME=$(mktemp -d) + + dub build + ''; + + installPhase = '' + mkdir -p $out/bin $out/man/man1 + + cp -a ./build/trash $out/bin/ + + ronn --roff --pipe MANUAL.md > $out/man/man1/trash.1 + ''; +} diff --git a/common/modules/cachix.nix b/common/modules/cachix.nix new file mode 100644 index 00000000..682c2912 --- /dev/null +++ b/common/modules/cachix.nix @@ -0,0 +1,51 @@ +{ + config, + pkgs, + ... +}: { + environment.systemPackages = with pkgs; [ + (writeShellApplication { + name = "rebuild-no-cache"; + runtimeInputs = [config.nh.package]; + text = '' + nh os switch -- --option binary-caches "https://cache.nixos.org" "$@" + ''; + }) + ]; + + nix = { + settings = { + substituters = [ + "https://hyprland.cachix.org" + "https://nix-gaming.cachix.org" + # Nixpkgs-Wayland + "https://cache.nixos.org" + "https://nixpkgs-wayland.cachix.org" + "https://nix-community.cachix.org" + # Nix-community + "https://nix-community.cachix.org" + # Nh + "https://viperml.cachix.org" + # Caddy + "https://caddycf.cachix.org" + # Personal config cache + "https://cache.nelim.org" + ]; + trusted-public-keys = [ + "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" + "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=" + # Nixpkgs-Wayland + "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" + "nixpkgs-wayland.cachix.org-1:3lwxaILxMRkVhehr5StQprHdEo4IrE8sRho9R9HOLYA=" + # Nix-community + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + # Nh + "viperml.cachix.org-1:qZhKBMTfmcLL+OG6fj/hzsMEedgKvZVFRRAhq7j8Vh8=" + # Caddy + "caddycf.cachix.org-1:6vbQaeiec/zKv9XfEwi9yWVCe7opbeJMu6w81UEXugY=" + # Personal config cache + "cache.nelim.org:JmFqkUdH11EA9EZOFAGVHuRYp7EbsdJDHvTQzG2pPyY=" + ]; + }; + }; +} diff --git a/common/modules/default.nix b/common/modules/default.nix new file mode 100644 index 00000000..47f6f85e --- /dev/null +++ b/common/modules/default.nix @@ -0,0 +1,8 @@ +{...}: { + imports = [ + ./cachix.nix + ./locale.nix + ./locate.nix + ./global.nix + ]; +} diff --git a/common/modules/global.nix b/common/modules/global.nix new file mode 100644 index 00000000..e736b519 --- /dev/null +++ b/common/modules/global.nix @@ -0,0 +1,23 @@ +{ + config, + lib, + nixpkgs, + ... +}: let + inherit (config.sops.secrets) access-token; + inherit (lib) hasAttr optionalString; +in { + # Minimize dowloads of indirect nixpkgs flakes + nix = { + 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; +} diff --git a/common/modules/locale.nix b/common/modules/locale.nix new file mode 100644 index 00000000..6db81086 --- /dev/null +++ b/common/modules/locale.nix @@ -0,0 +1,39 @@ +{pkgs, ...}: { + fonts = { + fontconfig = { + enable = true; + defaultFonts = { + emoji = ["Noto Color Emoji"]; + monospace = ["Noto Nerd Font"]; + sansSerif = ["Noto Nerd Font"]; + serif = ["Noto Nerd Font"]; + }; + }; + + packages = with pkgs; [ + (nerdfonts.override { + fonts = [ + "JetBrainsMono" + "Go-Mono" + "Iosevka" + "NerdFontsSymbolsOnly" + "SpaceMono" + "Ubuntu" + "Noto" + ]; + }) + noto-fonts + noto-fonts-cjk + noto-fonts-emoji + liberation_ttf + font-awesome + meslo-lgs-nf + jetbrains-mono + ubuntu_font_family + ]; + }; + + # Select internationalisation properties. + i18n.defaultLocale = "en_CA.UTF-8"; + console.useXkbConfig = true; +} diff --git a/common/modules/locate.nix b/common/modules/locate.nix new file mode 100644 index 00000000..7c24ddf2 --- /dev/null +++ b/common/modules/locate.nix @@ -0,0 +1,79 @@ +{ + config, + pkgs, + lib, + ... +}: let + inherit (config.vars) mainUser; + cfg = config.services.locate; + + locateGroup = lib.getName cfg.package.name; + + locate = "${cfg.package}/bin/locate"; + updatedb = "${cfg.package}/bin/updatedb"; + + database = "/var/lib/locate/locatedb"; + pruneFS = builtins.concatStringsSep " " cfg.pruneFS; + pruneNames = builtins.concatStringsSep " " cfg.pruneNames; + prunePaths = builtins.concatStringsSep " " cfg.prunePaths; + + updatedbBin = '' + ${updatedb} -o ${database} --prunefs "${pruneFS}" \ + --prunepaths "${prunePaths}" --prunenames "${pruneNames}" + ''; +in { + users.users.${mainUser}.extraGroups = [ + locateGroup + ]; + + # TODO: add timer + systemd.services.locate = { + wantedBy = ["default.target"]; + serviceConfig = { + User = mainUser; + Group = locateGroup; + StateDirectory = "locate"; + StateDirectoryMode = "0770"; + ExecStart = updatedbBin; + }; + }; + + home-manager.users.${mainUser}.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; + localuser = null; + 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" + ]; + }; +} diff --git a/configurations/android/nix-on-droid.nix b/common/nix-on-droid.nix similarity index 63% rename from configurations/android/nix-on-droid.nix rename to common/nix-on-droid.nix index 3cc85ab6..0b350c18 100644 --- a/configurations/android/nix-on-droid.nix +++ b/common/nix-on-droid.nix @@ -1,19 +1,14 @@ { config, - self, + lib, + nur, ... }: { imports = [ - self.nixosModules.base-droid - { - roles.base = { - enable = true; - user = "nix-on-droid"; - }; - } - - self.nixosModules.tmux - {programs.tmux.enableCustomConf = true;} + ./vars + ./pkgs + ./modules/global.nix + nur.nixosModules.nur ]; nix = { @@ -29,39 +24,34 @@ # Nix-community "https://nix-community.cachix.org" - # Personal cache - "https://cache.nelim.org" + # FIXME: cache doesn't work + # Personal config cache + # "https://cache.nelim.org" ]; - trustedPublicKeys = [ # Nix-community "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" - - # Personal cache - "cache.nelim.org:JmFqkUdH11EA9EZOFAGVHuRYp7EbsdJDHvTQzG2pPyY=" + # Personal config cache + # "cache.nelim.org:JmFqkUdH11EA9EZOFAGVHuRYp7EbsdJDHvTQzG2pPyY=" ]; }; # Global hm settings home-manager.config = { imports = [ - self.homeManagerModules.neovim + # Make the vars be the same on Nix and HM { - programs.neovim = { - enable = true; - user = "nix-on-droid"; - - ideConfig = { - enableGolang = false; - enableJava = false; - enableNix = false; - enablePython = false; - }; + options.vars = lib.mkOption { + type = lib.types.attrs; + readOnly = true; + default = config.vars; }; } - self.homeManagerModules.shell - {programs.bash.enable = true;} + nur.hmModules.nur + + ./home + ./pkgs { programs.bash.sessionVariables = { @@ -83,9 +73,6 @@ # 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'"; diff --git a/common/overlays/default.nix b/common/overlays/default.nix new file mode 100644 index 00000000..5ccbd6cf --- /dev/null +++ b/common/overlays/default.nix @@ -0,0 +1,5 @@ +{nixpkgs-wayland, ...} @ inputs: [ + (import ./dracula-theme inputs) + + nixpkgs-wayland.overlay +] diff --git a/common/overlays/dracula-theme/default.nix b/common/overlays/dracula-theme/default.nix new file mode 100644 index 00000000..6076f967 --- /dev/null +++ b/common/overlays/dracula-theme/default.nix @@ -0,0 +1,46 @@ +{ + bat-theme-src, + gtk-theme-src, + xresources-theme-src, + ... +} @ inputs: (final: prev: { + dracula-theme = prev.dracula-theme.overrideAttrs (oldAttrs: let + git-colors = prev.callPackage ./git.nix inputs; + plymouth = prev.callPackage ./plymouth.nix inputs; + wallpaper = prev.fetchurl (import ./wallpaper.nix); + in { + version = gtk-theme-src.shortRev; + src = gtk-theme-src; + + installPhase = '' + runHook preInstall + + mkdir -p $out/share/plymouth/themes $out/wallpapers + cp -a ${wallpaper} $out/wallpapers/waves.png + + cp -a ${bat-theme-src}/Dracula.tmTheme $out/bat + cp -a ${git-colors}/git-colors $out/git-colors + cp -a ${plymouth}/share/plymouth/themes/dracula $out/share/plymouth/themes/ + cp -a ${xresources-theme-src}/Xresources $out/xres + + # ------------------------------------------- + mkdir -p $out/share/themes/Dracula + cp -a {assets,cinnamon,gnome-shell,gtk-2.0,gtk-3.0,gtk-3.20,gtk-4.0,index.theme,metacity-1,unity,xfwm4} $out/share/themes/Dracula + + cp -a kde/{color-schemes,plasma} $out/share/ + cp -a kde/kvantum $out/share/Kvantum + + mkdir -p $out/share/aurorae/themes + cp -a kde/aurorae/* $out/share/aurorae/themes/ + + mkdir -p $out/share/sddm/themes + cp -a kde/sddm/* $out/share/sddm/themes/ + + mkdir -p $out/share/icons/Dracula-cursors + mv kde/cursors/Dracula-cursors/index.theme $out/share/icons/Dracula-cursors/cursor.theme + mv kde/cursors/Dracula-cursors/cursors $out/share/icons/Dracula-cursors/cursors + + runHook postInstall + ''; + }); +}) diff --git a/common/overlays/dracula-theme/git.nix b/common/overlays/dracula-theme/git.nix new file mode 100644 index 00000000..7cdc4479 --- /dev/null +++ b/common/overlays/dracula-theme/git.nix @@ -0,0 +1,23 @@ +{ + stdenv, + git-theme-src, + ... +}: +stdenv.mkDerivation { + name = "dracula-git"; + version = git-theme-src.shortRev; + + src = git-theme-src; + + installPhase = '' + # Git colors + cp -a ./config/gitconfig ./git-colors + chmod 777 ./git-colors + + line=$(grep -n 'Dracula Dark Theme' ./git-colors | cut -d: -f1) + sed -i "1,$((line-1))d" ./git-colors + + mkdir $out + cp -a ./git-colors $out + ''; +} diff --git a/common/overlays/dracula-theme/plymouth.nix b/common/overlays/dracula-theme/plymouth.nix new file mode 100644 index 00000000..45318fa7 --- /dev/null +++ b/common/overlays/dracula-theme/plymouth.nix @@ -0,0 +1,20 @@ +{ + stdenv, + plymouth-theme-src, + ... +}: +stdenv.mkDerivation { + name = "dracula-plymouth"; + version = plymouth-theme-src.shortRev; + + src = plymouth-theme-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/ + ''; +} diff --git a/common/overlays/dracula-theme/wallpaper.nix b/common/overlays/dracula-theme/wallpaper.nix new file mode 100644 index 00000000..c1ae71e0 --- /dev/null +++ b/common/overlays/dracula-theme/wallpaper.nix @@ -0,0 +1,4 @@ +{ + url = "https://raw.githubusercontent.com/aynp/dracula-wallpapers/main/Art/4k/Waves%201.png"; + hash = "sha256-f9FwSOSvqTeDj4bOjYUQ6TM+/carCD9o5dhg/MnP/lk="; +} diff --git a/common/overlays/nix/patch b/common/overlays/nix/patch new file mode 100644 index 00000000..4b4bc053 --- /dev/null +++ b/common/overlays/nix/patch @@ -0,0 +1,12 @@ +diff --git a/src/libstore/path.cc b/src/libstore/path.cc +index e642abcd5..0e584ef33 100644 +--- a/src/libstore/path.cc ++++ b/src/libstore/path.cc +@@ -12,7 +12,7 @@ static void checkName(std::string_view path, std::string_view name) + if (!((c >= '0' && c <= '9') + || (c >= 'a' && c <= 'z') + || (c >= 'A' && c <= 'Z') +- || c == '+' || c == '-' || c == '.' || c == '_' || c == '?' || c == '=')) ++ || c == '+' || c == '-' || c == '.' || c == '_' || c == '?' || c == '=' || c == '!')) + throw BadStorePath("store path '%s' contains illegal character '%s'", path, c); + } diff --git a/packages/coloryou/LICENSE b/common/pkgs/coloryou/LICENSE similarity index 100% rename from packages/coloryou/LICENSE rename to common/pkgs/coloryou/LICENSE diff --git a/packages/coloryou/coloryou.py b/common/pkgs/coloryou/coloryou.py similarity index 98% rename from packages/coloryou/coloryou.py rename to common/pkgs/coloryou/coloryou.py index e796fde7..66c8efbb 100755 --- a/packages/coloryou/coloryou.py +++ b/common/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/common/pkgs/coloryou/default.nix b/common/pkgs/coloryou/default.nix new file mode 100644 index 00000000..537936f0 --- /dev/null +++ b/common/pkgs/coloryou/default.nix @@ -0,0 +1,19 @@ +{python3Packages, ...}: +python3Packages.buildPythonPackage { + pname = "coloryou"; + version = "0.0.1"; + + src = ./.; + + propagatedBuildInputs = with python3Packages; [utils material-color-utilities]; + + postInstall = '' + mv -v $out/bin/coloryou.py $out/bin/coloryou + ''; + + meta = { + description = '' + Get Material You colors from an image. + ''; + }; +} diff --git a/packages/coloryou/requirements.txt b/common/pkgs/coloryou/requirements.txt similarity index 100% rename from packages/coloryou/requirements.txt rename to common/pkgs/coloryou/requirements.txt diff --git a/common/pkgs/coloryou/setup.py b/common/pkgs/coloryou/setup.py new file mode 100644 index 00000000..24704abc --- /dev/null +++ b/common/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/common/pkgs/coloryou/shell.nix b/common/pkgs/coloryou/shell.nix new file mode 100644 index 00000000..5ac2d6d6 --- /dev/null +++ b/common/pkgs/coloryou/shell.nix @@ -0,0 +1,7 @@ +with import <nixpkgs> {}; +with pkgs.python311Packages; + buildPythonPackage { + name = "coloryou"; + src = ./.; + propagatedBuildInputs = [material-color-utilities utils]; + } diff --git a/common/pkgs/curseforge-server-downloader/default.nix b/common/pkgs/curseforge-server-downloader/default.nix new file mode 100644 index 00000000..667e048d --- /dev/null +++ b/common/pkgs/curseforge-server-downloader/default.nix @@ -0,0 +1,13 @@ +{ + buildGoModule, + curseforge-server-downloader-src, + ... +}: +buildGoModule { + pname = "curseforge-server-downloader"; + version = "unstable"; + + src = curseforge-server-downloader-src; + doCheck = false; + vendorHash = null; +} diff --git a/common/pkgs/default.nix b/common/pkgs/default.nix new file mode 100644 index 00000000..77d5d74f --- /dev/null +++ b/common/pkgs/default.nix @@ -0,0 +1,26 @@ +{ + lib, + pkgs, + ... +} @ inputs: let + inherit (lib) concatMapAttrs filterAttrs mkOption pathExists types; + + mkPackage = name: v: { + ${name} = pkgs.callPackage ./${name} inputs; + }; + + rmNotPackage = name: value: + value + == "directory" + && pathExists ./${name}/default.nix; + + packages = filterAttrs rmNotPackage (builtins.readDir ./.); + + pkgSet = concatMapAttrs mkPackage packages; +in { + options.customPkgs = mkOption { + type = types.attrs; + }; + + config.customPkgs = pkgSet; +} diff --git a/common/pkgs/pam-fprint-grosshack/default.nix b/common/pkgs/pam-fprint-grosshack/default.nix new file mode 100644 index 00000000..64b9c3fd --- /dev/null +++ b/common/pkgs/pam-fprint-grosshack/default.nix @@ -0,0 +1,41 @@ +{ + stdenv, + meson, + ninja, + pkg-config, + glib, + libfprint, + polkit, + dbus, + systemd, + pam, + libpam-wrapper, + pam-fprint-grosshack-src, + ... +}: +stdenv.mkDerivation { + name = "pam-fprint-grosshack"; + version = pam-fprint-grosshack-src.shortRev; + + src = pam-fprint-grosshack-src; + + 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/packages/pokemon-colorscripts/default.nix b/common/pkgs/pokemon-colorscripts/default.nix similarity index 62% rename from packages/pokemon-colorscripts/default.nix rename to common/pkgs/pokemon-colorscripts/default.nix index b0025068..c193638d 100644 --- a/packages/pokemon-colorscripts/default.nix +++ b/common/pkgs/pokemon-colorscripts/default.nix @@ -1,15 +1,12 @@ { - # nix build inputs - mkVersion, stdenv, - pokemon-colorscripts-src, - # deps python3Packages, + pokemon-colorscripts-src, ... }: stdenv.mkDerivation { - pname = "pokemon-colorscripts"; - version = mkVersion pokemon-colorscripts-src; + name = "pokemon-colorscripts"; + version = pokemon-colorscripts-src.shortRev; src = pokemon-colorscripts-src; @@ -27,11 +24,4 @@ stdenv.mkDerivation { 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/common/pkgs/rars-flatlaf/default.nix b/common/pkgs/rars-flatlaf/default.nix new file mode 100644 index 00000000..0a6585a3 --- /dev/null +++ b/common/pkgs/rars-flatlaf/default.nix @@ -0,0 +1,110 @@ +{ + config, + writeShellApplication, + stdenvNoCC, + jre, + fetchFromGitHub, + fetchurl, + makeWrapper, + makeDesktopItem, + rsync, + ... +}: +stdenvNoCC.mkDerivation rec { + name = "rars-flatlaf"; + + src = fetchFromGitHub { + owner = "privat"; + repo = "rars"; + rev = "fd34014efd65b3cb5a52f1729c3b8240cae0c332"; + hash = "sha256-D8X/cr+fnq/OOFYfMG9aPss95J8Z2yiROuF9kmHkK40="; + fetchSubmodules = true; + }; + + desktopItem = let + hyprland = config.home-manager.users.${config.vars.mainUser}.wayland.windowManager.hyprland.finalPackage; + execScript = writeShellApplication { + name = "execScript"; + runtimeInputs = [hyprland]; + text = "(sleep 1; hyprctl dispatch togglefloating) & ${name}"; + }; + in + makeDesktopItem { + name = "RARS"; + desktopName = "RARS"; + exec = "${execScript}/bin/execScript"; + icon = name; + }; + + nativeBuildInputs = [makeWrapper rsync jre]; + + installPhase = let + flatlaf = fetchurl { + url = "https://repo1.maven.org/maven2/com/formdev/flatlaf/3.2/flatlaf-3.2.jar"; + hash = "sha256-HAG+G9undDXWtySokKl7lkIUCFI7lEBduu+UgSVaxAA="; + }; + icon = fetchurl { + url = "https://riscv.or.jp/wp-content/uploads/2019/06/cropped-RISC-V-logo-figonly-mod-2.png"; + hash = "sha256-e1/iVmadVzyO77ikBr1cdXsJdDj8TiXh3Oyjek9GwqM="; + }; + in + /* + bash + */ + '' + # ./build-jar.sh + mkdir -p build + find src -name "*.java" | xargs javac --release 8 -d build + if [[ "$OSTYPE" == "darwin"* ]]; then + find src -type f -not -name "*.java" -exec rsync -R {} build \; + else + find src -type f -not -name "*.java" -exec cp --parents {} build \; + fi + cp -rf build/src/* build + rm -r build/src + cp README.md License.txt build + cd build + jar cfm ../rars.jar ./META-INF/MANIFEST.MF * + chmod +x ../rars.jar + + cd .. + + # ./build-jar-flatlaf.sh + mkdir -p build-flatlaf/ + cd build-flatlaf/ + + cp ${flatlaf} ../flatlaf.jar + + jar x < ../rars.jar + jar x < "../flatlaf.jar" + + cat > META-INF/MANIFEST.MF <<EOF + Manifest-Version: 1.0 + Implementation-Version: 3.1.1 + Multi-Release: true + Main-Class: rars.Launch + EOF + + jar cfm ../rars-flatlaf.jar META-INF/MANIFEST.MF * + chmod +x ../rars-flatlaf.jar + + cd .. + + # InstallPhase + runHook preInstall + + cat > ./rars.desktop <<EOF + EOF + + mkdir -p "$out/share/pixmaps" + cp "${icon}" "$out/share/pixmaps/${name}.png" + install -D $desktopItem/share/applications/* $out/share/applications/rars.desktop + + export JAR=$out/share/java/${name}/${name}.jar + install -D ./${name}.jar $JAR + makeWrapper ${jre}/bin/java $out/bin/${name} \ + --add-flags "-jar $JAR" + + runHook postInstall + ''; +} diff --git a/common/pkgs/repl/default.nix b/common/pkgs/repl/default.nix new file mode 100644 index 00000000..38c3b90a --- /dev/null +++ b/common/pkgs/repl/default.nix @@ -0,0 +1,26 @@ +# modified from https://github.com/gytis-ivaskevicius/flake-utils/plus +{ + coreutils, + gnused, + writeShellScriptBin, + ... +}: let + repl = ./repl.nix; + example = command: desc: ''\n\u001b[33m ${command}\u001b[0m - ${desc}''; +in + writeShellScriptBin "repl" '' + case "$1" in + "-h"|"--help"|"help") + printf "%b\n\e[4mUsage\e[0m: \ + ${example "repl" "Loads system flake if available."} \ + ${example "repl /path/to/flake.nix" "Loads specified flake."}\n" + ;; + *) + if [ -z "$1" ]; then + nix repl --arg flakePath $(${coreutils}/bin/readlink -f "/etc/nixos") --file ${repl} + else + nix repl --arg flakePath $(${coreutils}/bin/readlink -f $1 | ${gnused}/bin/sed 's|/flake.nix||') --file ${repl} + fi + ;; + esac + '' diff --git a/common/pkgs/repl/repl.nix b/common/pkgs/repl/repl.nix new file mode 100644 index 00000000..7f14583e --- /dev/null +++ b/common/pkgs/repl/repl.nix @@ -0,0 +1,49 @@ +{ + flakePath ? null, + hostnamePath ? "/etc/hostname", + registryPath ? /etc/nix/registry.json, +}: let + inherit (builtins) getFlake head match currentSystem readFile pathExists filter fromJSON; + + selfFlake = + if pathExists registryPath + then filter (it: it.from.id == "self") (fromJSON (readFile registryPath)).flakes + else []; + + flakePath' = + toString + ( + if flakePath != null + then flakePath + else if selfFlake != [] + then (head selfFlake).to.path + else "/etc/nixos" + ); + + flake = + if pathExists flakePath' + then getFlake flakePath' + else {}; + hostname = + if pathExists hostnamePath + then head (match "([a-zA-Z0-9\\-]+)\n" (readFile hostnamePath)) + else ""; + + nixpkgsFromInputsPath = flake.inputs.nixpkgs.outPath or ""; + nixpkgs = + flake.pkgs.${currentSystem}.nixpkgs + or ( + if nixpkgsFromInputsPath != "" + then import nixpkgsFromInputsPath {} + else {} + ); + + nixpkgsOutput = removeAttrs (nixpkgs // nixpkgs.lib or {}) ["options" "config"]; +in + {inherit flake;} + // flake + // builtins + // (flake.nixosConfigurations or {}) + // flake.nixosConfigurations.${hostname} or {} + // nixpkgsOutput + // {getFlake = path: getFlake (toString path);} diff --git a/common/vars/default.nix b/common/vars/default.nix new file mode 100644 index 00000000..7a724151 --- /dev/null +++ b/common/vars/default.nix @@ -0,0 +1,89 @@ +{ + config, + lib, + ... +}: let + inherit (lib) mkOption types; + flakeDir = config.environment.variables.FLAKE; + cfg = config.vars; +in { + options.vars = { + mainUser = mkOption { + type = types.str; + description = '' + Username that was defined at the initial setup process + ''; + }; + + hostName = mkOption { + type = types.str; + description = '' + Hostname that was defined at the initial setup process + ''; + }; + + promptMainColor = mkOption { + type = types.enum ["red" "green" "blue" "purple" "orange" "yellow" "cyan" "pink"]; + default = "purple"; + }; + + promptColors = mkOption { + description = '' + Colors used in starship prompt + ''; + + default = import ./prompt-schemes.nix cfg.promptMainColor; + + readOnly = true; + type = with types; + submodule { + options = { + textColor = mkOption {type = str;}; + firstColor = mkOption {type = str;}; + secondColor = mkOption {type = str;}; + thirdColor = mkOption {type = str;}; + fourthColor = mkOption {type = str;}; + }; + }; + }; + + configDir = mkOption { + type = types.str; + default = "${flakeDir}/devices/${cfg.hostName}/config"; + description = '' + The path to where most of the devices' configs are in the .nix folder + ''; + }; + + mainMonitor = mkOption { + type = types.str; + description = '' + The name of the main monitor used for Hyprland + and Regreet which also uses Hyprland + ''; + # This is to allow a bash script to know whether this value exists + default = "null"; + }; + + greetdDupe = mkOption { + type = types.bool; + description = '' + If we should duplicate regreet on all monitors + ''; + default = true; + }; + + fontSize = mkOption { + type = types.nullOr types.float; + }; + + neovimIde = mkOption { + type = types.bool; + default = true; + }; + }; + + config = { + environment.variables.FLAKE = lib.mkDefault "/home/${cfg.mainUser}/.nix"; + }; +} diff --git a/homeManagerModules/shell/prompt-schemes.nix b/common/vars/prompt-schemes.nix similarity index 90% rename from homeManagerModules/shell/prompt-schemes.nix rename to common/vars/prompt-schemes.nix index 98553684..a8d69385 100644 --- a/homeManagerModules/shell/prompt-schemes.nix +++ b/common/vars/prompt-schemes.nix @@ -1,6 +1,4 @@ -{color ? null}: let - inherit (builtins) attrNames removeAttrs; - +color: let schemes = { "purple" = { textColor = "#090c0c"; @@ -76,6 +74,4 @@ }; }; in - if ! isNull color - then schemes.${color} - else attrNames (removeAttrs schemes ["color"]) + schemes.${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/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/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 d9433cd6..00000000 --- a/configurations/binto/modules/gpu-replay/default.nix +++ /dev/null @@ -1,99 +0,0 @@ -{ - config, - lib, - mainUser, - pkgs, - ... -}: let - inherit (lib) concatStringsSep getExe removePrefix; - inherit (pkgs.selfPackages) gpu-screen-recorder; - - 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 gpu-screen-recorder.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 - - gpu-screen-recorder.gsr-dbus-server - 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/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 078dfd4a..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-Aa1nhA0MTv8XA9femdueDQh01iYwWsuMMLE+7BIHWlM="; -} 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/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/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 2cf7ae8e..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*" -exec rm -r {} + - find ./. -name "*Start*" -exec rm -r {} + - ''; - }); - }; - }; - - 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 be7aba0b..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/.version +++ /dev/null @@ -1 +0,0 @@ -25.18.1 diff --git a/configurations/homie/modules/home-assistant/netdaemon/HomeAssistantGenerated b/configurations/homie/modules/home-assistant/netdaemon/HomeAssistantGenerated deleted file mode 100644 index b218bdfb..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/HomeAssistantGenerated +++ /dev/null @@ -1,13779 +0,0 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// Generated using NetDaemon CodeGenerator nd-codegen v25.18.1.0 -// At: 2025-05-10T19:44:57.7189076-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<InputNumberEntities>(); - 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<UpdateEntities>(); - serviceCollection.AddTransient<WakeWordEntities>(); - serviceCollection.AddTransient<WeatherEntities>(); - serviceCollection.AddTransient<ZoneEntities>(); - serviceCollection.AddTransient<InputSelectEntities>(); - 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_select" => new InputSelectEntity(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; } - - InputNumberEntities InputNumber { 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; } - - UpdateEntities Update { get; } - - WakeWordEntities WakeWord { get; } - - WeatherEntities Weather { get; } - - ZoneEntities Zone { get; } - - InputSelectEntities InputSelect { 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 InputNumberEntities InputNumber => 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 UpdateEntities Update => new(_haContext); - public WakeWordEntities WakeWord => new(_haContext); - public WeatherEntities Weather => new(_haContext); - public ZoneEntities Zone => new(_haContext); - public InputSelectEntities InputSelect => 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 Mc200010838791059 => new(_haContext, "device_tracker.mc200_01_083879_1059"); - public DeviceTrackerEntity Mc20001142816Ce44 => new(_haContext, "device_tracker.mc200_01_142816_ce44"); - public DeviceTrackerEntity Mc200011516196ec5 => new(_haContext, "device_tracker.mc200_01_151619_6ec5"); - 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>Material You Style Upgrades</summary> - public InputBooleanEntity MaterialYouStyles => new(_haContext, "input_boolean.material_you_styles"); - ///<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 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"); - ///<summary>Material You Contrast Level</summary> - public InputNumberEntity MaterialYouContrast => new(_haContext, "input_number.material_you_contrast"); -} - -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"); - ///<summary>Material You Base Color</summary> - public InputTextEntity MaterialYouBaseColor => new(_haContext, "input_text.material_you_base_color"); -} - -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>Backup Backup Manager state</summary> - public SensorEntity BackupBackupManagerState => new(_haContext, "sensor.backup_backup_manager_state"); - ///<summary>Backup Last successful automatic backup</summary> - public SensorEntity BackupLastSuccessfulAutomaticBackup => new(_haContext, "sensor.backup_last_successful_automatic_backup"); - ///<summary>Backup Next scheduled automatic backup</summary> - public SensorEntity BackupNextScheduledAutomaticBackup => new(_haContext, "sensor.backup_next_scheduled_automatic_backup"); - ///<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 Mc200010838791059EstimatedDistance => new(_haContext, "sensor.mc200_01_083879_1059_estimated_distance"); - ///<summary>Estimated distance</summary> - public NumericSensorEntity Mc20001142816Ce44EstimatedDistance => new(_haContext, "sensor.mc200_01_142816_ce44_estimated_distance"); - ///<summary>Estimated distance</summary> - public NumericSensorEntity Mc200011516196ec5EstimatedDistance => new(_haContext, "sensor.mc200_01_151619_6ec5_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 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 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 InputSelectEntities -{ - private readonly IHaContext _haContext; - public InputSelectEntities(IHaContext haContext) - { - _haContext = haContext; - } - - /// <summary>Enumerates all input_select entities currently registered (at runtime) in Home Assistant as InputSelectEntity</summary> - public IEnumerable<InputSelectEntity> EnumerateAll() => _haContext.GetAllEntities().Where(e => e.EntityId.StartsWith("input_select.")).Select(e => new InputSelectEntity(e)); - ///<summary>Material You Scheme Name</summary> - public InputSelectEntity MaterialYouScheme => new(_haContext, "input_select.material_you_scheme"); -} - -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("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("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("assumed_state")] - public bool? AssumedState { get; init; } - - [JsonPropertyName("sp_device_id")] - public object? SpDeviceId { get; init; } - - [JsonPropertyName("sp_device_is_brand_sonos")] - public bool? SpDeviceIsBrandSonos { get; init; } - - [JsonPropertyName("sp_device_is_chromecast")] - public bool? SpDeviceIsChromecast { get; init; } - - [JsonPropertyName("sp_device_music_source")] - public object? SpDeviceMusicSource { get; init; } - - [JsonPropertyName("sp_device_name")] - public object? SpDeviceName { 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_has_web_player_credentials")] - public bool? SpUserHasWebPlayerCredentials { 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("volume_step")] - public double? VolumeStep { get; init; } - - [JsonPropertyName("sp_source_list_hide")] - public IReadOnlyList<object>? SpSourceListHide { get; init; } - - [JsonPropertyName("media_playlist")] - public string? MediaPlaylist { get; init; } - - [JsonPropertyName("sp_device_is_restricted")] - public bool? SpDeviceIsRestricted { get; init; } - - [JsonPropertyName("sp_play_time_remaining_est")] - public object? SpPlayTimeRemainingEst { 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; } -} - -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("friendly_name")] - public string? FriendlyName { get; init; } - - [JsonPropertyName("icon")] - public string? Icon { 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; } - - [JsonPropertyName("icon")] - public string? Icon { 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; } - - [JsonPropertyName("initial")] - public object? Initial { get; init; } - - [JsonPropertyName("editable")] - public bool? Editable { get; init; } - - [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("icon")] - public string? Icon { 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; } -} - -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("device_class")] - public string? DeviceClass { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { 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("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("device_class")] - public string? DeviceClass { get; init; } - - [JsonPropertyName("friendly_name")] - public string? FriendlyName { 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("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("fbdd0001-aa76-423a-b52f-6f74ecde9e3c_34987_1025")] - public double? Fbdd0001aa76423ab52f6f74ecde9e3c349871025 { get; init; } - - [JsonPropertyName("album_com.spotify.music")] - public string? AlbumCom_spotify_music { get; init; } - - [JsonPropertyName("artist_com.spotify.music")] - public string? ArtistCom_spotify_music { get; init; } - - [JsonPropertyName("duration_com.spotify.music")] - public double? DurationCom_spotify_music { get; init; } - - [JsonPropertyName("media_id_com.spotify.music")] - public string? MediaIdCom_spotify_music { get; init; } - - [JsonPropertyName("playback_position_com.spotify.music")] - public double? PlaybackPositionCom_spotify_music { get; init; } - - [JsonPropertyName("playback_state_com.spotify.music")] - public string? PlaybackStateCom_spotify_music { get; init; } - - [JsonPropertyName("title_com.spotify.music")] - public string? TitleCom_spotify_music { 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("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 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; } -} - -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 InputSelectEntity : Entity<InputSelectEntity, EntityState<InputSelectAttributes>, InputSelectAttributes>, IInputSelectEntityCore -{ - public InputSelectEntity(IHaContext haContext, string entityId) : base(haContext, entityId) - { - } - - public InputSelectEntity(IEntityCore entity) : base(entity) - { - } -} - -public partial record InputSelectAttributes -{ - [JsonPropertyName("options")] - public IReadOnlyList<string>? Options { 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 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> - ///<param name="preannounce">Play a sound before the announcement.</param> - ///<param name="preannounceMediaId">Custom media ID to play before the announcement.</param> - public void Announce(ServiceTarget target, string? message = null, string? mediaId = null, bool? preannounce = null, string? preannounceMediaId = null) - { - _haContext.CallService("assist_satellite", "announce", target, new AssistSatelliteAnnounceParameters { Message = message, MediaId = mediaId, Preannounce = preannounce, PreannounceMediaId = preannounceMediaId }); - } - - ///<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> - ///<param name="preannounce">Play a sound before the start message or media.</param> - ///<param name="preannounceMediaId">Custom media ID to play before the start message or media.</param> - public void StartConversation(ServiceTarget target, string? startMessage = null, string? startMediaId = null, string? extraSystemPrompt = null, bool? preannounce = null, string? preannounceMediaId = null) - { - _haContext.CallService("assist_satellite", "start_conversation", target, new AssistSatelliteStartConversationParameters { StartMessage = startMessage, StartMediaId = startMediaId, ExtraSystemPrompt = extraSystemPrompt, Preannounce = preannounce, PreannounceMediaId = preannounceMediaId }); - } -} - -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; } - - ///<summary>Play a sound before the announcement.</summary> - [JsonPropertyName("preannounce")] - public bool? Preannounce { get; init; } - - ///<summary>Custom media ID to play before the announcement.</summary> - [JsonPropertyName("preannounce_media_id")] - public string? PreannounceMediaId { 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; } - - ///<summary>Play a sound before the start message or media.</summary> - [JsonPropertyName("preannounce")] - public bool? Preannounce { get; init; } - - ///<summary>Custom media ID to play before the start message or media.</summary> - [JsonPropertyName("preannounce_media_id")] - public string? PreannounceMediaId { 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>Retrieves 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>Retrieves 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>Retrieves 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>Retrieves 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 viewPath, string? dashboardPath = 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="colorTempKelvin">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? colorTempKelvin = 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, ColorTempKelvin = colorTempKelvin, 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="colorTempKelvin">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? colorTempKelvin = 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, ColorTempKelvin = colorTempKelvin, 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("color_temp_kelvin")] - public object? ColorTempKelvin { 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("color_temp_kelvin")] - public object? ColorTempKelvin { 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> - ///<param name="preannounce">Play a sound before the announcement.</param> - ///<param name="preannounceMediaId">Custom media ID to play before the announcement.</param> - public static void Announce(this AssistSatelliteEntity target, string? message = null, string? mediaId = null, bool? preannounce = null, string? preannounceMediaId = null) - { - target.CallService("announce", new AssistSatelliteAnnounceParameters { Message = message, MediaId = mediaId, Preannounce = preannounce, PreannounceMediaId = preannounceMediaId }); - } - - ///<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> - ///<param name="preannounce">Play a sound before the announcement.</param> - ///<param name="preannounceMediaId">Custom media ID to play before the announcement.</param> - public static void Announce(this IEnumerable<AssistSatelliteEntity> target, string? message = null, string? mediaId = null, bool? preannounce = null, string? preannounceMediaId = null) - { - target.CallService("announce", new AssistSatelliteAnnounceParameters { Message = message, MediaId = mediaId, Preannounce = preannounce, PreannounceMediaId = preannounceMediaId }); - } - - ///<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> - ///<param name="preannounce">Play a sound before the start message or media.</param> - ///<param name="preannounceMediaId">Custom media ID to play before the start message or media.</param> - public static void StartConversation(this AssistSatelliteEntity target, string? startMessage = null, string? startMediaId = null, string? extraSystemPrompt = null, bool? preannounce = null, string? preannounceMediaId = null) - { - target.CallService("start_conversation", new AssistSatelliteStartConversationParameters { StartMessage = startMessage, StartMediaId = startMediaId, ExtraSystemPrompt = extraSystemPrompt, Preannounce = preannounce, PreannounceMediaId = preannounceMediaId }); - } - - ///<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> - ///<param name="preannounce">Play a sound before the start message or media.</param> - ///<param name="preannounceMediaId">Custom media ID to play before the start message or media.</param> - public static void StartConversation(this IEnumerable<AssistSatelliteEntity> target, string? startMessage = null, string? startMediaId = null, string? extraSystemPrompt = null, bool? preannounce = null, string? preannounceMediaId = null) - { - target.CallService("start_conversation", new AssistSatelliteStartConversationParameters { StartMessage = startMessage, StartMediaId = startMediaId, ExtraSystemPrompt = extraSystemPrompt, Preannounce = preannounce, PreannounceMediaId = preannounceMediaId }); - } -} - -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>Retrieves 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>Retrieves 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>Retrieves events on a calendar within a time range.</summary> - public static void GetEvents(this ICalendarEntityCore target, CalendarGetEventsParameters data) - { - target.CallService("get_events", data); - } - - ///<summary>Retrieves 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>Retrieves 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>Retrieves 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 InputSelectEntityExtensionMethods -{ - ///<summary>Selects the first option.</summary> - public static void SelectFirst(this IInputSelectEntityCore target, object? data = null) - { - target.CallService("select_first", data); - } - - ///<summary>Selects the first option.</summary> - public static void SelectFirst(this IEnumerable<IInputSelectEntityCore> target, object? data = null) - { - target.CallService("select_first", data); - } - - ///<summary>Selects the last option.</summary> - public static void SelectLast(this IInputSelectEntityCore target, object? data = null) - { - target.CallService("select_last", data); - } - - ///<summary>Selects the last option.</summary> - public static void SelectLast(this IEnumerable<IInputSelectEntityCore> target, object? data = null) - { - target.CallService("select_last", data); - } - - ///<summary>Selects the next option.</summary> - public static void SelectNext(this IInputSelectEntityCore target, InputSelectSelectNextParameters data) - { - target.CallService("select_next", data); - } - - ///<summary>Selects the next option.</summary> - public static void SelectNext(this IEnumerable<IInputSelectEntityCore> target, InputSelectSelectNextParameters data) - { - target.CallService("select_next", data); - } - - ///<summary>Selects the next option.</summary> - ///<param name="target">The IInputSelectEntityCore to call this service for</param> - ///<param name="cycle">If the option should cycle from the last to the first option on the list.</param> - public static void SelectNext(this IInputSelectEntityCore target, bool? cycle = null) - { - target.CallService("select_next", new InputSelectSelectNextParameters { Cycle = cycle }); - } - - ///<summary>Selects the next option.</summary> - ///<param name="target">The IEnumerable<IInputSelectEntityCore> to call this service for</param> - ///<param name="cycle">If the option should cycle from the last to the first option on the list.</param> - public static void SelectNext(this IEnumerable<IInputSelectEntityCore> target, bool? cycle = null) - { - target.CallService("select_next", new InputSelectSelectNextParameters { Cycle = cycle }); - } - - ///<summary>Selects an option.</summary> - public static void SelectOption(this IInputSelectEntityCore target, InputSelectSelectOptionParameters data) - { - target.CallService("select_option", data); - } - - ///<summary>Selects an option.</summary> - public static void SelectOption(this IEnumerable<IInputSelectEntityCore> target, InputSelectSelectOptionParameters data) - { - target.CallService("select_option", data); - } - - ///<summary>Selects an option.</summary> - ///<param name="target">The IInputSelectEntityCore to call this service for</param> - ///<param name="option">Option to be selected. eg: "Item A"</param> - public static void SelectOption(this IInputSelectEntityCore target, string option) - { - target.CallService("select_option", new InputSelectSelectOptionParameters { Option = option }); - } - - ///<summary>Selects an option.</summary> - ///<param name="target">The IEnumerable<IInputSelectEntityCore> to call this service for</param> - ///<param name="option">Option to be selected. eg: "Item A"</param> - public static void SelectOption(this IEnumerable<IInputSelectEntityCore> target, string option) - { - target.CallService("select_option", new InputSelectSelectOptionParameters { Option = option }); - } - - ///<summary>Selects the previous option.</summary> - public static void SelectPrevious(this IInputSelectEntityCore target, InputSelectSelectPreviousParameters data) - { - target.CallService("select_previous", data); - } - - ///<summary>Selects the previous option.</summary> - public static void SelectPrevious(this IEnumerable<IInputSelectEntityCore> target, InputSelectSelectPreviousParameters data) - { - target.CallService("select_previous", data); - } - - ///<summary>Selects the previous option.</summary> - ///<param name="target">The IInputSelectEntityCore to call this service for</param> - ///<param name="cycle">If the option should cycle from the first to the last option on the list.</param> - public static void SelectPrevious(this IInputSelectEntityCore target, bool? cycle = null) - { - target.CallService("select_previous", new InputSelectSelectPreviousParameters { Cycle = cycle }); - } - - ///<summary>Selects the previous option.</summary> - ///<param name="target">The IEnumerable<IInputSelectEntityCore> to call this service for</param> - ///<param name="cycle">If the option should cycle from the first to the last option on the list.</param> - public static void SelectPrevious(this IEnumerable<IInputSelectEntityCore> target, bool? cycle = null) - { - target.CallService("select_previous", new InputSelectSelectPreviousParameters { Cycle = cycle }); - } - - ///<summary>Sets the options.</summary> - public static void SetOptions(this IInputSelectEntityCore target, InputSelectSetOptionsParameters data) - { - target.CallService("set_options", data); - } - - ///<summary>Sets the options.</summary> - public static void SetOptions(this IEnumerable<IInputSelectEntityCore> target, InputSelectSetOptionsParameters data) - { - target.CallService("set_options", data); - } - - ///<summary>Sets the options.</summary> - ///<param name="target">The IInputSelectEntityCore to call this service for</param> - ///<param name="options">List of options. eg: ["Item A", "Item B", "Item C"]</param> - public static void SetOptions(this IInputSelectEntityCore target, IEnumerable<string> options) - { - target.CallService("set_options", new InputSelectSetOptionsParameters { Options = options }); - } - - ///<summary>Sets the options.</summary> - ///<param name="target">The IEnumerable<IInputSelectEntityCore> to call this service for</param> - ///<param name="options">List of options. eg: ["Item A", "Item B", "Item C"]</param> - public static void SetOptions(this IEnumerable<IInputSelectEntityCore> target, IEnumerable<string> options) - { - target.CallService("set_options", new InputSelectSetOptionsParameters { Options = options }); - } -} - -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="colorTempKelvin">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? colorTempKelvin = 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, ColorTempKelvin = colorTempKelvin, 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="colorTempKelvin">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? colorTempKelvin = 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, ColorTempKelvin = colorTempKelvin, 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="colorTempKelvin">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? colorTempKelvin = 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, ColorTempKelvin = colorTempKelvin, 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="colorTempKelvin">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? colorTempKelvin = 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, ColorTempKelvin = colorTempKelvin, 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 faab891c..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/apps/Frontend/BathroomLight/BathroomLight.cs +++ /dev/null @@ -1,103 +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), - new LightTurnOnParameters - { - ColorTempKelvin = 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 6ef4703e..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/default.nix +++ /dev/null @@ -1,45 +0,0 @@ -{ - config, - pkgs, - ... -}: let - inherit (builtins) attrValues; - 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 = [ - (pkgs.callPackage ./update.nix {}) - ]; -} 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 348f8f75..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.18.1", - "hash": "sha256-1cfjbK52djI/ZFnO4Nekrit3XxyXziOjRD/2Bg1dBFQ=" - }, - { - "pname": "NetDaemon.AppModel.SourceDeployedApps", - "version": "25.18.1", - "hash": "sha256-BqFvxJHMWisAKoaoZ3h+hu/6/1vFH3DapuXRTBkTPgw=" - }, - { - "pname": "NetDaemon.Client", - "version": "25.18.1", - "hash": "sha256-qSfjJraGDdu+oWmopoaYxIVEWsshobg3aK5UO4Iyzfw=" - }, - { - "pname": "NetDaemon.Extensions.Logging", - "version": "25.18.1", - "hash": "sha256-wuYFqFotZNWsPsRv+lMGAvfnjodC7BHVB0l8WZvcd4g=" - }, - { - "pname": "NetDaemon.Extensions.Scheduling", - "version": "25.18.1", - "hash": "sha256-i6itPddldpFz8L5HGHZK+LqYTMCk9oq57dgCFXOKaMM=" - }, - { - "pname": "NetDaemon.Extensions.Tts", - "version": "25.18.1", - "hash": "sha256-mrEaeO2SCBsO2XYxk1fz961yfncEL2FqydBuOpIpaZs=" - }, - { - "pname": "NetDaemon.HassModel", - "version": "25.18.1", - "hash": "sha256-lmA5rK8LPX1sNbKzRRMGwWu1iFPRJo7UI97gOE54VXg=" - }, - { - "pname": "NetDaemon.HassModel.Integration", - "version": "25.18.1", - "hash": "sha256-IsFWklSTa4rLi1TuFLoghzzz+g2dtgyfcUTh+zxn+v0=" - }, - { - "pname": "NetDaemon.Runtime", - "version": "25.18.1", - "hash": "sha256-fFiQv9TwKMZTaDWw11wCnnaulCExrK1t8Zy6AHdZJXM=" - }, - { - "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 cc04d1a7..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:28335e5f72a9a0c9801e9e46c90157a2a143771b59124bf9d2cc3789e4908986"; - hash = "sha256-OrSdEWD8fHDkme2TPPmqd/6FyWOMmf4flRNEghJfZnc="; - finalImageName = imageName; - finalImageTag = "25.18.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 cd480395..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.18.1" /> - <PackageReference Include="NetDaemon.AppModel.SourceDeployedApps" Version="25.18.1" /> - <PackageReference Include="NetDaemon.Runtime" Version="25.18.1" /> - <PackageReference Include="NetDaemon.HassModel" Version="25.18.1" /> - <PackageReference Include="NetDaemon.HassModel.Integration" Version="25.18.1" /> - <PackageReference Include="NetDaemon.Client" Version="25.18.1" /> - <PackageReference Include="NetDaemon.Extensions.Scheduling" Version="25.18.1" /> - <PackageReference Include="NetDaemon.Extensions.Logging" Version="25.18.1" /> - <PackageReference Include="NetDaemon.Extensions.Tts" Version="25.18.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/netdaemon/update.nix b/configurations/homie/modules/home-assistant/netdaemon/update.nix deleted file mode 100644 index 50c84823..00000000 --- a/configurations/homie/modules/home-assistant/netdaemon/update.nix +++ /dev/null @@ -1,73 +0,0 @@ -{ - # nix build inputs - writeShellApplication, - # deps - alejandra, - dos2unix, - dotnet-sdk_9, - findutils, - gnused, - nix, - ... -}: let - nixFetchDeps = - #nix - '' - let - config = (builtins.getFlake ("$FLAKE")).nixosConfigurations.homie; - inherit (config) pkgs; - - netdaemonConfig = pkgs.callPackage "$FLAKE/configurations/homie/modules/home-assistant/netdaemon/package.nix" {}; - in - netdaemonConfig.fetch-deps - ''; -in - writeShellApplication { - name = "bumpNetdaemonDeps"; - - runtimeInputs = [ - alejandra - dos2unix - dotnet-sdk_9 - findutils - gnused - nix - ]; - - 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=//' /run/secrets/netdaemon)" - 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/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/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 ab7932ba..00000000 --- a/configurations/nos/modules/comics/kapowarr/module.nix +++ /dev/null @@ -1,116 +0,0 @@ -{ - config, - lib, - kapowarr, - pkgs, - ... -}: let - inherit - (lib) - getExe - mkEnableOption - mkIf - mkOption - mkPackageOption - # optionalString - types - ; - - cfg = config.services.kapowarr; -in { - options.services.kapowarr = { - enable = mkEnableOption "kapowarr"; - package = mkPackageOption kapowarr.packages.${pkgs.system} "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 c9c746f5..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:dd1c4c2a361794fd22de1faf78357b236193172f8824093a0e31fa8038e16a41"; - hash = "sha256-XFcgllNndjMr35Z6oLQCumHZJqVgdoUITzTNSY0oh8M="; - 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 e7781ad6..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:53d3a4ec77f79fcf8f71b959fdf9fc59235a1dc8e064f5acd24edb0cc8b70325"; - hash = "sha256-1ueS/UOEy0N7dYZf7b+GEY+2q6yugv3omzY2cDjpzMo="; - 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 603d995d..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:e7e9c0b3470ebff1b693f3a0a3302eb02505e62d67fc1b42c86c2811b4c6e451"; - hash = "sha256-xtZoNaUY8wUtULhtlrljcqp+zPJ3KZGtE4ielPa/u4s="; - 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 7e1450eb..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:ac8ba074707a020b1a865ae6671f17b6110068142484cee9f36df02ed6c41130"; - hash = "sha256-rqbyDdWggMx+9iE1v2KBziEqW+G1/YsXCD0ZmzMItjo="; - 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 603d995d..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:e7e9c0b3470ebff1b693f3a0a3302eb02505e62d67fc1b42c86c2811b4c6e451"; - hash = "sha256-xtZoNaUY8wUtULhtlrljcqp+zPJ3KZGtE4ielPa/u4s="; - 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 4c1863a8..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:eea4469cd57e660e3bea8f29a51aeb66f05badb47b85d8b539a1011df2fde49a"; - hash = "sha256-foZJtjvhEwxsvYMaEniS4OUA6ou9led9x4z8j4yvk88="; - 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/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 05123661..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:f45063889794008cfc02fcf9d359b55fe37d1f8ebaf89653c89e1dd0e876eb7d"; - hash = "sha256-+wfQue+miBX+gNtOgs/UTWBMt2lriJcAGwhnr6QWzK8="; - 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/server.nix b/configurations/nos/modules/docker/immich/images/server.nix deleted file mode 100644 index e709fb88..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:6680d88486251b0264a78a1934fe82eef875555aa6d84d703a0980328a5d5c31"; - hash = "sha256-NGvRah2apg5j3/X7rCdq5DJc0dFB90/JksbmU49Twa8="; - 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 369df2b0..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:558d6ddf36cd87bac5d4fb2ee8488730c4f65718961ef4ca7073062378aa7641"; - hash = "sha256-cfxVm4w/NFH1JbSByNAV6/Q5DnYRVKbizd/7nE2zCY0="; - 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 474221de..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:683358900cff8d299fa93add731b2976d7c9bc49f9593f40f5351498fd488767"; - hash = "sha256-7IQbvKZuTgaOuFnoKAF9AD24C9ZMhn09Hsycrkt+vXY="; - 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/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 922f75db..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:85718606c75bc0924921cb2df05b0f81c8a691952d44a5bc9f9946254493d1b4"; - hash = "sha256-OGR0zlxmwNH240tCowKx3Xpx1nVSyMj1rn+TTt/lH3g="; - 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 f7595205..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:105b7ffb9e88880a55a3fcd6116542f19af21aae8884a4e276e007d2816bbacb"; - hash = "sha256-QGt0p5at2bWwC7bSDfsvg1mhmtu4H3fK834DXo6/U/Q="; - 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 c456750a..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:bae1b72ad55cee030a416aaaef1f20eee076e4c1c6d490689904d4609a2cabac"; - hash = "sha256-x5/G+VrJxaLoWEpSStwyOupw3B0PnIedcRQ33k5sm+s="; - 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 c3e1f12c..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:21468f5acb6d66b5abb0b78192e94a03ba1aef2ca0303f3800226363c0ee7cda"; - hash = "sha256-+0OcAbdyqCP3YT718Nr7r6EpxyrDOHGj3S6uGLI1q78="; - 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 04a10746..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:c15da6c91de8d2f436196f3a768483ad32c258ed4e1beb3d367a27ed67253e66"; - hash = "sha256-SRR76LnvDjAc7rZCmyGbfq84nsYvAixk0mwFA4QkNh4="; - 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/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 fa8828c2..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:5402d0a13eab398c7c38f1b90af081d7f9e5977606ed869cecdb661403f6586a"; - hash = "sha256-jxlKKWWubnN2AskHltA73d19IMCdaJgWJsq0fItPUBA="; - finalImageName = imageName; - finalImageTag = "15-alpine"; -} 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 9e73f904..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:f7c4b928848c9901a4b18663a0a89274e89c11637576218e356864d1d5e3218f"; - hash = "sha256-GroCx/MmVYwqSWX9DXbHw60AZVGL+4fDfYn6FFvZXMk="; - 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/qbittorrent/vuetorrent.nix b/configurations/nos/modules/qbittorrent/vuetorrent.nix deleted file mode 100644 index 4784f644..00000000 --- a/configurations/nos/modules/qbittorrent/vuetorrent.nix +++ /dev/null @@ -1,6 +0,0 @@ -# This file was autogenerated. DO NOT EDIT! -{ - version = "2.24.2"; - url = "https://github.com/VueTorrent/VueTorrent/releases/download/v2.24.2/vuetorrent.zip"; - hash = "sha256-QD9LYDm6LqexL9Me9mHXWPwCkbn5n9OVGh60PHSW9OA="; -} 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/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/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 3c3374cc..00000000 --- a/configurations/wim/default.nix +++ /dev/null @@ -1,129 +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; - quickshell.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/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/devShells/README.md b/devShells/README.md deleted file mode 100644 index dbb553e6..00000000 --- a/devShells/README.md +++ /dev/null @@ -1,20 +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. | -| `qml` | qml shell to be loaded by my Neovim config dynamically. | -| `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 f7a436d7..00000000 --- a/devShells/default.nix +++ /dev/null @@ -1,42 +0,0 @@ -{ - pkgs, - self, - ... -}: let - inherit (pkgs.lib) 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 e88c51e0..00000000 --- a/devShells/neovim-shells/default.nix +++ /dev/null @@ -1,31 +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 [ - "c-lang" - "csharp" - "json" - "kotlin" - "lua" - "markdown" - "qml" - "rust" - "web" - ] 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/devices/README.md b/devices/README.md new file mode 100644 index 00000000..6dd48e77 --- /dev/null +++ b/devices/README.md @@ -0,0 +1,39 @@ +# Devices + +This directory encompasses every device's main configuration file. + +## List of my Devices + +| Name | Description | +| ---------- | ------------------------------------------------------------------------------------------------------- | +| `android` | My [Nix-On-Droid](https://github.com/nix-community/nix-on-droid) configuration for my OnePlus 9 Pro | +| `binto` | My desktop PC with a multi-monitor setup and an NVIDIA (cringe) 3070 | +| `cluster` | Two Lenovo mini PCs that make use of [NixOS-pcsd](https://github.com/matt1432/nixos-pcsd) to form a cluster | +| `nos` | My custom built NAS | +| `oksys` | A very old Acer laptop that went from sailing the seas for years to becoming my web server and VPN host. It is now retired indefinitely. | +| `servivi` | A gaming PC in a previous life, it is now used to experiment and do heavier stuff | +| `wim` | My 2-1 Lenovo Laptop that I use for uni | + +## Global Vars + +In every device's `default.nix`, you'll find these [settings](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/common/vars.nix) + +```nix +# $FLAKE/devices/<name>/default.nix + +vars = { + mainUser = "matt"; + hostName = "wim"; + ... +}; +``` + +from these declared settings, I get access to global variables +that are different on each host using a 'let in' block: + +```nix +let + inherit (config.vars) mainUser ...; +in { + ... +``` diff --git a/devices/android/default.nix b/devices/android/default.nix new file mode 100644 index 00000000..9a117acf --- /dev/null +++ b/devices/android/default.nix @@ -0,0 +1,25 @@ +{ + home-manager, + nixpkgs, + ... +} @ inputs: rec { + extraSpecialArgs = inputs; + home-manager-path = home-manager.outPath; + pkgs = import nixpkgs { + system = "aarch64-linux"; + overlays = import ../../common/overlays inputs; + }; + + modules = [ + { + options = with pkgs.lib; { + environment.variables.FLAKE = mkOption { + type = with types; nullOr str; + }; + }; + } + {home-manager.extraSpecialArgs = inputs;} + ../../common/nix-on-droid.nix + ./nix-on-droid.nix + ]; +} diff --git a/devices/android/nix-on-droid.nix b/devices/android/nix-on-droid.nix new file mode 100644 index 00000000..a45d4aa4 --- /dev/null +++ b/devices/android/nix-on-droid.nix @@ -0,0 +1,47 @@ +{pkgs, ...}: { + vars = { + mainUser = "nix-on-droid"; + hostName = "localhost"; + neovimIde = false; + }; + + environment.variables.FLAKE = "/data/data/com.termux.nix/files/home/.nix"; + + terminal.font = "${(pkgs.nerdfonts.override { + fonts = [ + "JetBrainsMono" + ]; + })}/share/fonts/truetype/NerdFonts/JetBrainsMonoNerdFontMono-Regular.ttf"; + + environment.packages = with pkgs; [ + diffutils + findutils + utillinux + tzdata + hostname + man + gnugrep + ripgrep + gnupg + gnused + gnutar + bzip2 + gzip + xz + zip + unzip + openssh + perl + alejandra + ]; + + 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/devices/binto/config/hypr/main.conf b/devices/binto/config/hypr/main.conf new file mode 100644 index 00000000..a14b8e95 --- /dev/null +++ b/devices/binto/config/hypr/main.conf @@ -0,0 +1,6 @@ +# Cosmetic +general { + gaps_in = 10 + gaps_out = 20 + border_size = 0 +} diff --git a/devices/binto/default.nix b/devices/binto/default.nix new file mode 100644 index 00000000..6e4ea844 --- /dev/null +++ b/devices/binto/default.nix @@ -0,0 +1,62 @@ +{config, ...}: let + inherit (config.vars) mainUser hostName; +in { + imports = [ + ./hardware-configuration.nix + + ../../modules/ags + ../../modules/audio.nix + ../../modules/hyprland + ../../modules/kmscon.nix + ../../modules/printer.nix + ../../modules/razer.nix + ../../modules/sshd.nix + ../../modules/tailscale.nix + + ./modules/gpu-replay.nix + ./modules/nix-gaming.nix + ]; + + vars = { + mainUser = "matt"; + hostName = "binto"; + promptMainColor = "purple"; + mainMonitor = "desc:GIGA-BYTE TECHNOLOGY CO. LTD. G27QC 0x00000B1D"; + greetdDupe = false; + fontSize = 12.5; + }; + + users.users.${mainUser} = { + isNormalUser = true; + extraGroups = [ + "wheel" + "input" + "uinput" + "adm" + "video" + "libvirtd" + ]; + }; + home-manager.users.${mainUser} = { + imports = [ + ../../home/firefox + + ./home/packages.nix + ]; + + # No touchy + home.stateVersion = "23.11"; + }; + + networking = { + inherit hostName; + networkmanager.enable = true; + firewall.enable = false; + }; + + # Set your time zone. + time.timeZone = "America/Montreal"; + + # No touchy + system.stateVersion = "23.11"; +} diff --git a/configurations/binto/hardware-configuration.nix b/devices/binto/hardware-configuration.nix similarity index 55% rename from configurations/binto/hardware-configuration.nix rename to devices/binto/hardware-configuration.nix index 275e09e2..22d17470 100644 --- a/configurations/binto/hardware-configuration.nix +++ b/devices/binto/hardware-configuration.nix @@ -1,5 +1,6 @@ { config, + lib, modulesPath, pkgs, ... @@ -10,29 +11,14 @@ 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" - ]; + kernelParams = ["amd_pstate=active"]; kernelModules = ["kvm-amd"]; # Zenpower for ryzen cpu monitoring - extraModulePackages = builtins.attrValues { - inherit - (config.boot.kernelPackages) - v4l2loopback - zenpower - ; - }; + extraModulePackages = with config.boot.kernelPackages; [ + v4l2loopback + zenpower + ]; blacklistedKernelModules = ["k10temp"]; supportedFilesystems = ["ntfs"]; @@ -47,7 +33,7 @@ loader = { efi.canTouchEfiVariables = true; - timeout = 0; + timeout = 2; systemd-boot = { enable = true; @@ -59,20 +45,13 @@ fileSystems = { "/" = { - device = "/dev/disk/by-label/NIXROOT"; + device = "/dev/disk/by-uuid/560976b6-85e0-44ca-bb73-e15a78e9c449"; 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"]; + options = ["subvol=@"]; }; "/boot" = { - device = "/dev/disk/by-label/NIXBOOT"; + device = "/dev/disk/by-uuid/1407-A10C"; fsType = "vfat"; }; @@ -82,17 +61,9 @@ }; }; - swapDevices = [ - { - device = "/swap/swapfile"; - size = 16 * 1024; - } - ]; - zramSwap.enable = true; - hardware = { - cpu.amd.updateMicrocode = config.hardware.enableRedistributableFirmware; + cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; uinput.enable = true; }; @@ -100,13 +71,10 @@ libvirtd.enable = true; spiceUSBRedirection.enable = true; }; - environment.systemPackages = builtins.attrValues { - inherit - (pkgs) - qemu - virtiofsd - ; - }; + environment.systemPackages = with pkgs; [ + qemu + virtiofsd + ]; nvidia = { enable = true; diff --git a/devices/binto/home/packages.nix b/devices/binto/home/packages.nix new file mode 100644 index 00000000..cddf0af5 --- /dev/null +++ b/devices/binto/home/packages.nix @@ -0,0 +1,33 @@ +{...}: { + xdg.desktopEntries."com.github.iwalton3.jellyfin-media-player" = { + name = "Jellyfin Media Player"; + comment = "Desktop client for Jellyfin"; + exec = "jellyfinmediaplayer --platform xcb"; + icon = "com.github.iwalton3.jellyfin-media-player"; + terminal = false; + type = "Application"; + categories = ["AudioVideo" "Video" "Player" "TV"]; + settings = { + Version = "1.0"; + StartupWMClass = "jellyfin-media-player"; + }; + actions = { + "DesktopF" = { + name = "Desktop [Fullscreen]"; + exec = "jellyfinmediaplayer --fullscreen --desktop --platform xcb"; + }; + "DesktopW" = { + name = "Desktop [Windowed]"; + exec = "jellyfinmediaplayer --windowed --desktop --platform xcb"; + }; + "TVF" = { + name = "TV [Fullscreen]"; + exec = "jellyfinmediaplayer --fullscreen --tv --platform xcb"; + }; + "TVW" = { + name = "TV [Windowed]"; + exec = "jellyfinmediaplayer --windowed --tv --platform xcb"; + }; + }; + }; +} diff --git a/devices/binto/modules/gpu-replay.nix b/devices/binto/modules/gpu-replay.nix new file mode 100644 index 00000000..01be48be --- /dev/null +++ b/devices/binto/modules/gpu-replay.nix @@ -0,0 +1,114 @@ +{ + pkgs, + config, + lib, + gpu-screen-recorder-src, + ... +}: let + inherit (config.vars) mainUser mainMonitor; + inherit (lib) concatStringsSep removePrefix; + hyprPkgs = config.home-manager.users.${mainUser}.wayland.windowManager.hyprland.finalPackage; + + gsr = pkgs.stdenv.mkDerivation { + name = "gpu-screen-recorder"; + version = gpu-screen-recorder-src.shortRev; + + src = gpu-screen-recorder-src; + + nativeBuildInputs = with pkgs; [ + pkg-config + makeWrapper + ]; + + buildInputs = with pkgs; [ + libpulseaudio + ffmpeg + wayland + libdrm + libva + xorg.libXcomposite + xorg.libXrandr + ]; + + buildPhase = '' + ./build.sh + ''; + + installPhase = '' + strip gsr-kms-server + strip gpu-screen-recorder + + install -Dm755 "gsr-kms-server" "$out/bin/gsr-kms-server" + install -Dm755 "gpu-screen-recorder" "$out/bin/gpu-screen-recorder" + #install -Dm644 "extra/gpu-screen-recorder.service" "$out/lib/systemd/user/gpu-screen-recorder.service" + + wrapProgram $out/bin/gpu-screen-recorder --prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath [ + pkgs.addOpenGLRunpath.driverLink + pkgs.libglvnd + ]}" + ''; + }; +in { + security.wrappers = { + gpu-screen-recorder = { + owner = "root"; + group = "video"; + capabilities = "cap_sys_nice+ep"; + source = "${gsr}/bin/gpu-screen-recorder"; + }; + + gsr-kms-server = { + owner = "root"; + group = "video"; + capabilities = "cap_sys_admin+ep"; + source = "${gsr}/bin/gsr-kms-server"; + }; + }; + + home-manager.users.${mainUser} = { + home.packages = with pkgs; [ + gsr + + (writeShellApplication { + name = "gpu-save-replay"; + runtimeInputs = [procps]; + text = '' + pkill --signal SIGUSR1 -f gpu-screen-recorder + ''; + }) + + (writeShellApplication { + name = "gsr-start"; + runtimeInputs = [pulseaudio hyprPkgs xorg.xrandr]; + text = '' + main="${removePrefix "desc:" 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 " " [ + ''-v no'' + ''-r 1200'' + ''-mf yes'' + ''-o /home/matt/Videos/Replay'' + # Audio settings + ''-ac aac'' + ''-a "$(pactl get-default-sink).monitor"'' + ''-a "$(pactl get-default-source)"'' + # Video settings + ''-w "$WINDOW"'' + ''-f 60'' + ''-c mkv'' + ''-k hevc'' + ''-q very_high'' + ]} + ''; + }) + ]; + + wayland.windowManager.hyprland.settings = { + bind = [",F8, exec, ags -r 'GSR.saveReplay()'"]; + }; + }; +} diff --git a/devices/binto/modules/nix-gaming.nix b/devices/binto/modules/nix-gaming.nix new file mode 100644 index 00000000..37044017 --- /dev/null +++ b/devices/binto/modules/nix-gaming.nix @@ -0,0 +1,28 @@ +{ + nix-gaming, + pkgs, + ... +}: { + programs = { + steam = { + # Disable HW accel to fix flickers + enable = true; + remotePlay.openFirewall = true; + + extraCompatPackages = with pkgs; [ + proton-ge-bin + ]; + }; + }; + + environment.systemPackages = with pkgs; [ + (lutris.override { + extraLibraries = pkgs: [ + # List library dependencies here + ]; + extraPkgs = pkgs: [ + nix-gaming.packages.${pkgs.system}.wine-ge + ]; + }) + ]; +} diff --git a/devices/cluster/default.nix b/devices/cluster/default.nix new file mode 100644 index 00000000..d947f327 --- /dev/null +++ b/devices/cluster/default.nix @@ -0,0 +1,61 @@ +deviceName: {config, ...}: let + inherit (config.vars) mainUser hostName; + + clusterIP = config.services.pcsd.virtualIps.caddy-vip.ip; +in { + imports = [ + ./hardware-configuration.nix + + ../../modules/kmscon.nix + ../../modules/sshd.nix + ../../modules/tailscale.nix + + ./modules/pcsd.nix + ]; + + vars = { + mainUser = "matt"; + hostName = deviceName; + promptMainColor = + if deviceName == "thingone" + then "green" + else if deviceName == "thingtwo" + then "red" + else "purple"; + }; + + users.users.${mainUser} = { + isNormalUser = true; + extraGroups = [ + "wheel" + "adm" + ]; + }; + + home-manager.users.${mainUser} = { + imports = []; + + # No touchy + home.stateVersion = "24.05"; + }; + + networking = { + inherit hostName; + resolvconf.enable = true; + nameservers = [ + clusterIP + "1.0.0.1" + ]; + extraHosts = '' + 10.0.0.244 thingone + 10.0.0.159 thingtwo + ''; + firewall.enable = false; + }; + + # Set your time zone. + time.timeZone = "America/Montreal"; + + # No touchy + system.stateVersion = "24.05"; +} diff --git a/configurations/cluster/hardware-configuration.nix b/devices/cluster/hardware-configuration.nix similarity index 81% rename from configurations/cluster/hardware-configuration.nix rename to devices/cluster/hardware-configuration.nix index ae6d0ab3..a5b573a3 100644 --- a/configurations/cluster/hardware-configuration.nix +++ b/devices/cluster/hardware-configuration.nix @@ -33,13 +33,6 @@ 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"; @@ -48,7 +41,7 @@ swapDevices = [ { - device = "/swap/swapfile"; + device = "/var/lib/swapfile"; size = 16 * 1024; } ]; diff --git a/configurations/cluster/modules/blocky/default.nix b/devices/cluster/modules/blocky.nix similarity index 100% rename from configurations/cluster/modules/blocky/default.nix rename to devices/cluster/modules/blocky.nix diff --git a/devices/cluster/modules/caddy.nix b/devices/cluster/modules/caddy.nix new file mode 100644 index 00000000..065e90b0 --- /dev/null +++ b/devices/cluster/modules/caddy.nix @@ -0,0 +1,169 @@ +{ + caddy-plugins, + pkgs, + config, + ... +}: let + inherit (config.vars) mainUser; + inherit (config.sops) secrets; + + caddy = caddy-plugins.packages.${pkgs.system}.default; +in { + imports = [caddy-plugins.nixosModules.default]; + + # User stuff + environment.systemPackages = [caddy]; + users.users.${mainUser}.extraGroups = ["caddy"]; + + systemd.services.caddy.serviceConfig = { + EnvironmentFile = secrets.caddy-cloudflare.path; + + # For some reason the service + # doesn't shutdown normally + KillSignal = "SIGKILL"; + RestartKillSignal = "SIGKILL"; + }; + + services.caddy = { + enable = true; + enableReload = false; + package = caddy; + + virtualHosts = let + clusterIP = config.services.pcsd.virtualIps.caddy-vip.ip; + nosIP = "10.0.0.121"; + serviviIP = "10.0.0.249"; + in { + "nelim.org" = { + serverAliases = ["*.nelim.org"]; + extraConfig = '' + tls { + dns cloudflare {$CLOUDFLARE_API_TOKEN} + resolvers 1.0.0.1 + } + ''; + + subDomains = { + # Misc one-liners + vault.reverseProxy = "${nosIP}:8781"; + hauk.reverseProxy = "${nosIP}:3003"; + headscale.reverseProxy = "${clusterIP}:8085"; + jelly.reverseProxy = "${nosIP}:8097"; + + pcsd = { + extraConfig = '' + reverse_proxy https://${clusterIP}:2224 { + transport http { + tls_insecure_skip_verify + } + } + ''; + }; + + # Resume builder + resume.reverseProxy = "${nosIP}:3060"; + resauth.reverseProxy = "${nosIP}:3100"; + + # Nextcloud & Co + office.reverseProxy = "http://${nosIP}:8055"; + nextcloud = { + subDomainName = "cloud"; + 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 + ''; + reverseProxy = "${nosIP}:8042"; + }; + + forgejo = { + subDomainName = "git"; + reverseProxy = "${nosIP}:3000"; + }; + + nix-binary-cache = { + subDomainName = "cache"; + reverseProxy = "${serviviIP}:5000"; + }; + + calibre = { + subDomainName = "books"; + reverseProxy = "${nosIP}:8083"; + }; + + immich = { + subDomainName = "photos"; + reverseProxy = "${nosIP}:2283"; + }; + + # FreshRSS & Co + bridge.reverseProxy = "${nosIP}:3006"; + drss.reverseProxy = "${nosIP}:3007"; + freshrss = { + subDomainName = "rss"; + reverseProxy = "${nosIP}:2800"; + }; + + jellyseer = { + subDomainName = "seerr"; + reverseProxy = "${nosIP}:5055"; + }; + + gameyfin = { + subDomainName = "games"; + reverseProxy = "${nosIP}:8074"; + }; + + wgui.reverseProxy = "${nosIP}:51821"; + + lan = { + reverseProxy = "${nosIP}:3020"; + extraConfig = '' + redir /index.html / + ''; + + subDirectories = { + bazarr.reverseProxy = "${nosIP}:6767"; + bazarr-french = { + subDirName = "bafrr"; + reverseProxy = "${nosIP}:6766"; + }; + + prowlarr.reverseProxy = "${nosIP}:9696"; + radarr.reverseProxy = "${nosIP}:7878"; + sabnzbd.reverseProxy = "${nosIP}:8382"; + sonarr.reverseProxy = "${nosIP}:8989"; + calibre.reverseProxy = "${nosIP}:8580"; + + 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/devices/cluster/modules/headscale/completion.bash b/devices/cluster/modules/headscale/completion.bash new file mode 100644 index 00000000..ed608597 --- /dev/null +++ b/devices/cluster/modules/headscale/completion.bash @@ -0,0 +1,338 @@ +# bash completion V2 for headscale -*- shell-script -*- + +__headscale_debug() +{ + if [[ -n ${BASH_COMP_DEBUG_FILE-} ]]; then + echo "$*" >> "${BASH_COMP_DEBUG_FILE}" + fi +} + +# Macs have bash3 for which the bash-completion package doesn't include +# _init_completion. This is a minimal version of that function. +__headscale_init_completion() +{ + COMPREPLY=() + _get_comp_words_by_ref "$@" cur prev words cword +} + +# This function calls the headscale program to obtain the completion +# results and the directive. It fills the 'out' and 'directive' vars. +__headscale_get_completion_results() { + local requestComp lastParam lastChar args + + # Prepare the command to request completions for the program. + # Calling ${words[0]} instead of directly headscale allows handling aliases + args=("${words[@]:1}") + requestComp="${words[0]} __complete ${args[*]}" + + lastParam=${words[$((${#words[@]}-1))]} + lastChar=${lastParam:$((${#lastParam}-1)):1} + __headscale_debug "lastParam ${lastParam}, lastChar ${lastChar}" + + if [[ -z ${cur} && ${lastChar} != = ]]; then + # If the last parameter is complete (there is a space following it) + # We add an extra empty parameter so we can indicate this to the go method. + __headscale_debug "Adding extra empty parameter" + requestComp="${requestComp} ''" + fi + + # When completing a flag with an = (e.g., headscale -n=<TAB>) + # bash focuses on the part after the =, so we need to remove + # the flag part from $cur + if [[ ${cur} == -*=* ]]; then + cur="${cur#*=}" + fi + + __headscale_debug "Calling ${requestComp}" + # Use eval to handle any environment variables and such + out=$(eval "${requestComp}" 2>/dev/null) + + # Extract the directive integer at the very end of the output following a colon (:) + directive=${out##*:} + # Remove the directive + out=${out%:*} + if [[ ${directive} == "${out}" ]]; then + # There is not directive specified + directive=0 + fi + __headscale_debug "The completion directive is: ${directive}" + __headscale_debug "The completions are: ${out}" +} + +__headscale_process_completion_results() { + local shellCompDirectiveError=1 + local shellCompDirectiveNoSpace=2 + local shellCompDirectiveNoFileComp=4 + local shellCompDirectiveFilterFileExt=8 + local shellCompDirectiveFilterDirs=16 + local shellCompDirectiveKeepOrder=32 + + if (((directive & shellCompDirectiveError) != 0)); then + # Error code. No completion. + __headscale_debug "Received error from custom completion go code" + return + else + if (((directive & shellCompDirectiveNoSpace) != 0)); then + if [[ $(type -t compopt) == builtin ]]; then + __headscale_debug "Activating no space" + compopt -o nospace + else + __headscale_debug "No space directive not supported in this version of bash" + fi + fi + if (((directive & shellCompDirectiveKeepOrder) != 0)); then + if [[ $(type -t compopt) == builtin ]]; then + # no sort isn't supported for bash less than < 4.4 + if [[ ${BASH_VERSINFO[0]} -lt 4 || ( ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -lt 4 ) ]]; then + __headscale_debug "No sort directive not supported in this version of bash" + else + __headscale_debug "Activating keep order" + compopt -o nosort + fi + else + __headscale_debug "No sort directive not supported in this version of bash" + fi + fi + if (((directive & shellCompDirectiveNoFileComp) != 0)); then + if [[ $(type -t compopt) == builtin ]]; then + __headscale_debug "Activating no file completion" + compopt +o default + else + __headscale_debug "No file completion directive not supported in this version of bash" + fi + fi + fi + + # Separate activeHelp from normal completions + local completions=() + local activeHelp=() + __headscale_extract_activeHelp + + if (((directive & shellCompDirectiveFilterFileExt) != 0)); then + # File extension filtering + local fullFilter filter filteringCmd + + # Do not use quotes around the $completions variable or else newline + # characters will be kept. + for filter in ${completions[*]}; do + fullFilter+="$filter|" + done + + filteringCmd="_filedir $fullFilter" + __headscale_debug "File filtering command: $filteringCmd" + $filteringCmd + elif (((directive & shellCompDirectiveFilterDirs) != 0)); then + # File completion for directories only + + local subdir + subdir=${completions[0]} + if [[ -n $subdir ]]; then + __headscale_debug "Listing directories in $subdir" + pushd "$subdir" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 || return + else + __headscale_debug "Listing directories in ." + _filedir -d + fi + else + __headscale_handle_completion_types + fi + + __headscale_handle_special_char "$cur" : + __headscale_handle_special_char "$cur" = + + # Print the activeHelp statements before we finish + if ((${#activeHelp[*]} != 0)); then + printf "\n"; + printf "%s\n" "${activeHelp[@]}" + printf "\n" + + # The prompt format is only available from bash 4.4. + # We test if it is available before using it. + if (x=${PS1@P}) 2> /dev/null; then + printf "%s" "${PS1@P}${COMP_LINE[@]}" + else + # Can't print the prompt. Just print the + # text the user had typed, it is workable enough. + printf "%s" "${COMP_LINE[@]}" + fi + fi +} + +# Separate activeHelp lines from real completions. +# Fills the $activeHelp and $completions arrays. +__headscale_extract_activeHelp() { + local activeHelpMarker="_activeHelp_ " + local endIndex=${#activeHelpMarker} + + while IFS='' read -r comp; do + if [[ ${comp:0:endIndex} == $activeHelpMarker ]]; then + comp=${comp:endIndex} + __headscale_debug "ActiveHelp found: $comp" + if [[ -n $comp ]]; then + activeHelp+=("$comp") + fi + else + # Not an activeHelp line but a normal completion + completions+=("$comp") + fi + done <<<"${out}" +} + +__headscale_handle_completion_types() { + __headscale_debug "__headscale_handle_completion_types: COMP_TYPE is $COMP_TYPE" + + case $COMP_TYPE in + 37|42) + # Type: menu-complete/menu-complete-backward and insert-completions + # If the user requested inserting one completion at a time, or all + # completions at once on the command-line we must remove the descriptions. + # https://github.com/spf13/cobra/issues/1508 + local tab=$'\t' comp + while IFS='' read -r comp; do + [[ -z $comp ]] && continue + # Strip any description + comp=${comp%%$tab*} + # Only consider the completions that match + if [[ $comp == "$cur"* ]]; then + COMPREPLY+=("$comp") + fi + done < <(printf "%s\n" "${completions[@]}") + ;; + + *) + # Type: complete (normal completion) + __headscale_handle_standard_completion_case + ;; + esac +} + +__headscale_handle_standard_completion_case() { + local tab=$'\t' comp + + # Short circuit to optimize if we don't have descriptions + if [[ "${completions[*]}" != *$tab* ]]; then + IFS=$'\n' read -ra COMPREPLY -d '' < <(compgen -W "${completions[*]}" -- "$cur") + return 0 + fi + + local longest=0 + local compline + # Look for the longest completion so that we can format things nicely + while IFS='' read -r compline; do + [[ -z $compline ]] && continue + # Strip any description before checking the length + comp=${compline%%$tab*} + # Only consider the completions that match + [[ $comp == "$cur"* ]] || continue + COMPREPLY+=("$compline") + if ((${#comp}>longest)); then + longest=${#comp} + fi + done < <(printf "%s\n" "${completions[@]}") + + # If there is a single completion left, remove the description text + if ((${#COMPREPLY[*]} == 1)); then + __headscale_debug "COMPREPLY[0]: ${COMPREPLY[0]}" + comp="${COMPREPLY[0]%%$tab*}" + __headscale_debug "Removed description from single completion, which is now: ${comp}" + COMPREPLY[0]=$comp + else # Format the descriptions + __headscale_format_comp_descriptions $longest + fi +} + +__headscale_handle_special_char() +{ + local comp="$1" + local char=$2 + if [[ "$comp" == *${char}* && "$COMP_WORDBREAKS" == *${char}* ]]; then + local word=${comp%"${comp##*${char}}"} + local idx=${#COMPREPLY[*]} + while ((--idx >= 0)); do + COMPREPLY[idx]=${COMPREPLY[idx]#"$word"} + done + fi +} + +__headscale_format_comp_descriptions() +{ + local tab=$'\t' + local comp desc maxdesclength + local longest=$1 + + local i ci + for ci in ${!COMPREPLY[*]}; do + comp=${COMPREPLY[ci]} + # Properly format the description string which follows a tab character if there is one + if [[ "$comp" == *$tab* ]]; then + __headscale_debug "Original comp: $comp" + desc=${comp#*$tab} + comp=${comp%%$tab*} + + # $COLUMNS stores the current shell width. + # Remove an extra 4 because we add 2 spaces and 2 parentheses. + maxdesclength=$(( COLUMNS - longest - 4 )) + + # Make sure we can fit a description of at least 8 characters + # if we are to align the descriptions. + if ((maxdesclength > 8)); then + # Add the proper number of spaces to align the descriptions + for ((i = ${#comp} ; i < longest ; i++)); do + comp+=" " + done + else + # Don't pad the descriptions so we can fit more text after the completion + maxdesclength=$(( COLUMNS - ${#comp} - 4 )) + fi + + # If there is enough space for any description text, + # truncate the descriptions that are too long for the shell width + if ((maxdesclength > 0)); then + if ((${#desc} > maxdesclength)); then + desc=${desc:0:$(( maxdesclength - 1 ))} + desc+="…" + fi + comp+=" ($desc)" + fi + COMPREPLY[ci]=$comp + __headscale_debug "Final comp: $comp" + fi + done +} + +__start_headscale() +{ + local cur prev words cword split + + COMPREPLY=() + + # Call _init_completion from the bash-completion package + # to prepare the arguments properly + if declare -F _init_completion >/dev/null 2>&1; then + _init_completion -n =: || return + else + __headscale_init_completion -n =: || return + fi + + __headscale_debug + __headscale_debug "========= starting completion logic ==========" + __headscale_debug "cur is ${cur}, words[*] is ${words[*]}, #words[@] is ${#words[@]}, cword is $cword" + + # The user could have moved the cursor backwards on the command-line. + # We need to trigger completion from the $cword location, so we need + # to truncate the command-line ($words) up to the $cword location. + words=("${words[@]:0:$cword+1}") + __headscale_debug "Truncated words[*]: ${words[*]}," + + local out directive + __headscale_get_completion_results + __headscale_process_completion_results +} + +if [[ $(type -t compopt) = "builtin" ]]; then + complete -o default -F __start_headscale headscale +else + complete -o default -o nospace -F __start_headscale headscale +fi + +# ex: ts=4 sw=4 et filetype=sh diff --git a/configurations/cluster/modules/headscale/default.nix b/devices/cluster/modules/headscale/default.nix similarity index 69% rename from configurations/cluster/modules/headscale/default.nix rename to devices/cluster/modules/headscale/default.nix index 079bee36..ec469678 100644 --- a/configurations/cluster/modules/headscale/default.nix +++ b/devices/cluster/modules/headscale/default.nix @@ -1,18 +1,32 @@ { config, - mainUser, + headscale, + lib, + pkgs, ... }: let - inherit (config.networking) hostName; + inherit (builtins) readFile; + inherit (lib) mkAfter mkForce; + inherit (pkgs.writers) writeYAML; - clusterIP = (builtins.head config.services.pcsd.virtualIps).ip; + inherit (config.vars) mainUser hostName; + headscale-flake = headscale.packages.${pkgs.system}.headscale; + + clusterIP = config.services.pcsd.virtualIps.caddy-vip.ip; in { + environment.systemPackages = [headscale-flake]; users.users.${mainUser}.extraGroups = ["headscale"]; + home-manager.users.${mainUser} + .programs.bash.bashrcExtra = mkAfter (readFile ./completion.bash); + services.headscale = { enable = true; + package = headscale-flake; + }; - settings = { + environment.etc."headscale/config.yaml".source = mkForce ( + writeYAML "headscale.yaml" { server_url = "https://headscale.nelim.org"; listen_addr = "${clusterIP}:8085"; prefixes = { @@ -35,7 +49,7 @@ in { private_key_path = "/var/lib/headscale/private.key"; noise.private_key_path = "/var/lib/headscale/noise_private.key"; - dns = let + dns_config = let caddyIp = if hostName == "thingone" then "100.64.0.8" @@ -43,7 +57,7 @@ in { in { magic_dns = false; override_local_dns = true; - nameservers.global = [caddyIp]; + nameservers = [caddyIp]; }; log = { @@ -65,6 +79,6 @@ in { region_name = "montreal"; }; }; - }; - }; + } + ); } diff --git a/configurations/cluster/modules/nfs-client/default.nix b/devices/cluster/modules/nfs-client.nix similarity index 86% rename from configurations/cluster/modules/nfs-client/default.nix rename to devices/cluster/modules/nfs-client.nix index 34a2e86d..5f7e9743 100644 --- a/configurations/cluster/modules/nfs-client/default.nix +++ b/devices/cluster/modules/nfs-client.nix @@ -2,9 +2,7 @@ # NFS client setup services.rpcbind.enable = true; boot.supportedFilesystems = ["nfs"]; - environment.systemPackages = builtins.attrValues { - inherit (pkgs) nfs-utils; - }; + environment.systemPackages = with pkgs; [nfs-utils]; systemd.mounts = let host = "10.0.0.249"; diff --git a/configurations/cluster/modules/pcsd/default.nix b/devices/cluster/modules/pcsd.nix similarity index 61% rename from configurations/cluster/modules/pcsd/default.nix rename to devices/cluster/modules/pcsd.nix index dd262eaf..62a23514 100644 --- a/configurations/cluster/modules/pcsd/default.nix +++ b/devices/cluster/modules/pcsd.nix @@ -5,10 +5,19 @@ }: let inherit (config.sops) secrets; in { - imports = [pcsd.nixosModules.default]; + imports = [ + pcsd.nixosModules.default + + ./blocky.nix + ./caddy.nix + ./headscale + ./nfs-client.nix + ./unbound.nix + ]; services.pcsd = { enable = true; + enableBinaryCache = true; enableWebUI = true; clusterName = "thingies"; @@ -16,46 +25,39 @@ in { corosyncKeyFile = secrets.corosync.path; clusterUserPasswordFile = secrets.pcs-pass.path; - virtualIps = [ - { - id = "caddy-vip"; + virtualIps = { + "caddy-vip" = { ip = "10.0.0.130"; interface = "eno1"; group = "caddy-grp"; - } - ]; + }; + }; - systemdResources = [ - { - systemdName = "unbound"; + systemdResources = { + "unbound" = { enable = true; group = "caddy-grp"; - } + startAfter = ["caddy-vip"]; + }; - { - systemdName = "blocky"; + "blocky" = { enable = true; group = "caddy-grp"; - } + startAfter = ["unbound"]; + }; - { - systemdName = "headscale"; + "caddy" = { enable = true; group = "caddy-grp"; - } + startAfter = ["blocky"]; + }; - { - systemdName = "caddy"; + "headscale" = { enable = true; group = "caddy-grp"; - } - - { - systemdName = "searx"; - enable = true; - group = "caddy-grp"; - } - ]; + startAfter = ["caddy"]; + }; + }; nodes = [ { diff --git a/devices/cluster/modules/unbound.nix b/devices/cluster/modules/unbound.nix new file mode 100644 index 00000000..e2bc9703 --- /dev/null +++ b/devices/cluster/modules/unbound.nix @@ -0,0 +1,81 @@ +{config, ...}: let + inherit (config.vars) mainUser hostName; +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 = { + interface = ["127.0.0.1"]; + port = 5335; + + # Custom DNS + local-zone = [ + "headscale.nelim.org redirect" + "git.nelim.org redirect" + "mc.nelim.org transparent" + "cv.nelim.org transparent" + "mc2.nelim.org transparent" + "ota.nelim.org redirect" + "nelim.org redirect" + ]; + local-data = let + wanIP = "166.62.179.208"; + caddyIp = + if hostName == "thingone" + then "100.64.0.8" + else "100.64.0.9"; + in [ + "\"headscale.nelim.org. IN A ${wanIP}\"" + + "\"git.nelim.org. IN A ${wanIP}\"" + + "\"mc.nelim.org IN A 100.64.0.7\"" + "\"_minecraft._tcp.mc.nelim.org. 180 IN SRV 0 0 25569 mc.nelim.org.\"" + + "\"cv.nelim.org IN A 100.64.0.7\"" + "\"_minecraft._tcp.cv.nelim.org. 180 IN SRV 0 0 25566 cv.nelim.org.\"" + + "\"mc2.nelim.org IN A 100.64.0.7\"" + "\"_minecraft._tcp.mc2.nelim.org. 180 IN SRV 0 0 25560 mc2.nelim.org.\"" + + "\"ota.nelim.org. IN A 100.64.0.5\"" + + "\"nelim.org 0 A ${caddyIp}\"" + ]; + + 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/devices/nos/default.nix b/devices/nos/default.nix new file mode 100644 index 00000000..2d829683 --- /dev/null +++ b/devices/nos/default.nix @@ -0,0 +1,53 @@ +{config, ...}: let + inherit (config.vars) mainUser hostName; +in { + imports = [ + ./hardware-configuration.nix + + ../../modules/kmscon.nix + ../../modules/sshd.nix + ../../modules/tailscale.nix + + ./modules/arion + ./modules/jellyfin + ./modules/mergerfs.nix + ./modules/qbittorrent + ./modules/snapraid.nix + ./modules/subtitles/cleanup.nix + ./modules/subtitles/syncing.nix + ]; + + vars = { + mainUser = "matt"; + hostName = "nos"; + promptMainColor = "orange"; + }; + + users.users.${mainUser} = { + isNormalUser = true; + extraGroups = [ + "wheel" + "adm" + "borg" + ]; + }; + + home-manager.users.${mainUser} = { + imports = []; + + # No touchy + home.stateVersion = "24.05"; + }; + + networking = { + inherit hostName; + resolvconf.enable = true; + firewall.enable = false; + }; + + # Set your time zone. + time.timeZone = "America/Montreal"; + + # No touchy + system.stateVersion = "24.05"; +} diff --git a/configurations/homie/hardware-configuration.nix b/devices/nos/hardware-configuration.nix similarity index 72% rename from configurations/homie/hardware-configuration.nix rename to devices/nos/hardware-configuration.nix index 06c79aec..76aec6fc 100644 --- a/configurations/homie/hardware-configuration.nix +++ b/devices/nos/hardware-configuration.nix @@ -7,6 +7,17 @@ imports = [(modulesPath + "/installer/scan/not-detected.nix")]; boot = { + kernelModules = ["kvm-intel"]; + + initrd.availableKernelModules = [ + "xhci_pci" + "ahci" + "nvme" + "usbhid" + "usb_storage" + "sd_mod" + ]; + loader = { efi.canTouchEfiVariables = true; timeout = 2; @@ -17,15 +28,6 @@ configurationLimit = 30; }; }; - - initrd.availableKernelModules = [ - "xhci_pci" - "ahci" - "nvme" - "usbhid" - "usb_storage" - "sd_mod" - ]; }; fileSystems = { @@ -34,28 +36,18 @@ 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; + + nvidia = { + enable = true; + enableCUDA = true; + }; } diff --git a/devices/nos/modules/arion/default.nix b/devices/nos/modules/arion/default.nix new file mode 100644 index 00000000..729fca9f --- /dev/null +++ b/devices/nos/modules/arion/default.nix @@ -0,0 +1,36 @@ +{...}: let + configPath = "/var/lib/arion"; +in { + imports = [ + ./forgejo/compose.nix + ./freshrss/compose.nix + ./gameyfin/compose.nix + ./hauk/compose.nix + ./homepage/compose.nix + ./immich/compose.nix + ./music/jbots/compose.nix + ./nextcloud/compose.nix + ./resume/compose.nix + ./vaultwarden/compose.nix + ./wg-easy/compose.nix + + ./media/bazarr/compose.nix + ./media/calibre/compose.nix + ./media/joal/compose.nix + ./media/prowlarr/compose.nix + ./media/radarr/compose.nix + ./media/sabnzbd/compose.nix + ./media/seerr/compose.nix + ./media/sonarr/compose.nix + ]; + + arion = { + enable = true; + rwDataDir = configPath; + }; + + services.borgbackup.configs.arion = { + paths = [configPath]; + exclude = ["**/lineageos*"]; + }; +} diff --git a/devices/nos/modules/arion/forgejo/compose.nix b/devices/nos/modules/arion/forgejo/compose.nix new file mode 100644 index 00000000..e003464e --- /dev/null +++ b/devices/nos/modules/arion/forgejo/compose.nix @@ -0,0 +1,67 @@ +{config, ...}: let + inherit (config.sops) secrets; + inherit (config.arion) rwDataDir; + + rwPath = rwDataDir + "/forgejo"; +in { + arion.projects."forgejo" = { + "forgejo" = { + image = ./images/forgejo.nix; + + ports = [ + # Redirect WAN port 22 to this port + "2222:22" + "3000:3000" + ]; + + restart = "always"; + depends_on = ["forgejo-db"]; + + env_file = [secrets.forgejo.path]; + environment = { + APP_NAME = "Gitea"; + + # TODO: change ids + USER_UID = "1000"; + USER_GID = "1000"; + + 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 = ./images/postgres.nix; + + restart = "always"; + + env_file = [secrets.forgejo-db.path]; + + volumes = ["${rwPath}/db:/var/lib/postgresql/data"]; + }; + + "act_runner" = { + image = ./images/act_runner.nix; + privileged = true; + + 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"]; + }; + }; +} diff --git a/devices/nos/modules/arion/forgejo/images/act_runner.nix b/devices/nos/modules/arion/forgejo/images/act_runner.nix new file mode 100644 index 00000000..0c1442fe --- /dev/null +++ b/devices/nos/modules/arion/forgejo/images/act_runner.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "vegardit/gitea-act-runner"; + imageDigest = "sha256:f793df4ed40227cd66dfbba730a448c23f14d81bf9d17857a352011bf6c06907"; + sha256 = "1c05n1w9f06mcwgpmswclbba898bwsqhx1mdlmi97nphphp9bmq5"; + finalImageName = "vegardit/gitea-act-runner"; + finalImageTag = "dind-latest"; +} diff --git a/devices/nos/modules/arion/forgejo/images/forgejo.nix b/devices/nos/modules/arion/forgejo/images/forgejo.nix new file mode 100644 index 00000000..e01599ce --- /dev/null +++ b/devices/nos/modules/arion/forgejo/images/forgejo.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "codeberg.org/forgejo/forgejo"; + imageDigest = "sha256:7aa26f80fb574cf7dc886e180d1e86462bf4110fd1d5343af33264c18ae3a1b3"; + sha256 = "1ij5cwbs8mv67pimkp43ia0fxli2rr5agy08sq8yimxmz4ayd60l"; + finalImageName = "codeberg.org/forgejo/forgejo"; + finalImageTag = "1.21.10-0"; +} diff --git a/devices/nos/modules/arion/forgejo/images/postgres.nix b/devices/nos/modules/arion/forgejo/images/postgres.nix new file mode 100644 index 00000000..851ba948 --- /dev/null +++ b/devices/nos/modules/arion/forgejo/images/postgres.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "postgres"; + imageDigest = "sha256:6779d7a308f3c9c518a644ad9326be6149dc50352c91927725936a1115e09b0d"; + sha256 = "1qckzi60db6q3dw61qqpfj4xsf7fa92aaf5x7ra2ac5sm1kbhl3x"; + finalImageName = "postgres"; + finalImageTag = "14"; +} diff --git a/devices/nos/modules/arion/freshrss/compose.nix b/devices/nos/modules/arion/freshrss/compose.nix new file mode 100644 index 00000000..a8352514 --- /dev/null +++ b/devices/nos/modules/arion/freshrss/compose.nix @@ -0,0 +1,83 @@ +{ + config, + pkgs, + ... +}: let + inherit (config.sops) secrets; + inherit (config.arion) rwDataDir; + + rwPath = rwDataDir + "/freshrss"; +in { + arion.projects."freshrss" = { + "freshrss" = { + image = ./images/freshrss.nix; + restart = "always"; + + ports = ["2800:80"]; + extra_hosts = [ + "drss.nelim.org=10.0.0.130" + "bridge.nelim.org=10.0.0.130" + ]; + + 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 = ./images/postgres.nix; + restart = "always"; + + volumes = [ + "${rwPath}/db:/var/lib/postgresql/data" + ]; + + env_file = [secrets.freshrss.path]; + + environment = { + POSTGRES_DB = "\${DB_BASE:-freshrss}"; + POSTGRES_USER = "\${DB_USER:-freshrss}"; + POSTGRES_PASSWORD = "\${DB_PASSWORD:-freshrss}"; + }; + }; + + "docker-hub-rss" = { + image = ./images/docker-hub-rss.nix; + restart = "always"; + ports = ["3007:3000"]; + }; + + "rss-bridge" = { + image = ./images/rss-bridge.nix; + restart = "always"; + + volumes = [ + "${rwPath}/bridge:/config" + ]; + ports = ["3006:80"]; + }; + }; +} diff --git a/devices/nos/modules/arion/freshrss/images/docker-hub-rss.nix b/devices/nos/modules/arion/freshrss/images/docker-hub-rss.nix new file mode 100644 index 00000000..716f6e39 --- /dev/null +++ b/devices/nos/modules/arion/freshrss/images/docker-hub-rss.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "theconnman/docker-hub-rss"; + imageDigest = "sha256:3850badd3ebdb7d6583c8b67ebbcdd077b4e4ff2d8362ee31d78e334462d616f"; + sha256 = "0h4lldnfd8nrrh598bxvnykkzjyqa9hqjb57g694fpy1zpqvy266"; + finalImageName = "theconnman/docker-hub-rss"; + finalImageTag = "latest"; +} diff --git a/devices/nos/modules/arion/freshrss/images/freshrss.nix b/devices/nos/modules/arion/freshrss/images/freshrss.nix new file mode 100644 index 00000000..99a85493 --- /dev/null +++ b/devices/nos/modules/arion/freshrss/images/freshrss.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "freshrss/freshrss"; + imageDigest = "sha256:c554223f485843553f7b7c9faff1f5c6c6113ce15b0288dd07210e97d8bbbbcc"; + sha256 = "1vjsr0hfq5dfma2dll6jzkir14ii423nlvjjq6gq0mp9s19jidr7"; + finalImageName = "freshrss/freshrss"; + finalImageTag = "latest"; +} diff --git a/devices/nos/modules/arion/freshrss/images/postgres.nix b/devices/nos/modules/arion/freshrss/images/postgres.nix new file mode 100644 index 00000000..851ba948 --- /dev/null +++ b/devices/nos/modules/arion/freshrss/images/postgres.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "postgres"; + imageDigest = "sha256:6779d7a308f3c9c518a644ad9326be6149dc50352c91927725936a1115e09b0d"; + sha256 = "1qckzi60db6q3dw61qqpfj4xsf7fa92aaf5x7ra2ac5sm1kbhl3x"; + finalImageName = "postgres"; + finalImageTag = "14"; +} diff --git a/devices/nos/modules/arion/freshrss/images/rss-bridge.nix b/devices/nos/modules/arion/freshrss/images/rss-bridge.nix new file mode 100644 index 00000000..b78f6890 --- /dev/null +++ b/devices/nos/modules/arion/freshrss/images/rss-bridge.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "rssbridge/rss-bridge"; + imageDigest = "sha256:b543b93acf3c5e5f011b940352032aabc98221716fed57b4c7f902908731beae"; + sha256 = "1lk5x15dlgcyly0in9xhn7ibxp9hp2h65x9q3axhqiz28dkd176a"; + finalImageName = "rssbridge/rss-bridge"; + finalImageTag = "latest"; +} diff --git a/devices/nos/modules/arion/gameyfin/compose.nix b/devices/nos/modules/arion/gameyfin/compose.nix new file mode 100644 index 00000000..772a279a --- /dev/null +++ b/devices/nos/modules/arion/gameyfin/compose.nix @@ -0,0 +1,19 @@ +{config, ...}: let + inherit (config.sops) secrets; +in { + arion.projects."gameyfin"."gameyfin" = { + image = ./images/gameyfin.nix; + restart = "always"; + user = "1000:1000"; + + env_file = [secrets.gameyfin.path]; + environment.GAMEYFIN_USER = "mathis"; + + volumes = [ + "/data/games:/opt/gameyfin-library" + ]; + + expose = ["8080"]; + ports = ["8074:8080"]; + }; +} diff --git a/devices/nos/modules/arion/gameyfin/images/gameyfin.nix b/devices/nos/modules/arion/gameyfin/images/gameyfin.nix new file mode 100644 index 00000000..60798556 --- /dev/null +++ b/devices/nos/modules/arion/gameyfin/images/gameyfin.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "grimsi/gameyfin"; + imageDigest = "sha256:97842e65252e0854ccced478c10a007ee57e7a35c98c3cb26ecce9d0fd5be41c"; + sha256 = "19gbbaqg4n188piyh3lb54rfwz5xpj6f6fkvpqsbls3v9a4ambjw"; + finalImageName = "grimsi/gameyfin"; + finalImageTag = "latest"; +} diff --git a/devices/nos/modules/arion/hauk/compose.nix b/devices/nos/modules/arion/hauk/compose.nix new file mode 100644 index 00000000..5481423d --- /dev/null +++ b/devices/nos/modules/arion/hauk/compose.nix @@ -0,0 +1,9 @@ +{...}: { + arion.projects."hauk"."hauk" = { + image = ./images/hauk.nix; + restart = "always"; + ports = ["3003:80"]; + + volumes = ["${./config.php}:/etc/hauk/config.php:ro"]; + }; +} diff --git a/configurations/nos/modules/docker/hauk/config.php b/devices/nos/modules/arion/hauk/config.php similarity index 100% rename from configurations/nos/modules/docker/hauk/config.php rename to devices/nos/modules/arion/hauk/config.php diff --git a/configurations/nos/modules/docker/hauk/images/hauk.nix b/devices/nos/modules/arion/hauk/images/hauk.nix similarity index 77% rename from configurations/nos/modules/docker/hauk/images/hauk.nix rename to devices/nos/modules/arion/hauk/images/hauk.nix index fb95ab96..aa7a2663 100644 --- a/configurations/nos/modules/docker/hauk/images/hauk.nix +++ b/devices/nos/modules/arion/hauk/images/hauk.nix @@ -1,8 +1,8 @@ pkgs: -pkgs.dockerTools.pullImage rec { +pkgs.dockerTools.pullImage { imageName = "bilde2910/hauk"; imageDigest = "sha256:c7614b8340c25d91f32bfd00ebb92f81c05a4506410849e83d9102ba6304400e"; sha256 = "0dx7g8hrm4gz5bwd2v12l0hvyvbwrf9yiyqsn1pvw62ii8j721zp"; - finalImageName = imageName; + finalImageName = "bilde2910/hauk"; finalImageTag = "latest"; } diff --git a/devices/nos/modules/arion/homepage/compose.nix b/devices/nos/modules/arion/homepage/compose.nix new file mode 100644 index 00000000..d777ea25 --- /dev/null +++ b/devices/nos/modules/arion/homepage/compose.nix @@ -0,0 +1,62 @@ +{ + config, + pkgs, + ... +}: let + inherit (config.sops) secrets; + inherit (pkgs.writers) writeYAML; +in { + arion.projects."homepage"."homepage" = { + image = ./images/homepage.nix; + restart = "always"; + + ports = [ + "3020:3000" + ]; + + extra_hosts = ["lan.nelim.org=10.0.0.130"]; + + env_file = [secrets.homepage.path]; + + volumes = let + services = writeYAML "services.yaml" (import ./services.nix); + + bookmarks = writeYAML "bookmarks.yaml" {}; + + settings = writeYAML "settings.yaml" { + # FIXME: title not working + title = "bruh"; + theme = "dark"; + color = "gray"; + target = "_self"; + + layout.video = { + style = "columns"; + row = 4; + # columns = 2; + }; + }; + + widgets = writeYAML "widgets.yaml" [ + { + resources = { + cpu = true; + memory = true; + disk = "/"; + }; + } + { + search = { + provider = "duckduckgo"; + target = "_blank"; + }; + } + ]; + in [ + "${bookmarks}:/app/config/bookmarks.yaml:ro" + "${services}:/app/config/services.yaml:ro" + "${settings}:/app/config/settings.yaml:ro" + "${widgets}:/app/config/widgets.yaml:ro" + ]; + }; +} diff --git a/devices/nos/modules/arion/homepage/images/homepage.nix b/devices/nos/modules/arion/homepage/images/homepage.nix new file mode 100644 index 00000000..831125f0 --- /dev/null +++ b/devices/nos/modules/arion/homepage/images/homepage.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "ghcr.io/gethomepage/homepage"; + imageDigest = "sha256:13d1bf9c5cf7d2b0f3af90ddfe59302f32374b8f48a56c6f6afc2a475bf919df"; + sha256 = "12kzw2dvlfv78nh6y0iqygjndbizxra39kpsrif5026p2hjm4gyp"; + finalImageName = "ghcr.io/gethomepage/homepage"; + finalImageTag = "latest"; +} diff --git a/devices/nos/modules/arion/homepage/services.nix b/devices/nos/modules/arion/homepage/services.nix new file mode 100644 index 00000000..370e1112 --- /dev/null +++ b/devices/nos/modules/arion/homepage/services.nix @@ -0,0 +1,274 @@ +[ + ##################################################### + ## 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"; + }; + } + { + jellyseerr = rec { + href = "https://seerr.nelim.org"; + icon = "jellyseerr.png"; + description = "request handler"; + widget = { + type = "jellyseerr"; + url = href; + key = "{{HOMEPAGE_VAR_SEERR_API}}"; + }; + }; + } + { + gitea = { + href = "https://git.nelim.org"; + icon = "gitea.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}}"; + }; + }; + } + { + 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"; + }; + } + { + calibre-web = { + href = "https://books.nelim.org"; + icon = "calibreweb.png"; + description = "online library"; + }; + } + ]; + } + ##################################################### + ## 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}}"; + }; + }; + } + { + sabnzbd = rec { + href = "https://lan.nelim.org/sabnzbd"; + icon = "sabnzbd.png"; + description = "nzb client"; + widget = { + type = "sabnzbd"; + url = href; + key = "{{HOMEPAGE_VAR_SAB_API}}"; + }; + }; + } + { + 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}}"; + }; + }; + } + { + "bazarr french" = rec { + href = "https://lan.nelim.org/bafrr"; + icon = "bazarr.png"; + description = "fetches subs"; + widget = { + type = "bazarr"; + url = href; + key = "{{HOMEPAGE_VAR_BAZARRFR_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 = "boosts YGGTorrent ratio"; + }; + } + ]; + } + ##################################################### + ## MISC PROJECTS + ##################################################### + { + "misc projects" = [ + { + freshrss = { + href = "https://rss.nelim.org"; + icon = "freshrss.png"; + description = "rss client"; + }; + } + { + docker-hub-rss = { + href = "https://drss.nelim.org"; + icon = "freshrss.png"; + description = "dockerhub feed maker"; + }; + } + { + rss-bridge = { + href = "https://bridge.nelim.org"; + icon = "rss-bridge.png"; + description = "make rss feeds from anything"; + }; + } + { + calibre = { + href = "https://lan.nelim.org/calibre"; + icon = "calibre.png"; + description = "library backend"; + }; + } + ]; + } + ##################################################### + ## 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"; + }; + } + { + steampunk = { + 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"; + }; + }; + } + ]; + } +] diff --git a/devices/nos/modules/arion/immich/compose.nix b/devices/nos/modules/arion/immich/compose.nix new file mode 100644 index 00000000..436c9055 --- /dev/null +++ b/devices/nos/modules/arion/immich/compose.nix @@ -0,0 +1,89 @@ +{config, ...}: let + inherit (config.sops) secrets; + inherit (config.arion) rwDataDir; + + rwPath = rwDataDir + "/immich"; + + UPLOAD_LOCATION = "${rwPath}/data"; +in { + arion.projects."immich" = { + "immich_server" = { + image = ./images/server.nix; + command = ["start.sh" "immich"]; + env_file = [ + "${./env}" + secrets.immich.path + ]; + + volumes = [ + "${UPLOAD_LOCATION}:/usr/src/app/upload:rw" + ]; + ports = [ + "2283:3001" + ]; + + depends_on = ["immich_redis" "immich_postgres"]; + restart = "always"; + + environment.NODE_ENV = "production"; + }; + + "immich_microservices" = { + image = ./images/server.nix; + command = ["start.sh" "microservices"]; + env_file = [ + "${./env}" + secrets.immich.path + ]; + + volumes = [ + "${UPLOAD_LOCATION}:/usr/src/app/upload:rw" + ]; + + depends_on = ["immich_redis" "immich_postgres"]; + restart = "always"; + }; + + "immich_machine_learning" = { + image = ./images/machine-learning.nix; + restart = "always"; + env_file = [ + "${./env}" + secrets.immich.path + ]; + + volumes = [ + "${rwPath}/cache:/cache" + ]; + }; + + "immich_redis" = { + image = ./images/redis.nix; + restart = "always"; + tmpfs = ["/data"]; + env_file = [ + "${./env}" + secrets.immich.path + ]; + }; + + "immich_postgres" = { + image = ./images/postgres.nix; + restart = "always"; + env_file = [ + "${./env}" + secrets.immich.path + ]; + + volumes = [ + "${rwPath}/db:/var/lib/postgresql/data" + ]; + + environment = { + POSTGRES_PASSWORD = "\${DB_PASSWORD}"; + POSTGRES_USER = "\${DB_USERNAME}"; + POSTGRES_DB = "\${DB_DATABASE_NAME}"; + }; + }; + }; +} diff --git a/devices/nos/modules/arion/immich/env b/devices/nos/modules/arion/immich/env new file mode 100644 index 00000000..0b0431ed --- /dev/null +++ b/devices/nos/modules/arion/immich/env @@ -0,0 +1,5 @@ +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/devices/nos/modules/arion/immich/images/machine-learning.nix b/devices/nos/modules/arion/immich/images/machine-learning.nix new file mode 100644 index 00000000..6adfd243 --- /dev/null +++ b/devices/nos/modules/arion/immich/images/machine-learning.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "ghcr.io/immich-app/immich-machine-learning"; + imageDigest = "sha256:b0a22ca87496019f495ed5ce89df08da237e0987d389376b435b2226a8c29463"; + sha256 = "001nj0dsqzb3lhvjrm88wv3cmm5yx8wldw3i7kq1vs80gi4ckhs1"; + finalImageName = "ghcr.io/immich-app/immich-machine-learning"; + finalImageTag = "v1.101.0"; +} diff --git a/devices/nos/modules/arion/immich/images/postgres.nix b/devices/nos/modules/arion/immich/images/postgres.nix new file mode 100644 index 00000000..a998b568 --- /dev/null +++ b/devices/nos/modules/arion/immich/images/postgres.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "tensorchord/pgvecto-rs"; + imageDigest = "sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0"; + sha256 = "0h1s11z5d4svg2whm7gw11dwpddg5k90fp62q3zirycms787f4d3"; + finalImageName = "tensorchord/pgvecto-rs"; + finalImageTag = "pg14-v0.2.0"; +} diff --git a/configurations/nos/modules/docker/immich/images/redis.nix b/devices/nos/modules/arion/immich/images/redis.nix similarity index 100% rename from configurations/nos/modules/docker/immich/images/redis.nix rename to devices/nos/modules/arion/immich/images/redis.nix diff --git a/devices/nos/modules/arion/immich/images/server.nix b/devices/nos/modules/arion/immich/images/server.nix new file mode 100644 index 00000000..18839d9d --- /dev/null +++ b/devices/nos/modules/arion/immich/images/server.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "ghcr.io/immich-app/immich-server"; + imageDigest = "sha256:0097562444db38ebd2e5f98e71bd27dc6dd69b7f786207f7d323febbf99b8f93"; + sha256 = "09iyqs2fspi021005iw510b6xj87lfwimng84izbxvya7l312kb0"; + finalImageName = "ghcr.io/immich-app/immich-server"; + finalImageTag = "v1.101.0"; +} diff --git a/devices/nos/modules/arion/lineageos/Caddyfile b/devices/nos/modules/arion/lineageos/Caddyfile new file mode 100755 index 00000000..923d9210 --- /dev/null +++ b/devices/nos/modules/arion/lineageos/Caddyfile @@ -0,0 +1,7 @@ +ota.nelim.org { + tls matt@nelim.org { + dns cloudflare {env.CLOUDFLARE_API_TOKEN} + resolvers 1.0.0.1 + } + reverse_proxy lineageOTA +} diff --git a/devices/nos/modules/arion/lineageos/compose.nix b/devices/nos/modules/arion/lineageos/compose.nix new file mode 100644 index 00000000..499e627f --- /dev/null +++ b/devices/nos/modules/arion/lineageos/compose.nix @@ -0,0 +1,74 @@ +{config, ...}: let + inherit (config.sops) secrets; + inherit (config.arion) rwDataDir; + + rwPath = rwDataDir + "/lineageos"; +in { + # FIXME: crashes when building + # TODO: make sure it works with latest arion custom module + + arion.projects."lineageos" = { + "builder" = { + image = "lineageos4microg/docker-lineage-cicd"; + container_name = "lineage_builder"; + + environment = { + BRANCH_NAME = "lineage-20.0"; + DEVICE_LIST = "lemonadep"; + SIGN_BUILDS = "true"; + SIGNATURE_SPOOFING = "restricted"; + WITH_GMS = "true"; + ZIP_SUBDIR = "false"; + OTA_URL = "https://ota.nelim.org/api"; + CUSTOM_PACKAGES = "AuroraStore AvesLibre Droidify MJPdfReader Mull OpenCalc"; + INCLUDE_PROPRIETARY = "false"; + PARALLEL_JOBS = 6; + CLEAN_AFTER_BUILD = "false"; + CCACHE_SIZE = "200G"; + }; + + volumes = [ + "${rwPath}/lineage/src:/srv/src" + "${rwPath}/lineage/zips:/srv/zips" + "${rwPath}/lineage/logs:/srv/logs" + "${rwPath}/lineage/cache:/srv/ccache" + "${rwPath}/lineage/keys:/srv/keys" + + "${toString ./.}/manifests:/srv/local_manifests:ro" + "${toString ./.}/scripts:/srv/userscripts:ro" + "/etc/timezone:/etc/timezone:ro" + "/etc/localtime:/etc/localtime:ro" + ]; + }; + + "OTA-server" = { + container_name = "lineageOTA"; + image = "docker.io/julianxhokaxhiu/lineageota"; + volumes = [ + "${rwPath}/lineage/zips:/var/www/html/builds/full:ro" + ]; + }; + + "caddy" = { + image = "quay.io/slothcroissant/caddy-cloudflaredns:latest"; + + ports = [ + "80:80" + "443:443" + ]; + + volumes = [ + "${rwPath}/caddy/data:/data" + "${rwPath}/caddy/config:/config" + + "${toString ./.}/Caddyfile:/etc/caddy/Caddyfile:ro" + ]; + + env_file = [secrets.caddy-cloudflare.path]; + environment = { + CLOUDFLARE_EMAIL = "matt@nelim.rg"; + ACME_AGREE = "true"; + }; + }; + }; +} diff --git a/devices/nos/modules/arion/lineageos/manifests/manifests.xml b/devices/nos/modules/arion/lineageos/manifests/manifests.xml new file mode 100644 index 00000000..9bf67d86 --- /dev/null +++ b/devices/nos/modules/arion/lineageos/manifests/manifests.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<manifest> + <remote name="gitea" fetch="https://git.nelim.org/" /> + + <project name="matt1432/android_vendor_customs" path="vendor/alternatives" remote="gitea" revision="master" /> + + <project name="lineageos4microg/android_vendor_partner_gms" path="vendor/partner_gms" remote="github" revision="master" /> + <project name="matt1432/android_vendor_mulchwebview" path="vendor/mulch" remote="gitea" revision="main" /> + <project name="jgudec/android_vendor_lawnchair" path="vendor/lawnchair" remote="github" revision="13" /> +</manifest> diff --git a/devices/nos/modules/arion/lineageos/manifests/roomservice.xml b/devices/nos/modules/arion/lineageos/manifests/roomservice.xml new file mode 100644 index 00000000..c13ef8f9 --- /dev/null +++ b/devices/nos/modules/arion/lineageos/manifests/roomservice.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<manifest> + <project name="TheMuppets/proprietary_vendor_oneplus_lemonadep" path="vendor/oneplus/lemonadep" remote="github" revision="lineage-20" /> + <project name="TheMuppets/proprietary_vendor_oneplus_sm8350-common" path="vendor/oneplus/sm8350-common" remote="github" revision="lineage-20" /> + + <project name="LineageOS/android_device_oneplus_lemonadep" path="device/oneplus/lemonadep" remote="github" revision="lineage-20" /> + <project name="LineageOS/android_hardware_oplus" path="hardware/oplus" remote="github" revision="lineage-20" /> + <project name="LineageOS/android_kernel_oneplus_sm8350" path="kernel/oneplus/sm8350" remote="github" revision="lineage-20" /> + <project name="LineageOS/android_device_oneplus_sm8350-common" path="device/oneplus/sm8350-common" remote="github" revision="lineage-20" /> +</manifest> diff --git a/devices/nos/modules/arion/lineageos/scripts/before.sh b/devices/nos/modules/arion/lineageos/scripts/before.sh new file mode 100755 index 00000000..f60ced3a --- /dev/null +++ b/devices/nos/modules/arion/lineageos/scripts/before.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +## See here for AndroidAuto: https://github.com/sn-00-x/aa4mg + +## add MulchWebView +sed -i "1s;^;\$(call inherit-product-if-exists, vendor/mulch/mulch.mk)\n\n;" "/srv/src/LINEAGE_20_0/vendor/lineage/config/common.mk" + +## add lawnchair overlay to build +sed -i "1s;^;\$(call inherit-product-if-exists, vendor/lawnchair/lawnchair.mk)\n\n;" "/srv/src/LINEAGE_20_0/vendor/lineage/config/common.mk" + +## remove Trebuchet +sed -i 's/overrides.*/overrides: ["Home", "Launcher2", "Launcher3", "Launcher3QuickStep", "ParanoidQuickStep", "PixelLauncher", "TrebuchetQuickStep", "TrebuchetOverlay"],/' "/srv/src/LINEAGE_20_0/vendor/lawnchair/Android.bp" + +## only add needed packages from microg +echo "PRODUCT_PACKAGES += \\ + GmsCore \\ + GsfProxy \\ + FakeStore \\ + IchnaeaNlpBackend \\ + NominatimGeocoderBackend" > "/srv/src/LINEAGE_20_0/vendor/partner_gms/products/gms.mk" diff --git a/devices/nos/modules/arion/media/bazarr/compose.nix b/devices/nos/modules/arion/media/bazarr/compose.nix new file mode 100644 index 00000000..d7b9c155 --- /dev/null +++ b/devices/nos/modules/arion/media/bazarr/compose.nix @@ -0,0 +1,57 @@ +{config, ...}: let + inherit (config.arion) rwDataDir; + + rwPath = rwDataDir + "/media/bazarr"; +in { + arion.projects."bazarr" = { + "bazarr" = { + image = ./images/bazarr.nix; + restart = "always"; + + environment = { + PUID = "1000"; + PGID = "1000"; + TZ = "America/New_York"; + }; + + extra_hosts = ["lan.nelim.org=10.0.0.130"]; + ports = [ + "6767:6767" + ]; + + volumes = [ + "${rwPath}/data:/config" + "/data:/data" + ]; + + extraOptions = { + deploy.resources.limits.cpus = "0.5"; + }; + }; + + "bazarr-fr" = { + image = ./images/bazarr.nix; + restart = "always"; + + environment = { + PUID = "1000"; + PGID = "1000"; + TZ = "America/New_York"; + }; + + extra_hosts = ["lan.nelim.org=10.0.0.130"]; + ports = [ + "6766:6767" + ]; + + volumes = [ + "${rwPath}/data-fr:/config" + "/data:/data" + ]; + + extraOptions = { + deploy.resources.limits.cpus = "0.5"; + }; + }; + }; +} diff --git a/devices/nos/modules/arion/media/bazarr/images/bazarr.nix b/devices/nos/modules/arion/media/bazarr/images/bazarr.nix new file mode 100644 index 00000000..59a3d12b --- /dev/null +++ b/devices/nos/modules/arion/media/bazarr/images/bazarr.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "ghcr.io/linuxserver/bazarr"; + imageDigest = "sha256:91f7199dc40ccb1ef6667e3f834bbc2c64ade9a25ec3941f6d5d908bddcd145e"; + sha256 = "18pbdw6ivchk2fwh8h7w91jl3zcr02zfqcf44adb0bvf1dziw30x"; + finalImageName = "ghcr.io/linuxserver/bazarr"; + finalImageTag = "latest"; +} diff --git a/devices/nos/modules/arion/media/calibre/compose.nix b/devices/nos/modules/arion/media/calibre/compose.nix new file mode 100644 index 00000000..cac05854 --- /dev/null +++ b/devices/nos/modules/arion/media/calibre/compose.nix @@ -0,0 +1,52 @@ +{config, ...}: let + inherit (config.arion) rwDataDir; + + rwPath = rwDataDir + "/media/calibre"; +in { + arion.projects."calibre" = { + "calibre" = { + image = ./images/calibre.nix; + restart = "always"; + + environment = { + PUID = "1000"; + PGID = "1000"; + TZ = "America/New_York"; + + # WebUI vars + SUBFOLDER = "/calibre/"; + TITLE = "CalibreDB"; + NO_DECOR = "true"; + }; + + volumes = ["${rwPath}/data-db:/config"]; + + extra_hosts = ["lan.nelim.org=10.0.0.130"]; + ports = [ + "8580:8080" + #"8081:8081" + ]; + #network_mode = "host"; + }; + + "calibre-web" = { + image = ./images/calibre-web.nix; + restart = "always"; + + environment = { + PUID = "1000"; + PGID = "1000"; + TZ = "America/New_York"; + DOCKER_MODS = "linuxserver/mods:universal-calibre"; + }; + + volumes = [ + "${rwPath}/data-web:/config" + "${rwPath}/data-db/Calibre Library:/books" + ]; + + extra_hosts = ["lan.nelim.org=10.0.0.130"]; + ports = ["8083:8083"]; + }; + }; +} diff --git a/devices/nos/modules/arion/media/calibre/images/calibre-web.nix b/devices/nos/modules/arion/media/calibre/images/calibre-web.nix new file mode 100644 index 00000000..e1cfe623 --- /dev/null +++ b/devices/nos/modules/arion/media/calibre/images/calibre-web.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "ghcr.io/linuxserver/calibre-web"; + imageDigest = "sha256:584366bdcad9b3e9e1143d9ff5b012f684f32071d515f532953680af7fa43418"; + sha256 = "1x3bkb2fv9vs30wy9b324wm956nv3zzh1wzn0z08ml4bpncyx61s"; + finalImageName = "ghcr.io/linuxserver/calibre-web"; + finalImageTag = "latest"; +} diff --git a/devices/nos/modules/arion/media/calibre/images/calibre.nix b/devices/nos/modules/arion/media/calibre/images/calibre.nix new file mode 100644 index 00000000..cec16b19 --- /dev/null +++ b/devices/nos/modules/arion/media/calibre/images/calibre.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "ghcr.io/linuxserver/calibre"; + imageDigest = "sha256:b0c387456c059ead0d4cf76861d633c66b34a6b888ec5834d353951f1bde1384"; + sha256 = "1xaq1m8kcxvvi082lf8p6j48niqbivq61ddm3hilw4sjp9phq2a5"; + finalImageName = "ghcr.io/linuxserver/calibre"; + finalImageTag = "latest"; +} diff --git a/devices/nos/modules/arion/media/joal/compose.nix b/devices/nos/modules/arion/media/joal/compose.nix new file mode 100644 index 00000000..465046cd --- /dev/null +++ b/devices/nos/modules/arion/media/joal/compose.nix @@ -0,0 +1,22 @@ +{config, ...}: let + inherit (config.arion) rwDataDir; + + rwPath = rwDataDir + "/media/joal"; +in { + arion.projects."joal"."joal" = { + image = ./images/joal.nix; + restart = "always"; + + volumes = ["${rwPath}/data:/data"]; + extra_hosts = ["lan.nelim.org=10.0.0.130"]; + 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" + ]; + }; +} diff --git a/configurations/nos/modules/docker/media/joal/images/joal.nix b/devices/nos/modules/arion/media/joal/images/joal.nix similarity index 76% rename from configurations/nos/modules/docker/media/joal/images/joal.nix rename to devices/nos/modules/arion/media/joal/images/joal.nix index 79ad5139..2a55bf3f 100644 --- a/configurations/nos/modules/docker/media/joal/images/joal.nix +++ b/devices/nos/modules/arion/media/joal/images/joal.nix @@ -1,8 +1,8 @@ pkgs: -pkgs.dockerTools.pullImage rec { +pkgs.dockerTools.pullImage { imageName = "anthonyraymond/joal"; imageDigest = "sha256:832718170bd2d3da97de1216a6fd2f3caf2d5d56065336320780dadaf4952c1e"; sha256 = "03wqqhpsjcdgr4q3n9vqyxb59324mxnwn8jn6kj2kb6zq8bz3qrj"; - finalImageName = imageName; + finalImageName = "anthonyraymond/joal"; finalImageTag = "latest"; } diff --git a/devices/nos/modules/arion/media/prowlarr/compose.nix b/devices/nos/modules/arion/media/prowlarr/compose.nix new file mode 100644 index 00000000..afcd3851 --- /dev/null +++ b/devices/nos/modules/arion/media/prowlarr/compose.nix @@ -0,0 +1,39 @@ +{config, ...}: let + inherit (config.arion) rwDataDir; + + rwPath = rwDataDir + "/media/prowlarr"; +in { + arion.projects."prowlarr" = { + "prowlarr" = { + image = ./images/prowlarr.nix; + restart = "always"; + + environment = { + PUID = "1000"; + PGID = "1000"; + TZ = "America/New_York"; + }; + + volumes = ["${rwPath}/data:/config"]; + extra_hosts = ["lan.nelim.org=10.0.0.130"]; + ports = ["9696:9696"]; + }; + + "flaresolverr" = { + image = ./images/flaresolverr.nix; + restart = "always"; + + environment = { + LOG_LEVEL = "info"; + LOG_HTML = "false"; + CAPTCHA_SOLVER = "none"; + TZ = "America/New_York"; + }; + + extra_hosts = ["lan.nelim.org=10.0.0.130"]; + ports = ["8191:8191"]; + + depends_on = ["prowlarr"]; + }; + }; +} diff --git a/devices/nos/modules/arion/media/prowlarr/images/flaresolverr.nix b/devices/nos/modules/arion/media/prowlarr/images/flaresolverr.nix new file mode 100644 index 00000000..3b8d5763 --- /dev/null +++ b/devices/nos/modules/arion/media/prowlarr/images/flaresolverr.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "ghcr.io/flaresolverr/flaresolverr"; + imageDigest = "sha256:088412db1051d04ab32c902266510011aec1dc9f7a3a3bda3f58b93186591347"; + sha256 = "1x3s1qvzjz9kbxs829dyjp2m1fabmcvvi1n5z56j0dh1s0vcpb20"; + finalImageName = "ghcr.io/flaresolverr/flaresolverr"; + finalImageTag = "latest"; +} diff --git a/devices/nos/modules/arion/media/prowlarr/images/prowlarr.nix b/devices/nos/modules/arion/media/prowlarr/images/prowlarr.nix new file mode 100644 index 00000000..ee2dbe6d --- /dev/null +++ b/devices/nos/modules/arion/media/prowlarr/images/prowlarr.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "ghcr.io/linuxserver/prowlarr"; + imageDigest = "sha256:a77b1f5b22fed9fd726e49bfa6800897676a3eee030d5f194d7858cb858aa6d0"; + sha256 = "1dbpm8cxqydm21ybkz8rvqyga4q7hg36w6fh8qdmgb4w4f3mv7pj"; + finalImageName = "ghcr.io/linuxserver/prowlarr"; + finalImageTag = "latest"; +} diff --git a/devices/nos/modules/arion/media/radarr/compose.nix b/devices/nos/modules/arion/media/radarr/compose.nix new file mode 100644 index 00000000..52e685f0 --- /dev/null +++ b/devices/nos/modules/arion/media/radarr/compose.nix @@ -0,0 +1,28 @@ +{config, ...}: let + inherit (config.arion) rwDataDir; + + rwPath = rwDataDir + "/media/radarr"; +in { + arion.projects."radarr"."radarr" = { + image = ./images/radarr.nix; + restart = "always"; + + extra_hosts = ["lan.nelim.org=10.0.0.130"]; + ports = ["7878:7878"]; + + environment = { + PUID = "1000"; + PGID = "1000"; + TZ = "America/New_York"; + }; + + volumes = [ + "${rwPath}/data:/config" + "/data:/data" + ]; + + extraOptions = { + deploy.resources.limits.cpus = "0.5"; + }; + }; +} diff --git a/devices/nos/modules/arion/media/radarr/images/radarr.nix b/devices/nos/modules/arion/media/radarr/images/radarr.nix new file mode 100644 index 00000000..e25f92ed --- /dev/null +++ b/devices/nos/modules/arion/media/radarr/images/radarr.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "ghcr.io/linuxserver/radarr"; + imageDigest = "sha256:1afb332d12843163750a40a4e03b0a91b03db8831f9455cbb6fc06ebddbfa16e"; + sha256 = "13axfd2fwscy1s538hlhyvr8b1vrpw0akx3kwkmslhkc1fq62hq0"; + finalImageName = "ghcr.io/linuxserver/radarr"; + finalImageTag = "latest"; +} diff --git a/devices/nos/modules/arion/media/sabnzbd/compose.nix b/devices/nos/modules/arion/media/sabnzbd/compose.nix new file mode 100644 index 00000000..c56001ff --- /dev/null +++ b/devices/nos/modules/arion/media/sabnzbd/compose.nix @@ -0,0 +1,28 @@ +{config, ...}: let + inherit (config.arion) rwDataDir; + + rwPath = rwDataDir + "/media/sabnzbd"; +in { + arion.projects."sabnzbd"."sabnzbd" = { + image = ./images/sabnzbd.nix; + restart = "always"; + + extra_hosts = ["lan.nelim.org=10.0.0.130"]; + ports = ["8382:8082"]; + + environment = { + PUID = "1000"; + PGID = "1000"; + TZ = "America/New_York"; + }; + + volumes = [ + "${rwPath}/data:/config" + "/data:/data" + ]; + + extraOptions = { + deploy.resources.limits.cpus = "2"; + }; + }; +} diff --git a/devices/nos/modules/arion/media/sabnzbd/images/sabnzbd.nix b/devices/nos/modules/arion/media/sabnzbd/images/sabnzbd.nix new file mode 100644 index 00000000..2719f306 --- /dev/null +++ b/devices/nos/modules/arion/media/sabnzbd/images/sabnzbd.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "ghcr.io/linuxserver/sabnzbd"; + imageDigest = "sha256:5b8d05994df326db82f744469e4321d1b9f4feb52f5d217c06ad384d5c8377e2"; + sha256 = "192f86wa3z8khr7fh7cnd1nin5ilmp3bhw5faygnv9fh58ywipmn"; + finalImageName = "ghcr.io/linuxserver/sabnzbd"; + finalImageTag = "latest"; +} diff --git a/devices/nos/modules/arion/media/seerr/compose.nix b/devices/nos/modules/arion/media/seerr/compose.nix new file mode 100644 index 00000000..24c2e44e --- /dev/null +++ b/devices/nos/modules/arion/media/seerr/compose.nix @@ -0,0 +1,22 @@ +{config, ...}: let + inherit (config.arion) rwDataDir; + + rwPath = rwDataDir + "/media/seerr"; +in { + arion.projects."seerr"."seerr" = { + image = ./images/jellyseerr.nix; + restart = "always"; + + environment = { + LOG_LEVEL = "debug"; + TZ = "America/New_York"; + }; + + volumes = [ + "${rwPath}/data:/app/config" + ]; + + extra_hosts = ["lan.nelim.org=10.0.0.130"]; + ports = ["5055:5055"]; + }; +} diff --git a/devices/nos/modules/arion/media/seerr/images/jellyseerr.nix b/devices/nos/modules/arion/media/seerr/images/jellyseerr.nix new file mode 100644 index 00000000..3998f531 --- /dev/null +++ b/devices/nos/modules/arion/media/seerr/images/jellyseerr.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "fallenbagel/jellyseerr"; + imageDigest = "sha256:6dcdb5ba50913a14b2bd7df6388607ce175121f3416679c2746501256ac9f075"; + sha256 = "0bcs4dfw6n78yp1br0z5ra6bf6f5hppxrs86b3b6pszzlp3ijjfw"; + finalImageName = "fallenbagel/jellyseerr"; + finalImageTag = "latest"; +} diff --git a/devices/nos/modules/arion/media/sonarr/compose.nix b/devices/nos/modules/arion/media/sonarr/compose.nix new file mode 100644 index 00000000..8acb2b6c --- /dev/null +++ b/devices/nos/modules/arion/media/sonarr/compose.nix @@ -0,0 +1,28 @@ +{config, ...}: let + inherit (config.arion) rwDataDir; + + rwPath = rwDataDir + "/media/sonarr"; +in { + arion.projects."sonarr"."sonarr" = { + image = ./images/sonarr.nix; + restart = "always"; + + extra_hosts = ["lan.nelim.org=10.0.0.130"]; + ports = ["8989:8989"]; + + environment = { + PUID = "1000"; + PGID = "1000"; + TZ = "America/New_York"; + }; + + volumes = [ + "${rwPath}/data:/config" + "/data:/data" + ]; + + extraOptions = { + deploy.resources.limits.cpus = "0.5"; + }; + }; +} diff --git a/devices/nos/modules/arion/media/sonarr/images/sonarr.nix b/devices/nos/modules/arion/media/sonarr/images/sonarr.nix new file mode 100644 index 00000000..5c7bd44b --- /dev/null +++ b/devices/nos/modules/arion/media/sonarr/images/sonarr.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "ghcr.io/linuxserver/sonarr"; + imageDigest = "sha256:f11f32d67bb7ef20333e22546b04a244e4e8172cb9744b026381cf898a1f2ece"; + sha256 = "02mlalvi577ggb9ia2wggxnm8kwz92dsh9v98qq3y0zpsizyr4gn"; + finalImageName = "ghcr.io/linuxserver/sonarr"; + finalImageTag = "latest"; +} diff --git a/devices/nos/modules/arion/music/jbots/compose.nix b/devices/nos/modules/arion/music/jbots/compose.nix new file mode 100644 index 00000000..06ea6484 --- /dev/null +++ b/devices/nos/modules/arion/music/jbots/compose.nix @@ -0,0 +1,29 @@ +{config, ...}: let + inherit (config.arion) rwDataDir; + + rwPath = rwDataDir + "/music/jbots"; +in { + arion.projects."jbots" = { + "musicbot_be" = { + container_name = "benis"; + image = ./images/jmusicbot.nix; + restart = "always"; + + volumes = [ + "${rwPath}/be/config.txt:/jmb/config/config.txt:ro" + "${rwPath}/be/playlists:/jmb/config/playlists:rw" + ]; + }; + + "musicbot_br" = { + container_name = "bruh"; + image = ./images/jmusicbot.nix; + restart = "always"; + + volumes = [ + "${rwPath}/br/config.txt:/jmb/config/config.txt:ro" + "${rwPath}/br/playlists:/jmb/config/playlists:rw" + ]; + }; + }; +} diff --git a/devices/nos/modules/arion/music/jbots/images/jmusicbot.nix b/devices/nos/modules/arion/music/jbots/images/jmusicbot.nix new file mode 100644 index 00000000..286715b5 --- /dev/null +++ b/devices/nos/modules/arion/music/jbots/images/jmusicbot.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "craumix/jmusicbot"; + imageDigest = "sha256:361930342510033352a489bcfa0e2eda86de5b33f4057cd4ce2c2cbe1616ea11"; + sha256 = "0rb1nrjinpiyavybclghbizqzg2jy0yrldb0qanfnf9qyr2p7k08"; + finalImageName = "craumix/jmusicbot"; + finalImageTag = "latest"; +} diff --git a/devices/nos/modules/arion/nextcloud/compose.nix b/devices/nos/modules/arion/nextcloud/compose.nix new file mode 100644 index 00000000..34b80cf9 --- /dev/null +++ b/devices/nos/modules/arion/nextcloud/compose.nix @@ -0,0 +1,106 @@ +{ + config, + lib, + ... +}: let + inherit (config.sops) secrets; + inherit (config.arion) rwDataDir; + inherit (lib) concatStrings; + + rwPath = rwDataDir + "/nextcloud"; +in { + arion.projects."nextcloud" = { + "app-server" = { + image = ./images/nextcloud.nix; + restart = "always"; + + expose = [ + "80" + "9000" + ]; + + 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"; + REDIS_HOST_PASSWORD = "password"; + TRUSTED_PROXIES = "cloud.nelim.org"; + NEXTCLOUD_INIT_HTACCESS = "true"; + }; + }; + + "onlyoffice-document-server" = { + image = ./images/onlyoffice.nix; + restart = "always"; + + environment.JWT_ENABLED = "false"; + + ports = ["8055:80"]; + expose = [ + "80" + "443" + ]; + + volumes = ["${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" + ]; + + # Fix mobile editing + entrypoint = ''bash -c "${let + filePath = "/var/www/onlyoffice/documentserver/web-apps/apps/*/mobile/dist/js/app.js"; + func = "isSupportEditFeature=function()"; + in + concatStrings [ + "sed -i 's/${func}{return!1}/${func}{return 1}/g' ${filePath};" + "/app/ds/run-document-server.sh;" + "apt update;" + "apt install imagemagick -y;" + ]}"''; + }; + + "nginx-server" = { + image = ./images/nginx.nix; + restart = "always"; + ports = ["8042:80"]; + volumes = [ + "${./nginx.conf}:/etc/nginx/nginx.conf" + "${rwPath}/data:/var/www/html" + ]; + }; + + "nextcloud-db" = { + image = ./images/postgres.nix; + restart = "always"; + env_file = [secrets.nextcloud.path]; + volumes = [ + "${rwPath}/database:/var/lib/postgresql/data" + "/etc/localtime:/etc/localtime:ro" + ]; + }; + + "nextcloud-cache" = { + image = ./images/redis.nix; + restart = "always"; + #mem_limit = "2048m"; + #mem_reservation = "512m"; + env_file = [secrets.nextcloud.path]; + command = ''/bin/sh -c "redis-server --requirepass $$REDIS_HOST_PASSWORD"''; + tmpfs = [ + "/data" + ]; + }; + }; +} diff --git a/devices/nos/modules/arion/nextcloud/images/nextcloud.nix b/devices/nos/modules/arion/nextcloud/images/nextcloud.nix new file mode 100644 index 00000000..d4d540ec --- /dev/null +++ b/devices/nos/modules/arion/nextcloud/images/nextcloud.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "nextcloud"; + imageDigest = "sha256:b08377deee6dbecf2d885c278ff711fb6e63d855d8fad4717056246b928cc9da"; + sha256 = "027w6m8mrf1a92mmp68pgf93fmwgjgh5q007f6ff9nblacqdn4zz"; + finalImageName = "nextcloud"; + finalImageTag = "fpm"; +} diff --git a/devices/nos/modules/arion/nextcloud/images/nginx.nix b/devices/nos/modules/arion/nextcloud/images/nginx.nix new file mode 100644 index 00000000..3b75b3b8 --- /dev/null +++ b/devices/nos/modules/arion/nextcloud/images/nginx.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "nginx"; + imageDigest = "sha256:6db391d1c0cfb30588ba0bf72ea999404f2764febf0f1f196acd5867ac7efa7e"; + sha256 = "0mhc4872dw11x8378mwqbvbwylwaxly8qj3vj121bf7qjln4ad6a"; + finalImageName = "nginx"; + finalImageTag = "latest"; +} diff --git a/devices/nos/modules/arion/nextcloud/images/onlyoffice.nix b/devices/nos/modules/arion/nextcloud/images/onlyoffice.nix new file mode 100644 index 00000000..063602bd --- /dev/null +++ b/devices/nos/modules/arion/nextcloud/images/onlyoffice.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "onlyoffice/documentserver"; + imageDigest = "sha256:3b53dc7da559cdfa7e0c1c2f64aedce0b7ba868080b07c338ef5794a8046ca85"; + sha256 = "023ip2iimlm9h0bhmwwylpwhl2230qjql0z8m96c2365nx0nsv70"; + finalImageName = "onlyoffice/documentserver"; + finalImageTag = "latest"; +} diff --git a/configurations/nos/modules/docker/nextcloud/images/postgres.nix b/devices/nos/modules/arion/nextcloud/images/postgres.nix similarity index 78% rename from configurations/nos/modules/docker/nextcloud/images/postgres.nix rename to devices/nos/modules/arion/nextcloud/images/postgres.nix index 5894f51d..9a0c2200 100644 --- a/configurations/nos/modules/docker/nextcloud/images/postgres.nix +++ b/devices/nos/modules/arion/nextcloud/images/postgres.nix @@ -1,8 +1,8 @@ pkgs: -pkgs.dockerTools.pullImage rec { +pkgs.dockerTools.pullImage { imageName = "postgres"; imageDigest = "sha256:20e49432a20e1a63bb985977c32ec8f110bc609b93de35ad4f19c5486abcefaa"; sha256 = "0jxkjj726jb1hal4j1vyhnrmbpyrkvawq5nf3dpiad8h3zamvk66"; - finalImageName = imageName; + finalImageName = "postgres"; finalImageTag = "14.2-alpine"; } diff --git a/configurations/nos/modules/docker/nextcloud/images/redis.nix b/devices/nos/modules/arion/nextcloud/images/redis.nix similarity index 77% rename from configurations/nos/modules/docker/nextcloud/images/redis.nix rename to devices/nos/modules/arion/nextcloud/images/redis.nix index c49ce9aa..67963f66 100644 --- a/configurations/nos/modules/docker/nextcloud/images/redis.nix +++ b/devices/nos/modules/arion/nextcloud/images/redis.nix @@ -1,8 +1,8 @@ pkgs: -pkgs.dockerTools.pullImage rec { +pkgs.dockerTools.pullImage { imageName = "redis"; imageDigest = "sha256:558d0845026fe0bf091a00c0ad647ffacf9df385d780d433ca70661f7276f834"; sha256 = "0bbbzjl2fc2wvwj45j4z8kff2fj82qjk5nsgi79bqzm72x428mjb"; - finalImageName = imageName; + finalImageName = "redis"; finalImageTag = "7.0.0-alpine"; } diff --git a/configurations/nos/modules/docker/nextcloud/nginx.conf b/devices/nos/modules/arion/nextcloud/nginx.conf similarity index 55% rename from configurations/nos/modules/docker/nextcloud/nginx.conf rename to devices/nos/modules/arion/nextcloud/nginx.conf index 5d82e1a9..55b8068c 100644 --- a/configurations/nos/modules/docker/nextcloud/nginx.conf +++ b/devices/nos/modules/arion/nextcloud/nginx.conf @@ -1,38 +1,39 @@ -user www-data; -worker_processes 1; +user www-data; +worker_processes 1; -error_log /var/log/nginx/error.log warn; -pid /var/run/nginx.pid; +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; events { - worker_connections 1024; + worker_connections 1024; } http { + upstream backend { - server app-server:9000; - #server unix:/var/run/php/php7.4-fpm.sock; + 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"; + "" ""; + default "immutable"; } - include /etc/nginx/mime.types; - default_type application/octet-stream; + 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"'; + 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; + access_log /var/log/nginx/access.log main; - sendfile on; + sendfile on; #tcp_nopush on; - keepalive_timeout 65; + keepalive_timeout 65; map $http_host $this_host { "" $host; @@ -45,27 +46,27 @@ http { } map $http_x_forwarded_host $the_host { - default $http_x_forwarded_host; - "" $this_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 + # 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; + 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 "none" always; + add_header X-XSS-Protection "1; mode=block" always; - # Remove X-Powered-By, which is an information leak + # Remove X-Powered-By, which is an information leak fastcgi_hide_header X-Powered-By; root /var/www/html; @@ -79,28 +80,20 @@ http { # Rule borrowed from `.htaccess` to handle Microsoft DAV clients location = / { - if ( $http_user_agent ~ ^DavClnt ) { + 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/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; - } + 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. @@ -114,29 +107,25 @@ http { } # 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 ~ ^/(?: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; + location ~* ^/ds-vpath/ { + rewrite /ds-vpath/(.*) /$1 break; + proxy_pass http://onlyoffice-document-server; + proxy_redirect off; - client_max_body_size 10G; + client_max_body_size 10G; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; + 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; + 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(?:$|/) { @@ -163,25 +152,20 @@ http { fastcgi_max_temp_file_size 0; } - location ~ \.(?:css|js|mjs|svg|gif|png|jpg|ico|wasm|tflite|map)$ { + location ~ \.(?:css|js|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 + 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 + expires 7d; # Cache-Control policy borrowed from `.htaccess` + access_log off; # Optional: Don't log access to assets } # Rule borrowed from `.htaccess` diff --git a/devices/nos/modules/arion/resume/compose.nix b/devices/nos/modules/arion/resume/compose.nix new file mode 100644 index 00000000..cbd24f53 --- /dev/null +++ b/devices/nos/modules/arion/resume/compose.nix @@ -0,0 +1,51 @@ +{config, ...}: let + inherit (config.sops) secrets; + inherit (config.arion) rwDataDir; + + rwPath = rwDataDir + "/resume"; +in { + arion.projects."resume" = { + "postgres" = { + image = ./images/postgres.nix; + restart = "always"; + + ports = ["5432:5432"]; + + volumes = [ + "${rwPath}/db:/var/lib/postgresql/data" + ]; + + env_file = [secrets.resume.path]; + }; + + "server" = { + image = ./images/resume-server.nix; + 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"; + }; + }; + + "client" = { + image = ./images/resume-client.nix; + restart = "always"; + + ports = ["3060:3000"]; + + depends_on = ["server"]; + + environment = { + PUBLIC_URL = "https://resume.nelim.org"; + PUBLIC_SERVER_URL = "https://resauth.nelim.org"; + }; + }; + }; +} diff --git a/devices/nos/modules/arion/resume/images/postgres.nix b/devices/nos/modules/arion/resume/images/postgres.nix new file mode 100644 index 00000000..32d3eefd --- /dev/null +++ b/devices/nos/modules/arion/resume/images/postgres.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "postgres"; + imageDigest = "sha256:90f25fbf7ea2cf70d6a6a2f9c475c5a297c2b41e15eddaa5d9d8fafc9146072c"; + sha256 = "0mhg4z6ydqz1hf4692pcxcakzr6n7rkwazkgkawl0s43wrak1bgx"; + finalImageName = "postgres"; + finalImageTag = "15-alpine"; +} diff --git a/configurations/nos/modules/docker/resume/images/resume-client.nix b/devices/nos/modules/arion/resume/images/resume-client.nix similarity index 75% rename from configurations/nos/modules/docker/resume/images/resume-client.nix rename to devices/nos/modules/arion/resume/images/resume-client.nix index 6e7ca7d8..9c531d9b 100644 --- a/configurations/nos/modules/docker/resume/images/resume-client.nix +++ b/devices/nos/modules/arion/resume/images/resume-client.nix @@ -1,8 +1,8 @@ pkgs: -pkgs.dockerTools.pullImage rec { +pkgs.dockerTools.pullImage { imageName = "amruthpillai/reactive-resume"; imageDigest = "sha256:9cbe8efde6f489da05367b5b2d0f0097b397f76fa1dcefd0352f174e50221826"; sha256 = "1ybsnr91518m7v2g9drp2pdibml4rsfa5mqnrjckwq1ai9mlg1rj"; - finalImageName = imageName; + finalImageName = "amruthpillai/reactive-resume"; finalImageTag = "client-latest"; } diff --git a/configurations/nos/modules/docker/resume/images/resume-server.nix b/devices/nos/modules/arion/resume/images/resume-server.nix similarity index 75% rename from configurations/nos/modules/docker/resume/images/resume-server.nix rename to devices/nos/modules/arion/resume/images/resume-server.nix index fb3ba582..df617eed 100644 --- a/configurations/nos/modules/docker/resume/images/resume-server.nix +++ b/devices/nos/modules/arion/resume/images/resume-server.nix @@ -1,8 +1,8 @@ pkgs: -pkgs.dockerTools.pullImage rec { +pkgs.dockerTools.pullImage { imageName = "amruthpillai/reactive-resume"; imageDigest = "sha256:f14519b5d72fab07a948ce0ac6ac8e09321f1b05865e9d951851467e8be0542f"; sha256 = "0znbhnixy22i80h2qjylsf8v0mg07scfirh2q5w8njf7sa52w0d6"; - finalImageName = imageName; + finalImageName = "amruthpillai/reactive-resume"; finalImageTag = "server-latest"; } diff --git a/devices/nos/modules/arion/vaultwarden/compose.nix b/devices/nos/modules/arion/vaultwarden/compose.nix new file mode 100644 index 00000000..ba9af9d9 --- /dev/null +++ b/devices/nos/modules/arion/vaultwarden/compose.nix @@ -0,0 +1,25 @@ +{config, ...}: let + inherit (config.arion) rwDataDir; + + rwPath = rwDataDir + "/vaultwarden"; +in { + arion.projects."vaultwarden" = { + "public-vault" = { + image = ./images/vaultwarden.nix; + restart = "always"; + + ports = ["8781:80"]; + volumes = ["${rwPath}/public-data:/data"]; + environment.WEBSOCKET_ENABLED = "true"; + }; + + "private-vault" = { + image = ./images/vaultwarden.nix; + restart = "always"; + + ports = ["8780:80"]; + volumes = ["${rwPath}/private-data:/data"]; + environment.WEBSOCKET_ENABLED = "true"; + }; + }; +} diff --git a/devices/nos/modules/arion/vaultwarden/images/vaultwarden.nix b/devices/nos/modules/arion/vaultwarden/images/vaultwarden.nix new file mode 100644 index 00000000..815a62b7 --- /dev/null +++ b/devices/nos/modules/arion/vaultwarden/images/vaultwarden.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "quay.io/vaultwarden/server"; + imageDigest = "sha256:edb8e2bab9cbca22e555638294db9b3657ffbb6e5d149a29d7ccdb243e3c71e0"; + sha256 = "1a8wp3p1zgviqi85lb4gp10wajagx6bqizfk524v42c49x1qpfpm"; + finalImageName = "quay.io/vaultwarden/server"; + finalImageTag = "latest"; +} diff --git a/devices/nos/modules/arion/wg-easy/compose.nix b/devices/nos/modules/arion/wg-easy/compose.nix new file mode 100644 index 00000000..2ba74096 --- /dev/null +++ b/devices/nos/modules/arion/wg-easy/compose.nix @@ -0,0 +1,40 @@ +{config, ...}: let + inherit (config.arion) rwDataDir; + + rwPath = rwDataDir + "/wg-easy"; +in { + arion.projects."wg-easy"."wg-easy" = { + image = ./images/wg-easy.nix; + restart = "always"; + privileged = true; + + capabilities = { + NET_ADMIN = true; + SYS_MODULE = true; + }; + + sysctls = { + "net.ipv4.ip_forward" = 1; + "net.ipv4.conf.all.src_valid_mark" = 1; + }; + + dns = ["1.0.0.1"]; + + environment = { + WG_HOST = "166.62.179.208"; + 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" + ]; + }; +} diff --git a/devices/nos/modules/arion/wg-easy/images/wg-easy.nix b/devices/nos/modules/arion/wg-easy/images/wg-easy.nix new file mode 100644 index 00000000..de45a428 --- /dev/null +++ b/devices/nos/modules/arion/wg-easy/images/wg-easy.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "ghcr.io/wg-easy/wg-easy"; + imageDigest = "sha256:daa94b77901bdef3cb10151416c095e64cf66a6539fa8f748c09812b60b97f49"; + sha256 = "02880zh6fdmjlyi9nrvz1vzj4qa5642079xyzpbx3c1rplg033md"; + finalImageName = "ghcr.io/wg-easy/wg-easy"; + finalImageTag = "latest"; +} diff --git a/devices/nos/modules/jellyfin/default.nix b/devices/nos/modules/jellyfin/default.nix new file mode 100644 index 00000000..d557a3ef --- /dev/null +++ b/devices/nos/modules/jellyfin/default.nix @@ -0,0 +1,125 @@ +{ + config, + jellyfin-flake, + jellyfin-ultrachromic-src, + lib, + pkgs, + ... +}: let + inherit (lib) hasAttr fileContents optionals; + inherit (config.vars) mainUser; + + optionalGroup = name: + optionals + (hasAttr name config.users.groups) + [config.users.groups.${name}.name]; +in { + imports = [ + ./jfa-go.nix + ./packages.nix + jellyfin-flake.nixosModules.default + ]; + + users.users."jellyfin".extraGroups = + optionalGroup mainUser + ++ optionalGroup "input" + ++ optionalGroup "media" + ++ optionalGroup "render"; + + services = { + jellyfin = { + enable = 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://raw.githubusercontent.com/jumoog/intro-skipper/master/manifest.json"; + } + ]; + + enableSlowResponseWarning = false; + }; + + branding = let + jellyTheme = pkgs.stdenv.mkDerivation { + name = "Ultrachromic"; + src = jellyfin-ultrachromic-src; + postInstall = "cp -ar $src $out"; + }; + + importFile = file: fileContents "${jellyTheme}/${file}"; + in { + customCss = '' + /* Base theme */ + ${importFile "base.css"} + ${importFile "accentlist.css"} + ${importFile "fixes.css"} + + ${importFile "type/dark_withaccent.css"} + + ${importFile "rounding.css"} + ${importFile "progress/floating.css"} + ${importFile "titlepage/title_banner-logo.css"} + ${importFile "header/header_transparent.css"} + ${importFile "login/login_frame.css"} + ${importFile "fields/fields_border.css"} + ${importFile "cornerindicator/indicator_floating.css"} + + /* Style backdrop */ + .backdropImage {filter: blur(18px) saturate(120%) contrast(120%) brightness(40%);} + + /* 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" + ]; + enableThrottling = true; + enableTonemapping = true; + downMixAudioBoost = 1; + }; + }; + }; + + nginx = { + enable = true; + config = fileContents ./nginx.conf; + }; + }; +} diff --git a/devices/nos/modules/jellyfin/images/jfa-go.nix b/devices/nos/modules/jellyfin/images/jfa-go.nix new file mode 100644 index 00000000..3854e0b4 --- /dev/null +++ b/devices/nos/modules/jellyfin/images/jfa-go.nix @@ -0,0 +1,8 @@ +pkgs: +pkgs.dockerTools.pullImage { + imageName = "hrfee/jfa-go"; + imageDigest = "sha256:e50d74379d91f9389afcd7db6bc4542ad2b1869f4af69c7f9fb5f9c02e7957da"; + sha256 = "02v0p4yrp4gjm88mqvdasaslfl51r194m6fj08bmq16bm6zz1n9l"; + finalImageName = "hrfee/jfa-go"; + finalImageTag = "unstable"; +} diff --git a/devices/nos/modules/jellyfin/jfa-go.nix b/devices/nos/modules/jellyfin/jfa-go.nix new file mode 100644 index 00000000..bfc46d84 --- /dev/null +++ b/devices/nos/modules/jellyfin/jfa-go.nix @@ -0,0 +1,20 @@ +{config, ...}: let + jellyService = config.systemd.services.jellyfin.serviceConfig; +in { + systemd.services."arion-jfa-go" = { + after = ["jellyfin.service"]; + partOf = ["jellyfin.service"]; + }; + + arion.projects."jfa-go"."jfa-go" = { + image = ./images/jfa-go.nix; + restart = "always"; + + ports = ["8056:8056"]; + + volumes = [ + "${jellyService.WorkingDirectory}/jfa-go:/data" + "/etc/localtime:/etc/localtime:ro" + ]; + }; +} diff --git a/devices/nos/modules/jellyfin/nginx.conf b/devices/nos/modules/jellyfin/nginx.conf new file mode 100644 index 00000000..40346c9d --- /dev/null +++ b/devices/nos/modules/jellyfin/nginx.conf @@ -0,0 +1,93 @@ +events { + worker_connections 1024; +} + +http { + # Must be in HTTP block + # Set in-memory cache-metadata size in keys_zone, size of video caching and how many days a cached object should persist + proxy_cache_path /var/cache/nginx/jellyfin-videos levels=1:2 keys_zone=jellyfin-videos:100m inactive=90d max_size=35000m; + map $request_uri $h264Level { + ~(h264-level=)(.+?)& $2; + } + map $request_uri $h264Profile { + ~(h264-profile=)(.+?)& $2; + } + + server { + listen 8097; + listen [::]:8097; + server_name jelly.nelim.org; + + ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc. + client_max_body_size 20M; + + location = / { + return 302 https://$host/web/; + } + + location / { + # Proxy main Jellyfin traffic + proxy_pass http://localhost:8096; + proxy_set_header Host $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-Proto $scheme; + proxy_set_header X-Forwarded-Protocol $scheme; + proxy_set_header X-Forwarded-Host $http_host; + + # Disable buffering when the nginx proxy gets very resource heavy upon streaming + proxy_buffering off; + } + + # location block for /web - This is purely for aesthetics so /web/#!/ works instead of having to go to /web/index.html/#!/ + location = /web/ { + # Proxy main Jellyfin traffic + proxy_pass http://localhost:8096/web/index.html; + proxy_set_header Host $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-Proto $scheme; + proxy_set_header X-Forwarded-Protocol $scheme; + proxy_set_header X-Forwarded-Host $http_host; + } + + location /socket { + # Proxy Jellyfin Websockets traffic + proxy_pass http://localhost:8096; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $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-Proto $scheme; + proxy_set_header X-Forwarded-Protocol $scheme; + proxy_set_header X-Forwarded-Host $http_host; + } + + location /accounts { + # No longer necessary on versions after v0.3.0 + # rewrite ^/accounts/(.*) /$1 break; + + # Remove the CSP header set for Jellyfin + proxy_hide_header Content-Security-Policy; + add_header Content-Security-Policy ""; + + proxy_pass http://localhost:8056/accounts; # Change as you need + + # For versions <= v0.3.0 + #proxy_pass http://localhost:8056; # Change as you need + + http2_push_preload on; + + proxy_set_header Host $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-Proto $scheme; + proxy_set_header X-Forwarded-Protocol $scheme; + proxy_set_header X-Forwarded-Host $http_host; + proxy_buffering off; + } + + } +} diff --git a/devices/nos/modules/jellyfin/packages.nix b/devices/nos/modules/jellyfin/packages.nix new file mode 100644 index 00000000..e78423e5 --- /dev/null +++ b/devices/nos/modules/jellyfin/packages.nix @@ -0,0 +1,52 @@ +{ + config, + lib, + pkgs, + ... +}: let + inherit (lib) hasAttr optionals; + + jellyPkgs = + if config.nvidia.enableCUDA + then pkgs.cudaPackages.pkgs + else pkgs; + + jellyWeb = jellyPkgs.jellyfin-web.overrideAttrs (_: o: { + # Inject skip intro button + patches = + [ + (pkgs.fetchpatch { + name = "skipintro.patch"; + url = "https://pastebin.com/raw/EEgvReaw"; + hash = "sha256-kfvOz0ukDY09kkbmZi24ch5KWJsVcThNEVnjlk4sAC0="; + }) + ] + ++ optionals (hasAttr "patches" o) o.patches; + + # Enable backdrops by default. Not sure if it actually works + postInstall = '' + substituteInPlace $out/share/jellyfin-web/main.jellyfin.bundle.js \ + --replace-fail \ + 'enableBackdrops:function(){return P}' \ + 'enableBackdrops:function(){return _}' + ''; + }); + + jellyfinPkg = jellyPkgs.jellyfin.overrideAttrs (_: o: { + # This was the only way I found to replace the jellyfin-web package + preInstall = '' + makeWrapperArgs+=( + --add-flags "--ffmpeg ${jellyPkgs.jellyfin-ffmpeg}/bin/ffmpeg" + --add-flags "--webdir ${jellyWeb}/share/jellyfin-web" + ) + ''; + }); +in { + services.jellyfin.package = jellyfinPkg; + + environment.systemPackages = [ + jellyfinPkg + jellyWeb + jellyPkgs.jellyfin-ffmpeg + ]; +} diff --git a/configurations/nos/modules/mergerfs/default.nix b/devices/nos/modules/mergerfs.nix similarity index 96% rename from configurations/nos/modules/mergerfs/default.nix rename to devices/nos/modules/mergerfs.nix index a0e08e7e..fb0992d4 100644 --- a/configurations/nos/modules/mergerfs/default.nix +++ b/devices/nos/modules/mergerfs.nix @@ -1,5 +1,5 @@ {pkgs, ...}: let - fsPkgs = builtins.attrValues {inherit (pkgs) mergerfs cifs-utils;}; + fsPkgs = with pkgs; [mergerfs cifs-utils]; in { system.fsPackages = fsPkgs; environment.systemPackages = fsPkgs; diff --git a/configurations/nos/modules/qbittorrent/default.nix b/devices/nos/modules/qbittorrent/default.nix similarity index 100% rename from configurations/nos/modules/qbittorrent/default.nix rename to devices/nos/modules/qbittorrent/default.nix diff --git a/configurations/nos/modules/qbittorrent/qbittorrent.nix b/devices/nos/modules/qbittorrent/qbittorrent.nix similarity index 97% rename from configurations/nos/modules/qbittorrent/qbittorrent.nix rename to devices/nos/modules/qbittorrent/qbittorrent.nix index 006e598d..4b6a64fb 100644 --- a/configurations/nos/modules/qbittorrent/qbittorrent.nix +++ b/devices/nos/modules/qbittorrent/qbittorrent.nix @@ -11,7 +11,7 @@ gen = import ./vuetorrent.nix; in pkgs.stdenv.mkDerivation { - pname = "vuetorrent"; + name = "vuetorrent"; inherit (gen) version; nativeBuildInputs = [pkgs.unzip]; @@ -47,7 +47,6 @@ in { configDir = mkOption { type = types.path; default = "${cfg.dataDir}/.config"; - defaultText = "/var/lib/qbittorrent/.config"; description = '' The directory where qBittorrent will store its configuration. ''; diff --git a/devices/nos/modules/qbittorrent/vuetorrent.nix b/devices/nos/modules/qbittorrent/vuetorrent.nix new file mode 100644 index 00000000..b9546a57 --- /dev/null +++ b/devices/nos/modules/qbittorrent/vuetorrent.nix @@ -0,0 +1,6 @@ +# This file was autogenerated. DO NOT EDIT! +{ + version = "2.7.3"; + url = "https://github.com/VueTorrent/VueTorrent/releases/download/v2.7.3/vuetorrent.zip"; + hash = "sha256-0wVocErUcBceSrSKamlTGGvjcoiHLDF1uBanVGhlfpk="; +} diff --git a/configurations/nos/modules/qbittorrent/wireguard.nix b/devices/nos/modules/qbittorrent/wireguard.nix similarity index 88% rename from configurations/nos/modules/qbittorrent/wireguard.nix rename to devices/nos/modules/qbittorrent/wireguard.nix index 9ab919fc..3f89cfaa 100644 --- a/configurations/nos/modules/qbittorrent/wireguard.nix +++ b/devices/nos/modules/qbittorrent/wireguard.nix @@ -4,10 +4,6 @@ ... }: let inherit (config.sops) secrets; - - wgPort = 51820; - clientIP = "10.2.0.2"; - serverIP = "146.70.198.2"; in { networking.wireguard = { enable = true; @@ -15,9 +11,9 @@ in { interfaces = { wg0 = { interfaceNamespace = "wg"; - ips = ["${clientIP}/32"]; + ips = ["10.2.0.2/32"]; - listenPort = wgPort; + listenPort = 51820; generatePrivateKeyFile = false; privateKeyFile = secrets.vpn.path; @@ -26,7 +22,7 @@ in { { publicKey = "aQ2NoOYEObG9tDMwdc4VxK6hjW+eA0PLfgbH7ffmagU="; allowedIPs = ["0.0.0.0/0"]; - endpoint = "${serverIP}:${toString wgPort}"; + endpoint = "146.70.198.2:51820"; } ]; }; @@ -54,7 +50,7 @@ in { 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 + ${pkgs.socat}/bin/socat tcp-listen:${port},fork,reuseaddr exec:'${pkgs.iproute2}/bin/ip netns exec wg ${pkgs.socat}/bin/socat STDIO "tcp-connect:10.2.0.2:${port}"',nofork ''; }; in { diff --git a/configurations/nos/modules/snapraid/default.nix b/devices/nos/modules/snapraid.nix similarity index 100% rename from configurations/nos/modules/snapraid/default.nix rename to devices/nos/modules/snapraid.nix diff --git a/devices/nos/modules/subtitles/cleanup.nix b/devices/nos/modules/subtitles/cleanup.nix new file mode 100644 index 00000000..31862cfc --- /dev/null +++ b/devices/nos/modules/subtitles/cleanup.nix @@ -0,0 +1,52 @@ +{ + config, + pkgs, + ... +}: let + inherit (config.vars) mainUser; + + scriptSrc = pkgs.fetchFromGitHub { + owner = "brianspilner01"; + repo = "media-server-scripts"; + rev = "00d9efcd37bb2667d23d7747240b59291cde64d3"; + hash = "sha256-Qql6Z+smU8vEJaai0POjdMnYpET9ak4NddNQevEQ8Ds="; + }; + + script = pkgs.concatTextFile { + name = "sub-clean.sh"; + files = ["${scriptSrc}/sub-clean.sh"]; + executable = true; + }; +in { + systemd = { + services.sub-clean = { + serviceConfig = { + Type = "oneshot"; + User = mainUser; + Group = config.users.users.${mainUser}.group; + }; + + path = with pkgs; [ + findutils + (writeShellApplication { + name = "sub-clean"; + runtimeInputs = [findutils gnugrep gawk]; + text = '' + exec ${script} "$@" + ''; + }) + ]; + + script = '' + find /data/anime -name '*.srt' -exec sub-clean "{}" \; + find /data/movies -name '*.srt' -exec sub-clean "{}" \; + find /data/tv -name '*.srt' -exec sub-clean "{}" \; + ''; + }; + timers.sub-clean = { + wantedBy = ["timers.target"]; + partOf = ["sub-clean.service"]; + timerConfig.OnCalendar = ["0:00:00"]; + }; + }; +} diff --git a/devices/nos/modules/subtitles/node-syncsub/.envrc b/devices/nos/modules/subtitles/node-syncsub/.envrc new file mode 100644 index 00000000..2377eaf3 --- /dev/null +++ b/devices/nos/modules/subtitles/node-syncsub/.envrc @@ -0,0 +1 @@ +use flake $FLAKE#node-dev diff --git a/devices/nos/modules/subtitles/node-syncsub/.eslintrc.json b/devices/nos/modules/subtitles/node-syncsub/.eslintrc.json new file mode 100644 index 00000000..0bdffacc --- /dev/null +++ b/devices/nos/modules/subtitles/node-syncsub/.eslintrc.json @@ -0,0 +1,133 @@ +{ + "env": { + "es2021": true + }, + "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], + "parser": "@typescript-eslint/parser", + "overrides": [], + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": ["@stylistic", "@typescript-eslint"], + "rules": { + "array-callback-return": ["error", { + "allowImplicit": true, + "checkForEach": true + }], + "no-constructor-return": ["error"], + "no-unreachable-loop": ["error", { "ignore": [ + "ForInStatement", "ForOfStatement" + ]}], + + + "block-scoped-var": ["error"], + "class-methods-use-this": ["error"], + "curly": ["warn"], + "default-case-last": ["warn"], + "default-param-last": ["error"], + "eqeqeq": ["error", "smart"], + "func-names": ["warn", "never"], + "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": [-2, -1, 0.1, 0, 1, 2, 3, 10, 33, 66, 100, 255, 360, 450, 1000], + "ignoreDefaultValues": true, + "ignoreArrayIndexes": true + }], + "no-multi-assign": ["error"], + "no-new": ["error"], + "no-new-func": ["error"], + "no-new-wrappers": ["error"], + "no-object-constructor": ["error"], + "no-proto": ["error"], + "no-return-assign": ["error"], + "no-sequences": ["error"], + "no-shadow": ["error", { "builtinGlobals": true }], + "no-undef-init": ["warn"], + "no-undefined": ["error"], + "no-useless-constructor": ["warn"], + "no-useless-escape": ["off"], + "no-useless-return": ["error"], + "no-var": ["error"], + "no-void": ["error"], + "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-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "warn", + "@typescript-eslint/no-unsafe-declaration-merging": "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 + }], + "@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": 100, + "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-property-newline": ["warn", {"allowAllPropertiesOnSameLine": false}], + "@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/devices/nos/modules/subtitles/node-syncsub/default.nix b/devices/nos/modules/subtitles/node-syncsub/default.nix new file mode 100644 index 00000000..2c84e43e --- /dev/null +++ b/devices/nos/modules/subtitles/node-syncsub/default.nix @@ -0,0 +1,47 @@ +{ + buildNpmPackage, + ffmpeg, + nodejs_20, + subsync, + symlinkJoin, + typescript, + ... +}: let + nodeSubSync = buildNpmPackage { + name = "node-syncsub"; + src = ./.; + npmDepsHash = "sha256-O00VQPCUX6T+rtK3VcAibBipXFwNs4AFA3251qycPBQ="; + + nativeBuildInputs = [ + nodejs_20 + ffmpeg + subsync + typescript + ]; + + buildPhase = '' + tsc -p tsconfig.json + ''; + + installPhase = '' + mkdir -p $out/bin + mv node_modules package.json $out + + echo '#!/usr/bin/env node' > $out/bin/node-syncsub + cat ./build/main.js >> $out/bin/node-syncsub + rm ./build/main.js + chmod +x $out/bin/node-syncsub + + mv ./build/**.js $out/bin + ''; + }; +in + symlinkJoin { + name = "node-syncsub"; + meta.mainProgram = "node-syncsub"; + paths = [ + ffmpeg + subsync + nodeSubSync + ]; + } diff --git a/apps/extract-subs/src/lang-codes.ts b/devices/nos/modules/subtitles/node-syncsub/lang-codes.ts similarity index 100% rename from apps/extract-subs/src/lang-codes.ts rename to devices/nos/modules/subtitles/node-syncsub/lang-codes.ts diff --git a/devices/nos/modules/subtitles/node-syncsub/main.ts b/devices/nos/modules/subtitles/node-syncsub/main.ts new file mode 100755 index 00000000..68589815 --- /dev/null +++ b/devices/nos/modules/subtitles/node-syncsub/main.ts @@ -0,0 +1,194 @@ +import { + mkdir, + readdir as readDir, + rename as mv, +} from 'fs/promises'; + +import { ffprobe as ffProbe } from 'fluent-ffmpeg'; +import { spawnSync as spawn } from 'child_process'; + +import { ISO6391To3, ISO6393To1 } from './lang-codes'; + +const SPAWN_OPTS = { + shell: true, + stdio: [process.stdin, process.stdout, process.stderr], +}; + +/** + * These are the cli arguments + * + * @param directory 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 DIR = process.argv[2]; +let langs = process.argv[3].split(','); + + +// Check if there are 2 params +if (DIR && langs) { + main(); +} +else { + console.error('Error: no argument passed'); + process.exit(1); +} + +const escapePath = (p: string) => p.replaceAll("'", "'\\''"); + +function getVideoPath(files: string[]) { + const fileName = DIR.split('/').at(-1) ?? ''; + + const videoFiles = files.filter((f) => + f.includes(fileName) && f.endsWith('mkv')); + + if (videoFiles.length === 0) { + console.warn('No video files were found'); + process.exit(0); + } + + return `${DIR}/${videoFiles[0]}`; +} + +async function backupSubs(files: string[]) { + // Check if backup folder already exists and create it if not + if (!files.some((f) => f.endsWith('.srt.bak'))) { + await mkdir(`${DIR}/.srt.bak`); + } + else { + // TODO: compare with subs outside of backup dir + const backups = await readDir(`${DIR}/.srt.bak`); + + // Remove synced subtitles from the list to sync + // langs - backups + langs = langs.filter((n) => !backups + .some((s) => { + const l2 = s.split('.').at(-2) ?? ''; + const l3 = ISO6391To3.get(l2); + + return n === l3; + })); + } + + if (langs.length === 0) { + console.warn('Subtitles have already been synced'); + process.exit(0); + } +} + +function runSubSync( + cmd: string[], + onError = (error?: string) => { + console.error(error); + }, +) { + const { error } = spawn('subsync', cmd, SPAWN_OPTS); + + if (error) { + onError(error.message); + } + + spawn('chmod', ['-R', '775', `'${escapePath(DIR)}'`], SPAWN_OPTS); +} + +async function main() { + const files = await readDir(DIR); + + const VIDEO = getVideoPath(files); + const BASE_NAME = VIDEO.split('/').at(-1)?.replace(/\.[^.]*$/, ''); + + backupSubs(files); + + // ffprobe the video file to see available audio tracks + ffProbe(VIDEO, (_e, data) => { + if (!data?.streams) { + console.error('Couldn\'t find streams in video file'); + process.exit(0); + } + + const AVAIL_LANGS = data.streams + .filter((s) => s.codec_type === 'audio') + .map((s) => s['tags'] && s['tags']['language']); + + // Sync subtitles one by one + langs.forEach(async(lang) => { + const FILE_NAME = `${BASE_NAME}.${ISO6393To1.get(lang)}.srt`; + const IN_FILE = `${DIR}/.srt.bak/${FILE_NAME}`; + const OUT_FILE = `${DIR}/${FILE_NAME}`; + + const cmd = [ + '--cli sync', + `--sub-lang ${lang}`, + + `--ref-stream-by-lang ${AVAIL_LANGS.includes(lang) ? + lang : + AVAIL_LANGS[0]}`, + '--ref-stream-by-type "audio"', + + `--sub '${escapePath(IN_FILE)}'`, + `--out '${escapePath(OUT_FILE)}'`, + `--ref '${escapePath(VIDEO)}'`, + ]; + + if (files.includes(FILE_NAME)) { + await mv(OUT_FILE, IN_FILE); + + runSubSync(cmd, async() => { + await mv(IN_FILE, OUT_FILE); + }); + } + else { + let subs = data.streams.filter((s) => { + return s['tags'] && + 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 + subs = subs.filter((s) => s.codec_name !== 'hdmv_pgs_subtitle'); + + // Prefer normal subs + if (subs.length !== 1) { + subs = subs.filter((s) => s.disposition?.forced === 0); + } + + if (subs.length === 0) { + console.warn(`No subtitle tracks were found for ${lang}`); + } + else { + // Extract subtitle + spawn('ffmpeg', [ + '-i', `'${escapePath(VIDEO)}'`, + '-map', `"0:${subs[0].index}"`, `'${escapePath(IN_FILE)}'`, + ], SPAWN_OPTS); + + // Delete subtitle from video + spawn('mv', [ + `'${escapePath(VIDEO)}'`, + `'${escapePath(VIDEO)}.bak'`, + ], SPAWN_OPTS); + + spawn('ffmpeg', [ + '-i', `'${escapePath(VIDEO)}.bak'`, + '-map', '0', + '-map', `-0:${subs[0].index}`, + '-c', 'copy', `'${escapePath(VIDEO)}'`, + ], SPAWN_OPTS); + + spawn('rm', [`'${escapePath(VIDEO)}.bak'`], SPAWN_OPTS); + + // Sync extracted subtitle + runSubSync(cmd, async() => { + await mv(IN_FILE, OUT_FILE); + }); + } + } + }); + }); +} diff --git a/devices/nos/modules/subtitles/node-syncsub/package-lock.json b/devices/nos/modules/subtitles/node-syncsub/package-lock.json new file mode 100644 index 00000000..b4dd66f2 --- /dev/null +++ b/devices/nos/modules/subtitles/node-syncsub/package-lock.json @@ -0,0 +1,1818 @@ +{ + "name": "node-syncsub", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@types/fluent-ffmpeg": "^2.1.24", + "fluent-ffmpeg": "^2.1.2" + }, + "devDependencies": { + "@stylistic/eslint-plugin": "^1.4.0", + "@types/node": "^20.10.5", + "@typescript-eslint/eslint-plugin": "^6.9.1", + "@typescript-eslint/parser": "^6.9.1", + "eslint": "^8.52.0", + "typescript": "^5.3.3" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.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": "^12.22.0 || ^14.17.0 || >=16.0.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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/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==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/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==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@stylistic/eslint-plugin": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-1.7.0.tgz", + "integrity": "sha512-ThMUjGIi/jeWYNvOdjZkoLw1EOVs0tEuKXDgWvTn8uWaEz55HuPlajKxjKLpv19C+qRDbKczJfzUODfCdME53A==", + "dev": true, + "dependencies": { + "@stylistic/eslint-plugin-js": "1.7.0", + "@stylistic/eslint-plugin-jsx": "1.7.0", + "@stylistic/eslint-plugin-plus": "1.7.0", + "@stylistic/eslint-plugin-ts": "1.7.0", + "@types/eslint": "^8.56.2" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/eslint-plugin-js": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.7.0.tgz", + "integrity": "sha512-PN6On/+or63FGnhhMKSQfYcWutRlzOiYlVdLM6yN7lquoBTqUJHYnl4TA4MHwiAt46X5gRxDr1+xPZ1lOLcL+Q==", + "dev": true, + "dependencies": { + "@types/eslint": "^8.56.2", + "acorn": "^8.11.3", + "escape-string-regexp": "^4.0.0", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/eslint-plugin-jsx": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-1.7.0.tgz", + "integrity": "sha512-BACdBwXakQvjYIST5N2WWhRbvhRsIxa/F59BiZol+0IH4FSmDXhie7v/yaxDIIA9CbfElzOmIA5nWNYTVXcnwQ==", + "dev": true, + "dependencies": { + "@stylistic/eslint-plugin-js": "^1.7.0", + "@types/eslint": "^8.56.2", + "estraverse": "^5.3.0", + "picomatch": "^4.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/eslint-plugin-plus": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-1.7.0.tgz", + "integrity": "sha512-AabDw8sXsc70Ydx3qnbeTlRHZnIwY6UKEenBPURPhY3bfYWX+/pDpZH40HkOu94v8D0DUrocPkeeEUxl4e0JDg==", + "dev": true, + "dependencies": { + "@types/eslint": "^8.56.2", + "@typescript-eslint/utils": "^6.21.0" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@stylistic/eslint-plugin-ts": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-1.7.0.tgz", + "integrity": "sha512-QsHv98mmW1xaucVYQTyLDgEpybPJ/6jPPxVBrIchntWWwj74xCWKUiw79hu+TpYj/Pbhd9rkqJYLNq3pQGYuyA==", + "dev": true, + "dependencies": { + "@stylistic/eslint-plugin-js": "1.7.0", + "@types/eslint": "^8.56.2", + "@typescript-eslint/utils": "^6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.6.tgz", + "integrity": "sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/fluent-ffmpeg": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/@types/fluent-ffmpeg/-/fluent-ffmpeg-2.1.24.tgz", + "integrity": "sha512-g5oQO8Jgi2kFS3tTub7wLvfLztr1s8tdXmRd8PiL/hLMLzTIAyMR2sANkTggM/rdEDAg3d63nYRRVepwBiCw5A==", + "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==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.11.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", + "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "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==", + "dev": true + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "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==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "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.4" + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "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==", + "dev": true, + "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": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/fluent-ffmpeg": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz", + "integrity": "sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q==", + "dependencies": { + "async": ">=0.2.9", + "which": "^1.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "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==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/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==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "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==" + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "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==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "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.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.1.tgz", + "integrity": "sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", + "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/devices/nos/modules/subtitles/node-syncsub/package.json b/devices/nos/modules/subtitles/node-syncsub/package.json new file mode 100644 index 00000000..ed3f8425 --- /dev/null +++ b/devices/nos/modules/subtitles/node-syncsub/package.json @@ -0,0 +1,14 @@ +{ + "devDependencies": { + "@stylistic/eslint-plugin": "^1.4.0", + "@types/node": "^20.10.5", + "@typescript-eslint/eslint-plugin": "^6.9.1", + "@typescript-eslint/parser": "^6.9.1", + "eslint": "^8.52.0", + "typescript": "^5.3.3" + }, + "dependencies": { + "@types/fluent-ffmpeg": "^2.1.24", + "fluent-ffmpeg": "^2.1.2" + } +} diff --git a/devices/nos/modules/subtitles/node-syncsub/tsconfig.json b/devices/nos/modules/subtitles/node-syncsub/tsconfig.json new file mode 100644 index 00000000..b18570e4 --- /dev/null +++ b/devices/nos/modules/subtitles/node-syncsub/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "commonjs", + "lib": [ + "ES2022" + ], + "outDir": "build", + "strict": true, + "moduleResolution": "node", + "baseUrl": ".", + "typeRoots": [ + "./node_modules/@types", + ], + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "esModuleInterop": true + } +} diff --git a/devices/nos/modules/subtitles/syncing.nix b/devices/nos/modules/subtitles/syncing.nix new file mode 100644 index 00000000..e6152b15 --- /dev/null +++ b/devices/nos/modules/subtitles/syncing.nix @@ -0,0 +1,42 @@ +{ + config, + pkgs, + subsync, + ... +}: let + inherit (config.vars) mainUser; + + subsyncPkg = subsync.packages.${pkgs.system}.default; + + node-syncsub = pkgs.callPackage ./node-syncsub { + subsync = subsyncPkg; + }; +in { + environment.systemPackages = [subsyncPkg node-syncsub]; + + systemd = { + services.subsync-job = { + serviceConfig = { + Type = "oneshot"; + User = mainUser; + Group = config.users.users.${mainUser}.group; + }; + + path = with pkgs; [ + findutils + node-syncsub + ]; + + script = '' + find /data/movies -name '*.mkv' -printf "%h\0" | xargs -0 -I '{}' node-syncsub '{}' "eng,fre" + # find /data/anime -name '*.mkv' -printf "%h\0" | xargs -0 -I '{}' node-syncsub '{}' "eng,fre" + # find /data/tv -name '*.mkv' -printf "%h\0" | xargs -0 -I '{}' node-syncsub '{}' "eng,fre" + ''; + }; + #timers.subsync-job = { + # wantedBy = ["timers.target"]; + # partOf = ["subsync-job.service"]; + # timerConfig.OnCalendar = ["0:00:00"]; + #}; + }; +} diff --git a/devices/oksys/default.nix b/devices/oksys/default.nix new file mode 100644 index 00000000..d446520c --- /dev/null +++ b/devices/oksys/default.nix @@ -0,0 +1,45 @@ +# Not currently operational +{config, ...}: let + inherit (config.vars) mainUser hostName; +in { + imports = [ + ./hardware-configuration.nix + + ../../modules/sshd.nix + ../../modules/tailscale.nix + + ./modules/remote-builder.nix + ]; + + vars = { + mainUser = "matt"; + hostName = "oksys"; + neovimIde = false; + }; + + users.users.${mainUser} = { + isNormalUser = true; + extraGroups = [ + "wheel" + "adm" + ]; + }; + home-manager.users.${mainUser} = { + imports = []; + + # No touchy + home.stateVersion = "24.05"; + }; + + networking = { + inherit hostName; + resolvconf.enable = true; + firewall.enable = false; + }; + + # Set your time zone. + time.timeZone = "America/Montreal"; + + # No touchy + system.stateVersion = "24.05"; +} diff --git a/configurations/nos/hardware-configuration.nix b/devices/oksys/hardware-configuration.nix similarity index 52% rename from configurations/nos/hardware-configuration.nix rename to devices/oksys/hardware-configuration.nix index bb192c7d..92d45683 100644 --- a/configurations/nos/hardware-configuration.nix +++ b/devices/oksys/hardware-configuration.nix @@ -1,55 +1,39 @@ { config, modulesPath, - self, ... }: { nixpkgs.hostPlatform = "x86_64-linux"; - imports = [ - (modulesPath + "/installer/scan/not-detected.nix") - self.nixosModules.nvidia - ]; + imports = [(modulesPath + "/installer/scan/not-detected.nix")]; - nvidia = { - enable = true; - enableCUDA = true; + services.logind = { + lidSwitchDocked = "ignore"; + lidSwitchExternalPower = "ignore"; }; boot = { - kernelModules = ["kvm-intel"]; + loader = { + timeout = 2; + grub = { + enable = true; + device = "/dev/sda"; + }; + }; initrd.availableKernelModules = [ - "xhci_pci" + "uhci_hcd" + "ehci_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"]; + fsType = "ext4"; }; "/boot" = { @@ -60,7 +44,7 @@ swapDevices = [ { - device = "/swap/swapfile"; + device = "/var/lib/swapfile"; size = 16 * 1024; } ]; diff --git a/devices/oksys/modules/remote-builder.nix b/devices/oksys/modules/remote-builder.nix new file mode 100644 index 00000000..4e810129 --- /dev/null +++ b/devices/oksys/modules/remote-builder.nix @@ -0,0 +1,44 @@ +{config, ...}: let + servivi = "100.64.0.7"; +in { + # https://nixos.wiki/wiki/Distributed_build + home-manager.users.root = { + home.file.".ssh/config".text = + /* + ssh_config + */ + '' + Host ${servivi} + # Prevent using ssh-agent or another keyfile, useful for testing + IdentitiesOnly yes + IdentityFile ${config.sops.secrets.nixremote.path} + + # The weakly privileged user on the remote builder – if not set, + # 'root' is used – which will hopefully fail + User nixremote + ''; + }; + + programs.ssh.knownHosts = { + ${servivi}.publicKey = "servivi ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMkNW0H4Fl6NFgahlgGbSvglg1DrX4yl1ht9Lp+vHE2A"; + }; + + nix = { + buildMachines = [ + { + hostName = servivi; + system = "x86_64-linux"; + protocol = "ssh-ng"; + maxJobs = 1; + speedFactor = 2; + supportedFeatures = ["nixos-test" "benchmark" "big-parallel" "kvm"]; + mandatoryFeatures = []; + } + ]; + distributedBuilds = true; + # optional, useful when the builder has a faster internet connection than yours + extraOptions = '' + builders-use-substitutes = true + ''; + }; +} diff --git a/devices/servivi/default.nix b/devices/servivi/default.nix new file mode 100644 index 00000000..0bb496f4 --- /dev/null +++ b/devices/servivi/default.nix @@ -0,0 +1,65 @@ +{config, ...}: let + inherit (config.vars) mainUser hostName; +in { + imports = [ + ./hardware-configuration.nix + + ../../modules/arion + ../../modules/kmscon.nix + ../../modules/sshd.nix + ../../modules/tailscale.nix + + ./modules/binary-cache.nix + ./modules/minecraft.nix + ./modules/nfs.nix + ]; + + vars = { + mainUser = "matt"; + hostName = "servivi"; + promptMainColor = "blue"; + }; + + users.users = { + ${mainUser} = { + isNormalUser = true; + 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 root@oksys" + ]; + }; + }; + + home-manager.users.${mainUser} = { + imports = []; + + # No touchy + home.stateVersion = "24.05"; + }; + + arion.enable = true; + + networking = { + inherit hostName; + resolvconf.enable = true; + firewall.enable = false; + }; + + # Set your time zone. + time.timeZone = "America/Montreal"; + + # No touchy + system.stateVersion = "24.05"; +} diff --git a/configurations/servivi/hardware-configuration.nix b/devices/servivi/hardware-configuration.nix similarity index 67% rename from configurations/servivi/hardware-configuration.nix rename to devices/servivi/hardware-configuration.nix index 9e5f9e7a..eb9067ed 100644 --- a/configurations/servivi/hardware-configuration.nix +++ b/devices/servivi/hardware-configuration.nix @@ -13,13 +13,7 @@ kernelModules = ["kvm-amd"]; # Zenpower for ryzen cpu monitoring - extraModulePackages = builtins.attrValues { - inherit - (config.boot.kernelPackages) - zenpower - ; - }; - + extraModulePackages = with config.boot.kernelPackages; [zenpower]; blacklistedKernelModules = ["k10temp"]; initrd.availableKernelModules = [ @@ -41,9 +35,6 @@ configurationLimit = 30; }; }; - - # Support building binaries for arm64 - binfmt.emulatedSystems = ["aarch64-linux"]; }; fileSystems = { @@ -52,26 +43,12 @@ 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/devices/servivi/modules/binary-cache.nix b/devices/servivi/modules/binary-cache.nix new file mode 100644 index 00000000..0c6e05da --- /dev/null +++ b/devices/servivi/modules/binary-cache.nix @@ -0,0 +1,49 @@ +{ + config, + pkgs, + ... +}: let + inherit (config.vars) mainUser; + inherit (config.sops) secrets; +in { + services.nix-serve = { + enable = true; + secretKeyFile = secrets.binary-cache-key.path; + }; + + # Populate cache + systemd = { + services.buildAll = { + serviceConfig = { + Type = "oneshot"; + User = mainUser; + Group = config.users.users.${mainUser}.group; + }; + + path = with pkgs; [ + git + nix + nixci + openssh + ]; + + 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 flake update + nixci . + cd .. + rm -r nix-clone + ''; + }; + timers.buildAll = { + wantedBy = ["timers.target"]; + partOf = ["buildAll.service"]; + timerConfig.OnCalendar = ["0:00:00"]; + }; + }; +} diff --git a/devices/servivi/modules/minecraft.nix b/devices/servivi/modules/minecraft.nix new file mode 100644 index 00000000..c1df5632 --- /dev/null +++ b/devices/servivi/modules/minecraft.nix @@ -0,0 +1,173 @@ +{ + config, + nms, + pkgs, + ... +}: let + inherit (config.vars) mainUser; +in { + imports = [nms.nixosModules.default]; + + environment.systemPackages = [ + config.customPkgs.curseforge-server-downloader + ]; + + systemd.services.mc-steampunk.path = with pkgs; [curl]; + + services = { + borgbackup.configs.mc = { + paths = ["/var/lib/minecraft"]; + startAt = "01/3:00"; + }; + + modded-minecraft-servers = { + eula = true; + user = mainUser; + + instances = let + jre17 = pkgs.temurin-bin-17; + jre18 = pkgs.temurin-bin-18; + + defaults = { + spawn-protection = 0; + max-tick-time = 5 * 60 * 1000; + allow-flight = true; + }; + in { + # Vanilla Survival + sv = { + enable = false; + + serverConfig = + { + server-port = 25569; + + extra-options = { + }; + } + // defaults; + }; + + # Vanilla Creative + cv = { + enable = false; + + jvmMaxAllocation = "6G"; + jvmInitialAllocation = "2G"; + jvmPackage = jre18; + jvmOpts = ""; + + 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; + }; + + # Modded https://www.curseforge.com/minecraft/modpacks/steam-punk + # curseforge-server-downloader --pack 643605 --version latest + steampunk = { + enable = true; + + jvmMaxAllocation = "12G"; + jvmInitialAllocation = "2G"; + jvmPackage = jre18; + jvmOpts = ""; + + serverConfig = + { + server-port = 25569; + motd = ""; + + extra-options = { + allow-nether = true; + enable-command-block = true; + enable-status = true; + entity-broadcast-range-percentage = 100; + force-gamemode = false; + function-permission-level = 2; + gamemode = "survival"; + generate-structures = true; + max-build-height = 256; + max-players = 8; + difficulty = "normal"; + view-distance = 12; + simulation-distance = 10; + sync-chunk-writes = true; + use-native-transport = true; + }; + } + // defaults; + }; + + # Modded https://www.curseforge.com/minecraft/modpacks/ultimate-building-modpack + # With https://www.curseforge.com/minecraft/mc-mods/bits-and-chisels + builder = { + enable = true; + + jvmMaxAllocation = "6G"; + jvmInitialAllocation = "2G"; + jvmPackage = jre18; + jvmOpts = ""; + + serverConfig = + { + server-port = 25566; + motd = "creative mode gaming with mods"; + + extra-options = { + generate-structures = false; + level-type = "minecraft:flat"; + difficulty = "hard"; + enable-command-block = true; + enforce-white-list = false; + gamemode = "creative"; + max-players = 6; + view-distance = 16; + }; + } + // defaults; + }; + + # Vault Hunters + vh = { + enable = false; + + jvmMaxAllocation = "12G"; + jvmInitialAllocation = "2G"; + jvmPackage = jre17; + jvmOpts = ""; + + serverConfig = + { + server-port = 25569; + motd = "we do a little hunting of the vaults"; + + extra-options = { + difficulty = "hard"; + enable-command-block = true; + entity-broadcast-range-percentage = 150; + level-type = "default"; + max-players = 8; + spawn-protection = 0; + sync-chunk-writes = true; + use-native-transport = true; + view-distance = 10; + }; + } + // defaults; + }; + }; + }; + }; +} diff --git a/configurations/servivi/modules/nfs/default.nix b/devices/servivi/modules/nfs.nix similarity index 100% rename from configurations/servivi/modules/nfs/default.nix rename to devices/servivi/modules/nfs.nix diff --git a/devices/wim/config/hypr/main.conf b/devices/wim/config/hypr/main.conf new file mode 100644 index 00000000..680ad837 --- /dev/null +++ b/devices/wim/config/hypr/main.conf @@ -0,0 +1,44 @@ +# Cosmetic +general { + gaps_in = 5 + gaps_out = 5 + border_size = 2 + col.active_border = rgb(411C6C) + col.inactive_border = rgba(595959aa) +} + +decoration { + rounding = 20 + + blur { + enabled = true + size = 3 + passes = 1 + } + + drop_shadow = false +} + +animations { + enabled = yes + + bezier = myBezier, 0.05, 0.9, 0.1, 1.05 + + bezier = easeInBack, 0.36, 0, 0.66, -0.56 + bezier = easeOutBack, 0.34, 1.56, 0.64, 1 + bezier = softEaseOutBack, 0.34, 1.26, 0.64, 1 + + animation = windows, 1, 7, myBezier + animation = windowsIn, 1, 7, easeOutBack, slide + animation = windowsOut, 1, 7, easeInBack, slide + animation = windowsMove, 1, 7, easeOutBack, slide + + animation = workspaces, 1, 6, softEaseOutBack, slide + + animation = fade, 1, 7, default + animation = fadeIn, 1, 7, easeOutBack + animation = fadeOut, 1, 7, easeInBack + + animation = border, 1, 10, default + animation = borderangle, 1, 8, default +} diff --git a/devices/wim/default.nix b/devices/wim/default.nix new file mode 100644 index 00000000..efa3106f --- /dev/null +++ b/devices/wim/default.nix @@ -0,0 +1,62 @@ +{config, ...}: let + inherit (config.vars) mainUser hostName; +in { + imports = [ + ./hardware-configuration.nix + + ../../modules/ags + ../../modules/audio.nix + ../../modules/hyprland + ../../modules/kmscon.nix + ../../modules/plymouth.nix + ../../modules/printer.nix + ../../modules/tailscale.nix + + ./modules/security.nix + ]; + + vars = { + mainUser = "matt"; + hostName = "wim"; + promptMainColor = "purple"; + fontSize = 12.5; + mainMonitor = "eDP-1"; + }; + + users.users.${mainUser} = { + isNormalUser = true; + extraGroups = [ + "wheel" + "input" + "uinput" + "adm" + "video" + "libvirtd" + ]; + }; + home-manager.users.${mainUser} = { + imports = [ + ../../home/firefox + + ./home/packages.nix + ]; + + # No touchy + home.stateVersion = "23.05"; + }; + + networking = { + inherit hostName; + networkmanager = { + enable = true; + wifi.backend = "wpa_supplicant"; + }; + firewall.enable = false; + }; + + # Set your time zone. + time.timeZone = "America/Montreal"; + + # No touchy + system.stateVersion = "23.05"; +} diff --git a/configurations/wim/hardware-configuration.nix b/devices/wim/hardware-configuration.nix similarity index 69% rename from configurations/wim/hardware-configuration.nix rename to devices/wim/hardware-configuration.nix index c06ac913..1570a6e8 100644 --- a/configurations/wim/hardware-configuration.nix +++ b/devices/wim/hardware-configuration.nix @@ -10,18 +10,11 @@ boot = { kernelPackages = pkgs.linuxPackages_zen; - kernelParams = [ - "amd_pstate=active" - ]; - kernelModules = ["amdgpu" "kvm-amd" "acpi_call"]; + kernelParams = ["amd_pstate=active"]; + kernelModules = ["amdgpu" "kvm-amd"]; - extraModulePackages = builtins.attrValues { - inherit - (config.boot.kernelPackages) - acpi_call - zenpower - ; - }; + # Zenpower for ryzen cpu monitoring + extraModulePackages = with config.boot.kernelPackages; [zenpower]; blacklistedKernelModules = ["k10temp"]; initrd = { @@ -34,6 +27,7 @@ loader = { efi.canTouchEfiVariables = true; + timeout = 0; systemd-boot = { enable = true; @@ -52,44 +46,31 @@ 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 = { + opengl = { enable = true; - enable32Bit = true; + driSupport32Bit = true; + extraPackages = + if pkgs ? rocmPackages.clr + then with pkgs.rocmPackages; [clr clr.icd] + else with pkgs; [rocm-opencl-icd rocm-opencl-runtime]; }; bluetooth = { enable = true; - powerOnBoot = false; + powerOnBoot = true; }; }; @@ -97,29 +78,16 @@ libvirtd.enable = true; waydroid.enable = true; }; - environment.systemPackages = builtins.attrValues { - inherit - (pkgs) - qemu - powertop - ; - }; + environment.systemPackages = with 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 = { @@ -147,7 +115,9 @@ power-profiles-daemon.enable = false; udev.extraRules = - # udev + /* + udev + */ '' # give permanent path to keyboard XF86* binds SUBSYSTEMS=="input", ATTRS{id/product}=="0006", ATTRS{id/vendor}=="0000", SYMLINK += "video-bus" diff --git a/devices/wim/home/packages.nix b/devices/wim/home/packages.nix new file mode 100644 index 00000000..9a8f312a --- /dev/null +++ b/devices/wim/home/packages.nix @@ -0,0 +1,41 @@ +{pkgs, ...}: { + home.packages = + (with pkgs.python311Packages; [ + python + pyclip # For Waydroid? + ]) + ++ (with pkgs; [ + # Misc CLI + acpi + + (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}" "$@" + '') + ]); + + 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/configurations/wim/modules/security/default.nix b/devices/wim/modules/security.nix similarity index 78% rename from configurations/wim/modules/security/default.nix rename to devices/wim/modules/security.nix index 89a9cf69..9af7762f 100644 --- a/configurations/wim/modules/security/default.nix +++ b/devices/wim/modules/security.nix @@ -1,18 +1,18 @@ { + config, lib, - pkgs, ... }: let inherit (lib) mkDefault mkBefore; - inherit (pkgs.selfPackages) pam-fprint-grosshack; + inherit (config.customPkgs) 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 + auth sufficient ${pam_fprintd_grosshackSo} timeout=99 + auth sufficient pam_unix.so try_first_pass nullok ''; in { services.fprintd.enable = true; @@ -34,5 +34,6 @@ in { sudo.text = mkDefault (mkBefore grosshackConf); login.text = mkDefault (mkBefore grosshackConf); polkit-1.text = mkDefault (mkBefore grosshackConf); + hyprlock.text = mkDefault (mkBefore grosshackConf); }; } diff --git a/flake.lock b/flake.lock index e0b8c2a4..01aeefe8 100644 --- a/flake.lock +++ b/flake.lock @@ -2,61 +2,44 @@ "nodes": { "ags": { "inputs": { - "astal": [ - "astal" - ], "nixpkgs": [ "nixpkgs" - ], - "systems": [ - "systems" ] }, "locked": { - "lastModified": 1744304930, - "narHash": "sha256-Ud+mprss2S7jEfvkm8S0YYitqCmy8v1WPu+I4/Vgdx8=", - "owner": "matt1432", + "lastModified": 1712605440, + "narHash": "sha256-ijIrU2b6yPiTC4hWgfd+C+KtAnMJJe+1bo5M4PqVCVk=", + "owner": "Aylur", "repo": "ags", - "rev": "b9c2222e5b28727840dace04415acb733f76e3bc", + "rev": "75251984746a82ec21a61f14cedd2e83ca55d357", "type": "github" }, "original": { - "owner": "matt1432", - "ref": "overlay", + "owner": "Aylur", "repo": "ags", "type": "github" } }, - "aquamarine": { + "arion": { "inputs": { - "hyprutils": [ - "hyprland", - "hyprutils" - ], - "hyprwayland-scanner": [ - "hyprland", - "hyprwayland-scanner" - ], + "flake-parts": "flake-parts", + "haskell-flake": "haskell-flake", + "hercules-ci-effects": "hercules-ci-effects", "nixpkgs": [ - "hyprland", "nixpkgs" - ], - "systems": [ - "hyprland", - "systems" ] }, "locked": { - "lastModified": 1745357003, - "narHash": "sha256-jYwzQkv1r7HN/4qrAuKp+NR4YYNp2xDrOX5O9YVqkWo=", - "owner": "hyprwm", - "repo": "aquamarine", - "rev": "a19cf76ee1a15c1c12083fa372747ce46387289f", + "lastModified": 1712285456, + "narHash": "sha256-A4EBTlFfeosNaO8zpN7rlWTgF9AHy755NxKBvhJ1b0w=", + "owner": "hercules-ci", + "repo": "arion", + "rev": "1886d25075aaf24c8bc687b3d2a87ae1f5d154ec", "type": "github" }, "original": { - "owner": "hyprwm", - "repo": "aquamarine", + "owner": "hercules-ci", + "repo": "arion", "type": "github" } }, @@ -64,23 +47,19 @@ "inputs": { "nixpkgs": [ "nixpkgs" - ], - "systems": [ - "systems" ] }, "locked": { - "lastModified": 1744305027, - "narHash": "sha256-6dVuAwHp45Z8iXfTpIxV0D7A9NkWWx37yJ0+nG9AGzs=", - "owner": "matt1432", - "repo": "astal", - "rev": "54a5c81323dc10cad1464af653dd5ca187413882", + "lastModified": 1710876438, + "narHash": "sha256-Uf6m0XD+ol7pb26QykZQmZoRdRkKDlLoCrYGiANMvuQ=", + "owner": "Aylur", + "repo": "Astal", + "rev": "4e4b4eb6b38ffdfbfc4ca87878817d075c8bd988", "type": "github" }, "original": { - "owner": "matt1432", - "ref": "overlay", - "repo": "astal", + "owner": "Aylur", + "repo": "Astal", "type": "github" } }, @@ -100,39 +79,44 @@ "type": "github" } }, - "bazarr-bulk": { + "caddy-plugins": { "inputs": { "nixpkgs": [ "nixpkgs" ] }, "locked": { - "lastModified": 1727959396, - "narHash": "sha256-T4j2U4AeM+WB4qiSWW2u0nnF1DlZJ5d09qHmdDDZIKE=", - "owner": "mateoradman", - "repo": "bazarr-bulk", - "rev": "c07f52d30edcf95b5fb5090cc4ef04da30b705d6", + "lastModified": 1712559998, + "narHash": "sha256-tB/IldFDPL2FUvlaqavm8mkgHZB044oALjb3CJCzTls=", + "owner": "matt1432", + "repo": "nixos-caddy-cloudflare", + "rev": "66f66f38efb907c3cc5337820a5ed830120dd772", "type": "github" }, "original": { - "owner": "mateoradman", - "repo": "bazarr-bulk", + "owner": "matt1432", + "repo": "nixos-caddy-cloudflare", "type": "github" } }, - "caule-themes-src": { - "flake": false, + "coc-stylelintplus": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": [ + "nixpkgs" + ] + }, "locked": { - "lastModified": 1696467225, - "narHash": "sha256-biNz3ZO3nFfEgchoPu9M3lXiTj9BDxkUaZiCNq0Jy8M=", - "owner": "ricardoquecria", - "repo": "caule-themes-pack-1", - "rev": "0ec8a4b7acf63d8618bcf2fdd968d6256e998acb", + "lastModified": 1701045677, + "narHash": "sha256-Uw7TY8kqcikjeoT3y6Bh7UHvS8Z4jYJTvSkeFKrxfOQ=", + "owner": "matt1432", + "repo": "coc-stylelintplus", + "rev": "3a318b03c4d794ceb80bf24a083334d5cbcc86e5", "type": "github" }, "original": { - "owner": "ricardoquecria", - "repo": "caule-themes-pack-1", + "owner": "matt1432", + "repo": "coc-stylelintplus", "type": "github" } }, @@ -152,85 +136,14 @@ "type": "github" } }, - "custom-sidebar-src": { - "flake": false, - "locked": { - "lastModified": 1747095792, - "narHash": "sha256-zc9XwYn9MbbV2aUn1arsRSyiA4EALG8mmqtdPQrZGRQ=", - "owner": "elchininet", - "repo": "custom-sidebar", - "rev": "022ca670aae1b64de709c88eb3a83424253f07d2", - "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": 1747167754, - "narHash": "sha256-rb8bd7KjON2+aZ2pE9yyjNT2jaZPIbzVPDYW7dvJMLU=", + "lastModified": 1700917419, + "narHash": "sha256-95CAKjBRELX2f7oWSHFWJnI0mikAoxhfUphe9k51Qf4=", "owner": "Eisa01", "repo": "mpv-scripts", - "rev": "100fea81ae8560c6fb113b1f6bb20857a41a5705", + "rev": "48d68283cea47ff8e904decc9003b3abc3e2123e", "type": "github" }, "original": { @@ -239,49 +152,34 @@ "type": "github" } }, - "extended-ollama-conversation-src": { + "firefox-gx-src": { "flake": false, "locked": { - "lastModified": 1722207930, - "narHash": "sha256-WF54xX9DF8QJf7kZtsDyCSZRR6ktm6gNpI7WqKSIjZY=", - "owner": "TheNimaj", - "repo": "extended_ollama_conversation", - "rev": "d8ea4190e75b9f8127cd55403e775dd47dd2b79b", + "lastModified": 1708376786, + "narHash": "sha256-xECzIpSr923mlUc5Pk/y0d2BrXVECow2NaL4p79i+/U=", + "owner": "Godiesc", + "repo": "firefox-gx", + "rev": "fd5d51fc9986e854093ff162237281d2fd067e53", "type": "github" }, "original": { - "owner": "TheNimaj", - "repo": "extended_ollama_conversation", + "owner": "Godiesc", + "ref": "v.9.0", + "repo": "firefox-gx", "type": "github" } }, "flake-compat": { "locked": { - "lastModified": 1747046372, - "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", - "owner": "edolstra", + "lastModified": 1688025799, + "narHash": "sha256-ktpB4dRtnksm9F5WawoIkEneh1nrEvuxb5lJFt1iOyw=", + "owner": "nix-community", "repo": "flake-compat", - "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", + "rev": "8bf105319d44f6b9f0d764efa4fdef9f1cc9ba1c", "type": "github" }, "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-compat_2": { - "flake": false, - "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", - "type": "github" - }, - "original": { - "owner": "edolstra", + "owner": "nix-community", "repo": "flake-compat", "type": "github" } @@ -289,15 +187,16 @@ "flake-parts": { "inputs": { "nixpkgs-lib": [ + "arion", "nixpkgs" ] }, "locked": { - "lastModified": 1743550720, - "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", + "lastModified": 1712014858, + "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "c621e8422220273271f52058f618c94e405bb0f5", + "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", "type": "github" }, "original": { @@ -306,33 +205,77 @@ "type": "github" } }, - "flake-root": { + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": [ + "arion", + "hercules-ci-effects", + "nixpkgs" + ] + }, "locked": { - "lastModified": 1723604017, - "narHash": "sha256-rBtQ8gg+Dn4Sx/s+pvjdq3CB2wQNzx9XGFq/JVGCB6k=", - "owner": "srid", - "repo": "flake-root", - "rev": "b759a56851e10cb13f6b8e5698af7b59c44be26e", + "lastModified": 1709336216, + "narHash": "sha256-Dt/wOWeW6Sqm11Yh+2+t0dfEWxoMxGBvv3JpIocFl9E=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "f7b3c975cf067e56e7cda6cb098ebe3fb4d74ca2", "type": "github" }, "original": { - "owner": "srid", - "repo": "flake-root", + "id": "flake-parts", + "type": "indirect" + } + }, + "flake-parts_3": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1712014858, + "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_4": { + "inputs": { + "nixpkgs-lib": [ + "nixpkgs-wayland", + "nix-eval-jobs", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1701473968, + "narHash": "sha256-YcVE5emp1qQ8ieHUnxt1wCZCC3ZfAS+SRRWZ2TMda7E=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "34fed993f1674c8d06d58b37ce1e0fe5eebcb9f5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", "type": "github" } }, "flake-utils": { "inputs": { - "systems": [ - "systems" - ] + "systems": "systems" }, "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", "owner": "numtide", "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", "type": "github" }, "original": { @@ -341,23 +284,39 @@ "type": "github" } }, - "flakegen": { + "flake-utils_2": { "inputs": { - "systems": [ - "systems" - ] + "systems": "systems_2" }, "locked": { - "lastModified": 1707120544, - "narHash": "sha256-pXwH9NLXjhjnaz1n7w5m36gVUZ1GVkvtltsLnvVPFJY=", - "owner": "jorsn", - "repo": "flakegen", - "rev": "8b11749b0724700273462a674dd16e5549fe2790", + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "type": "github" }, "original": { - "owner": "jorsn", - "repo": "flakegen", + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "inputs": { + "systems": "systems_7" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", "type": "github" } }, @@ -377,35 +336,14 @@ "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": 1746981553, - "narHash": "sha256-XXSHTS/WWqGblbBLuzHSYCY5FVTDSHBHfBWubmoNSy0=", + "lastModified": 1712530293, + "narHash": "sha256-YVdD7LcfwHwbZwhFl7wIe9GwFKg5yVDDrtDbHC6SS8A=", "ref": "refs/heads/master", - "rev": "2a0fb9f449bc045295ece44ac5f0b9a9ad20c830", - "revCount": 1096, + "rev": "d5bf41fed6628083200370cd5acf3ff43b592891", + "revCount": 544, "type": "git", "url": "https://repo.dec05eba.com/gpu-screen-recorder" }, @@ -414,37 +352,14 @@ "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": 1745785192, - "narHash": "sha256-T0X0h4Bz3sy5jqtB1PkpjFnB8jO3CehOxgRwPPG54Ds=", + "lastModified": 1712613812, + "narHash": "sha256-uhcRV7E7GDjWjetUHcz/E/g36m/yYTg3c9WJo6gYTJA=", "owner": "dracula", "repo": "gtk", - "rev": "3834a1bac175b226cff6b1c94faac9aba2819bd5", + "rev": "18350cafd8e9c775737f97fb5acf0890e29bc47a", "type": "github" }, "original": { @@ -453,6 +368,65 @@ "type": "github" } }, + "haskell-flake": { + "locked": { + "lastModified": 1675296942, + "narHash": "sha256-u1X1sblozi5qYEcLp1hxcyo8FfDHnRUVX3dJ/tW19jY=", + "owner": "srid", + "repo": "haskell-flake", + "rev": "c2cafce9d57bfca41794dc3b99c593155006c71e", + "type": "github" + }, + "original": { + "owner": "srid", + "ref": "0.1.0", + "repo": "haskell-flake", + "type": "github" + } + }, + "headscale": { + "inputs": { + "flake-utils": "flake-utils_2", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1711135921, + "narHash": "sha256-vv8+DnV4inQn+MfXCB0WMVLXAW4NbP2Em3VASbjeIjA=", + "owner": "juanfont", + "repo": "headscale", + "rev": "8a8e25a8d1e6bc5fa27b7f72f99bbf24b290e0a6", + "type": "github" + }, + "original": { + "owner": "juanfont", + "repo": "headscale", + "type": "github" + } + }, + "hercules-ci-effects": { + "inputs": { + "flake-parts": "flake-parts_2", + "nixpkgs": [ + "arion", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1710478346, + "narHash": "sha256-Xjf8BdnQG0tLhPMlqQdwCIjOp7Teox0DP3N/jjyiGM4=", + "owner": "hercules-ci", + "repo": "hercules-ci-effects", + "rev": "64e7763d72c1e4c1e5e6472640615b6ae2d40fbf", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "hercules-ci-effects", + "type": "github" + } + }, "home-manager": { "inputs": { "nixpkgs": [ @@ -460,11 +434,11 @@ ] }, "locked": { - "lastModified": 1747279714, - "narHash": "sha256-UdxlE8yyrKiGq3bgGyJ78AdFwh+fuRAruKtyFY5Zq5I=", + "lastModified": 1712462372, + "narHash": "sha256-WA3bbBWhd3o1wAgyHZNypjb/LG4oq+IWxFq8ey8yNPU=", "owner": "nix-community", "repo": "home-manager", - "rev": "954615c510c9faa3ee7fb6607ff72e55905e69f2", + "rev": "a561ad6ab38578c812cc9af3b04f2cc60ebf48c9", "type": "github" }, "original": { @@ -473,6 +447,31 @@ "type": "github" } }, + "hypr-official-plugins": { + "inputs": { + "hyprland": [ + "hyprland" + ], + "systems": [ + "hypr-official-plugins", + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1712420644, + "narHash": "sha256-h2X8qhN5RKYQXzT1kxKgUz1u1QthqOrP9xk800mTM6E=", + "owner": "hyprwm", + "repo": "hyprland-plugins", + "rev": "5ec0140d4aeca42b8a33e7f335f979e376d1b549", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprland-plugins", + "type": "github" + } + }, "hyprcursor": { "inputs": { "hyprlang": [ @@ -489,11 +488,11 @@ ] }, "locked": { - "lastModified": 1745948457, - "narHash": "sha256-lzTV10FJTCGNtMdgW5YAhCAqezeAzKOd/97HbQK8GTU=", + "lastModified": 1712434681, + "narHash": "sha256-qwmR2p1oc48Bj7gUDvb1oGL19Rjs2PmEmk4ChV01A5o=", "owner": "hyprwm", "repo": "hyprcursor", - "rev": "ac903e80b33ba6a88df83d02232483d99f327573", + "rev": "818d8c4b69e0997483d60b75f701fe14b561a7a3", "type": "github" }, "original": { @@ -502,50 +501,18 @@ "type": "github" } }, - "hyprgraphics": { - "inputs": { - "hyprutils": [ - "hyprland", - "hyprutils" - ], - "nixpkgs": [ - "hyprland", - "nixpkgs" - ], - "systems": [ - "hyprland", - "systems" - ] - }, - "locked": { - "lastModified": 1745015490, - "narHash": "sha256-apEJ9zoSzmslhJ2vOKFcXTMZLUFYzh1ghfB6Rbw3Low=", - "owner": "hyprwm", - "repo": "hyprgraphics", - "rev": "60754910946b4e2dc1377b967b7156cb989c5873", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "hyprgraphics", - "type": "github" - } - }, "hyprgrass": { "inputs": { "hyprland": [ "hyprland" - ], - "nixpkgs": [ - "nixpkgs" ] }, "locked": { - "lastModified": 1746964339, - "narHash": "sha256-yF8z6nFD+43KweC2/UCc6ZtCktGlzpa2EG4yonZfK5o=", + "lastModified": 1712492736, + "narHash": "sha256-9cn+HqCFLUlqcP42Z6BtKrwvzcAOdUXgF95W7f8WUXU=", "owner": "horriblename", "repo": "hyprgrass", - "rev": "51da8d137e042c117fe46a5c019ec38c0de0342a", + "rev": "e2a7dc5260e46c946188bf8eba1e8229a52ae79b", "type": "github" }, "original": { @@ -554,33 +521,46 @@ "type": "github" } }, + "hypridle": { + "inputs": { + "hyprlang": "hyprlang", + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems_3" + }, + "locked": { + "lastModified": 1710180874, + "narHash": "sha256-ZSn3wXQuRz36Ta/L+UCFKuUVG6QpwK2QmRkPjpQprU4=", + "owner": "hyprwm", + "repo": "hypridle", + "rev": "4395339a2dc410bcf49f3e24f9ed3024fdb25b0a", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hypridle", + "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", + "hyprlang": "hyprlang_2", "nixpkgs": [ "nixpkgs" ], - "pre-commit-hooks": [ - "pre-commit-hooks" - ], - "systems": [ - "systems" - ], + "systems": "systems_4", + "wlroots": "wlroots", "xdph": "xdph" }, "locked": { - "lastModified": 1747301504, - "narHash": "sha256-GAI36RNzF9yC0JOauS1+h681ElwdbD9q/qxxuIqcejQ=", + "lastModified": 1712615721, + "narHash": "sha256-A+C0MvLIvMPMKiex0pASzTIbQAqnYjEcCN2l5C9lx2I=", "owner": "hyprwm", "repo": "Hyprland", - "rev": "a5c9b3e49047b4f03f79c5146d8925363eab3072", + "rev": "a06272ae552a3f6bdcb9c63c20fe25b05e5579d1", "type": "github" }, "original": { @@ -589,32 +569,6 @@ "type": "github" } }, - "hyprland-plugins": { - "inputs": { - "hyprland": [ - "hyprland" - ], - "nixpkgs": [ - "nixpkgs" - ], - "systems": [ - "systems" - ] - }, - "locked": { - "lastModified": 1746806942, - "narHash": "sha256-fziL5ORI599D6Wp+BKlspxOqZ1HhCCLkq4C4FBwIwJo=", - "owner": "hyprwm", - "repo": "hyprland-plugins", - "rev": "c491d2831448645f24a1597a17f564aa52691ac6", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "hyprland-plugins", - "type": "github" - } - }, "hyprland-protocols": { "inputs": { "nixpkgs": [ @@ -627,11 +581,11 @@ ] }, "locked": { - "lastModified": 1743714874, - "narHash": "sha256-yt8F7NhMFCFHUHy/lNjH/pjZyIDFNk52Q4tivQ31WFo=", + "lastModified": 1691753796, + "narHash": "sha256-zOEwiWoXk3j3+EoF3ySUJmberFewWlagvewDRuWYAso=", "owner": "hyprwm", "repo": "hyprland-protocols", - "rev": "3a5c2bda1c1a4e55cc1330c782547695a93f05b2", + "rev": "0c2ce70625cb30aef199cb388f99e19a61a6ce03", "type": "github" }, "original": { @@ -640,95 +594,19 @@ "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": 1745951494, - "narHash": "sha256-2dModE32doiyQMmd6EDAQeZnz+5LOs6KXyE0qX76WIg=", - "owner": "hyprwm", - "repo": "hyprland-qtutils", - "rev": "4be1d324faf8d6e82c2be9f8510d299984dfdd2e", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "hyprland-qtutils", - "type": "github" - } - }, "hyprlang": { "inputs": { - "hyprutils": [ - "hyprland", - "hyprutils" - ], "nixpkgs": [ - "hyprland", + "hypridle", "nixpkgs" - ], - "systems": [ - "hyprland", - "systems" ] }, "locked": { - "lastModified": 1746655412, - "narHash": "sha256-kVQ0bHVtX6baYxRWWIh4u3LNJZb9Zcm2xBeDPOGz5BY=", + "lastModified": 1708212860, + "narHash": "sha256-nW3Zrhh9RJcMTvOcXAaKADnJM/g6tDf3121lJtTHnYo=", "owner": "hyprwm", "repo": "hyprlang", - "rev": "557241780c179cf7ef224df392f8e67dab6cef83", + "rev": "11d5ccda071c153dfdc18ef65338956a51cef96a", "type": "github" }, "original": { @@ -737,46 +615,7 @@ "type": "github" } }, - "hyprpaper": { - "inputs": { - "hyprgraphics": [ - "hyprland", - "hyprgraphics" - ], - "hyprlang": [ - "hyprland", - "hyprlang" - ], - "hyprutils": [ - "hyprland", - "hyprutils" - ], - "hyprwayland-scanner": [ - "hyprland", - "hyprwayland-scanner" - ], - "nixpkgs": [ - "nixpkgs" - ], - "systems": [ - "systems" - ] - }, - "locked": { - "lastModified": 1746738843, - "narHash": "sha256-qe4OwoBal5fYoTDV8psE+1jAG8Qv5lJDfWqS/4hEHPU=", - "owner": "hyprwm", - "repo": "hyprpaper", - "rev": "99213a1854d172c529e815834e5b43dab95a3b67", - "type": "github" - }, - "original": { - "owner": "hyprwm", - "repo": "hyprpaper", - "type": "github" - } - }, - "hyprutils": { + "hyprlang_2": { "inputs": { "nixpkgs": [ "hyprland", @@ -788,133 +627,110 @@ ] }, "locked": { - "lastModified": 1746635225, - "narHash": "sha256-W9G9bb0zRYDBRseHbVez0J8qVpD5QbizX67H/vsudhM=", + "lastModified": 1711671891, + "narHash": "sha256-C/Wwsy/RLxHP1axFFl+AnwJRWfd8gxDKKoa8nt8Qk3c=", "owner": "hyprwm", - "repo": "hyprutils", - "rev": "674ea57373f08b7609ce93baff131117a0dfe70d", + "repo": "hyprlang", + "rev": "c1402612146ba06606ebf64963a02bc1efe11e74", "type": "github" }, "original": { "owner": "hyprwm", - "repo": "hyprutils", + "repo": "hyprlang", "type": "github" } }, - "hyprwayland-scanner": { + "hyprlang_3": { "inputs": { "nixpkgs": [ - "hyprland", + "hyprlock", "nixpkgs" ], - "systems": [ - "hyprland", - "systems" - ] + "systems": "systems_5" }, "locked": { - "lastModified": 1739870480, - "narHash": "sha256-SiDN5BGxa/1hAsqhgJsS03C3t2QrLgBT8u+ENJ0Qzwc=", + "lastModified": 1711250455, + "narHash": "sha256-LSq1ZsTpeD7xsqvlsepDEelWRDtAhqwetp6PusHXJRo=", "owner": "hyprwm", - "repo": "hyprwayland-scanner", - "rev": "206367a08dc5ac4ba7ad31bdca391d098082e64b", + "repo": "hyprlang", + "rev": "b3e430f81f3364c5dd1a3cc9995706a4799eb3fa", "type": "github" }, "original": { "owner": "hyprwm", - "repo": "hyprwayland-scanner", + "repo": "hyprlang", "type": "github" } }, - "jovian": { + "hyprlock": { "inputs": { - "nix-github-actions": [ - "nix-github-actions" + "hyprlang": "hyprlang_3", + "nixpkgs": [ + "nixpkgs" ], + "systems": "systems_6" + }, + "locked": { + "lastModified": 1712587141, + "narHash": "sha256-rbzVe2WNdHynJrnyJsKOOrV8yuuJ7QIuah3ZHWERSnA=", + "owner": "hyprwm", + "repo": "hyprlock", + "rev": "bc87adf9ec997090f15d9b662d6ca2f86e25f264", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprlock", + "type": "github" + } + }, + "jellyfin-flake": { + "inputs": { "nixpkgs": [ "nixpkgs" ] }, "locked": { - "lastModified": 1747322066, - "narHash": "sha256-ni6Lj30KbbUGIdTJA8KoL7vlSr1tn2uadCczaFTwciY=", - "owner": "Jovian-Experiments", - "repo": "Jovian-NixOS", - "rev": "6dba63701931daedbdf0ef6be7fbec4f59dc3706", - "type": "github" - }, - "original": { - "owner": "Jovian-Experiments", - "repo": "Jovian-NixOS", - "type": "github" - } - }, - "kapowarr": { - "inputs": { - "libgencomics": "libgencomics", - "nixpkgs": [ - "nixpkgs" - ], - "systems": [ - "systems" - ], - "treefmt-nix": [ - "treefmt-nix" - ] - }, - "locked": { - "lastModified": 1747452031, - "narHash": "sha256-Z4rYXcup5bkixLNxerQCL7EnDqW8z0x4kS73IMJJ8+I=", + "lastModified": 1709785905, + "narHash": "sha256-RUI/to18Mx76ocQmmKAlrbRSN+/sewNt+fdp9iDYWGM=", "owner": "matt1432", - "repo": "Kapowarr", - "rev": "3b408f456a6a67e84e7429f537ebd1c42477ae83", + "repo": "nixos-jellyfin", + "rev": "50274dcec43e2179d6cbf1e045eea5354e6af606", "type": "github" }, "original": { "owner": "matt1432", - "repo": "Kapowarr", + "repo": "nixos-jellyfin", "type": "github" } }, - "kompass": { - "inputs": { - "astal": [ - "astal" - ], - "nixpkgs": [ - "nixpkgs" - ], - "systems": [ - "systems" - ] - }, + "jellyfin-ultrachromic-src": { + "flake": false, "locked": { - "lastModified": 1745323308, - "narHash": "sha256-24sYD/Yxu5AuyoFatLwkTMFJIZqWXHngX5u5/8RUmjo=", - "owner": "kotontrion", - "repo": "kompass", - "rev": "9849f59c5c97af7ab76d8219f182e259d50a6929", + "lastModified": 1688568900, + "narHash": "sha256-DnmvmRTkgmaZVNeOpnqPF6vBouFYGTypRxjyvq0AWI0=", + "owner": "CTalvio", + "repo": "Ultrachromic", + "rev": "b56db9cfdd40c83e563158d50787374708e92c9b", "type": "github" }, "original": { - "owner": "kotontrion", - "repo": "kompass", + "owner": "CTalvio", + "repo": "Ultrachromic", "type": "github" } }, "lib-aggregate": { "inputs": { - "flake-utils": [ - "flake-utils" - ], - "nixpkgs-lib": "nixpkgs-lib" + "flake-utils": "flake-utils_3", + "nixpkgs-lib": "nixpkgs-lib_2" }, "locked": { - "lastModified": 1746965643, - "narHash": "sha256-T7nR7mzTt0XiXQpOAzIRa+SHIaewZrg0OTVh3lhPs2o=", + "lastModified": 1712491724, + "narHash": "sha256-E5EcBzf/zaR3hD8g1CDtqqwXXebSWtqOvoaR+LDjTME=", "owner": "nix-community", "repo": "lib-aggregate", - "rev": "918f12f361dd078dab1f654e3ed21bc83f91d8b1", + "rev": "2737d0204685c3274390229a09eb8f7eaa1a9e89", "type": "github" }, "original": { @@ -923,295 +739,68 @@ "type": "github" } }, - "libgencomics": { - "inputs": { - "nixpkgs": [ - "kapowarr", - "nixpkgs" - ], - "systems": [ - "kapowarr", - "systems" - ], - "treefmt-nix": [ - "kapowarr", - "treefmt-nix" - ] - }, - "locked": { - "lastModified": 1747187755, - "narHash": "sha256-PApfGydy9BqPfqFrxl7gC9V9216j9V6u9iA3xbYvRzY=", - "owner": "matt1432", - "repo": "LibgenComics", - "rev": "154556d19069c4fcb7a37d1c9591f768e10abddb", - "type": "github" - }, - "original": { - "owner": "matt1432", - "repo": "LibgenComics", - "type": "github" - } - }, - "libratbag-src": { + "modernx-src": { "flake": false, "locked": { - "lastModified": 1746957004, - "narHash": "sha256-+aCORAue2hs8DPcWPszzMwGC9SMfJ/A0zpn7tCwuD9Y=", - "owner": "libratbag", - "repo": "libratbag", - "rev": "78d1124c3e7b992470017ab8a5b5af009745fe4f", + "lastModified": 1712549438, + "narHash": "sha256-q7DwyfmOIM7K1L7vvCpq1EM0RVpt9E/drhAa9rLYb1k=", + "owner": "cyl0", + "repo": "ModernX", + "rev": "3f2ed6b993059c6986bf34be3998048c50547187", "type": "github" }, "original": { - "owner": "libratbag", - "repo": "libratbag", - "type": "github" - } - }, - "lix": { - "inputs": { - "flake-compat": "flake-compat_2", - "nix2container": "nix2container", - "nixpkgs": "nixpkgs", - "nixpkgs-regression": "nixpkgs-regression", - "pre-commit-hooks": "pre-commit-hooks" - }, - "locked": { - "lastModified": 1737234286, - "narHash": "sha256-CCKIAE84dzkrnlxJCKFyffAxP3yfsOAbdvydUGqq24g=", - "rev": "2837da71ec1588c1187d2e554719b15904a46c8b", - "revCount": 16631, - "type": "git", - "url": "https://git.lix.systems/lix-project/lix" - }, - "original": { - "rev": "2837da71ec1588c1187d2e554719b15904a46c8b", - "type": "git", - "url": "https://git.lix.systems/lix-project/lix" - } - }, - "material-symbols-src": { - "flake": false, - "locked": { - "lastModified": 1746806368, - "narHash": "sha256-ph/3haj1lfq0aOwXh6sXRt6YOC2RforP90PiZe4Hch4=", - "owner": "beecho01", - "repo": "material-symbols", - "rev": "e448eda274c537a5ae3c143221f089d4790ea892", - "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": 1745902480, - "narHash": "sha256-pQttcfCaw9K8BD/T2CZdRAb9QEFobyeUj/KmNStgzEg=", - "owner": "Samillion", - "repo": "ModernZ", - "rev": "cd23007c69f1f7d82a80b9369e9ab974abb82837", - "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", + "owner": "cyl0", + "repo": "ModernX", "type": "github" } }, "nh": { "inputs": { - "nixpkgs": [ - "nixpkgs" - ] + "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1746889600, - "narHash": "sha256-I82pvD0mdInsQTFA7SisvmJAusgdp8hJXLFBVd73URw=", - "owner": "nix-community", + "lastModified": 1712310030, + "narHash": "sha256-YsTIJWqANadeXKKAtw41IKGOD55/bML7H9No8lu3h4Q=", + "owner": "viperML", "repo": "nh", - "rev": "9bbd96385f5534ccc2ba7f0b3c29192d7f0eb68c", + "rev": "fd98e31fbf741045b9a649b004b99dfa61f5a63b", "type": "github" }, "original": { - "owner": "nix-community", + "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" - ] + "flake-parts": "flake-parts_4", + "nix-github-actions": "nix-github-actions", + "nixpkgs": "nixpkgs_5", + "treefmt-nix": "treefmt-nix" }, "locked": { - "lastModified": 1744371964, - "narHash": "sha256-QuSt8PsB1huFQVXeSASfbXX0r5hmEFLNgYX4dpKewWs=", + "lastModified": 1705242886, + "narHash": "sha256-TLj334vRwFtSym3m+NnKcNCnKKPNoTC/TDZL40vmOso=", "owner": "nix-community", "repo": "nix-eval-jobs", - "rev": "e376e07271dd405d5427e2dd4a29864fb5347f34", + "rev": "6b03a93296faf174b97546fd573c8b379f523a8d", "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": 1747299968, - "narHash": "sha256-o1O/z2pmtBBMZlkNJTL16gJfc4NUdfdSLWuyk0GU5b0=", - "owner": "Mic92", - "repo": "nix-fast-build", - "rev": "c81770298382b911f7f14db37b0c3e82848ab330", - "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" - ], + "nmd": "nmd", "nmt": "nmt" }, "locked": { @@ -1230,19 +819,15 @@ }, "nix-gaming": { "inputs": { - "flake-parts": [ - "flake-parts" - ], - "nixpkgs": [ - "nixpkgs" - ] + "flake-parts": "flake-parts_3", + "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1747273974, - "narHash": "sha256-2OzfizT3iwD+2dO1Fl4T6+52XBbviq4DuTMTGRK3P9k=", + "lastModified": 1712452624, + "narHash": "sha256-R35K+4krhK5B2fcV6W2HFe/uhXmP8YGTb35uZ+nDAxw=", "owner": "fufexan", "repo": "nix-gaming", - "rev": "bafc474d9d2ac0f97411b48679b00811fff39cfa", + "rev": "06314bbf8fedd83c7253442994a2f0c81d47988e", "type": "github" }, "original": { @@ -1254,15 +839,17 @@ "nix-github-actions": { "inputs": { "nixpkgs": [ + "nixpkgs-wayland", + "nix-eval-jobs", "nixpkgs" ] }, "locked": { - "lastModified": 1737420293, - "narHash": "sha256-F1G5ifvqTpJq7fdkT34e/Jy9VCyzd5XfJ9TO8fHhJWE=", + "lastModified": 1701208414, + "narHash": "sha256-xrQ0FyhwTZK6BwKhahIkUVZhMNk21IEI1nUcWSONtpo=", "owner": "nix-community", "repo": "nix-github-actions", - "rev": "f4158fa080ef4503c8f4c820967d946c2af31ec9", + "rev": "93e39cc1a087d65bcf7a132e75a650c44dd2b734", "type": "github" }, "original": { @@ -1278,11 +865,11 @@ ] }, "locked": { - "lastModified": 1746934494, - "narHash": "sha256-3n6i+F0sDASjkhbvgFDpPDZGp7z19IrRtjfF9TwJpCA=", + "lastModified": 1712459390, + "narHash": "sha256-e12bNDottaGoBgd0AdH/bQvk854xunlWAdZwr/oHO1c=", "owner": "Mic92", "repo": "nix-index-database", - "rev": "e9b21b01e4307176b9718a29ac514838e7f6f4ff", + "rev": "4676d72d872459e1e3a248d049609f110c570e9a", "type": "github" }, "original": { @@ -1291,6 +878,24 @@ "type": "github" } }, + "nix-melt": { + "inputs": { + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "lastModified": 1708375128, + "narHash": "sha256-GIASK5tYXM2TQIYwg5Kb+Kl+myZU6Mv9JT4u+gZbr30=", + "owner": "nix-community", + "repo": "nix-melt", + "rev": "46d1c35ec006da573143c78b404a5e2bd834d997", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-melt", + "type": "github" + } + }, "nix-on-droid": { "inputs": { "home-manager": [ @@ -1302,14 +907,14 @@ ], "nixpkgs-docs": "nixpkgs-docs", "nixpkgs-for-bootstrap": "nixpkgs-for-bootstrap", - "nmd": "nmd" + "nmd": "nmd_2" }, "locked": { - "lastModified": 1747158007, - "narHash": "sha256-uwRCd2RAAdMOvReceeaWHGp8RoGjFyIouQN053MsMSk=", + "lastModified": 1710434231, + "narHash": "sha256-yrWnsG28518tbIapJWiluweHORuuIwAQrA8lga0Sqlw=", "owner": "nix-community", "repo": "nix-on-droid", - "rev": "7f68d674b30997434868c9e93784724fdbf37367", + "rev": "2d93311c4f3f300154d2085e4b4b1d550237da92", "type": "github" }, "original": { @@ -1318,140 +923,18 @@ "type": "github" } }, - "nix-serve-ng": { - "inputs": { - "flake-compat": [ - "flake-compat" - ], - "lix": "lix", - "nixpkgs": [ - "nixpkgs" - ], - "utils": [ - "flake-utils" - ] - }, - "locked": { - "lastModified": 1746904788, - "narHash": "sha256-9ZssgGwiihWtwsPCNx31lH8Be8QH/gz/fMTXL/gyCvg=", - "owner": "aristanetworks", - "repo": "nix-serve-ng", - "rev": "d1b8a9a02f3ac0c7e0050e0daf039c5c069c76fb", - "type": "github" - }, - "original": { - "owner": "aristanetworks", - "repo": "nix-serve-ng", - "type": "github" - } - }, - "nix2container": { - "flake": false, - "locked": { - "lastModified": 1724996935, - "narHash": "sha256-njRK9vvZ1JJsP8oV2OgkBrpJhgQezI03S7gzskCcHos=", - "owner": "nlewo", - "repo": "nix2container", - "rev": "fa6bb0a1159f55d071ba99331355955ae30b3401", - "type": "github" - }, - "original": { - "owner": "nlewo", - "repo": "nix2container", - "type": "github" - } - }, - "nixcord": { - "inputs": { - "flake-compat": [ - "flake-compat" - ], - "nixpkgs": [ - "nixpkgs" - ], - "systems": [ - "systems" - ], - "treefmt-nix": [ - "treefmt-nix" - ] - }, - "locked": { - "lastModified": 1747290621, - "narHash": "sha256-BezYMFJjc2uXfFKn4fbq63fNaUXgEU7mvvab1CxO/2k=", - "owner": "kaylorben", - "repo": "nixcord", - "rev": "5be9b1c492cd45c08da6fa4ec857a6b45f55e65a", - "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": 1746955667, - "narHash": "sha256-VgVbPqZl8S09EGWFmgX++aFsz0Z7VmskSJGBXFE4eEs=", - "owner": "nix-community", - "repo": "nixd", - "rev": "7d19dfe5b65035aa255b83147375fdd8257459b9", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nixd", - "type": "github" - } - }, - "nixos-jellyfin": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ], - "systems": [ - "systems" - ] - }, - "locked": { - "lastModified": 1746087983, - "narHash": "sha256-X9WL5+AZCBPK1EmG/6wsPNB8e/FNy9d0W6VsO3B5Vdk=", - "owner": "matt1432", - "repo": "nixos-jellyfin", - "rev": "937a2287568742e2a672a07bb227c744e6118b60", - "type": "github" - }, - "original": { - "owner": "matt1432", - "repo": "nixos-jellyfin", - "type": "github" - } - }, "nixpkgs": { "locked": { - "lastModified": 1733348545, - "narHash": "sha256-b4JrUmqT0vFNx42aEN9LTWOHomkTKL/ayLopflVf81U=", + "lastModified": 1711668574, + "narHash": "sha256-u1dfs0ASQIEr1icTVrsKwg2xToIpn7ZXxW3RHfHxshg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "9ecb50d2fae8680be74c08bb0a995c5383747f89", + "rev": "219951b495fc2eac67b1456824cc1ec1fd2ee659", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-24.11-small", + "ref": "nixos-23.11", "repo": "nixpkgs", "type": "github" } @@ -1474,27 +957,45 @@ }, "nixpkgs-for-bootstrap": { "locked": { - "lastModified": 1720244366, - "narHash": "sha256-WrDV0FPMVd2Sq9hkR5LNHudS3OSMmUrs90JUTN+MXpA=", + "lastModified": 1708105575, + "narHash": "sha256-sS4AItZeUnAei6v8FqxNlm+/27MPlfoGym/TZP0rmH0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "49ee0e94463abada1de470c9c07bfc12b36dcf40", + "rev": "1d1817869c47682a6bee85b5b0a6537b6c0fba26", "type": "github" }, "original": { "owner": "NixOS", "repo": "nixpkgs", - "rev": "49ee0e94463abada1de470c9c07bfc12b36dcf40", + "rev": "1d1817869c47682a6bee85b5b0a6537b6c0fba26", "type": "github" } }, "nixpkgs-lib": { "locked": { - "lastModified": 1746925973, - "narHash": "sha256-03BE0+8MEQ5hSU5+8OI24X7Rhn5GruYZr18KWAZ5Rzk=", + "dir": "lib", + "lastModified": 1711703276, + "narHash": "sha256-iMUFArF0WCatKK6RzfUJknjem0H9m4KgorO/p3Dopkk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d8fe5e6c92d0d190646fb9f1056741a229980089", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib_2": { + "locked": { + "lastModified": 1712450863, + "narHash": "sha256-K6IkdtMtq9xktmYPj0uaYc8NsIqHuaAoRBaMgu9Fvrw=", "owner": "nix-community", "repo": "nixpkgs.lib", - "rev": "f9077b977f4c06f04afdfcac722fa942dd25818c", + "rev": "3c62b6a12571c9a7f65ab037173ee153d539905f", "type": "github" }, "original": { @@ -1503,46 +1004,66 @@ "type": "github" } }, - "nixpkgs-regression": { + "nixpkgs-pacemaker": { "locked": { - "lastModified": 1643052045, - "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "lastModified": 1707746079, + "narHash": "sha256-oaN25Bz/8ZvqUTigsSsw/G+CQGzYe/VseMVwqi761co=", + "owner": "matt1432", + "repo": "nixpkgs", + "rev": "c23dfe7eababf4387a5d154a8a4a2336dd33e406", + "type": "github" + }, + "original": { + "owner": "matt1432", + "ref": "ocf-fix", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1708819810, + "narHash": "sha256-1KosU+ZFXf31GPeCBNxobZWMgHsSOJcrSFA6F2jhzdE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "rev": "89a2a12e6c8c6a56c72eb3589982c8e2f89c70ea", "type": "github" }, "original": { "owner": "NixOS", + "ref": "release-23.11", "repo": "nixpkgs", - "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + } + }, + "nixpkgs-wayland": { + "inputs": { + "flake-compat": "flake-compat", + "lib-aggregate": "lib-aggregate", + "nix-eval-jobs": "nix-eval-jobs", + "nixpkgs": "nixpkgs_6" + }, + "locked": { + "lastModified": 1712600485, + "narHash": "sha256-68LRBXPgPShdgJ+L2f37TiyG5TyNfQL0PChSVir7uYc=", + "owner": "nix-community", + "repo": "nixpkgs-wayland", + "rev": "2b2ef52556abb7ebbeb15e4759b418370470b4a8", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs-wayland", "type": "github" } }, "nixpkgs_2": { "locked": { - "lastModified": 1747179050, - "narHash": "sha256-qhFMmDkeJX9KJwr5H32f1r7Prs7XbQWtO0h3V0a0rFY=", - "ref": "nixos-unstable", - "rev": "adaa24fbf46737f3f1b5497bf64bae750f82942e", - "shallow": true, - "type": "git", - "url": "https://github.com/NixOS/nixpkgs" - }, - "original": { - "ref": "nixos-unstable", - "shallow": true, - "type": "git", - "url": "https://github.com/NixOS/nixpkgs" - } - }, - "nixpkgs_3": { - "locked": { - "lastModified": 1730768919, - "narHash": "sha256-8AKquNnnSaJRXZxc5YmF/WfmxiHX6MMZZasRP6RRQkE=", + "lastModified": 1712420723, + "narHash": "sha256-VnG0Eu394Ga2FCe8Q66m6OEQF8iAqjDYsjmtl+N2omk=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a04d33c0c3f1a59a2c1cb0c6e34cd24500e5a1dc", + "rev": "9e7f26f82acb057498335362905fde6fea4ca50a", "type": "github" }, "original": { @@ -1552,7 +1073,119 @@ "type": "github" } }, + "nixpkgs_3": { + "locked": { + "lastModified": 1707092692, + "narHash": "sha256-ZbHsm+mGk/izkWtT4xwwqz38fdlwu7nUUKXTOmm4SyE=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "faf912b086576fd1a15fca610166c98d47bc667e", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1712439257, + "narHash": "sha256-aSpiNepFOMk9932HOax0XwNxbA38GOUVOiXfUVPOrck=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ff0dbd94265ac470dda06a657d5fe49de93b4599", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_5": { + "locked": { + "lastModified": 1703134684, + "narHash": "sha256-SQmng1EnBFLzS7WSRyPM9HgmZP2kLJcPAz+Ug/nug6o=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d6863cbcbbb80e71cecfc03356db1cda38919523", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_6": { + "locked": { + "lastModified": 1712439257, + "narHash": "sha256-aSpiNepFOMk9932HOax0XwNxbA38GOUVOiXfUVPOrck=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "ff0dbd94265ac470dda06a657d5fe49de93b4599", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_7": { + "locked": { + "lastModified": 1708296515, + "narHash": "sha256-FyF489fYNAUy7b6dkYV6rGPyzp+4tThhr80KNAaF/yY=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "b98a4e1746acceb92c509bc496ef3d0e5ad8d4aa", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_8": { + "locked": { + "lastModified": 1712163089, + "narHash": "sha256-Um+8kTIrC19vD4/lUCN9/cU9kcOsD1O1m+axJqQPyMM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "fd281bd6b7d3e32ddfa399853946f782553163b5", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "nmd": { + "flake": false, + "locked": { + "lastModified": 1666190571, + "narHash": "sha256-Z1hc7M9X6L+H83o9vOprijpzhTfOBjd0KmUTnpHAVjA=", + "owner": "rycee", + "repo": "nmd", + "rev": "b75d312b4f33bd3294cd8ae5c2ca8c6da2afc169", + "type": "gitlab" + }, + "original": { + "owner": "rycee", + "repo": "nmd", + "type": "gitlab" + } + }, + "nmd_2": { "inputs": { "nixpkgs": [ "nix-on-droid", @@ -1574,6 +1207,26 @@ "type": "sourcehut" } }, + "nms": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1703659416, + "narHash": "sha256-+S75gs0rUWlWpiozAh3sCPar+gfZ96efG7Ifpo5rleA=", + "owner": "matt1432", + "repo": "nixos-minecraft-servers", + "rev": "cee4e78311e225aae0af6a49f410d5da23d40b66", + "type": "github" + }, + "original": { + "owner": "matt1432", + "repo": "nixos-minecraft-servers", + "type": "github" + } + }, "nmt": { "flake": false, "locked": { @@ -1590,18 +1243,31 @@ "type": "gitlab" } }, + "nur": { + "locked": { + "lastModified": 1712605683, + "narHash": "sha256-+ZnPwPchvPG+rOFfpxLjKm+5ZNRtYUBtn1KkEojgsSc=", + "owner": "nix-community", + "repo": "NUR", + "rev": "1db8af43c9b75768461a01d84e17596e331df77f", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "NUR", + "type": "github" + } + }, "nurl": { "inputs": { - "nixpkgs": [ - "nixpkgs" - ] + "nixpkgs": "nixpkgs_7" }, "locked": { - "lastModified": 1726505596, - "narHash": "sha256-WAFqmlsShuQngk6LMFlgz7Oyc41TAQeTa/49phhRizY=", + "lastModified": 1708368674, + "narHash": "sha256-QzvpuikAHHHN91pDkBDoUx3x8LJVHbk2JDwYXe87WCc=", "owner": "nix-community", "repo": "nurl", - "rev": "3a3ba7f0d14d92e1266395d826c6e229797d0044", + "rev": "7f789ea2da9ff52724efb38df01ecda87704fc87", "type": "github" }, "original": { @@ -1613,11 +1279,11 @@ "nvim-theme-src": { "flake": false, "locked": { - "lastModified": 1740373692, - "narHash": "sha256-4CVwtc/uig6GcE+orMHxmRFyZOcDiB2huvqNqRMEGXE=", + "lastModified": 1708834650, + "narHash": "sha256-I3rtbJYv1D+kniOLL9hmTF3ucp/qSNewnO2GmYAERko=", "owner": "Mofiqul", "repo": "dracula.nvim", - "rev": "96c9d19ce81b26053055ad6f688277d655b3f7d2", + "rev": "8d8bddb8814c3e7e62d80dda65a9876f97eb699c", "type": "github" }, "original": { @@ -1626,21 +1292,68 @@ "type": "github" } }, + "pam-fprint-grosshack-src": { + "flake": false, + "locked": { + "lastModified": 1658952526, + "narHash": "sha256-obczZbf/oH4xGaVvp3y3ZyDdYhZnxlCWvL0irgEYIi0=", + "owner": "mishakmak", + "repo": "pam-fprint-grosshack", + "rev": "45b42524fb5783e1e555067743d7e0f70d27888a", + "type": "gitlab" + }, + "original": { + "owner": "mishakmak", + "repo": "pam-fprint-grosshack", + "type": "gitlab" + } + }, + "pcs-src": { + "flake": false, + "locked": { + "lastModified": 1711377409, + "narHash": "sha256-yUskmL/qt4q22rs2/txfaq7WoMUfZnhizVXX+NhAf1k=", + "owner": "ClusterLabs", + "repo": "pcs", + "rev": "4eb3853568f2728447785c40b13c536e12e9d779", + "type": "github" + }, + "original": { + "owner": "ClusterLabs", + "repo": "pcs", + "type": "github" + } + }, + "pcs-web-ui-src": { + "flake": false, + "locked": { + "lastModified": 1711823267, + "narHash": "sha256-fQiyqT2dITQcIcpxKA4lo0QsWze6rFT+fXTrFu6OFfI=", + "owner": "ClusterLabs", + "repo": "pcs-web-ui", + "rev": "b0982778eb6a168299dc48b02ff75c8562906c9d", + "type": "github" + }, + "original": { + "owner": "ClusterLabs", + "repo": "pcs-web-ui", + "type": "github" + } + }, "pcsd": { "inputs": { - "nixpkgs": [ - "nixpkgs" - ], - "systems": [ - "systems" - ] + "nixpkgs": "nixpkgs_8", + "nixpkgs-pacemaker": "nixpkgs-pacemaker", + "pcs-src": "pcs-src", + "pcs-web-ui-src": "pcs-web-ui-src", + "pyagentx-src": "pyagentx-src" }, "locked": { - "lastModified": 1746047967, - "narHash": "sha256-/u5M3B1xqpzvXq1qL+UDEbE7d8eL7ISJCXbCIzOE8QM=", + "lastModified": 1712460400, + "narHash": "sha256-RsTVcT6FYzaL+U9wXUpzyBekJscB238B3wPiQguGMK0=", "owner": "matt1432", "repo": "nixos-pcsd", - "rev": "66cac820594cc90a5f7da9f1a129c0a675ff2193", + "rev": "9cb2fcfcea2a652ae2be2f08654ec2bf732afed6", "type": "github" }, "original": { @@ -1649,30 +1362,95 @@ "type": "github" } }, - "piper-src": { + "persist-properties-src": { "flake": false, "locked": { - "lastModified": 1741362667, - "narHash": "sha256-SgUNP6m/wu+V5F5w4qkMViCV2HvRCCvffbOspJpD9pU=", - "owner": "libratbag", - "repo": "piper", - "rev": "c9f8249b1c1a422d75c74071965ed3aa5cd17dbd", + "lastModified": 1668485020, + "narHash": "sha256-C2nejhkxAZgfKRl9FrZZqODq2xW6zCbv/sBiqXSAd2k=", + "owner": "d87", + "repo": "mpv-persist-properties", + "rev": "ddb1e6bd7a7d57da9b567ea8dc5227906f416ec6", "type": "github" }, "original": { - "owner": "libratbag", - "repo": "piper", + "owner": "d87", + "repo": "mpv-persist-properties", + "type": "github" + } + }, + "plymouth-theme-src": { + "flake": false, + "locked": { + "lastModified": 1704576657, + "narHash": "sha256-nHirp6UMvBd4rMpXu5xWtBf9GN/jasHhZrUol6HGXpA=", + "owner": "matt1432", + "repo": "dracula-plymouth", + "rev": "54c523dbae26bf68683f27cda79c92da87229ab0", + "type": "github" + }, + "original": { + "owner": "matt1432", + "repo": "dracula-plymouth", + "type": "github" + } + }, + "pocketsphinx-src": { + "flake": false, + "locked": { + "lastModified": 1707149455, + "narHash": "sha256-imrwUIpORpfInitVjU11SKPPpjvObKyfI8IB4f41hfY=", + "owner": "cmusphinx", + "repo": "pocketsphinx", + "rev": "7be89aae3e76568e02e4f3d41cf1adcb7654430c", + "type": "github" + }, + "original": { + "owner": "cmusphinx", + "repo": "pocketsphinx", + "type": "github" + } + }, + "pocketsphinx-src_2": { + "flake": false, + "locked": { + "lastModified": 1645539790, + "narHash": "sha256-YZwuVYg8Uqt1gOYXeYC8laRj+IObbuO9f/BjcQKRwkY=", + "owner": "cmusphinx", + "repo": "pocketsphinx", + "rev": "5da71f0a05350c923676b02a69423d1291825d5b", + "type": "github" + }, + "original": { + "owner": "cmusphinx", + "ref": "last-pre-1.0", + "repo": "pocketsphinx", + "type": "github" + } + }, + "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" } }, "pokemon-colorscripts-src": { "flake": false, "locked": { - "lastModified": 1729309951, - "narHash": "sha256-gKVmpHKt7S2XhSxLDzbIHTjJMoiIk69Fch202FZffqU=", + "lastModified": 1666991310, + "narHash": "sha256-rj0qKYHCu9SyNsj1PZn1g7arjcHuIDGHwubZg/yJt7A=", "owner": "phoneybadger", "repo": "pokemon-colorscripts", - "rev": "5802ff67520be2ff6117a0abc78a08501f6252ad", + "rev": "0483c85b93362637bdd0632056ff986c07f30868", "type": "gitlab" }, "original": { @@ -1681,160 +1459,71 @@ "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": { + "pyagentx-src": { "flake": false, "locked": { - "lastModified": 1733318908, - "narHash": "sha256-SVQVsbafSM1dJ4fpgyBqLZ+Lft+jcQuMtEL3lQWx2Sk=", - "owner": "cachix", - "repo": "git-hooks.nix", - "rev": "6f4e2a2112050951a314d2733a994fbab94864c6", + "lastModified": 1511257724, + "narHash": "sha256-uXFRtQskF2HhHi3KhJwajPvt8c8unrBBOqxGimV74Rc=", + "owner": "ondrejmular", + "repo": "pyagentx", + "rev": "8fcc2f056b54b92c67a264671198fd197d5a1799", "type": "github" }, "original": { - "owner": "cachix", - "repo": "git-hooks.nix", + "owner": "ondrejmular", + "repo": "pyagentx", + "rev": "8fcc2f056b54b92c67a264671198fd197d5a1799", "type": "github" } }, - "pre-commit-hooks_2": { - "inputs": { - "flake-compat": [ - "flake-compat" - ], - "gitignore": "gitignore", - "nixpkgs": "nixpkgs_3" - }, - "locked": { - "lastModified": 1746537231, - "narHash": "sha256-Wb2xeSyOsCoTCTj7LOoD6cdKLEROyFAArnYoS+noCWo=", - "owner": "cachix", - "repo": "git-hooks.nix", - "rev": "fa466640195d38ec97cf0493d6d6882bc4d14969", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "git-hooks.nix", - "type": "github" - } - }, - "quickshell": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1747274589, - "narHash": "sha256-4n7sw2OliabN/M1CTpYQlMlJyAJemBMdrLDpLDYpb+k=", - "ref": "refs/heads/master", - "rev": "3102a39bda57707a5b30d6155309da7f20408790", - "revCount": 516, - "type": "git", - "url": "https://git.outfoxxed.me/quickshell/quickshell" - }, - "original": { - "type": "git", - "url": "https://git.outfoxxed.me/quickshell/quickshell" - } - }, "root": { "inputs": { "ags": "ags", + "arion": "arion", "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", + "caddy-plugins": "caddy-plugins", + "coc-stylelintplus": "coc-stylelintplus", + "curseforge-server-downloader-src": "curseforge-server-downloader-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", + "firefox-gx-src": "firefox-gx-src", "git-theme-src": "git-theme-src", "gpu-screen-recorder-src": "gpu-screen-recorder-src", - "grim-hyprland": "grim-hyprland", "gtk-theme-src": "gtk-theme-src", + "headscale": "headscale", "home-manager": "home-manager", + "hypr-official-plugins": "hypr-official-plugins", "hyprgrass": "hyprgrass", + "hypridle": "hypridle", "hyprland": "hyprland", - "hyprland-plugins": "hyprland-plugins", - "hyprpaper": "hyprpaper", - "jovian": "jovian", - "kapowarr": "kapowarr", - "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", + "hyprlock": "hyprlock", + "jellyfin-flake": "jellyfin-flake", + "jellyfin-ultrachromic-src": "jellyfin-ultrachromic-src", + "modernx-src": "modernx-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-melt": "nix-melt", "nix-on-droid": "nix-on-droid", - "nix-serve-ng": "nix-serve-ng", - "nixcord": "nixcord", - "nixd": "nixd", - "nixos-jellyfin": "nixos-jellyfin", - "nixpkgs": "nixpkgs_2", + "nixpkgs": "nixpkgs_4", + "nixpkgs-wayland": "nixpkgs-wayland", + "nms": "nms", + "nur": "nur", "nurl": "nurl", "nvim-theme-src": "nvim-theme-src", + "pam-fprint-grosshack-src": "pam-fprint-grosshack-src", "pcsd": "pcsd", - "piper-src": "piper-src", + "persist-properties-src": "persist-properties-src", + "plymouth-theme-src": "plymouth-theme-src", + "pocketsphinx-src": "pocketsphinx-src", + "pointer-event-src": "pointer-event-src", "pokemon-colorscripts-src": "pokemon-colorscripts-src", - "pr-tracker": "pr-tracker", - "pre-commit-hooks": "pre-commit-hooks_2", - "quickshell": "quickshell", "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" + "subsync": "subsync", + "touch-gestures-src": "touch-gestures-src", + "trash-d-src": "trash-d-src", + "vimplugin-riscv-src": "vimplugin-riscv-src", + "xresources-theme-src": "xresources-theme-src" } }, "scss-reset": { @@ -1858,16 +1547,14 @@ "nixpkgs": [ "nixpkgs" ], - "sops-nix": [ - "sops-nix" - ] + "sops-nix": "sops-nix" }, "locked": { - "lastModified": 1746919476, - "narHash": "sha256-3o0OyCoila/0jKAz8NSB7pY4zpOJZ7teBoQnHZF5Zqg=", + "lastModified": 1709358901, + "narHash": "sha256-/6XBTAxSATwbCudcqnDyx0yM2ic8ctKxdkp5wvH1VIk=", "ref": "refs/heads/main", - "rev": "6d066eafc7f751adb063f1910b8c5009774dc3ff", - "revCount": 98, + "rev": "d6f17af6dc95428212abb0219195bdab2498fb3a", + "revCount": 54, "type": "git", "url": "ssh://git@git.nelim.org/matt1432/nixos-secrets" }, @@ -1876,50 +1563,20 @@ "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": [ + "secrets", "nixpkgs" - ] + ], + "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1746485181, - "narHash": "sha256-PxrrSFLaC7YuItShxmYbMgSuFFuwxBB+qsl9BZUnRvg=", + "lastModified": 1708987867, + "narHash": "sha256-k2lDaDWNTU5sBVHanYzjDKVDmk29RHIgdbbXu5sdzBA=", "owner": "Mic92", "repo": "sops-nix", - "rev": "e93ee1d900ad264d65e9701a5c6f895683433386", + "rev": "a1c8de14f60924fafe13aea66b46157f0150f4cf", "type": "github" }, "original": { @@ -1928,55 +1585,77 @@ "type": "github" } }, - "spotifyplus-src": { + "sphinxbase-src": { "flake": false, "locked": { - "lastModified": 1747076973, - "narHash": "sha256-GCRE4TejCiOjGtQEkDzXhOhTCtPdK9lBMhEatikwL8A=", - "owner": "thlucas1", - "repo": "homeassistantcomponent_spotifyplus", - "rev": "514e1af02e560a84e21386d6cc2ad473ebb90724", + "lastModified": 1654774494, + "narHash": "sha256-w/Huz4+crTzdiSyQVAx0h3lhtTTrtPyKp3xpQD5EG9g=", + "owner": "cmusphinx", + "repo": "sphinxbase", + "rev": "617e53691889336a482631380f75b453445d0dae", "type": "github" }, "original": { - "owner": "thlucas1", - "repo": "homeassistantcomponent_spotifyplus", + "owner": "cmusphinx", + "repo": "sphinxbase", + "rev": "617e53691889336a482631380f75b453445d0dae", "type": "github" } }, - "spotifywebapi-src": { - "flake": false, + "subsync": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "pocketsphinx-src": "pocketsphinx-src_2", + "sphinxbase-src": "sphinxbase-src" + }, "locked": { - "lastModified": 1747069738, - "narHash": "sha256-WzwJugwerbkQWn4TYutCOAjcsRjTZAia5dT4R3Pnkz4=", - "owner": "thlucas1", - "repo": "SpotifyWebApiPython", - "rev": "4794d2420479579c08b94f9cda865ee5c7764498", + "lastModified": 1712018289, + "narHash": "sha256-JYG+GQuyvDoZ6TWD0lDjaWDNTq5FxNh3AymTHxWyggI=", + "owner": "matt1432", + "repo": "subsync", + "rev": "ee9e1592ae4ec7c694d8857aa72be079d81ea209", "type": "github" }, "original": { - "owner": "thlucas1", - "repo": "SpotifyWebApiPython", + "owner": "matt1432", + "repo": "subsync", + "rev": "ee9e1592ae4ec7c694d8857aa72be079d81ea209", "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": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { "locked": { "lastModified": 1689347949, "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", @@ -1991,18 +1670,112 @@ "type": "github" } }, + "systems_4": { + "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" + } + }, + "systems_5": { + "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" + } + }, + "systems_6": { + "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" + } + }, + "systems_7": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "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" + } + }, + "trash-d-src": { + "flake": false, + "locked": { + "lastModified": 1692895205, + "narHash": "sha256-oPxeoEqOYf6DCg5rJxINqAIlMbxqzAJcZDUY/EzADzY=", + "owner": "rushsteve1", + "repo": "trash-d", + "rev": "d88bb672612761c8e299e717857bf9c85a903e99", + "type": "github" + }, + "original": { + "owner": "rushsteve1", + "repo": "trash-d", + "type": "github" + } + }, "treefmt-nix": { "inputs": { "nixpkgs": [ + "nixpkgs-wayland", + "nix-eval-jobs", "nixpkgs" ] }, "locked": { - "lastModified": 1747299117, - "narHash": "sha256-JGjCVbxS+9t3tZ2IlPQ7sdqSM4c+KmIJOXVJPfWmVOU=", + "lastModified": 1702979157, + "narHash": "sha256-RnFBbLbpqtn4AoJGXKevQMCGhra4h6G2MPcuTSZZQ+g=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "e758f27436367c23bcd63cd973fa5e39254b530e", + "rev": "2961375283668d867e64129c22af532de8e77734", "type": "github" }, "original": { @@ -2011,120 +1784,39 @@ "type": "github" } }, - "ts-for-gir-src": { + "vimplugin-riscv-src": { "flake": false, "locked": { - "lastModified": 1742620702, - "narHash": "sha256-w6dAjvfuDbfsI9Wxg9MSavsHkXAznomrFs5sD2Q/eZg=", - "owner": "gjsify", - "repo": "ts-for-gir", - "rev": "3f4d63534dd03ad8bbcfb57b3308adfafc27f725", + "lastModified": 1708141837, + "narHash": "sha256-9OByJMfa85gu98g8rGJKtDgXqQdzZ8pc0du4UVomeqY=", + "owner": "henry-hsieh", + "repo": "riscv-asm-vim", + "rev": "4a287063af666292af74d912fd97b7af5fa32925", "type": "github" }, "original": { - "owner": "gjsify", - "repo": "ts-for-gir", + "owner": "henry-hsieh", + "repo": "riscv-asm-vim", "type": "github" } }, - "tuya-local-src": { + "wlroots": { "flake": false, "locked": { - "lastModified": 1747225051, - "narHash": "sha256-f5z45yCOUa/Dmvl0UEAStcSJwaVn5DT+tHelUii+NgY=", - "owner": "make-all", - "repo": "tuya-local", - "rev": "85a9061caec697d2b2d4bf57056860d4f9874f01", - "type": "github" + "host": "gitlab.freedesktop.org", + "lastModified": 1709983277, + "narHash": "sha256-wXWIJLd4F2JZeMaihWVDW/yYXCLEC8OpeNJZg9a9ly8=", + "owner": "wlroots", + "repo": "wlroots", + "rev": "50eae512d9cecbf0b3b1898bb1f0b40fa05fe19b", + "type": "gitlab" }, "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": 1746598350, - "narHash": "sha256-jrWzIoaorwQk8phqxAM5zoio4reM1e+qjXd/4Syhp24=", - "owner": "seblj", - "repo": "roslyn.nvim", - "rev": "8dc729a651ae980088246caf651e5ff24e21077a", - "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": 1745833925, - "narHash": "sha256-94Bm3WWIx/dP88RbmSCOJvE9qPYcaPhgkfGuNyNSYek=", - "owner": "fwartner", - "repo": "home-assistant-wakewords-collection", - "rev": "c7fbdcef2342974f05831dddae15462fd00bad4f", - "type": "github" - }, - "original": { - "owner": "fwartner", - "repo": "home-assistant-wakewords-collection", - "type": "github" + "host": "gitlab.freedesktop.org", + "owner": "wlroots", + "repo": "wlroots", + "rev": "50eae512d9cecbf0b3b1898bb1f0b40fa05fe19b", + "type": "gitlab" } }, "xdph": { @@ -2137,14 +1829,6 @@ "hyprland", "hyprlang" ], - "hyprutils": [ - "hyprland", - "hyprutils" - ], - "hyprwayland-scanner": [ - "hyprland", - "hyprwayland-scanner" - ], "nixpkgs": [ "hyprland", "nixpkgs" @@ -2155,11 +1839,11 @@ ] }, "locked": { - "lastModified": 1745871725, - "narHash": "sha256-M24SNc2flblWGXFkGQfqSlEOzAGZnMc9QG3GH4K/KbE=", + "lastModified": 1709299639, + "narHash": "sha256-jYqJM5khksLIbqSxCLUUcqEgI+O2LdlSlcMEBs39CAU=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "76bbf1a6b1378e4ab5230bad00ad04bc287c969e", + "rev": "2d2fb547178ec025da643db57d40a971507b82fe", "type": "github" }, "original": { @@ -2168,19 +1852,19 @@ "type": "github" } }, - "yamaha-soundbar-src": { + "xresources-theme-src": { "flake": false, "locked": { - "lastModified": 1745912100, - "narHash": "sha256-LIVQlduYCCrcLaZxCokoNcbkwzUHWfnsD0BRPObhOkA=", - "owner": "osk2", - "repo": "yamaha-soundbar", - "rev": "ad779df8e0887118ce97284480dd129f5d87490e", + "lastModified": 1647833631, + "narHash": "sha256-6fltsAluqOqYIh2NX0I/LC3WCWkb9Fn8PH6LNLBQbrY=", + "owner": "dracula", + "repo": "xresources", + "rev": "539ef24e9b0c5498a82d59bfa2bad9b618d832a3", "type": "github" }, "original": { - "owner": "osk2", - "repo": "yamaha-soundbar", + "owner": "dracula", + "repo": "xresources", "type": "github" } } diff --git a/flake.nix b/flake.nix index f08f5421..f3da46bf 100644 --- a/flake.nix +++ b/flake.nix @@ -1,528 +1,457 @@ -# Do not modify! This file is generated. { + outputs = inputs @ { + self, + home-manager, + nixpkgs, + nix-on-droid, + secrets, + ... + }: let + supportedSystems = ["x86_64-linux" "aarch64-linux"]; + + perSystem = attrs: + nixpkgs.lib.genAttrs supportedSystems (system: let + pkgs = nixpkgs.legacyPackages.${system}; + in + attrs system pkgs); + + # Default system + mkNixOS = mods: + nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + specialArgs = inputs; + modules = + [ + {home-manager.extraSpecialArgs = inputs;} + ./common + ] + ++ mods; + }; + + # Nix-On-Droid + inherit (nix-on-droid.lib) nixOnDroidConfiguration; + in { + nixosConfigurations = { + wim = mkNixOS [ + ./devices/wim + secrets.nixosModules.default + ]; + binto = mkNixOS [./devices/binto]; + + nos = mkNixOS [ + ./devices/nos + secrets.nixosModules.nos + ]; + + servivi = mkNixOS [ + ./devices/servivi + secrets.nixosModules.servivi + ]; + + # Cluster + thingone = mkNixOS [ + (import ./devices/cluster "thingone") + secrets.nixosModules.thingy + ]; + thingtwo = mkNixOS [ + (import ./devices/cluster "thingtwo") + secrets.nixosModules.thingy + ]; + + live-image = mkNixOS [ + ("${nixpkgs}/nixos/modules/installer/" + + "cd-dvd/installation-cd-minimal.nix") + {home-manager.users.nixos.home.stateVersion = "24.05";} + {vars.mainUser = "nixos";} + ]; + }; + + nixOnDroidConfigurations.default = nixOnDroidConfiguration ( + import ./devices/android inputs + ); + + formatter = perSystem (_: pkgs: pkgs.alejandra); + + devShells = perSystem (_: pkgs: { + default = pkgs.mkShell { + packages = with pkgs; [ + alejandra + git + + (pkgs.writeShellScriptBin "mkIso" (lib.concatStrings [ + "nix build $(realpath /etc/nixos)#nixosConfigurations." + "live-image.config.system.build.isoImage" + ])) + ]; + }; + + ags = pkgs.mkShell { + packages = with pkgs; [ + nodejs_18 + ]; + }; + + node-dev = pkgs.mkShell { + packages = with pkgs; + [ + nodejs_latest + ffmpeg + typescript + ] + ++ (with nodePackages; [ + ts-node + ]); + }; + }); + }; + inputs = { - 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"; + # Main inputs + nixpkgs = { type = "github"; + owner = "NixOS"; + repo = "nixpkgs"; + ref = "nixos-unstable"; }; + home-manager = { - inputs.nixpkgs.follows = "nixpkgs"; + type = "github"; 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"; - }; - kapowarr = { - inputs = { - nixpkgs.follows = "nixpkgs"; - systems.follows = "systems"; - treefmt-nix.follows = "treefmt-nix"; - }; - owner = "matt1432"; - repo = "Kapowarr"; - 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 = "nix-community"; - 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 = { - ref = "nixos-unstable"; - shallow = true; - type = "git"; - url = "https://github.com/NixOS/nixpkgs"; - }; - 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"; - owner = "cachix"; - repo = "git-hooks.nix"; - type = "github"; - }; - quickshell = { - inputs.nixpkgs.follows = "nixpkgs"; - type = "git"; - url = "https://git.outfoxxed.me/quickshell/quickshell"; }; + 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"; + }; + + nix-on-droid = { type = "github"; + owner = "nix-community"; + repo = "nix-on-droid"; + + inputs = { + nixpkgs.follows = "nixpkgs"; + home-manager.follows = "home-manager"; + }; }; - spotifyplus-src = { - flake = false; - owner = "thlucas1"; - repo = "homeassistantcomponent_spotifyplus"; + + # Overlays + nixpkgs-wayland = { type = "github"; + owner = "nix-community"; + repo = "nixpkgs-wayland"; }; - spotifywebapi-src = { - flake = false; - owner = "thlucas1"; - repo = "SpotifyWebApiPython"; + + nur = { type = "github"; + owner = "nix-community"; + repo = "NUR"; }; - subscleaner-src = { - flake = false; - owner = "rogs"; - repo = "subscleaner"; - type = "gitlab"; - }; - systems = { - owner = "nix-systems"; - repo = "default-linux"; + + nix-gaming = { type = "github"; + owner = "fufexan"; + repo = "nix-gaming"; }; - treefmt-nix = { + + # Cluster Inputs + pcsd = { + type = "github"; + owner = "matt1432"; + repo = "nixos-pcsd"; + }; + + headscale = { + type = "github"; + owner = "juanfont"; + repo = "headscale"; + inputs.nixpkgs.follows = "nixpkgs"; - owner = "numtide"; - repo = "treefmt-nix"; - type = "github"; }; - ts-for-gir-src = { - flake = false; - owner = "gjsify"; - repo = "ts-for-gir"; + + caddy-plugins = { 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 = { + owner = "matt1432"; + repo = "nixos-caddy-cloudflare"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # Servivi inputs + nms = { + type = "github"; + owner = "matt1432"; + repo = "nixos-minecraft-servers"; + + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # Nos inputs + arion = { + type = "github"; + owner = "hercules-ci"; + repo = "arion"; + + inputs.nixpkgs.follows = "nixpkgs"; + }; + + jellyfin-flake = { + type = "github"; + owner = "matt1432"; + repo = "nixos-jellyfin"; + + inputs.nixpkgs.follows = "nixpkgs"; + }; + + subsync = { + type = "github"; + owner = "matt1432"; + repo = "subsync"; + + # Keep version that uses Sphinxbase + rev = "ee9e1592ae4ec7c694d8857aa72be079d81ea209"; + + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # Desktop inputs + hyprland = { + type = "github"; + owner = "hyprwm"; + repo = "Hyprland"; + + inputs.nixpkgs.follows = "nixpkgs"; + }; + hypridle = { + type = "github"; + owner = "hyprwm"; + repo = "hypridle"; + + inputs.nixpkgs.follows = "nixpkgs"; + }; + hyprlock = { + type = "github"; + owner = "hyprwm"; + repo = "hyprlock"; + + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # FIXME: https://github.com/horriblename/hyprgrass/issues/76 + hyprgrass = { + type = "github"; owner = "horriblename"; - repo = "fcitx-virtualkeyboard-adapter"; - type = "github"; + repo = "hyprgrass"; + + inputs.hyprland.follows = "hyprland"; }; - wakewords-src = { - flake = false; - owner = "fwartner"; - repo = "home-assistant-wakewords-collection"; + hypr-official-plugins = { type = "github"; + owner = "hyprwm"; + repo = "hyprland-plugins"; + + inputs.hyprland.follows = "hyprland"; }; - yamaha-soundbar-src = { - flake = false; - owner = "osk2"; - repo = "yamaha-soundbar"; + + ags = { type = "github"; + owner = "Aylur"; + repo = "ags"; + + inputs.nixpkgs.follows = "nixpkgs"; + }; + astal = { + type = "github"; + owner = "Aylur"; + repo = "Astal"; + + inputs.nixpkgs.follows = "nixpkgs"; + }; + + coc-stylelintplus = { + type = "github"; + owner = "matt1432"; + repo = "coc-stylelintplus"; + + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # Nix tools + nurl = { + type = "github"; + owner = "nix-community"; + repo = "nurl"; + }; + + nix-index-db = { + type = "github"; + owner = "Mic92"; + repo = "nix-index-database"; + + inputs.nixpkgs.follows = "nixpkgs"; + }; + + nh = { + type = "github"; + owner = "viperML"; + repo = "nh"; + }; + + nix-melt = { + type = "github"; + owner = "nix-community"; + repo = "nix-melt"; + }; + + # -= Non-flake inputs =- + + ## Custom packages + pocketsphinx-src = { + type = "github"; + owner = "cmusphinx"; + repo = "pocketsphinx"; + flake = false; + }; + + trash-d-src = { + type = "github"; + owner = "rushsteve1"; + repo = "trash-d"; + flake = false; + }; + + pam-fprint-grosshack-src = { + type = "gitlab"; + owner = "mishakmak"; + repo = "pam-fprint-grosshack"; + flake = false; + }; + + pokemon-colorscripts-src = { + type = "gitlab"; + owner = "phoneybadger"; + repo = "pokemon-colorscripts"; + flake = false; + }; + + curseforge-server-downloader-src = { + type = "github"; + owner = "Malpiszonekx4"; + repo = "curseforge-server-downloader"; + flake = false; + }; + + vimplugin-riscv-src = { + type = "github"; + owner = "henry-hsieh"; + repo = "riscv-asm-vim"; + flake = false; + }; + + ## Overlays + gpu-screen-recorder-src = { + type = "git"; + url = "https://repo.dec05eba.com/gpu-screen-recorder"; + flake = false; + }; + + # MPV scripts + modernx-src = { + type = "github"; + owner = "cyl0"; + repo = "ModernX"; + flake = false; + }; + + persist-properties-src = { + type = "github"; + owner = "d87"; + repo = "mpv-persist-properties"; + flake = false; + }; + + pointer-event-src = { + type = "github"; + owner = "christoph-heinrich"; + repo = "mpv-pointer-event"; + flake = false; + }; + + touch-gestures-src = { + type = "github"; + owner = "christoph-heinrich"; + repo = "mpv-touch-gestures"; + flake = false; + }; + + eisa-scripts-src = { + type = "github"; + owner = "Eisa01"; + repo = "mpv-scripts"; + flake = false; + }; + + ## Dracula and theme src + jellyfin-ultrachromic-src = { + type = "github"; + owner = "CTalvio"; + repo = "Ultrachromic"; + flake = false; + }; + + bat-theme-src = { + type = "github"; + owner = "matt1432"; + repo = "bat"; + flake = false; + }; + + firefox-gx-src = { + type = "github"; + owner = "Godiesc"; + repo = "firefox-gx"; + ref = "v.9.0"; + flake = false; + }; + + git-theme-src = { + type = "github"; + owner = "dracula"; + repo = "git"; + flake = false; + }; + + gtk-theme-src = { + type = "github"; + owner = "dracula"; + repo = "gtk"; + flake = false; + }; + + nvim-theme-src = { + type = "github"; + owner = "Mofiqul"; + repo = "dracula.nvim"; + flake = false; + }; + + plymouth-theme-src = { + type = "github"; + owner = "matt1432"; + repo = "dracula-plymouth"; + flake = false; + }; + + xresources-theme-src = { + type = "github"; + owner = "dracula"; + repo = "xresources"; + flake = false; }; }; - outputs = inputs: inputs.flakegen ./_outputs.nix inputs; } diff --git a/home/firefox/addons/addons.json b/home/firefox/addons/addons.json new file mode 100644 index 00000000..85a45887 --- /dev/null +++ b/home/firefox/addons/addons.json @@ -0,0 +1,20 @@ +[ + { + "slug": "600-sound-volume" + }, + { + "slug": "google-container" + }, + { + "slug": "checkmarks-web-ext" + }, + { + "slug": "ttv-lol-pro" + }, + { + "slug": "floccus" + }, + { + "slug": "opera-gx-witchcraft-purple" + } +] diff --git a/scopedPackages/firefox-addons/default.nix b/home/firefox/addons/default.nix similarity index 52% rename from scopedPackages/firefox-addons/default.nix rename to home/firefox/addons/default.nix index b1d78836..fc75dfd1 100644 --- a/scopedPackages/firefox-addons/default.nix +++ b/home/firefox/addons/default.nix @@ -1,9 +1,7 @@ { fetchurl, lib, - pkgs, stdenv, - ... } @ args: let buildFirefoxXpiAddon = lib.makeOverridable ({ stdenv ? args.stdenv, @@ -27,7 +25,9 @@ allowSubstitutes = true; buildCommand = - # bash + /* + bash + */ '' dst="$out/share/mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}" mkdir -p "$dst" @@ -39,4 +39,21 @@ inherit buildFirefoxXpiAddon fetchurl lib stdenv; }; in - lib.makeScope pkgs.newScope (_: packages // {inherit buildFirefoxXpiAddon;}) + packages + // { + inherit buildFirefoxXpiAddon; + + seventv = buildFirefoxXpiAddon { + pname = "frankerfacez"; + version = "4.0"; + addonId = "frankerfacez@frankerfacez.com"; + url = "https://cdn.frankerfacez.com/script/frankerfacez-4.0-an+fx.xpi"; + sha256 = "sha256-U/yAra2c+RlGSaQtHfBz9XYsoDaJ67gmPJBsFrpqoE8="; + meta = with lib; { + homepage = "https://www.frankerfacez.com/"; + description = "The Twitch Enhancement Suite. Get custom emotes and tons of new features you'll never want to go without."; + license = licenses.asl20; + platforms = platforms.all; + }; + }; + } diff --git a/home/firefox/addons/ffz-settings (2023-12-13).json b/home/firefox/addons/ffz-settings (2023-12-13).json new file mode 100644 index 00000000..b745c0b9 --- /dev/null +++ b/home/firefox/addons/ffz-settings (2023-12-13).json @@ -0,0 +1 @@ +{"version":2,"type":"full","values":{"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.use-cluster","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.enabled","chat.emotes.2x","chat.emotes.limit-size","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.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","metadata.featured-follow","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.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.disable-handling","chat.filtering.blocked-types","chat.replies.style","channel.raids.no-autojoin","channel.raids.blocked-channels","chat.hide-community-highlights","chat.subs.gift-banner","chat.banners.last-events","chat.banners.charity","chat.banners.hype-train","chat.banners.kappa-train","chat.banners.polls","chat.banners.prediction","chat.community-chest.show","chat.bits.show-pinned","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.bits.show-rewards","chat.rituals.show","chat.hype.message-style","chat.hype.show-pinned","chat.subs.show","chat.subs.compact","chat.subs.merge-gifts","chat.subs.merge-gifts-visibility","metadata.modview.hide-info","layout.swap-sidebars","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.uptime","directory.hide-live","directory.hide-promoted","directory.hide-vodcasts","directory.hide-recommended","directory.block-titles","directory.blocked-tags","directory.default-sort","clips.layout.big","player.theatre.metadata","player.theatre.no-whispers","player.theatre.auto-enter","player.embed-metadata","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-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","add-ons","addons.dev.server","experiments","i18n.debug.open","socket.info","profiles","backup","clear","provider","home","debug.graphql-test","faq","chat.filtering.syntax-help","feedback","feedback.log","changelog","addon-changelog","legal","debug.chat-test","directory.game.blocked-games","directory.game.hidden-thumbnails","addon-changelog.unread-mentions-counter","addon-changelog.smokemotes","addon-changelog.smm2-links","addon-changelog.screenshoter","addon-changelog.repetition-detector","addon-changelog.pronouns","addon-changelog.prattlenot","addon-changelog.poll-shim","addon-changelog.new-account-highlighter","addon-changelog.inline-tab-completion","addon-changelog.fs-chat","addon-changelog.first-message-highlighter","addon-changelog.ffzap-liriklive","addon-changelog.ffzap-bttv","addon-changelog.emoteless","addon-changelog.declutter","addon-changelog.deck","addon-changelog.clip-confirm","addon-changelog.chatterino-badges","addon-changelog.brcm","addon-changelog.aplatypuss-emotes","addon-changelog.ModTools","addon-changelog.7tv-emotes","addon.seventv_emotes.animated_avatars","addon.seventv_emotes.badges","addon.seventv_emotes.nametag_paints","addon.seventv_emotes.global_emotes","addon.seventv_emotes.channel_emotes","addon.seventv_emotes.personal_emotes","addon.seventv_emotes.unlisted_emotes","addon.seventv_emotes.update_messages","ffzap.betterttv.global_emoticons","ffzap.betterttv.arbitrary_emoticons","ffzap.betterttv.channel_emoticons","ffzap.betterttv.pro_badges","ffzap.betterttv.pro_emoticons","ffzap.core.remove_spaces","ffzap.core.message_deletion","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","addon.chatterino_badges.badges","first_message_highlight.priority","first_message_highlight.highlight_color","first_message_highlight.remember_historical","first_message_highlight.highlight_historical","first_message_highlight.only_moderated_channels","addon.inlinetab.tips","addon.inlinetab.tip-count","addon.inlinetab.no_commands","addon.inlinetab.no_mentions","addon.inlinetab.mention_prefix","newusers.minage","newusers.priority","newusers.highlightcolor","addon.pronouns.color","addon.pronouns.border","addon.pronouns.color.aeaer","addon.pronouns.color.any","addon.pronouns.color.eem","addon.pronouns.color.faefaer","addon.pronouns.color.hehim","addon.pronouns.color.heshe","addon.pronouns.color.hethem","addon.pronouns.color.itits","addon.pronouns.color.other","addon.pronouns.color.perper","addon.pronouns.color.sheher","addon.pronouns.color.shethem","addon.pronouns.color.theythem","addon.pronouns.color.vever","addon.pronouns.color.xexem","addon.pronouns.color.ziehir"],"cfg-collapsed":[],"addons.enabled":["7tv-emotes","ffzap-core","ffzap-bttv","chatterino-badges","first-message-highlighter","inline-tab-completion","new-account-highlighter","pronouns"],"p:0:addon.seventv_emotes.unlisted_emotes":true,"p:0:addon.seventv_emotes.nametag_paints":false,"p:0:layout.portrait":true,"p:0:layout.portrait-min-chat":true,"p:0:layout.subtember":false,"p:0:clips.layout.big":true,"p:0:layout.side-nav.hide-offline":true,"p:0:layout.display-bits-button":false,"p:0:layout.hide-discover-luna":true,"p:0:layout.turbo-cta":false,"p:0:layout.prime-offers":false,"p:0:channel.auto-click-chat":true,"p:0:channel.auto-skip-trailer":true,"p:0:metadata.player-stats":true,"p:0:sub-button.prime-notice":false,"p:0:chat.bits.show-pinned":false,"p:0:chat.community-chest.show":false,"p:0:chat.rich.all-links":true,"p:0:chat.subs.merge-gifts":20,"p:0:chat.filtering.ignore-clear":true,"p:0:chat.filtering.remove-deleted":0,"p:0:chat.filtering.display-deleted":"DETAILED","p:0:chat.bits.animated":false,"p:0:chat.bits.cheer-notice":false,"p:0:chat.bits.show":false,"p:0:chat.points.auto-rewards":true,"p:0:chat.points.show-rewards":false,"p:0:chat.points.show-callouts":false,"p:0:chat.drops.auto-rewards":true,"p:0:chat.emote-menu.icon":true,"p:0:chat.emote-menu.show-quick-nav":true,"p:0:chat.emote-menu.tall":true,"p:0:chat.emote-menu.clear-search":true,"p:0:chat.emote-menu.combine-tabs":true,"p:0:directory.hide-recommended":false,"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/home/firefox/addons/generated-firefox-addons.nix b/home/firefox/addons/generated-firefox-addons.nix new file mode 100644 index 00000000..12038b0d --- /dev/null +++ b/home/firefox/addons/generated-firefox-addons.nix @@ -0,0 +1,134 @@ +{ + buildFirefoxXpiAddon, + fetchurl, + lib, + stdenv, +}: { + "600-sound-volume" = buildFirefoxXpiAddon { + pname = "600-sound-volume"; + version = "1.5.5"; + addonId = "{c4b582ec-4343-438c-bda2-2f691c16c262}"; + url = "https://addons.mozilla.org/firefox/downloads/file/4219765/600_sound_volume-1.5.5.xpi"; + sha256 = "efc686d54727f29b5c796f4037f19a5d5f31f77354c9c5f8f47d8768ba24fe98"; + meta = with lib; { + homepage = "http://resourcefulman.net/"; + description = "Up to 600% volume boost"; + license = licenses.mpl20; + mozPermissions = [ + "<all_urls>" + "tabs" + "activeTab" + "storage" + "webRequest" + "webRequestBlocking" + ]; + platforms = platforms.all; + }; + }; + "checkmarks-web-ext" = buildFirefoxXpiAddon { + pname = "checkmarks-web-ext"; + version = "1.6.1"; + addonId = "{bd97f89b-17ba-4539-9fec-06852d07f917}"; + url = "https://addons.mozilla.org/firefox/downloads/file/3594420/checkmarks_web_ext-1.6.1.xpi"; + sha256 = "c3ccf4b302ee96c9b883c4a1f7d26395ab4e276b976cab2d65c9cd898964e4f0"; + meta = with lib; { + homepage = "https://github.com/tanwald/checkmarks"; + description = "Checks, sorts, formats bookmarks and loads favicons."; + license = licenses.gpl3; + mozPermissions = [ + "<all_urls>" + "bookmarks" + "browsingData" + "storage" + "tabs" + "webNavigation" + "webRequest" + "webRequestBlocking" + ]; + platforms = platforms.all; + }; + }; + "floccus" = buildFirefoxXpiAddon { + pname = "floccus"; + version = "5.0.10"; + addonId = "floccus@handmadeideas.org"; + url = "https://addons.mozilla.org/firefox/downloads/file/4247541/floccus-5.0.10.xpi"; + sha256 = "8e8ef6e0737df84405c98bf902b1d4b4ffaff743aa880e9205759c8c16dac236"; + meta = with lib; { + homepage = "https://floccus.org"; + description = "Sync your bookmarks across browsers via Nextcloud, WebDAV or 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; + }; + }; + "opera-gx-witchcraft-purple" = buildFirefoxXpiAddon { + pname = "opera-gx-witchcraft-purple"; + version = "2.0"; + addonId = "{bf197856-a3c2-4280-84c5-9b556379b706}"; + url = "https://addons.mozilla.org/firefox/downloads/file/3522842/opera_gx_witchcraft_purple-2.0.xpi"; + sha256 = "aa3c6377b8571c42a3988de042694be70ec6a250a9aea7ae1cc262acdc9374eb"; + meta = with lib; { + description = "inspired by Opera GX"; + license = licenses.cc-by-sa-30; + mozPermissions = []; + platforms = platforms.all; + }; + }; + "ttv-lol-pro" = buildFirefoxXpiAddon { + pname = "ttv-lol-pro"; + version = "2.3.6"; + addonId = "{76ef94a4-e3d0-4c6f-961a-d38a429a332b}"; + url = "https://addons.mozilla.org/firefox/downloads/file/4252535/ttv_lol_pro-2.3.6.xpi"; + sha256 = "5d9a5f4b4b4d46a39e9d6c9df28fc1d342a1af6d6389196c9c1bd0006036a647"; + 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; + }; + }; +} diff --git a/home/firefox/custom.css b/home/firefox/custom.css new file mode 100644 index 00000000..54572632 --- /dev/null +++ b/home/firefox/custom.css @@ -0,0 +1,157 @@ +.browser-toolbar > * #alltabs-button, +#appMenu-fxa-status2, +#appMenu-fxa-separator { + display: none !important; +} + +:root * { + --margin-left-icons-personal: 3px !important; + --tab-height-personal: 40px !important; + --uc-tab-corner-height: 41px !important; + --uc-vertical-toolbar-width: 46px !important; +} + +/* Fix left side of tabs going past what it should */ +scrollbox { + margin-left: 5px; +} + +/* https://github.com/Godiesc/firefox-gx/blob/main/Tricks/README.md */ +/* Extensions button into the "left-sidebar" - Immovable */ + +:root:not([chromehidden~="toolbar"],[sizemode="fullscreen"]) #PersonalToolbar { + --padding-top-left-sidebar: 110px !important; /* 182px to one-line config */ +} + +:root:not([chromehidden~="toolbar"], [sizemode="fullscreen"]) #unified-extensions-button { + --toolbarbutton-hover-background: transparent !important; + --toolbarbutton-active-background: transparent !important; + position: fixed; + display: flex; + top: 42px !important; + left: 2px !important; + z-index: 2 !important; + fill: var(--general-color) !important; + width: calc(var(--uc-vertical-toolbar-width) - 4px) !important; +} + +:root:not([chromehidden~="toolbar"], [sizemode="fullscreen"]) #unified-extensions-button:hover, +:root:not([chromehidden~="toolbar"], [sizemode="fullscreen"]) #unified-extensions-button[open] { + transform: scale(1.12) !important; + transition: ease-in-out !important; +} + +:root:not([chromehidden~="toolbar"], [sizemode="fullscreen"]) #unified-extensions-button:active { + transform: scale(1.0) !important; + transition-duration: 0ms !important; +} + +#appMenu-addon-installed-notification, +#notification-popup { + margin-top: -1px !important; + margin-inline: -505px !important; +} + +#customizationui-widget-panel { + margin-top: -1px !important; + margin-inline: -200px !important; +} + +#PersonalToolbar .toolbarbutton-1 { + margin-block: 0px !important; +} +#PersonalToolbar #PlacesToolbarItems > .bookmark-item { + margin-block: 6px !important; +} + +/* -------------------------------------------------------------- */ +/* Fix menu */ +:root:not([chromehidden~="toolbar"], [sizemode="fullscreen"]) #PanelUI-menu-button, :root[sizemode="maximized"] #appMenu-popup, +:root[sizemode="maximized"] #appMenu-popup { + --tab-height-personal: unset !important; +} + +:root:not([chromehidden~="toolbar"])[sizemode="maximized"] #appMenu-popup > panelmultiview > box > box > panelview { + padding-top: unset !important; +} + +/* Hamburger menu width */ +:root:not([chromehidden~="toolbar"], [sizemode="fullscreen"]):is([sizemode="maximized"]) #PanelUI-menu-button[open] > stack, +:root:not([chromehidden~="toolbar"]) #PanelUI-menu-button .toolbarbutton-badge-stack { + min-width: 46px !important; +} +toolbar .toolbarbutton-1 > .toolbarbutton-badge-stack { + padding: 10px !important; +} + +:root:not([chromehidden~="toolbar"]) #PanelUI-menu-button[open] > .toolbarbutton-badge-stack { + width: unset !important; +} + +:root[sizemode="maximized"]:not([chromehidden~="toolbar"]) #appMenu-popup panelview { + width: unset !important; +} + +:root:not([chromehidden~="toolbar"]) #PanelUI-menu-button > stack{ + display: unset; + align-items: unset !important; +} + +:root:not([chromehidden~="toolbar"]) #PanelUI-menu-button>stack::after { + width: unset !important; + content: unset; + color: unset !important; + padding-inline-start: unset !important; + padding-block: unset !important; + text-shadow: unset !important; +} + +:root:not([chromehidden~="toolbar"])[sizemode="maximized"] #appMenu-popup { + appearance: unset !important; + margin-top: -1px !important; + clip-path: unset; + --arrowpanel-menuitem-padding: unset !important; +} + +:root:is([sizemode="maximized"]):not([tabsintitlebar], [chromehidden~="toolbar"]) #appMenu-popup { + margin-top: unset !important; +} + +.subviewbutton:is(#appMenu-popup toolbarbutton):not(.subviewbutton-back) { + padding-inline-start: unset !important; +} +.subviewbutton:not(.subviewbutton-iconic, .toolbarbutton-text, [checked="true"])>.toolbarbutton-icon, .syncNowBtn { + width: unset; + height: unset; + margin-inline-end: unset !important; +} + +#appMenu-zoom-controls{ + padding-inline-start: unset !important; +} + +#appMenu-fxa-status2:not([fxastatus])>#appMenu-fxa-label2 { + margin-inline-end: unset !important; +} + +:root:not([chromehidden~="toolbar"])[sizemode="maximized"] #appMenu-fxa-status2 { + padding-top: unset !important; + border-image: unset !important; + border-top: unset !important; +} + +:root:is([sizemode="normal"], [sizemode="fullscreen"]) #appMenu-fxa-label2 { + margin-inline-start: unset !important; +} + +#appMenu-fxa-status2:not([fxastatus="signedin"]) { + margin-inline-end: unset !important; + margin-inline-start: unset !important; +} +#appMenu-fxa-status2:not([fxastatus="signedin"]):hover toolbarbutton { + background-color: unset !important; +} + +:root:not([chromehidden~="toolbar"])[sizemode="maximized"] #appMenu-popup { + --arrowpanel-menuitem-padding: unset !important; +} diff --git a/home/firefox/default.nix b/home/firefox/default.nix new file mode 100644 index 00000000..89b18594 --- /dev/null +++ b/home/firefox/default.nix @@ -0,0 +1,205 @@ +{ + config, + pkgs, + firefox-gx-src, + ... +}: let + inherit (builtins) readFile; + firefox-addons = pkgs.recurseIntoAttrs (pkgs.callPackage ./addons {}); + sound-volume = firefox-addons."600-sound-volume"; + + firefox-gx = pkgs.callPackage ./firefox-gx { + inherit firefox-gx-src; + }; +in { + home.file = { + ".mozilla/firefox/matt/chrome/components".source = "${firefox-gx}/chrome/components"; + ".mozilla/firefox/matt/chrome/icons".source = "${firefox-gx}/chrome/icons"; + ".mozilla/firefox/matt/chrome/images".source = "${firefox-gx}/chrome/images"; + ".mozilla/firefox/matt/chrome/userContent.css".source = "${firefox-gx}/chrome/userContent.css"; + }; + + programs.firefox = { + enable = true; + profiles.matt = { + isDefault = true; + id = 0; + + userChrome = '' + ${readFile "${firefox-gx}/chrome/userChrome.css"} + ${readFile ./custom.css} + ''; + extraConfig = readFile "${firefox-gx}/user.js"; + + settings = { + # Theme + "firefoxgx.tab-shapes" = true; + "firefoxgx.left-sidebar" = true; + "userChrome.tab.bottom_rounded_corner" = true; + "userChrome.tab.bottom_rounded_corner.wave" = false; + "userChrome.tab.bottom_rounded_corner.australis" = true; + "widget.use-xdg-desktop-portal.file-picker" = 1; + + # Open previous windows and tabs + "browser.startup.page" = 3; + + # Prefs + "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" = ""; + "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 = "DuckDuckGo"; + force = true; + engines = { + "Nixpkgs" = { + urls = [ + { + template = "https://github.com/search?q=repo%3ANixOS%2Fnixpkgs%20{searchTerms}&type=code"; + } + ]; + iconUpdateURL = "https://github.githubassets.com/favicons/favicon.png"; + updateInterval = 24 * 60 * 60 * 1000; # every day + definedAliases = ["@pkgs"]; + }; + + "NixOS Wiki" = { + urls = [ + { + template = "https://nixos.wiki/index.php?search={searchTerms}"; + } + ]; + iconUpdateURL = "https://nixos.wiki/favicon.png"; + updateInterval = 24 * 60 * 60 * 1000; # every day + definedAliases = ["@nw"]; + }; + + "MyNixos" = { + urls = [ + { + template = "https://mynixos.com/search?q={searchTerms}"; + } + ]; + iconUpdateURL = "https://mynixos.com/favicon.ico"; + updateInterval = 24 * 60 * 60 * 1000; # every day + definedAliases = ["@mn"]; + }; + + "Noogle" = { + urls = [ + { + template = "https://noogle.dev/q?term={searchTerms}"; + } + ]; + iconUpdateURL = "https://noogle.dev/favicon.ico"; + updateInterval = 24 * 60 * 60 * 1000; # every day + definedAliases = ["@ng"]; + }; + + "Firefox Add-ons" = { + urls = [ + { + template = "https://addons.mozilla.org/en-US/firefox/search/?q={searchTerms}"; + } + ]; + iconUpdateURL = "https://addons.mozilla.org/favicon.ico"; + updateInterval = 24 * 60 * 60 * 1000; # every day + definedAliases = ["@fa"]; + }; + + "ProtonDB" = { + urls = [ + { + template = "https://www.protondb.com/search?q={searchTerms}"; + } + ]; + iconUpdateURL = "https://www.protondb.com/favicon.ico"; + updateInterval = 24 * 60 * 60 * 1000; # every day + definedAliases = ["@pdb"]; + }; + + "YouTube" = { + urls = [ + { + template = "https://www.youtube.com/results?search_query={searchTerms}"; + } + ]; + iconUpdateURL = "https://www.youtube.com/favicon.ico"; + updateInterval = 24 * 60 * 60 * 1000; # every day + definedAliases = ["@yt" "@youtube"]; + }; + + "Bing".metaData.hidden = true; + "Google".metaData.hidden = true; + "eBay".metaData.hidden = true; + }; + order = [ + "DuckDuckGo" + "MyNixos" + "NixOS Wiki" + "Nixpkgs" + "Noogle" + "Wikipedia (en)" + "YouTube" + "Firefox Add-ons" + "ProtonDB" + "Amazon.ca" + ]; + }; + + extensions = with config.nur.repos; + (with bandithedoge.firefoxAddons; [ + sponsorblock + stylus + #tridactyl + ublock-origin + ]) + ++ (with rycee.firefox-addons; [ + bitwarden + darkreader + istilldontcareaboutcookies + image-search-options + return-youtube-dislikes + undoclosetabbutton + ]) + ++ (with firefox-addons; [ + floccus + sound-volume + google-container + checkmarks-web-ext + ttv-lol-pro + seventv + opera-gx-witchcraft-purple + ]); + }; + }; +} diff --git a/home/firefox/firefox-gx/default.nix b/home/firefox/firefox-gx/default.nix new file mode 100644 index 00000000..b96ddd4f --- /dev/null +++ b/home/firefox/firefox-gx/default.nix @@ -0,0 +1,29 @@ +{ + lib, + stdenvNoCC, + firefox-gx-src, +}: +stdenvNoCC.mkDerivation { + pname = "firefox-gx"; + version = firefox-gx-src.shortRev; + + src = firefox-gx-src; + + installPhase = '' + # Personal changes + sed -i 's/var(--fuchsia))/var(--purple))/' ./chrome/components/ogx_root-personal.css + + # Fix new tab background for nix + substituteInPlace ./chrome/components/ogx_root-personal.css \ + --replace-fail '../newtab/wallpaper-dark.png' "$out/chrome/newtab/private-dark.png" + + mkdir -p $out + cp -r ./* $out + ''; + + meta = with lib; { + description = "Firefox Theme CSS to Opera GX Lovers"; + homepage = "https://github.com/Godiesc/firefox-gx"; + license = licenses.mspl; + }; +} diff --git a/home/foot.nix b/home/foot.nix new file mode 100644 index 00000000..37e3ba39 --- /dev/null +++ b/home/foot.nix @@ -0,0 +1,91 @@ +{ + config, + lib, + ... +}: let + inherit (config.vars) fontSize; +in { + 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"; + + # FIXME: Figure out font size with Dpi-aware + font = "JetBrainsMono Nerd Font:size=${ + lib.strings.floatToString 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"; + }; + }; + }; + }; +} diff --git a/home/mpv/default.nix b/home/mpv/default.nix new file mode 100644 index 00000000..3bfa6295 --- /dev/null +++ b/home/mpv/default.nix @@ -0,0 +1,56 @@ +{pkgs, ...} @ inputs: { + # For kdialog-open-files + home.packages = with pkgs; [ + kdialog + ]; + + programs.mpv = { + enable = true; + + # https://github.com/mpv-player/mpv/wiki/User-Scripts + scripts = with (import ./scripts inputs); [ + modernx + # Dep of touch-gestures + pointer-event + touch-gestures + # Ctrl + o + kdialog-open-files + persist-properties + undo-redo + ]; + + 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; + }; + }; + }; +} diff --git a/home/mpv/scripts/default.nix b/home/mpv/scripts/default.nix new file mode 100644 index 00000000..b4cb5751 --- /dev/null +++ b/home/mpv/scripts/default.nix @@ -0,0 +1,16 @@ +{pkgs, ...} @ inputs: let + buildLua = + pkgs.callPackage + "${pkgs.path}/pkgs/applications/video/mpv/scripts/buildLua.nix" {}; + + buildLuaScript = file: + pkgs.callPackage file (inputs // {inherit buildLua;}); +in + pkgs.recurseIntoAttrs { + modernx = buildLuaScript ./modernx.nix; + pointer-event = buildLuaScript ./pointer-event.nix; + touch-gestures = buildLuaScript ./touch-gestures.nix; + kdialog-open-files = buildLuaScript ./kdialog-open-files.nix; + persist-properties = buildLuaScript ./persist-properties.nix; + undo-redo = buildLuaScript ./undo-redo.nix; + } diff --git a/home/mpv/scripts/kdialog-open-files.nix b/home/mpv/scripts/kdialog-open-files.nix new file mode 100644 index 00000000..6706613b --- /dev/null +++ b/home/mpv/scripts/kdialog-open-files.nix @@ -0,0 +1,16 @@ +{ + fetchurl, + buildLua, + ... +}: +buildLua rec { + pname = "zenity-open-files"; + version = "unstable"; + + 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}"; +} diff --git a/home/mpv/scripts/modernx.nix b/home/mpv/scripts/modernx.nix new file mode 100644 index 00000000..7e37462e --- /dev/null +++ b/home/mpv/scripts/modernx.nix @@ -0,0 +1,25 @@ +{ + modernx-src, + makeFontsConf, + buildLua, + ... +}: +buildLua (finalAttrs: { + pname = "modernx"; + version = modernx-src.shortRev; + + src = modernx-src; + + # Make font available to script + postInstall = '' + mkdir -p $out/share/fonts + cp -r ./Material-Design-Iconic-Font.ttf $out/share/fonts + ''; + passthru.extraWrapperArgs = [ + "--set" + "FONTCONFIG_FILE" + (toString (makeFontsConf { + fontDirectories = ["${finalAttrs.finalPackage}/share/fonts"]; + })) + ]; +}) diff --git a/home/mpv/scripts/persist-properties.nix b/home/mpv/scripts/persist-properties.nix new file mode 100644 index 00000000..409b4812 --- /dev/null +++ b/home/mpv/scripts/persist-properties.nix @@ -0,0 +1,11 @@ +{ + persist-properties-src, + buildLua, + ... +}: +buildLua { + pname = "persist-properties"; + version = persist-properties-src.shortRev; + + src = persist-properties-src; +} diff --git a/home/mpv/scripts/pointer-event.nix b/home/mpv/scripts/pointer-event.nix new file mode 100644 index 00000000..9bc00794 --- /dev/null +++ b/home/mpv/scripts/pointer-event.nix @@ -0,0 +1,11 @@ +{ + pointer-event-src, + buildLua, + ... +}: +buildLua { + pname = "pointer-event"; + version = pointer-event-src.shortRev; + + src = pointer-event-src; +} diff --git a/home/mpv/scripts/touch-gestures.nix b/home/mpv/scripts/touch-gestures.nix new file mode 100644 index 00000000..87bfd5a8 --- /dev/null +++ b/home/mpv/scripts/touch-gestures.nix @@ -0,0 +1,11 @@ +{ + touch-gestures-src, + buildLua, + ... +}: +buildLua { + pname = "touch-gestures"; + version = touch-gestures-src.shortRev; + + src = touch-gestures-src; +} diff --git a/home/mpv/scripts/undo-redo.nix b/home/mpv/scripts/undo-redo.nix new file mode 100644 index 00000000..fd4b3af7 --- /dev/null +++ b/home/mpv/scripts/undo-redo.nix @@ -0,0 +1,12 @@ +{ + eisa-scripts-src, + buildLua, + ... +}: +buildLua rec { + pname = "undo-redo"; + version = eisa-scripts-src.shortRev; + + src = eisa-scripts-src; + scriptPath = "${src}/scripts/UndoRedo.lua"; +} diff --git a/home/obs.nix b/home/obs.nix new file mode 100644 index 00000000..ecbed813 --- /dev/null +++ b/home/obs.nix @@ -0,0 +1,16 @@ +{ + nixpkgs-wayland, + pkgs, + ... +}: let + waypkgs = nixpkgs-wayland.packages.${pkgs.system}; +in { + programs = { + obs-studio = { + enable = true; + plugins = with waypkgs; [ + obs-wlrobs + ]; + }; + }; +} diff --git a/home/theme/default.nix b/home/theme/default.nix new file mode 100644 index 00000000..2d4e3aae --- /dev/null +++ b/home/theme/default.nix @@ -0,0 +1,23 @@ +{pkgs, ...}: { + imports = [ + ./gtk.nix + ./qt.nix + ]; + + home.pointerCursor = { + name = "Dracula-cursors"; + package = pkgs.dracula-theme; + size = 24; + + gtk.enable = true; + + x11 = { + enable = true; + defaultCursor = "Dracula-cursors"; + }; + }; + + xresources.extraConfig = + builtins.readFile + "${pkgs.dracula-theme}/xres"; +} diff --git a/modules/desktop/theme/gtk/gradience.nix b/home/theme/gradience.nix similarity index 86% rename from modules/desktop/theme/gtk/gradience.nix rename to home/theme/gradience.nix index 60488b4d..14a0f582 100644 --- a/modules/desktop/theme/gtk/gradience.nix +++ b/home/theme/gradience.nix @@ -1,4 +1,8 @@ -{pkgs, ...}: { +{ + pkgs, + lib, + ... +}: { gradience = rec { # https://github.com/V-Mann-Nick/nix-home-manager/blob/main/gnome/theme.nix package = pkgs.gradience.overrideAttrs (old: { @@ -34,14 +38,16 @@ build = pkgs.stdenv.mkDerivation { name = "gradience-build"; + preset = lib.fileContents "${presets}/curated/dracula-dark.json"; + passAsFile = ["preset"]; 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 + ${package}/bin/gradience-cli apply -p $presetPath --gtk both + ${package}/bin/gradience-cli gnome-shell -p $presetPath -v dark ''; installPhase = '' mkdir -p $out diff --git a/home/theme/gtk.nix b/home/theme/gtk.nix new file mode 100644 index 00000000..9b944fe8 --- /dev/null +++ b/home/theme/gtk.nix @@ -0,0 +1,63 @@ +{ + pkgs, + lib, + config, + ... +}: let + inherit (config.vars) fontSize; + inherit (import ./gradience.nix {inherit pkgs lib;}) gradience; +in { + home.packages = with 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 = fontSize; + }; + + gtk3 = { + extraConfig = { + "gtk-application-prefer-dark-theme" = 1; + }; + extraCss = builtins.readFile "${gradience.build}/gtk-3.0/gtk.css"; + }; + + gtk4 = { + extraConfig = { + "gtk-application-prefer-dark-theme" = 1; + }; + extraCss = builtins.readFile "${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}"; + }; +} diff --git a/home/theme/qt.nix b/home/theme/qt.nix new file mode 100644 index 00000000..4cee1617 --- /dev/null +++ b/home/theme/qt.nix @@ -0,0 +1,42 @@ +{ + pkgs, + lib, + config, + ... +}: let + inherit (config.vars) fontSize; +in { + home.packages = with pkgs; [ + libsForQt5.qtstyleplugin-kvantum + qt6Packages.qtstyleplugin-kvantum + ]; + + qt = { + enable = true; + platformTheme = "qtct"; + }; + + xdg.configFile = let + floatFont = lib.strings.floatToString 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 = "${pkgs.dracula-theme}/share/Kvantum/Dracula-purple-solid/Dracula-purple-solid.kvconfig"; + "Kvantum/Dracula/Dracula.svg".source = "${pkgs.dracula-theme}/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"; + }; +} diff --git a/home/wezterm/default.nix b/home/wezterm/default.nix new file mode 100644 index 00000000..4b987146 --- /dev/null +++ b/home/wezterm/default.nix @@ -0,0 +1,51 @@ +{...}: { + programs = { + wezterm = { + enable = true; + + extraConfig = + /* + lua + */ + '' + local config = wezterm.config_builder(); + + -- default stuff + config.disable_default_key_bindings = true; + config.enable_wayland = false; + + -- theme & appearance + config.color_scheme = 'Dracula'; + config.xcursor_theme = 'Dracula-cursors'; + + config.hide_tab_bar_if_only_one_tab = true; + config.window_background_opacity = 0.8; + config.window_padding = { + top = '10px', + right = '2px', + bottom = '10px', + left = 0, + }; + + -- disable ligatures + config.harfbuzz_features = { 'calt=0', 'clig=0', 'liga=0' }; + config.font = wezterm.font('JetBrains Mono'); + + -- scrollback + config.enable_scroll_bar = true; + config.scrollback_lines = 3500; + + config.keys = { + { + -- Spawn a window with from the cwd + key = 'Enter', + mods = 'SHIFT|CTRL', + action = wezterm.action.SpawnWindow, + }, + }; + + return config; + ''; + }; + }; +} diff --git a/home/wofi/default.nix b/home/wofi/default.nix new file mode 100644 index 00000000..03838d16 --- /dev/null +++ b/home/wofi/default.nix @@ -0,0 +1,17 @@ +{...}: { + programs = { + wofi = { + enable = true; + settings = { + prompt = ""; + allow_images = true; + normal_window = true; + image_size = "48"; + matching = "fuzzy"; + insensitive = true; + no_actions = true; + }; + style = builtins.readFile ./style.css; + }; + }; +} diff --git a/home/wofi/style.css b/home/wofi/style.css new file mode 100644 index 00000000..62a32b6a --- /dev/null +++ b/home/wofi/style.css @@ -0,0 +1,92 @@ +/* https://github.com/dracula/wofi/blob/master/style.css */ +* { + font-size: 16px; +} + +window, +undershoot { + all: unset; +} + +#input { + all: unset; + border-radius: 9px; + color: #f8f8f2; + background-color: rgba(#44475a, 0.6); + border: 1px solid #44475a; + padding: 8px; + margin: 16.2px; + margin-bottom: 0; +} + +#outer-box { + all: unset; + box-shadow: 0 0 4.5px 0 rgba(0, 0, 0, 0.6); + 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; +} + +#inner-box { + padding: 16.2px; + min-width: 500px; + min-height: 450px; +} + +#scroll scrollbar, #scroll scrollbar * { + all: unset; +} + +#scroll scrollbar { + transition: 200ms; + background-color: rgba(23, 23, 23, 0.3); + + &:hover { + background-color: rgba(23, 23, 23, 0.7); + } +} +#scroll scrollbar.vertical:hover slider { + background-color: rgba(238, 238, 238, 0.7); + min-width: .6em; +} +#scroll scrollbar.horizontal:hover slider { + background-color: rgba(238, 238, 238, 0.7); + min-height: .6em; +} +#scroll .vertical slider { + background-color: rgba(238, 238, 238, 0.5); + border-radius: 9px; + min-width: .4em; + min-height: 2em; + transition: 200ms; +} +#scroll .horizontal slider { + background-color: rgba(238, 238, 238, 0.5); + border-radius: 9px; + min-height: .4em; + min-width: 2em; + transition: 200ms; +} + +#entry { + all: unset; + padding: 9px; +} + +#entry image, #entry label { + all: unset; +} + #entry image { + margin-right: 9px; +} + +#entry:selected { + background-color: rgba(189, 147, 249, 0.5); + border-radius: 9px; + box-shadow: inset 0 0 0 3px rgba(238, 238, 238, 0.03); +} +#entry:selected image { + -gtk-icon-shadow: 3px 3px rgba(0, 0, 0, 0.8); +} 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 3b087b7b..00000000 --- a/homeManagerModules/firefox/default.nix +++ /dev/null @@ -1,278 +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-bin; - - 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; - - # 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; - "findbar.highlightAll" = true; - "browser.tabs.groups.enabled" = true; - - # Enable devtools - "devtools.chrome.enabled" = true; - "devtools.debugger.remote-enabled" = true; - - # remove telemetry - "datareporting.healthreport.uploadEnabled" = false; - "datareporting.healthreport.infoURL" = ""; - "datareporting.policy.dataSubmissionEnabled" = false; - "datareporting.usage.uploadEnabled" = false; - "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; - - # Firefox-gx user.js - "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; - }; - - 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 - 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/.luarc.json b/homeManagerModules/neovim/.luarc.json deleted file mode 100644 index e69de29b..00000000 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 40339c05..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', 'BufEnter' }, { - 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 006beb58..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', 'BufEnter' }, { - 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 05a0b1e5..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', 'BufEnter' }, { - 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 84f0f723..00000000 --- a/homeManagerModules/neovim/langs/default.nix +++ /dev/null @@ -1,145 +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 - ./kotlin - ./lua - ./python - ./qml - ./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 55d109c5..00000000 --- a/homeManagerModules/neovim/langs/golang/default.nix +++ /dev/null @@ -1,33 +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]; - - extraLuaConfig = - # 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 24df0f66..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', 'BufEnter' }, { - 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 3da9abc1..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', 'BufEnter' }, { - 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', 'BufEnter' }, { - 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 d0038d19..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', 'BufEnter' }, { - 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/kotlin/default.nix b/homeManagerModules/neovim/langs/kotlin/default.nix deleted file mode 100644 index 4a048882..00000000 --- a/homeManagerModules/neovim/langs/kotlin/default.nix +++ /dev/null @@ -1,47 +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', 'BufEnter' }, { - pattern = { 'kotlin' }, - - callback = function() - vim.cmd[[setlocal ts=4 sw=4 sts=0 expandtab]]; - - if (devShells['kotlin'] == nil) then - devShells['kotlin'] = 1; - - require('nix-develop').nix_develop_extend({'${flakeEnv}#kotlin'}, function() - vim.cmd[[LspStart]]; - end); - end - end, - }); - - local lsp = require('lspconfig'); - local default_capabilities = require('cmp_nvim_lsp').default_capabilities(); - - lsp.kotlin_language_server.setup({ - capabilities = default_capabilities, - autostart = false, - }); - ''; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/langs/kotlin/shell.nix b/homeManagerModules/neovim/langs/kotlin/shell.nix deleted file mode 100644 index f91b4f7d..00000000 --- a/homeManagerModules/neovim/langs/kotlin/shell.nix +++ /dev/null @@ -1,10 +0,0 @@ -{ - mkShell, - kotlin-language-server, - ... -}: -mkShell { - packages = [ - kotlin-language-server - ]; -} diff --git a/homeManagerModules/neovim/langs/lua/default.nix b/homeManagerModules/neovim/langs/lua/default.nix deleted file mode 100644 index 09662361..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', 'BufEnter' }, { - 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 8a97cbc1..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', 'BufEnter' }, { - 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 8fe6f691..00000000 --- a/homeManagerModules/neovim/langs/python/default.nix +++ /dev/null @@ -1,74 +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 = p: - (attrValues { - inherit - (p) - python-lsp-server - pyls-isort - pylsp-mypy - python-lsp-ruff - python-lsp-jsonrpc - ; - }) - ++ p.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 = { - -- auto-completion options - jedi_completion = { - fuzzy = true, - }, - - -- import sorting - pyls_isort = { - enabled = true, - }, - - -- type checker - pylsp_mypy = { - enabled = true, - }, - - -- linter - ruff = { - enabled = true, - formatEnabled = true, - lineLength = 100, - }, - }, - }, - }, - }); - ''; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/langs/qml/default.nix b/homeManagerModules/neovim/langs/qml/default.nix deleted file mode 100644 index c173ac22..00000000 --- a/homeManagerModules/neovim/langs/qml/default.nix +++ /dev/null @@ -1,49 +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', 'BufEnter' }, { - pattern = { 'qml' }, - - callback = function() - vim.cmd[[setlocal ts=4 sw=4 sts=0 expandtab]]; - - if (devShells['qml'] == nil) then - devShells['qml'] = 1; - - require('nix-develop').nix_develop_extend({'${flakeEnv}#qml'}, function() - vim.cmd[[LspStart]]; - end); - end - end, - }); - - local lsp = require('lspconfig'); - local default_capabilities = require('cmp_nvim_lsp').default_capabilities(); - - lsp.qmlls.setup({ - cmd = { 'qmlls', '-E' }, - root_dir = lsp.util.root_pattern('*.qml', '.git'), - capabilities = default_capabilities, - autostart = false, - }); - ''; - }; - }; - }; - - # For accurate stack trace - _file = ./default.nix; -} diff --git a/homeManagerModules/neovim/langs/qml/shell.nix b/homeManagerModules/neovim/langs/qml/shell.nix deleted file mode 100644 index 2578bac7..00000000 --- a/homeManagerModules/neovim/langs/qml/shell.nix +++ /dev/null @@ -1,19 +0,0 @@ -{ - lib, - mkShell, - kdePackages, - quickshell, - ... -}: -mkShell { - packages = [ - kdePackages.qtdeclarative - ]; - - shellHook = '' - export QML2_IMPORT_PATH="$QML2_IMPORT_PATH:${lib.makeSearchPath "lib/qt-6/qml" [ - quickshell - kdePackages.qtdeclarative - ]}" - ''; -} diff --git a/homeManagerModules/neovim/langs/rust/default.nix b/homeManagerModules/neovim/langs/rust/default.nix deleted file mode 100644 index d59047f6..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', 'BufEnter' }, { - 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 3127ab8e..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', 'BufEnter' }, { - 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', 'BufEnter' }, { - pattern = 'html', - - callback = function() - vim.cmd[[setlocal ts=4 sw=4 expandtab]]; - - loadDevShell(); - end, - }); - - vim.api.nvim_create_autocmd({ 'FileType', 'BufEnter' }, { - 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/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/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/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 2900eecc..00000000 --- a/inputs/default.nix +++ /dev/null @@ -1,443 +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 { - type = "git"; - url = "https://github.com/NixOS/nixpkgs"; - ref = "nixos-unstable"; - shallow = true; - }; - - 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 = "nix-community"; - 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"; - }; - - kapowarr = mkInput { - owner = "matt1432"; - repo = "Kapowarr"; - # type = "path"; - # path = "/home/matt/git/Kapowarr"; - }; - }; - - 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"; - }; - }; - - shellInputs = { - quickshell = mkInput { - type = "git"; - url = "https://git.outfoxxed.me/quickshell/quickshell"; - }; - - 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 - { - 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.shellInputs - // (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 04f0072c..00000000 --- a/lib/flake/default.nix +++ /dev/null @@ -1,127 +0,0 @@ -inputs: let - inherit (builtins) functionArgs mapAttrs removeAttrs; -in rec { - # This is for packages from flakes that don't offer overlays - overrideAll = pkgs: pkg: extraArgs: let - pkgFile = pkgs.lib.head (pkgs.lib.splitString [":"] pkg.meta.position); - args = functionArgs (import pkgFile); - in - pkg.override ((mapAttrs (n: v: pkgs.${n} or v) args) // extraArgs); - - # 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 - inputs.self.overlays.forced - ] - ++ (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 344baf50..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-dZNYQw45dXdWJ3lgF+7OTDuD3gGGxVf01QB2lwzjK/M="; - - 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 1223d182..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.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", - "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.6", - "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.1.6.tgz", - "integrity": "sha512-62u896rWCtKKE43soodq5e/QcRsA22I+7/4Ov7LESWnKRO6BVo2A1DFLDmXL9e28TB0CfHc3YtkbPm7iwajqkg==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.11", - "@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.10", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.10.tgz", - "integrity": "sha512-FxbQ9giWxUWKUk2O5XZ6PduVnH2CZ/fmMKMBkH71MHJvWr7WL5AHKevhzF1L5uYWB2P548o1RzVxrNd3dpmk6g==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.11", - "@inquirer/type": "^3.0.6" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/core": { - "version": "10.1.11", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.11.tgz", - "integrity": "sha512-BXwI/MCqdtAhzNQlBEFE7CEflhPkl/BqvAuV/aK6lW3DClIfYVDWPP/kXuXHtBWC7/EEbNqd/1BGq2BGBBnuxw==", - "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.11", - "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.11.tgz", - "integrity": "sha512-YoZr0lBnnLFPpfPSNsQ8IZyKxU47zPyVi9NLjCWtna52//M/xuL0PGPAxHxxYhdOhnvY2oBafoM+BI5w/JK7jw==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.11", - "@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.13", - "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.13.tgz", - "integrity": "sha512-HgYNWuZLHX6q5y4hqKhwyytqAghmx35xikOGY3TcgNiElqXGPas24+UzNPOwGUZa5Dn32y25xJqVeUcGlTv+QQ==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.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/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.10", - "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.1.10.tgz", - "integrity": "sha512-kV3BVne3wJ+j6reYQUZi/UN9NZGZLxgc/tfyjeK3mrx1QI7RXPxGp21IUTv+iVHcbP4ytZALF8vCHoxyNSC6qg==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.11", - "@inquirer/type": "^3.0.6" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/number": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.13.tgz", - "integrity": "sha512-IrLezcg/GWKS8zpKDvnJ/YTflNJdG0qSFlUM/zNFsdi4UKW/CO+gaJpbMgQ20Q58vNKDJbEzC6IebdkprwL6ew==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.11", - "@inquirer/type": "^3.0.6" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/password": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.13.tgz", - "integrity": "sha512-NN0S/SmdhakqOTJhDwOpeBEEr8VdcYsjmZHDb0rblSh2FcbXQOr+2IApP7JG4WE3sxIdKytDn4ed3XYwtHxmJQ==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.11", - "@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.5.1", - "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.5.1.tgz", - "integrity": "sha512-5AOrZPf2/GxZ+SDRZ5WFplCA2TAQgK3OYrXCYmJL5NaTu4ECcoWFlfUZuw7Es++6Njv7iu/8vpYJhuzxUH76Vg==", - "license": "MIT", - "dependencies": { - "@inquirer/checkbox": "^4.1.6", - "@inquirer/confirm": "^5.1.10", - "@inquirer/editor": "^4.2.11", - "@inquirer/expand": "^4.0.13", - "@inquirer/input": "^4.1.10", - "@inquirer/number": "^3.0.13", - "@inquirer/password": "^4.0.13", - "@inquirer/rawlist": "^4.1.1", - "@inquirer/search": "^3.0.13", - "@inquirer/select": "^4.2.1" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/rawlist": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.1.tgz", - "integrity": "sha512-VBUC0jPN2oaOq8+krwpo/mf3n/UryDUkKog3zi+oIi8/e5hykvdntgHUB9nhDM78RubiyR1ldIOfm5ue+2DeaQ==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.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/search": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.13.tgz", - "integrity": "sha512-9g89d2c5Izok/Gw/U7KPC3f9kfe5rA1AJ24xxNZG0st+vWekSk7tB9oE+dJv5JXd0ZSijomvW0KPMoBd8qbN4g==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.11", - "@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.2.1", - "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.2.1.tgz", - "integrity": "sha512-gt1Kd5XZm+/ddemcT3m23IP8aD8rC9drRckWoP/1f7OL46Yy2FGi8DSmNjEjQKtPl6SV96Kmjbl6p713KXJ/Jg==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.11", - "@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.3", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.2.3.tgz", - "integrity": "sha512-OdCYfRqfpuLUFonTNjvd30rCBZUneHpSQkCqfaeWQ9qrKcl6XlWeDBNVwGb+INAIxRshuN2jF+BE0L6gbBO2mw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "dependencies": { - "strnum": "^2.1.0" - }, - "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.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.2.tgz", - "integrity": "sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ==", - "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.6.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-12.6.1.tgz", - "integrity": "sha512-MGFnzHVS3l3oM3cy+LWkyR7UUtVEn3D5U41CZbEY34szToWoJAvaVtCTz1mxsEzZFk/HXWyCArn0HDgloTXMDw==", - "license": "MIT", - "dependencies": { - "@inquirer/core": "^10.1.11", - "@inquirer/prompts": "^7.5.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.1.1", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.1.tgz", - "integrity": "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==", - "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/README.md b/modules/ags/README.md new file mode 100644 index 00000000..888cf3b8 --- /dev/null +++ b/modules/ags/README.md @@ -0,0 +1,41 @@ +# [AGS](https://github.com/Aylur/ags) + +## Nix + +This directory is the Nix entrypoint to my AGS configration. + +On system activation, if this module is imported, it will +generate the `config.js` of the host with the host's name +as the parameter in `transpileTypeScript` to support a different +setup per device. + +## Non-Nix + +To use this setup without Nix: + +```js +/* ~/.config/ags/config.js */ + +import { transpileTypeScript } from './js/utils.js'; + +export default (await transpileTypeScript('wim')).default; +``` + +If you want to try my main config, this is what you need to have +as your `config.js` after copying the contents of `./config` to +`~/.config/ags` + +## Dependencies + +The main dependencies to try it are as follows: + +- **bun** to transpile TS to JS +- **dart-sass** to compile SCSS to CSS +- **[coloryou](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/common/pkgs/coloryou)** for media player colors +- **playerctl** for media player functionality + +If you're interested in my 2-1 laptop setup, you'll need: + +- **ydotool** for my custom on-screen keyboard +- **lisgd** to have touch screen gestures # TODO: switch to hyprgrass +when it has better binds diff --git a/modules/ags/astal/.envrc b/modules/ags/astal/.envrc new file mode 100644 index 00000000..1ea98949 --- /dev/null +++ b/modules/ags/astal/.envrc @@ -0,0 +1 @@ +use flake $FLAKE#ags diff --git a/modules/ags/astal/.eslintrc.json b/modules/ags/astal/.eslintrc.json new file mode 120000 index 00000000..6a026651 --- /dev/null +++ b/modules/ags/astal/.eslintrc.json @@ -0,0 +1 @@ +../config/.eslintrc.json \ No newline at end of file diff --git a/modules/ags/astal/.stylelintrc.yml b/modules/ags/astal/.stylelintrc.yml new file mode 120000 index 00000000..38c9691a --- /dev/null +++ b/modules/ags/astal/.stylelintrc.yml @@ -0,0 +1 @@ +../config/.stylelintrc.yml \ No newline at end of file diff --git a/modules/ags/astal/greeter.ts b/modules/ags/astal/greeter.ts new file mode 100644 index 00000000..be1e95b1 --- /dev/null +++ b/modules/ags/astal/greeter.ts @@ -0,0 +1,7 @@ +import Greeter from './ts/greetd/main'; + +App.config({ + windows: () => [ + Greeter(), + ], +}); diff --git a/modules/ags/astal/js/utils.js b/modules/ags/astal/js/utils.js new file mode 100644 index 00000000..3bb911b6 --- /dev/null +++ b/modules/ags/astal/js/utils.js @@ -0,0 +1,47 @@ +const { execAsync, monitorFile } = Utils; + + +/** @param {string} host */ +const watchAndCompileSass = (host) => { + const reloadCss = () => { + const scss = `${App.configDir}/scss/${host}.scss`; + const css = `/tmp/astal-${host}/style.css`; + + execAsync(`sass ${scss} ${css}`).then(() => { + App.resetCss(); + App.applyCss(css); + }).catch(print); + }; + + monitorFile( + `${App.configDir}/scss`, + reloadCss, + ); + reloadCss(); +}; + +/** @param {string} host */ +export const transpileTypeScript = async(host) => { + const outPath = `/tmp/astal-${host}/index.js`; + + await execAsync([ + 'bash', '-c', + // Create the dir if it doesn't exist + `mkdir -p /tmp/astal-${host}; ` + + + // Let bun see tsconfig.json + `cd ${App.configDir};` + + + `bun build ${App.configDir}/${host}.ts ` + + '--external resource:///* ' + + '--external gi://* ' + + '--external cairo ' + + + // Since bun wants to write in cwd, we just redirect stdin instead + `> ${outPath}`, + ]).catch(print); + + watchAndCompileSass(host); + + return await import(`file://${outPath}`); +}; diff --git a/modules/ags/astal/package-lock.json b/modules/ags/astal/package-lock.json new file mode 100644 index 00000000..0df85aa4 --- /dev/null +++ b/modules/ags/astal/package-lock.json @@ -0,0 +1,3565 @@ +{ + "name": "astal", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "fzf": "^0.5.2" + }, + "devDependencies": { + "@girs/adw-1": "^1.4.3-3.2.9", + "@girs/cairo-1.0": "^1.0.0-3.2.7", + "@girs/gjs": "^3.2.7", + "@girs/gtk-4.0": "^4.12.0-3.2.8", + "@girs/gvc-1.0": "^1.0.0-3.1.0", + "@girs/nm-1.0": "^1.43.1-3.1.0", + "@stylistic/eslint-plugin": "^1.4.0", + "@typescript-eslint/eslint-plugin": "^6.9.1", + "@typescript-eslint/parser": "^6.9.1", + "eslint": "^8.52.0", + "stylelint-config-standard-scss": "^11.0.0" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "peer": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.6.1.tgz", + "integrity": "sha512-ubEkAaTfVZa+WwGhs5jbo5Xfqpeaybr/RvWzvFxRs4jfq16wH8l8Ty/QEEpINxll4xhuGfdMbipRyz5QZh9+FA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "peer": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^2.2.4" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.2.4.tgz", + "integrity": "sha512-PuWRAewQLbDhGeTvFuq2oClaSCKPIBmHyIobCV39JHRYN0byDcUWJl5baPeNUcqrjtdMNqFooE0FGl31I3JOqw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "peer": true, + "engines": { + "node": "^14 || ^16 || >=18" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.9.tgz", + "integrity": "sha512-qqGuFfbn4rUmyOB0u8CVISIp5FfJ5GAR3mBrZ9/TKndHakdnm6pY0L/fbLcpPnrzwCyyTEZl1nUcXAYHEWneTA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "peer": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^2.6.1", + "@csstools/css-tokenizer": "^2.2.4" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.0.2.tgz", + "integrity": "sha512-RpHaZ1h9LE7aALeQXmXrJkRG84ZxIsctEN2biEUmFyKpzFM3zZ35eUMcIzZFsw/2olQE6v69+esEqU2f1MKycg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "peer": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^6.0.13" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.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": "^12.22.0 || ^14.17.0 || >=16.0.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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@girs/adw-1": { + "version": "1.4.3-3.2.9", + "resolved": "https://registry.npmjs.org/@girs/adw-1/-/adw-1-1.4.3-3.2.9.tgz", + "integrity": "sha512-FJPtFRLJHXHZl5WEPjXmyKXaoIgBWurZMroSxNxpRGFVlbxx7wq4Q1k1iKKVxcKbe69z66GQsHV2BgaeQK0aXg==", + "dev": true, + "dependencies": { + "@girs/cairo-1.0": "^1.0.0-3.2.9", + "@girs/freetype2-2.0": "^2.0.0-3.2.9", + "@girs/gdk-4.0": "^4.0.0-3.2.9", + "@girs/gdkpixbuf-2.0": "^2.0.0-3.2.9", + "@girs/gio-2.0": "^2.78.0-3.2.9", + "@girs/gjs": "^3.2.9", + "@girs/glib-2.0": "^2.78.0-3.2.9", + "@girs/gmodule-2.0": "^2.0.0-3.2.9", + "@girs/gobject-2.0": "^2.78.0-3.2.9", + "@girs/graphene-1.0": "^1.0.0-3.2.9", + "@girs/gsk-4.0": "^4.0.0-3.2.9", + "@girs/gtk-4.0": "^4.12.5-3.2.9", + "@girs/harfbuzz-0.0": "^8.2.1-3.2.9", + "@girs/pango-1.0": "^1.51.0-3.2.9", + "@girs/pangocairo-1.0": "^1.0.0-3.2.9" + } + }, + "node_modules/@girs/adw-1/node_modules/@girs/gtk-4.0": { + "version": "4.12.5-3.2.9", + "resolved": "https://registry.npmjs.org/@girs/gtk-4.0/-/gtk-4.0-4.12.5-3.2.9.tgz", + "integrity": "sha512-TweLlhryVS8DnDQouLdJtGv3AeJ9Dv/nKFatPSDlcwUFYCSDa9+R5gA5L7GNh3NobPIa6ZMAT4oAv2fJS7zYFw==", + "dev": true, + "dependencies": { + "@girs/cairo-1.0": "^1.0.0-3.2.9", + "@girs/freetype2-2.0": "^2.0.0-3.2.9", + "@girs/gdk-4.0": "^4.0.0-3.2.9", + "@girs/gdkpixbuf-2.0": "^2.0.0-3.2.9", + "@girs/gio-2.0": "^2.78.0-3.2.9", + "@girs/gjs": "^3.2.9", + "@girs/glib-2.0": "^2.78.0-3.2.9", + "@girs/gmodule-2.0": "^2.0.0-3.2.9", + "@girs/gobject-2.0": "^2.78.0-3.2.9", + "@girs/graphene-1.0": "^1.0.0-3.2.9", + "@girs/gsk-4.0": "^4.0.0-3.2.9", + "@girs/harfbuzz-0.0": "^8.2.1-3.2.9", + "@girs/pango-1.0": "^1.51.0-3.2.9", + "@girs/pangocairo-1.0": "^1.0.0-3.2.9" + } + }, + "node_modules/@girs/cairo-1.0": { + "version": "1.0.0-3.2.9", + "resolved": "https://registry.npmjs.org/@girs/cairo-1.0/-/cairo-1.0-1.0.0-3.2.9.tgz", + "integrity": "sha512-yeBoeyniCKU3IcgpoKUywlviBx2kEVeYjglFw4v5eGGvaBugPWvlShqePxfNmfh2A4cjFzzdLXRN6brQEHgQEA==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.9", + "@girs/glib-2.0": "^2.78.0-3.2.9", + "@girs/gobject-2.0": "^2.78.0-3.2.9" + } + }, + "node_modules/@girs/freetype2-2.0": { + "version": "2.0.0-3.2.9", + "resolved": "https://registry.npmjs.org/@girs/freetype2-2.0/-/freetype2-2.0-2.0.0-3.2.9.tgz", + "integrity": "sha512-Og9CTSl2QYnuCtX2L6rYa9WVUetYbaD1Y7BwEe3kOSG2OkDB+hunnF82x1Ctg1iKRRBXgWxadKb28bm2wKx/Jw==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.9", + "@girs/gobject-2.0": "^2.78.0-3.2.9" + } + }, + "node_modules/@girs/gdk-4.0": { + "version": "4.0.0-3.2.9", + "resolved": "https://registry.npmjs.org/@girs/gdk-4.0/-/gdk-4.0-4.0.0-3.2.9.tgz", + "integrity": "sha512-86+32kDXaSqzicqMCx35O8ZkCrG5Qyyozaq1NQdWhBNUopGNiTLtVkf90aIP0y8ZccIeJKidCWEO3IYiRmmHkg==", + "dev": true, + "dependencies": { + "@girs/cairo-1.0": "^1.0.0-3.2.9", + "@girs/freetype2-2.0": "^2.0.0-3.2.9", + "@girs/gdkpixbuf-2.0": "^2.0.0-3.2.9", + "@girs/gio-2.0": "^2.78.0-3.2.9", + "@girs/gjs": "^3.2.9", + "@girs/glib-2.0": "^2.78.0-3.2.9", + "@girs/gmodule-2.0": "^2.0.0-3.2.9", + "@girs/gobject-2.0": "^2.78.0-3.2.9", + "@girs/harfbuzz-0.0": "^8.2.1-3.2.9", + "@girs/pango-1.0": "^1.51.0-3.2.9", + "@girs/pangocairo-1.0": "^1.0.0-3.2.9" + } + }, + "node_modules/@girs/gdkpixbuf-2.0": { + "version": "2.0.0-3.2.9", + "resolved": "https://registry.npmjs.org/@girs/gdkpixbuf-2.0/-/gdkpixbuf-2.0-2.0.0-3.2.9.tgz", + "integrity": "sha512-7guULwcaulcOvqvAB8pd6Xr9B2YmK1sQK6CYm5bHZQw9N18LnZkm9ATOAXjXLieaUSeERA6LnBPmtkLUZdeTzA==", + "dev": true, + "dependencies": { + "@girs/gio-2.0": "^2.78.0-3.2.9", + "@girs/gjs": "^3.2.9", + "@girs/glib-2.0": "^2.78.0-3.2.9", + "@girs/gmodule-2.0": "^2.0.0-3.2.9", + "@girs/gobject-2.0": "^2.78.0-3.2.9" + } + }, + "node_modules/@girs/gio-2.0": { + "version": "2.78.0-3.2.9", + "resolved": "https://registry.npmjs.org/@girs/gio-2.0/-/gio-2.0-2.78.0-3.2.9.tgz", + "integrity": "sha512-A3F1AkBPF8Up6bSfH9zbAUsQqv4dB0jvfUIo5b+SJs6Mt9FhpqNEUMyqeCFTDKDA9n2sK6JxAJviwsW9dxViJA==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.9", + "@girs/glib-2.0": "^2.78.0-3.2.9", + "@girs/gobject-2.0": "^2.78.0-3.2.9" + } + }, + "node_modules/@girs/gjs": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/@girs/gjs/-/gjs-3.2.9.tgz", + "integrity": "sha512-dJfCNdtt4OLRywlhKOc+h27l5KoOiDhbhkuuG/WaV/jn9KaQ1BMAyVWdBEZu6WzPJlsiWYujis0fe5ZJnrgoDA==", + "dev": true, + "dependencies": { + "@girs/glib-2.0": "^2.78.0-3.2.9", + "@girs/gobject-2.0": "^2.78.0-3.2.9" + } + }, + "node_modules/@girs/glib-2.0": { + "version": "2.78.0-3.2.9", + "resolved": "https://registry.npmjs.org/@girs/glib-2.0/-/glib-2.0-2.78.0-3.2.9.tgz", + "integrity": "sha512-wcbnSojav6jc4//PYsAJPwXizFlz35/F+AHyFbvutOSdNz4xzzUUZqUhhH2lmoyR8WDvkVWBcQitCmYmPNe6Xg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.9", + "@girs/gobject-2.0": "^2.78.0-3.2.9" + } + }, + "node_modules/@girs/gmodule-2.0": { + "version": "2.0.0-3.2.9", + "resolved": "https://registry.npmjs.org/@girs/gmodule-2.0/-/gmodule-2.0-2.0.0-3.2.9.tgz", + "integrity": "sha512-10JS6N7VkPxcom5I3hzD65NmZzQ63ZFmN+2KXZPwTDU6K2A2QrxZB2/3Q3j6KKNc+e/d9GhStL9ISUPLErHoNg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.9", + "@girs/glib-2.0": "^2.78.0-3.2.9", + "@girs/gobject-2.0": "^2.78.0-3.2.9" + } + }, + "node_modules/@girs/gobject-2.0": { + "version": "2.78.0-3.2.9", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.78.0-3.2.9.tgz", + "integrity": "sha512-zszoqx7/z7KseQnc7WUXz1jgs3oYskT748cMKLQ7n4pRtL6klrTzlPbM42Szs+Uk6wOKJ+o+MMdcpb8znflDBg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.9", + "@girs/glib-2.0": "^2.78.0-3.2.9" + } + }, + "node_modules/@girs/graphene-1.0": { + "version": "1.0.0-3.2.9", + "resolved": "https://registry.npmjs.org/@girs/graphene-1.0/-/graphene-1.0-1.0.0-3.2.9.tgz", + "integrity": "sha512-2iTdpt7XTJAH/K5GiKoF2r0BHe1JghpV+rh81WYtFqM/r9CLs5GipESuraVQvZeK2vyrZcGRjVmoDoiKiA3BlQ==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.9", + "@girs/glib-2.0": "^2.78.0-3.2.9", + "@girs/gobject-2.0": "^2.78.0-3.2.9" + } + }, + "node_modules/@girs/gsk-4.0": { + "version": "4.0.0-3.2.9", + "resolved": "https://registry.npmjs.org/@girs/gsk-4.0/-/gsk-4.0-4.0.0-3.2.9.tgz", + "integrity": "sha512-LtGbMKBVYPburnI1JGt2d3uKzHgk4A2QtO4n/kP0T99Rmnxr+D2xwR+VdqcdgkLXoTzdlvodfK1b7W/eILB7CQ==", + "dev": true, + "dependencies": { + "@girs/cairo-1.0": "^1.0.0-3.2.9", + "@girs/freetype2-2.0": "^2.0.0-3.2.9", + "@girs/gdk-4.0": "^4.0.0-3.2.9", + "@girs/gdkpixbuf-2.0": "^2.0.0-3.2.9", + "@girs/gio-2.0": "^2.78.0-3.2.9", + "@girs/gjs": "^3.2.9", + "@girs/glib-2.0": "^2.78.0-3.2.9", + "@girs/gmodule-2.0": "^2.0.0-3.2.9", + "@girs/gobject-2.0": "^2.78.0-3.2.9", + "@girs/graphene-1.0": "^1.0.0-3.2.9", + "@girs/harfbuzz-0.0": "^8.2.1-3.2.9", + "@girs/pango-1.0": "^1.51.0-3.2.9", + "@girs/pangocairo-1.0": "^1.0.0-3.2.9" + } + }, + "node_modules/@girs/gtk-4.0": { + "version": "4.12.0-3.2.8", + "resolved": "https://registry.npmjs.org/@girs/gtk-4.0/-/gtk-4.0-4.12.0-3.2.8.tgz", + "integrity": "sha512-KtlRh8neW0ExJb9FiV0jN4dbA3wkMNmYQ1FD7iFOGNGTJapHCiPHlPRPeMOiH8jBdR6jMc2ec8dkQIeDSNMSXA==", + "dev": true, + "dependencies": { + "@girs/cairo-1.0": "^1.0.0-3.2.8", + "@girs/freetype2-2.0": "^2.0.0-3.2.8", + "@girs/gdk-4.0": "^4.0.0-3.2.8", + "@girs/gdkpixbuf-2.0": "^2.0.0-3.2.8", + "@girs/gio-2.0": "^2.77.0-3.2.8", + "@girs/gjs": "^3.2.8", + "@girs/glib-2.0": "^2.77.0-3.2.8", + "@girs/gmodule-2.0": "^2.0.0-3.2.8", + "@girs/gobject-2.0": "^2.77.0-3.2.8", + "@girs/graphene-1.0": "^1.0.0-3.2.8", + "@girs/gsk-4.0": "^4.0.0-3.2.8", + "@girs/harfbuzz-0.0": "^8.1.1-3.2.8", + "@girs/pango-1.0": "^1.51.0-3.2.8", + "@girs/pangocairo-1.0": "^1.0.0-3.2.8" + } + }, + "node_modules/@girs/gtk-4.0/node_modules/@girs/gio-2.0": { + "version": "2.77.0-3.2.8", + "resolved": "https://registry.npmjs.org/@girs/gio-2.0/-/gio-2.0-2.77.0-3.2.8.tgz", + "integrity": "sha512-o8FsnnuSrIAUK0cMs35WarFTGBWt09/HXbtYQd3h8eObCglLCnWN2xeDrTuYZuL4LP4URbszotQaG2XgA8eiEQ==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.8", + "@girs/glib-2.0": "^2.77.0-3.2.8", + "@girs/gobject-2.0": "^2.77.0-3.2.8" + } + }, + "node_modules/@girs/gtk-4.0/node_modules/@girs/glib-2.0": { + "version": "2.77.0-3.2.8", + "resolved": "https://registry.npmjs.org/@girs/glib-2.0/-/glib-2.0-2.77.0-3.2.8.tgz", + "integrity": "sha512-v9UHdr8tL6yIqDpP/rhw1v/1GvhjPkLztQ9fZEr7zox0DO7E7P+xRwPNT6NqAJFGldlaM7BASepRrOvfPKA+1g==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.8", + "@girs/gobject-2.0": "^2.77.0-3.2.8" + } + }, + "node_modules/@girs/gtk-4.0/node_modules/@girs/gobject-2.0": { + "version": "2.77.0-3.2.8", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.77.0-3.2.8.tgz", + "integrity": "sha512-zomYz1kVDLkOfOlXP9sgyDU68zcV69zcBwrVWXAG7L0XoJzxiRWW7baA3mEaDcApOFyaxGCDGrorv6l5PzY7ZQ==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.8", + "@girs/glib-2.0": "^2.77.0-3.2.8" + } + }, + "node_modules/@girs/gtk-4.0/node_modules/@girs/harfbuzz-0.0": { + "version": "8.1.1-3.2.8", + "resolved": "https://registry.npmjs.org/@girs/harfbuzz-0.0/-/harfbuzz-0.0-8.1.1-3.2.8.tgz", + "integrity": "sha512-nEXjYY5uvBl2qv63R88vR+4Jcqzz+3q8KqJqZ3iZ8sG7wsp58eATAhMZrod9SwDmca5U07pJ+q0lkQefk/X0qQ==", + "dev": true, + "dependencies": { + "@girs/freetype2-2.0": "^2.0.0-3.2.8", + "@girs/gjs": "^3.2.8", + "@girs/glib-2.0": "^2.77.0-3.2.8", + "@girs/gobject-2.0": "^2.77.0-3.2.8" + } + }, + "node_modules/@girs/gvc-1.0": { + "version": "1.0.0-3.2.9", + "resolved": "https://registry.npmjs.org/@girs/gvc-1.0/-/gvc-1.0-1.0.0-3.2.9.tgz", + "integrity": "sha512-AeuMkIS5jiCELliycQG8pok9AOSuWBznBOI8sAOoBQvcM0+W6MESai7YzCMNGfKARrJhcclPUihZOkGXvPcsjQ==", + "dev": true, + "dependencies": { + "@girs/gio-2.0": "^2.78.0-3.2.9", + "@girs/gjs": "^3.2.9", + "@girs/glib-2.0": "^2.78.0-3.2.9", + "@girs/gobject-2.0": "^2.78.0-3.2.9" + } + }, + "node_modules/@girs/harfbuzz-0.0": { + "version": "8.2.1-3.2.9", + "resolved": "https://registry.npmjs.org/@girs/harfbuzz-0.0/-/harfbuzz-0.0-8.2.1-3.2.9.tgz", + "integrity": "sha512-5o4Ow44ndt9Jnyp5vw6tWYSFESY/inH/3nNoWk1bWpG5TFxOwvW05RiSpdKXb4nTXaDWPBXLZF4Its9Q/GrW2w==", + "dev": true, + "dependencies": { + "@girs/freetype2-2.0": "^2.0.0-3.2.9", + "@girs/gjs": "^3.2.9", + "@girs/glib-2.0": "^2.78.0-3.2.9", + "@girs/gobject-2.0": "^2.78.0-3.2.9" + } + }, + "node_modules/@girs/nm-1.0": { + "version": "1.43.1-3.1.0", + "resolved": "https://registry.npmjs.org/@girs/nm-1.0/-/nm-1.0-1.43.1-3.1.0.tgz", + "integrity": "sha512-2jawCPFAFlBmlsQ0334+SIYZJ1zXiHClU0PRiPZPAuOx+NzIpvAjEjprynrwFHwZ2azjmSjFp5AQ/wTTiDLJ/g==", + "dev": true, + "dependencies": { + "@girs/gio-2.0": "^2.76.1-3.1.0", + "@girs/gjs": "^3.1.0", + "@girs/glib-2.0": "^2.76.1-3.1.0", + "@girs/gobject-2.0": "^2.76.1-3.1.0" + } + }, + "node_modules/@girs/nm-1.0/node_modules/@girs/gio-2.0": { + "version": "2.76.1-3.2.3", + "resolved": "https://registry.npmjs.org/@girs/gio-2.0/-/gio-2.0-2.76.1-3.2.3.tgz", + "integrity": "sha512-6SK2z2YsZrxdoumXW7taI1S2HIBvWcFoKWAot0A5coMskJOnt6HnNxIMTBbN5YhkOs855YHqfaLYeNNU3Y3M2A==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.3", + "@girs/glib-2.0": "^2.76.1-3.2.3", + "@girs/gobject-2.0": "^2.76.1-3.2.3" + } + }, + "node_modules/@girs/nm-1.0/node_modules/@girs/glib-2.0": { + "version": "2.76.1-3.2.3", + "resolved": "https://registry.npmjs.org/@girs/glib-2.0/-/glib-2.0-2.76.1-3.2.3.tgz", + "integrity": "sha512-pY/ZE2WPco9E8Cz5+wTqxEOdVpipEQBRDJXVd/KQCoRjTSvgoMLLEE8B84W0LgOgR8ns99XtGZrf0U0y4qFqyA==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.3", + "@girs/gobject-2.0": "^2.76.1-3.2.3" + } + }, + "node_modules/@girs/nm-1.0/node_modules/@girs/gobject-2.0": { + "version": "2.76.1-3.2.3", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.76.1-3.2.3.tgz", + "integrity": "sha512-9X35d1ZRO4xY9b0iOm51MwjfbgvOGQtNs2A9IWcSlaoI4LB5mCRlPlQ1UFhpqcbbmdrL+Cce/0p3F36x5rn/dg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.3", + "@girs/glib-2.0": "^2.76.1-3.2.3" + } + }, + "node_modules/@girs/pango-1.0": { + "version": "1.51.0-3.2.9", + "resolved": "https://registry.npmjs.org/@girs/pango-1.0/-/pango-1.0-1.51.0-3.2.9.tgz", + "integrity": "sha512-dWIvPJoFnpgWQcflTyGhXN5TmlmW0OvTG6kjBFwVJLwT2H6vugUKk9665MvEQDywaeGZzdfrJqQo/oFplhVSBg==", + "dev": true, + "dependencies": { + "@girs/cairo-1.0": "^1.0.0-3.2.9", + "@girs/freetype2-2.0": "^2.0.0-3.2.9", + "@girs/gio-2.0": "^2.78.0-3.2.9", + "@girs/gjs": "^3.2.9", + "@girs/glib-2.0": "^2.78.0-3.2.9", + "@girs/gobject-2.0": "^2.78.0-3.2.9", + "@girs/harfbuzz-0.0": "^8.2.1-3.2.9" + } + }, + "node_modules/@girs/pangocairo-1.0": { + "version": "1.0.0-3.2.9", + "resolved": "https://registry.npmjs.org/@girs/pangocairo-1.0/-/pangocairo-1.0-1.0.0-3.2.9.tgz", + "integrity": "sha512-9tpiYEwdx9829p0oQFrC5Y38USGeap2Y+yNeD8Klf1Pb9pGC/lVjAjrqmGC/nSAyLHz3SlK1kTDP1fBsqoCEng==", + "dev": true, + "dependencies": { + "@girs/cairo-1.0": "^1.0.0-3.2.9", + "@girs/freetype2-2.0": "^2.0.0-3.2.9", + "@girs/gio-2.0": "^2.78.0-3.2.9", + "@girs/gjs": "^3.2.9", + "@girs/glib-2.0": "^2.78.0-3.2.9", + "@girs/gobject-2.0": "^2.78.0-3.2.9", + "@girs/harfbuzz-0.0": "^8.2.1-3.2.9", + "@girs/pango-1.0": "^1.51.0-3.2.9" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/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==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/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==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@stylistic/eslint-plugin": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-1.7.0.tgz", + "integrity": "sha512-ThMUjGIi/jeWYNvOdjZkoLw1EOVs0tEuKXDgWvTn8uWaEz55HuPlajKxjKLpv19C+qRDbKczJfzUODfCdME53A==", + "dev": true, + "dependencies": { + "@stylistic/eslint-plugin-js": "1.7.0", + "@stylistic/eslint-plugin-jsx": "1.7.0", + "@stylistic/eslint-plugin-plus": "1.7.0", + "@stylistic/eslint-plugin-ts": "1.7.0", + "@types/eslint": "^8.56.2" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/eslint-plugin-js": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.7.0.tgz", + "integrity": "sha512-PN6On/+or63FGnhhMKSQfYcWutRlzOiYlVdLM6yN7lquoBTqUJHYnl4TA4MHwiAt46X5gRxDr1+xPZ1lOLcL+Q==", + "dev": true, + "dependencies": { + "@types/eslint": "^8.56.2", + "acorn": "^8.11.3", + "escape-string-regexp": "^4.0.0", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/eslint-plugin-jsx": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-1.7.0.tgz", + "integrity": "sha512-BACdBwXakQvjYIST5N2WWhRbvhRsIxa/F59BiZol+0IH4FSmDXhie7v/yaxDIIA9CbfElzOmIA5nWNYTVXcnwQ==", + "dev": true, + "dependencies": { + "@stylistic/eslint-plugin-js": "^1.7.0", + "@types/eslint": "^8.56.2", + "estraverse": "^5.3.0", + "picomatch": "^4.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/eslint-plugin-plus": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-1.7.0.tgz", + "integrity": "sha512-AabDw8sXsc70Ydx3qnbeTlRHZnIwY6UKEenBPURPhY3bfYWX+/pDpZH40HkOu94v8D0DUrocPkeeEUxl4e0JDg==", + "dev": true, + "dependencies": { + "@types/eslint": "^8.56.2", + "@typescript-eslint/utils": "^6.21.0" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@stylistic/eslint-plugin-ts": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-1.7.0.tgz", + "integrity": "sha512-QsHv98mmW1xaucVYQTyLDgEpybPJ/6jPPxVBrIchntWWwj74xCWKUiw79hu+TpYj/Pbhd9rkqJYLNq3pQGYuyA==", + "dev": true, + "dependencies": { + "@stylistic/eslint-plugin-js": "1.7.0", + "@types/eslint": "^8.56.2", + "@typescript-eslint/utils": "^6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.6.tgz", + "integrity": "sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/@types/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "dev": true, + "peer": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true, + "peer": true + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.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==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz", + "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==", + "dev": true, + "peer": true, + "dependencies": { + "camelcase": "^6.3.0", + "map-obj": "^4.1.0", + "quick-lru": "^5.1.1", + "type-fest": "^1.2.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true, + "peer": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "peer": true, + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.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.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-functions-list": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.1.tgz", + "integrity": "sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12 || >=16" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "peer": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz", + "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "peer": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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==", + "dev": true, + "peer": true + }, + "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==", + "dev": true, + "peer": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "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==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "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.4" + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "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==", + "dev": true, + "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": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "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==", + "dev": true, + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/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==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "peer": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "peer": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "peer": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", + "dev": true, + "peer": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "peer": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "peer": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "peer": 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==", + "dev": true, + "peer": true + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "peer": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "peer": true, + "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==", + "dev": true + }, + "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==", + "dev": true, + "peer": true + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "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==", + "dev": true, + "peer": true + }, + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/known-css-properties": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.29.0.tgz", + "integrity": "sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "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==", + "dev": true, + "peer": true + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true, + "peer": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true, + "peer": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true, + "peer": true + }, + "node_modules/meow": { + "version": "10.1.5", + "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.5.tgz", + "integrity": "sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/minimist": "^1.2.2", + "camelcase-keys": "^7.0.0", + "decamelize": "^5.0.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.2", + "read-pkg-up": "^8.0.0", + "redent": "^4.0.0", + "trim-newlines": "^4.0.2", + "type-fest": "^1.2.2", + "yargs-parser": "^20.2.9" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "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==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "peer": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "peer": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "peer": true, + "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-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true, + "peer": true + }, + "node_modules/picomatch": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.1.tgz", + "integrity": "sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true + }, + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", + "dev": true + }, + "node_modules/postcss-safe-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "node_modules/postcss-scss": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz", + "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-scss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.4.29" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", + "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-6.0.0.tgz", + "integrity": "sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==", + "dev": true, + "peer": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^3.0.2", + "parse-json": "^5.2.0", + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-8.0.0.tgz", + "integrity": "sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==", + "dev": true, + "peer": true, + "dependencies": { + "find-up": "^5.0.0", + "read-pkg": "^6.0.0", + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/redent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-4.0.0.tgz", + "integrity": "sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==", + "dev": true, + "peer": true, + "dependencies": { + "indent-string": "^5.0.0", + "strip-indent": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "peer": true, + "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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "peer": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "peer": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "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==", + "dev": true, + "peer": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "peer": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", + "dev": true, + "peer": true + }, + "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==", + "dev": true, + "peer": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", + "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", + "dev": true, + "peer": true, + "dependencies": { + "min-indent": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==", + "dev": true, + "peer": true + }, + "node_modules/stylelint": { + "version": "15.11.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.11.0.tgz", + "integrity": "sha512-78O4c6IswZ9TzpcIiQJIN49K3qNoXTM8zEJzhaTE/xRTCZswaovSEVIa/uwbOltZrk16X4jAxjaOhzz/hTm1Kw==", + "dev": true, + "peer": true, + "dependencies": { + "@csstools/css-parser-algorithms": "^2.3.1", + "@csstools/css-tokenizer": "^2.2.0", + "@csstools/media-query-list-parser": "^2.1.4", + "@csstools/selector-specificity": "^3.0.0", + "balanced-match": "^2.0.0", + "colord": "^2.9.3", + "cosmiconfig": "^8.2.0", + "css-functions-list": "^3.2.1", + "css-tree": "^2.3.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.1", + "fastest-levenshtein": "^1.0.16", + "file-entry-cache": "^7.0.0", + "global-modules": "^2.0.0", + "globby": "^11.1.0", + "globjoin": "^0.1.4", + "html-tags": "^3.3.1", + "ignore": "^5.2.4", + "import-lazy": "^4.0.0", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.29.0", + "mathml-tag-names": "^2.1.3", + "meow": "^10.1.5", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.28", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^6.0.0", + "postcss-selector-parser": "^6.0.13", + "postcss-value-parser": "^4.2.0", + "resolve-from": "^5.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "style-search": "^0.1.0", + "supports-hyperlinks": "^3.0.0", + "svg-tags": "^1.0.0", + "table": "^6.8.1", + "write-file-atomic": "^5.0.1" + }, + "bin": { + "stylelint": "bin/stylelint.mjs" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + } + }, + "node_modules/stylelint-config-recommended": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-13.0.0.tgz", + "integrity": "sha512-EH+yRj6h3GAe/fRiyaoO2F9l9Tgg50AOFhaszyfov9v6ayXJ1IkSHwTxd7lB48FmOeSGDPLjatjO11fJpmarkQ==", + "dev": true, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "stylelint": "^15.10.0" + } + }, + "node_modules/stylelint-config-recommended-scss": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-13.1.0.tgz", + "integrity": "sha512-8L5nDfd+YH6AOoBGKmhH8pLWF1dpfY816JtGMePcBqqSsLU+Ysawx44fQSlMOJ2xTfI9yTGpup5JU77c17w1Ww==", + "dev": true, + "dependencies": { + "postcss-scss": "^4.0.9", + "stylelint-config-recommended": "^13.0.0", + "stylelint-scss": "^5.3.0" + }, + "peerDependencies": { + "postcss": "^8.3.3", + "stylelint": "^15.10.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + } + } + }, + "node_modules/stylelint-config-standard": { + "version": "34.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-34.0.0.tgz", + "integrity": "sha512-u0VSZnVyW9VSryBG2LSO+OQTjN7zF9XJaAJRX/4EwkmU0R2jYwmBSN10acqZisDitS0CLiEiGjX7+Hrq8TAhfQ==", + "dev": true, + "dependencies": { + "stylelint-config-recommended": "^13.0.0" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "stylelint": "^15.10.0" + } + }, + "node_modules/stylelint-config-standard-scss": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard-scss/-/stylelint-config-standard-scss-11.1.0.tgz", + "integrity": "sha512-5gnBgeNTgRVdchMwiFQPuBOtj9QefYtfXiddrOMJA2pI22zxt6ddI2s+e5Oh7/6QYl7QLJujGnaUR5YyGq72ow==", + "dev": true, + "dependencies": { + "stylelint-config-recommended-scss": "^13.1.0", + "stylelint-config-standard": "^34.0.0" + }, + "peerDependencies": { + "postcss": "^8.3.3", + "stylelint": "^15.10.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + } + } + }, + "node_modules/stylelint-scss": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-5.3.2.tgz", + "integrity": "sha512-4LzLaayFhFyneJwLo0IUa8knuIvj+zF0vBFueQs4e3tEaAMIQX8q5th8ziKkgOavr6y/y9yoBe+RXN/edwLzsQ==", + "dev": true, + "dependencies": { + "known-css-properties": "^0.29.0", + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-selector-parser": "^6.0.13", + "postcss-value-parser": "^4.2.0" + }, + "peerDependencies": { + "stylelint": "^14.5.1 || ^15.0.0" + } + }, + "node_modules/stylelint/node_modules/balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true, + "peer": true + }, + "node_modules/stylelint/node_modules/file-entry-cache": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-7.0.2.tgz", + "integrity": "sha512-TfW7/1iI4Cy7Y8L6iqNdZQVvdXn0f8B4QcIXmkIbtTIe/Okm/nSlHb4IwGzRVOd3WfSieCgvf5cMzEfySAIl0g==", + "dev": true, + "peer": true, + "dependencies": { + "flat-cache": "^3.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/stylelint/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", + "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true, + "peer": true + }, + "node_modules/table": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "dev": true, + "peer": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "peer": true + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/trim-newlines": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.1.1.tgz", + "integrity": "sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", + "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "peer": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "peer": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/modules/ags/astal/package.json b/modules/ags/astal/package.json new file mode 100644 index 00000000..9ea05bd9 --- /dev/null +++ b/modules/ags/astal/package.json @@ -0,0 +1,19 @@ +{ + "main": "config.js", + "dependencies": { + "fzf": "^0.5.2" + }, + "devDependencies": { + "@girs/adw-1": "^1.4.3-3.2.9", + "@girs/cairo-1.0": "^1.0.0-3.2.7", + "@girs/gjs": "^3.2.7", + "@girs/gtk-4.0": "^4.12.0-3.2.8", + "@girs/gvc-1.0": "^1.0.0-3.1.0", + "@girs/nm-1.0": "^1.43.1-3.1.0", + "@stylistic/eslint-plugin": "^1.4.0", + "@typescript-eslint/eslint-plugin": "^6.9.1", + "@typescript-eslint/parser": "^6.9.1", + "eslint": "^8.52.0", + "stylelint-config-standard-scss": "^11.0.0" + } +} diff --git a/modules/ags/astal/scss/greeter.scss b/modules/ags/astal/scss/greeter.scss new file mode 100644 index 00000000..34cf7798 --- /dev/null +++ b/modules/ags/astal/scss/greeter.scss @@ -0,0 +1,16 @@ +window { + all: unset; + background-color: transparent; +} + + +.base { + background-color: #{"@window_bg_color"}; + border: 1.3px solid #{"@accent_bg_color"}; + border-radius: 12px; + padding: 5px; +} + +dropdown popover.menu { + padding-top: 0; +} diff --git a/modules/ags/astal/ts/greetd/main.ts b/modules/ags/astal/ts/greetd/main.ts new file mode 100644 index 00000000..ca1cefa6 --- /dev/null +++ b/modules/ags/astal/ts/greetd/main.ts @@ -0,0 +1,115 @@ +const { Box, Entry, Label, Window } = Widget; +const { execAsync, idle, readFileAsync } = Utils; + +const greetd = await Service.import('greetd'); + +const { Gtk } = imports.gi; + +const DEFAULT_NAME = 'matt'; + +// Types +import { StringObject } from 'types/@girs/gtk-4.0/gtk-4.0.cjs'; + + +// Run Wallpaper daemon here to not cause issues at startup +execAsync(['bash', '-c', + `swww init --no-cache && swww img -t none ${App.configDir}/.wallpaper`]).catch(print); + +const parsePasswd = (fileContent: string) => { + const splitUsers = fileContent.split('\n'); + const parsedUsers = splitUsers.map((u) => { + const user = u.split(':'); + + return { + name: user[0], + uid: Number(user[2]), + gid: Number(user[3]), + desc: user[4], + home: user[5], + shell: user[6], + }; + }); + + // 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(await readFileAsync('/etc/passwd')); + +const dropdown = Gtk.DropDown.new_from_strings(users.map((u) => u.name)); + +const password = Entry({ + placeholderText: 'Password', + visibility: false, + + setup: (self) => idle(() => { + self.grab_focus(); + }), + + on_accept: () => { + greetd.login( + (dropdown.selectedItem as StringObject)['string'] || '', + password.text || '', + 'Hyprland', + + ).catch((error) => { + response.label = JSON.stringify(error); + }); + }, + +}); + +const response = Label(); + +export default () => Window({ + name: 'greeter', + keymode: 'on-demand', + + child: Box({ + vertical: true, + hpack: 'center', + vpack: 'center', + hexpand: true, + vexpand: true, + cssClasses: ['base'], + + children: [ + Box({ + vertical: true, + hpack: 'center', + vpack: 'center', + hexpand: true, + vexpand: true, + + setup: (self) => { + self.add_css_class('linked'); + + idle(() => { + const usernames = [] as string[]; + + for (let i = 0; i < dropdown.model.get_n_items(); ++i) { + const name = (dropdown.model.get_item(i) as StringObject)['string']; + + if (name) { + usernames.push(name); + } + } + + if (usernames.includes(DEFAULT_NAME)) { + dropdown.set_selected(usernames.indexOf(DEFAULT_NAME)); + } + }); + }, + + children: [ + dropdown, + password, + ], + }), + response, + ], + }), +}); diff --git a/modules/ags/astal/tsconfig.json b/modules/ags/astal/tsconfig.json new file mode 100644 index 00000000..0feb1cf1 --- /dev/null +++ b/modules/ags/astal/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ES2022", + "lib": [ + "ES2022" + ], + "allowJs": true, + "checkJs": true, + "strict": true, + "noImplicitAny": false, + "baseUrl": ".", + "paths": { + "gi://Adw": ["./node_modules/@girs/adw-1/adw-1.d.ts"], + "gi://Adw?version=1": ["./node_modules/@girs/adw-1/adw-1.d.ts"] + }, + "typeRoots": [ + "./types", + "./node_modules" + ], + "skipLibCheck": true + }, +} diff --git a/modules/ags/config/.envrc b/modules/ags/config/.envrc index 674cafba..1ea98949 100644 --- a/modules/ags/config/.envrc +++ b/modules/ags/config/.envrc @@ -1 +1 @@ -use flake "$FLAKE#node" +use flake $FLAKE#ags diff --git a/modules/ags/config/.eslintrc.json b/modules/ags/config/.eslintrc.json new file mode 100644 index 00000000..4ad07f36 --- /dev/null +++ b/modules/ags/config/.eslintrc.json @@ -0,0 +1,148 @@ +{ + "env": { + "es2021": true + }, + "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], + "parser": "@typescript-eslint/parser", + "overrides": [], + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": ["@stylistic", "@typescript-eslint"], + "rules": { + "array-callback-return": ["error", { + "allowImplicit": true, + "checkForEach": true + }], + "no-constructor-return": ["error"], + "no-unreachable-loop": ["error", { "ignore": [ + "ForInStatement", "ForOfStatement" + ]}], + + + "block-scoped-var": ["error"], + "class-methods-use-this": ["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, 10, 33, 66, 100, 255, 360, 450, 1000], + "ignoreDefaultValues": true, + "ignoreArrayIndexes": true + }], + "no-multi-assign": ["error"], + "no-new": ["error"], + "no-new-func": ["error"], + "no-new-wrappers": ["error"], + "no-object-constructor": ["error"], + "no-proto": ["error"], + "no-return-assign": ["error"], + "no-sequences": ["error"], + "no-shadow": ["error", { "builtinGlobals": true }], + "no-undef-init": ["warn"], + "no-undefined": ["error"], + "no-useless-constructor": ["warn"], + "no-useless-escape": ["off"], + "no-useless-return": ["error"], + "no-var": ["error"], + "no-void": ["error"], + "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-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "warn", + "@typescript-eslint/no-unsafe-declaration-merging": "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 + }], + "@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": 100, + "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-property-newline": ["warn", {"allowAllPropertiesOnSameLine": false}], + "@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"] + }, + "globals": { + "ARGV": "readonly", + "imports": "readonly", + "print": "readonly", + "console": "readonly", + "logError": "readonly", + "setTimeout": "readonly", + "setInterval": "readonly", + "Widget": "readonly", + "Service": "readonly", + "Variable": "readonly", + "Utils": "readonly", + "App": "readonly" + } +} 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/.stylelintrc.yml b/modules/ags/config/.stylelintrc.yml new file mode 100644 index 00000000..bf5a5120 --- /dev/null +++ b/modules/ags/config/.stylelintrc.yml @@ -0,0 +1,17 @@ +extends: stylelint-config-standard-scss +ignoreFiles: + - "**/*.js" + - "**/*.ts" +rules: + selector-type-no-unknown: null + selector-class-pattern: null + declaration-empty-line-before: null + no-descending-specificity: null + selector-pseudo-class-no-unknown: null + color-function-notation: legacy + alpha-value-notation: number + scss/operator-no-unspaced: null + scss/no-global-function-names: null + scss/dollar-variable-empty-line-before: null + no-invalid-position-at-import-rule: null + font-family-no-missing-generic-family-keyword: null 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/binto.ts b/modules/ags/config/binto.ts new file mode 100644 index 00000000..e66d6d36 --- /dev/null +++ b/modules/ags/config/binto.ts @@ -0,0 +1,34 @@ +import Brightness from './services/brightness.ts'; +import GSR from './services/gpu-screen-recorder.ts'; +import Pointers from './services/pointers.ts'; + +import AppLauncher from './ts/applauncher/main.ts'; +import Bar from './ts/bar/binto.ts'; +import { NotifPopups, NotifCenter } from './ts/notifications/binto.ts'; +import OSD from './ts/osd/main.ts'; +import Powermenu from './ts/powermenu.ts'; + + +// TODO: add workspace indicator +App.config({ + icons: './icons', + + onConfigParsed: () => { + Brightness.capsName = 'input30::capslock'; + globalThis.Brightness = Brightness; + globalThis.Pointers = Pointers; + setTimeout(() => { + globalThis.GSR = new GSR(); + }, 1000); + }, + + windows: () => [ + AppLauncher(), + NotifCenter(), + Powermenu(), + + Bar(), + NotifPopups(), + OSD(), + ], +}); 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 b13f59bb..00000000 --- a/modules/ags/config/default.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ - npmDepsHash = "sha256-Zns+ehFnBAVsVV/gJi2J3oY2t8hVPkxGDLD0PMwl07s="; -} 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/global-types.d.ts b/modules/ags/config/global-types.d.ts new file mode 100644 index 00000000..92ec6d02 --- /dev/null +++ b/modules/ags/config/global-types.d.ts @@ -0,0 +1,193 @@ +import { Widget } from 'types/@girs/gtk-3.0/gtk-3.0.cjs'; +import GObject from 'types/@girs/gobject-2.0/gobject-2.0'; + +import { Variable as Var } from 'types/variable'; +import { Widget as agsWidget } from 'types/widgets/widget'; +export type AgsWidget = agsWidget<unknown> & Widget; + +// For ./ts/applauncher/main.ts +import { Application } from 'types/service/applications.ts'; +import { CursorBoxProps } from 'ts/misc/cursorbox'; +export type AgsAppItem = AgsEventBox<Widget, { app: Application } +& CursorBoxProps<Widget, unknown>>; + +// For ./ts/bar/hovers/keyboard.ts +export type Keyboard = { + address: string; + name: string; + rules: string; + model: string; + layout: string; + variant: string; + options: string; + active_keymap: string; + main: boolean; +}; + +// For ./ts/bar/items/workspaces.ts +// TODO: improve type +export type Workspace = AgsRevealer<unknown & Widget, unknown & { id: number }>; + +// For ./ts/bar/fullscreen.ts +export type DefaultProps = RevealerProps<CenterBoxGeneric>; + +// For ./ts/media-player/gesture.ts +export type Gesture = { + attribute?: object + setup?(self: OverlayGeneric): void + props?: OverlayProps<unknown & Widget, unknown> +}; + +// For ./ts/media-player/mpris.ts +type PlayerDragProps = unknown & { dragging: boolean }; +export type PlayerDrag = AgsCenterBox< +unknown & Widget, unknown & Widget, unknown & Widget, unknown & PlayerDragProps +>; +type Colors = { + imageAccent: string; + buttonAccent: string; + buttonText: string; + hoverAccent: string; +}; + +// For ./ts/media-player +export type PlayerBoxProps = { + bgStyle: string, + player: MprisPlayer, +}; +export type PlayerBox = AgsCenterBox< +unknown & Widget, unknown & Widget, unknown & Widget, PlayerBoxProps +>; +export type PlayerOverlay = AgsOverlay<AgsWidget, { + players: Map; + setup: boolean; + dragging: boolean; + includesWidget(playerW: PlayerBox): PlayerBox; + showTopOnly(): void; + moveToTop(player: PlayerBox): void; +}>; +export type PlayerButtonType = { + player: MprisPlayer + colors: Var<Colors> + children: StackProps['children'] + onClick: string + prop: string +}; + +// For ./ts/notifications/gesture.js +type NotifGestureProps = { + dragging: boolean; + hovered: boolean + ready: boolean + id: number; + slideAway(side: 'Left' | 'Right'): void; +}; +export type NotifGesture = AgsEventBox<BoxGeneric, NotifGestureProps>; + +// For ./ts/osd/ctor.ts +export type OSDStack = AgsStack<unknown & Widget, { + popup(osd: string): void, +}>; +export type ConnectFunc = (self?: ProgressBarGeneric) => void; +export type OSD = { + name: string; + icon: IconPropsGeneric['icon']; + info: { + mod: GObject.Object; + signal?: string | string[]; + logic?(self: ProgressBarGeneric): void; + widget?: AgsWidget; + } +}; + +// For ./ts/on-screen-keyboard +export type OskWindow = Window<BoxGeneric, { + startY: null | number; + setVisible: (state: boolean) => void; + killGestureSigs: () => void; + setSlideUp: () => void; + setSlideDown: () => void; +}>; + +// For CursorBox +import { CursorBox, CursorBoxProps } from 'ts/misc/cursorbox'; +export type CursorBox = CursorBox; +export type CursorBoxProps = CursorBoxProps; + +// For PopupWindow +export type PopupChild = Binding< +Var<Widget>, +'is_listening' | 'is_polling' | 'value', +Widget[] +>; +export type HyprTransition = 'slide' | 'slide top' | 'slide bottom' | 'slide left' | +'slide right' | 'popin' | 'fade'; +export type CloseType = 'none' | 'stay' | 'released' | 'clicked'; +export type PopupWindowProps<Child extends Widget, Attr = unknown> = +WindowProps<Child> & { + transition?: HyprTransition; + on_open?(self: PopupWindow<Child, Attr>): void + on_close?(self: PopupWindow<Child, Attr>): void + blur?: boolean + close_on_unfocus?: CloseType + attribute?: Attr; + content?: Widget + anchor?: Array<'top' | 'bottom' | 'right' | 'left'>; +}; +import { PopupWindow } from 'ts/misc/popup'; +export type PopupWindow = PopupWindow; + +// For ./ts/quick-settings +import { BluetoothDevice as BTDev } from 'types/service/bluetooth.ts'; +export type APType = { + bssid: string + address: string + lastSeen: number + ssid: string + active: boolean + strength: number + iconName: string +}; +export type APBox = AgsBox<unknown & Widget, { ap: Var<APType> }>; +export type DeviceBox = AgsBox<unknown & Widget, { dev: BTDev }>; + + +// Generic widgets +import AgsBox from 'types/widgets/box.ts'; +export type BoxGeneric = AgsBox<unknown & Widget, unknown>; + +import AgsCenterBox, { CenterBoxProps } from 'types/widgets/centerbox'; +export type CenterBoxGeneric = AgsCenterBox< +unknown & Widget, unknown & Widget, unknown & Widget, unknown +>; +export type CenterBoxPropsGeneric = CenterBoxProps< +unknown & Widget, unknown & Widget, unknown & Widget, unknown +>; + +import AgsEventBox from 'types/widgets/eventbox'; +export type EventBoxGeneric = AgsEventBox<unknown & Widget, unknown>; + +import AgsIcon, { IconProps } from 'types/widgets/icon'; +export type IconGeneric = AgsIcon<unknown>; +export type IconPropsGeneric = IconProps<unknown>; + +import AgsLabel from 'types/widgets/label'; +export type LabelGeneric = AgsLabel<unknown>; + +import AgsOverlay, { OverlayProps } from 'types/widgets/overlay'; +export type OverlayGeneric = AgsOverlay<unknown & Widget, unknown>; + +import AgsProgressBar from 'types/widgets/progressbar'; +export type ProgressBarGeneric = AgsProgressBar<unknown & Widget, unknown>; + +import AgsRevealer, { RevealerProps } from 'types/widgets/revealer'; +export type RevealerGeneric = AgsRevealer<unknown & Widget, unknown>; + +import AgsStack, { StackProps } from 'types/widgets/stack'; +export type StackGeneric = AgsStack<{ [name: string]: Widget; }, unknown>; + +import AgsScrollable from 'types/widgets/scrollable'; +export type ScrollableGeneric = AgsScrollable<unkown & Widget, unknown>; + +import AgsWindow from 'types/widgets/window'; +export type WindowGeneric = AgsWindow<unknown & Widget, unknown>; diff --git a/modules/ags/config/js/utils.js b/modules/ags/config/js/utils.js new file mode 100644 index 00000000..7ed4398b --- /dev/null +++ b/modules/ags/config/js/utils.js @@ -0,0 +1,47 @@ +const { execAsync, monitorFile } = Utils; + + +/** @param {string} host */ +const watchAndCompileSass = (host) => { + const reloadCss = () => { + const scss = `${App.configDir}/scss/${host}.scss`; + const css = `/tmp/ags-${host}/style.css`; + + execAsync(`sass ${scss} ${css}`).then(() => { + App.resetCss(); + App.applyCss(css); + }).catch(print); + }; + + monitorFile( + `${App.configDir}/scss`, + reloadCss, + ); + reloadCss(); +}; + +/** @param {string} host */ +export const transpileTypeScript = async(host) => { + const outPath = `/tmp/ags-${host}/index.js`; + + await execAsync([ + 'bash', '-c', + // Create the dir if it doesn't exist + `mkdir -p /tmp/ags-${host}; ` + + + // Let bun see tsconfig.json + `cd ${App.configDir};` + + + `bun build ${App.configDir}/${host}.ts ` + + '--external resource:///* ' + + '--external gi://* ' + + '--external cairo ' + + + // Since bun wants to write in cwd, we just redirect stdin instead + `> ${outPath}`, + ]).catch(print); + + watchAndCompileSass(host); + + return await import(`file://${outPath}`); +}; 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 index a6a8c4ed..d9b767ef 100644 --- a/modules/ags/config/package-lock.json +++ b/modules/ags/config/package-lock.json @@ -1,2574 +1,3667 @@ { - "name": "ags", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "ags", - "version": "0.0.0", - "dependencies": { - "@eslint/js": "9.26.0", - "@stylistic/eslint-plugin": "4.2.0", - "astal": "https://gitpkg.vercel.app/Aylur/astal/lang/gjs/src?4820a3e37cc8eb81db6ed991528fb23472a8e4de", - "eslint": "9.26.0", - "eslint-plugin-jsdoc": "50.6.17", - "fzf": "0.5.2", - "jiti": "2.4.2", - "typescript-eslint": "8.32.1" - } - }, - "node_modules/@es-joy/jsdoccomment": { - "version": "0.50.1", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.50.1.tgz", - "integrity": "sha512-fas3qe1hw38JJgU/0m5sDpcrbZGysBeZcMwW5Ws9brYxY64MJyWLXRZCj18keTycT1LFTrFXdSNMS+GRVaU6Hw==", - "license": "MIT", - "dependencies": { - "@types/eslint": "^9.6.1", - "@types/estree": "^1.0.6", - "@typescript-eslint/types": "^8.11.0", - "comment-parser": "1.4.1", - "esquery": "^1.6.0", - "jsdoc-type-pratt-parser": "~4.1.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", - "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.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.2.tgz", - "integrity": "sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==", - "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.26.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.26.0.tgz", - "integrity": "sha512-I9XlJawFdSMvWjDt6wksMCrgns5ggLNfFwFvnShsleWruvXM514Qxk8V246efTw+eo9JABvVz+u3q2RiAowKxQ==", - "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.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@modelcontextprotocol/sdk": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.11.3.tgz", - "integrity": "sha512-rmOWVRUbUJD7iSvJugjUbFZshTAuJ48MXoZ80Osx1GM0K/H1w7rSEvmw8m6vdWxNASgtaHIhAgre4H/E9GJiYQ==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "cors": "^2.8.5", - "cross-spawn": "^7.0.5", - "eventsource": "^3.0.2", - "express": "^5.0.1", - "express-rate-limit": "^7.5.0", - "pkce-challenge": "^5.0.0", - "raw-body": "^3.0.0", - "zod": "^3.23.8", - "zod-to-json-schema": "^3.24.1" - }, - "engines": { - "node": ">=18" - } - }, - "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/@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/eslint": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", - "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "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.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.32.1.tgz", - "integrity": "sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg==", - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.32.1", - "@typescript-eslint/type-utils": "8.32.1", - "@typescript-eslint/utils": "8.32.1", - "@typescript-eslint/visitor-keys": "8.32.1", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" - }, - "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/eslint-plugin/node_modules/ignore": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.4.tgz", - "integrity": "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "8.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.32.1.tgz", - "integrity": "sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "8.32.1", - "@typescript-eslint/types": "8.32.1", - "@typescript-eslint/typescript-estree": "8.32.1", - "@typescript-eslint/visitor-keys": "8.32.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.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.32.1.tgz", - "integrity": "sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.32.1", - "@typescript-eslint/visitor-keys": "8.32.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.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.32.1.tgz", - "integrity": "sha512-mv9YpQGA8iIsl5KyUPi+FGLm7+bA4fgXaeRcFKRDRwDMu4iwrSHeDPipwueNXhdIIZltwCJv+NkxftECbIZWfA==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "8.32.1", - "@typescript-eslint/utils": "8.32.1", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" - }, - "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.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.32.1.tgz", - "integrity": "sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==", - "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.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.32.1.tgz", - "integrity": "sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.32.1", - "@typescript-eslint/visitor-keys": "8.32.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.1.0" - }, - "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.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.32.1.tgz", - "integrity": "sha512-DsSFNIgLSrc89gpq1LJB7Hm1YpuhK086DRDJSNrewcGvYloWW1vZLHBTIvarKZDcAORIy/uWNx8Gad+4oMpkSA==", - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.32.1", - "@typescript-eslint/types": "8.32.1", - "@typescript-eslint/typescript-estree": "8.32.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.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.32.1.tgz", - "integrity": "sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.32.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/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", - "license": "MIT", - "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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?4820a3e37cc8eb81db6ed991528fb23472a8e4de", - "integrity": "sha512-YCfB1aVkxP1aWGbSi+/NsYv2n0JnzamFk+0j3AoJdGlfFIGuPm3gHR3U7RYm4Nuq7/VO0GDc95C2YNaAxm1MVQ==", - "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/body-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", - "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", - "license": "MIT", - "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.0", - "http-errors": "^2.0.0", - "iconv-lite": "^0.6.3", - "on-finished": "^2.4.1", - "qs": "^6.14.0", - "raw-body": "^3.0.0", - "type-is": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "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/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/content-disposition": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", - "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "license": "MIT", - "engines": { - "node": ">=6.6.0" - } - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "license": "MIT", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "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/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "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.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.26.0.tgz", - "integrity": "sha512-Hx0MOjPh6uK9oq9nVsATZKE/Wlbai7KFjfCuw9UHaguDW3x+HF0O5nIi3ud39TWgrTjTO5nHxmL3R1eANinWHQ==", - "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.26.0", - "@eslint/plugin-kit": "^0.2.8", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@modelcontextprotocol/sdk": "^1.8.0", - "@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", - "zod": "^3.24.2" - }, - "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.17", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.6.17.tgz", - "integrity": "sha512-hq+VQylhd12l8qjexyriDsejZhqiP33WgMTy2AmaGZ9+MrMWVqPECsM87GPxgHfQn0zw+YTuhqjUfk1f+q67aQ==", - "license": "BSD-3-Clause", - "dependencies": { - "@es-joy/jsdoccomment": "~0.50.1", - "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-exports": "^0.2.4", - "semver": "^7.6.3", - "spdx-expression-parse": "^4.0.0" - }, - "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/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventsource": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", - "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", - "license": "MIT", - "dependencies": { - "eventsource-parser": "^3.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/eventsource-parser": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.2.tgz", - "integrity": "sha512-6RxOBZ/cYgd8usLwsEl+EC09Au/9BcmCKYF2/xbml6DNczf7nv0MQb+7BA2F+li6//I+28VNlQR37XfQtcAJuA==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/express": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", - "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", - "license": "MIT", - "dependencies": { - "accepts": "^2.0.0", - "body-parser": "^2.2.0", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "finalhandler": "^2.1.0", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "merge-descriptors": "^2.0.0", - "mime-types": "^3.0.0", - "on-finished": "^2.4.1", - "once": "^1.4.0", - "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", - "range-parser": "^1.2.1", - "router": "^2.2.0", - "send": "^1.1.0", - "serve-static": "^2.2.0", - "statuses": "^2.0.1", - "type-is": "^2.0.1", - "vary": "^1.1.2" - }, - "engines": { - "node": ">= 18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express-rate-limit": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", - "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/express-rate-limit" - }, - "peerDependencies": { - "express": "^4.11 || 5 || ^5.0.0-beta.1" - } - }, - "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/finalhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", - "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 0.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/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/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/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/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/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/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/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "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/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "license": "MIT" - }, - "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/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/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "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-exports": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/parse-imports-exports/-/parse-imports-exports-0.2.4.tgz", - "integrity": "sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==", - "license": "MIT", - "dependencies": { - "parse-statements": "1.0.11" - } - }, - "node_modules/parse-statements": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/parse-statements/-/parse-statements-1.0.11.tgz", - "integrity": "sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==", - "license": "MIT" - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/path-to-regexp": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", - "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", - "license": "MIT", - "engines": { - "node": ">=16" - } - }, - "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/pkce-challenge": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz", - "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==", - "license": "MIT", - "engines": { - "node": ">=16.20.0" - } - }, - "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-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", - "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.6.3", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "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/router": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "depd": "^2.0.0", - "is-promise": "^4.0.0", - "parseurl": "^1.3.3", - "path-to-regexp": "^8.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "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/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "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/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/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/send": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", - "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.5", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "mime-types": "^3.0.1", - "ms": "^2.1.3", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "statuses": "^2.0.1" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", - "license": "MIT", - "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "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/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "engines": { - "node": ">= 0.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/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/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "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/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/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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.32.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.32.1.tgz", - "integrity": "sha512-D7el+eaDHAmXvrZBy1zpzSNIRqnCOrkwTgZxTu3MUqRWk8k0q9m9Ho4+vPf7iHtgUfrK/o8IZaEApsxPlHTFCg==", - "license": "MIT", - "dependencies": { - "@typescript-eslint/eslint-plugin": "8.32.1", - "@typescript-eslint/parser": "8.32.1", - "@typescript-eslint/utils": "8.32.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/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "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" - } - }, - "node_modules/zod": { - "version": "3.24.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.4.tgz", - "integrity": "sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-to-json-schema": { - "version": "3.24.5", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", - "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==", - "license": "ISC", - "peerDependencies": { - "zod": "^3.24.1" - } + "name": "config", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "fzf": "^0.5.2" + }, + "devDependencies": { + "@girs/dbusmenugtk3-0.4": "^0.4.0-3.2.0", + "@girs/gobject-2.0": "^2.76.1-3.2.3", + "@girs/gtk-3.0": "^3.24.39-3.2.2", + "@girs/gvc-1.0": "^1.0.0-3.1.0", + "@girs/nm-1.0": "^1.43.1-3.1.0", + "@stylistic/eslint-plugin": "^1.4.0", + "@typescript-eslint/eslint-plugin": "^6.9.1", + "@typescript-eslint/parser": "^6.9.1", + "eslint": "^8.52.0", + "stylelint-config-standard-scss": "^11.0.0" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "peer": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "peer": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.2.tgz", + "integrity": "sha512-sLYGdAdEY2x7TSw9FtmdaTrh2wFtRJO5VMbBrA8tEqEod7GEggFmxTSK9XqExib3yMuYNcvcTdCZIP6ukdjAIA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" } + ], + "peer": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^2.2.1" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.2.1.tgz", + "integrity": "sha512-Zmsf2f/CaEPWEVgw29odOj+WEVoiJy9s9NOv5GgNY9mZ1CZ7394By6wONrONrTsnNDv6F9hR02nvFihrGVGHBg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "peer": true, + "engines": { + "node": "^14 || ^16 || >=18" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.5.tgz", + "integrity": "sha512-IxVBdYzR8pYe89JiyXQuYk4aVVoCPhMJkz6ElRwlVysjwURTsTk/bmY/z4FfeRE+CRBMlykPwXEVUg8lThv7AQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "peer": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^2.3.2", + "@csstools/css-tokenizer": "^2.2.1" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.0.0.tgz", + "integrity": "sha512-hBI9tfBtuPIi885ZsZ32IMEU/5nlZH/KOVYJCOh7gyMxaVLGmLedYqFN6Ui1LXkI8JlC8IsuC0rF0btcRZKd5g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "peer": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^6.0.13" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", + "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.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": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.52.0.tgz", + "integrity": "sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@girs/atk-1.0": { + "version": "2.45.1-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/atk-1.0/-/atk-1.0-2.45.1-3.2.2.tgz", + "integrity": "sha512-+ba+w8s3CuIHBXNtfUtqbMy+lpa+SxY+ksu5i9QSINvKod6RHXSglXYiRAjKsP3nVyTc+FaF7ymYvqGbM42HHw==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2", + "@girs/gobject-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/atk-1.0/node_modules/@girs/gobject-2.0": { + "version": "2.77.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.77.0-3.2.2.tgz", + "integrity": "sha512-psnnFhNY+49SXzdTDpHwnySMTDtHYDP9rxMx1Xb1UVE1JaxwuI0YLrylt+Zv0boGczmwol8afxZw2Z9TnSSocg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/cairo-1.0": { + "version": "1.0.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/cairo-1.0/-/cairo-1.0-1.0.0-3.2.2.tgz", + "integrity": "sha512-vQ5bV++lRtAFA3aOIVTcGYTfYJhfaxmoerGDiLryGpgQCyN5uA1xbNzwKiQeU1vb3wtByuRCl3/vLQ3Xkl866w==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2", + "@girs/gobject-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/cairo-1.0/node_modules/@girs/gobject-2.0": { + "version": "2.77.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.77.0-3.2.2.tgz", + "integrity": "sha512-psnnFhNY+49SXzdTDpHwnySMTDtHYDP9rxMx1Xb1UVE1JaxwuI0YLrylt+Zv0boGczmwol8afxZw2Z9TnSSocg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/dbusmenu-0.4": { + "version": "0.4.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/dbusmenu-0.4/-/dbusmenu-0.4-0.4.0-3.2.2.tgz", + "integrity": "sha512-sdxllzUo469QRdsamma8WqxVHe+6aETC++yLaeZwRwtQvjyXcFB6R4ja7m18W2v4fQEvNeJxbzK/aCQTuaNZgA==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2", + "@girs/gobject-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/dbusmenu-0.4/node_modules/@girs/gobject-2.0": { + "version": "2.77.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.77.0-3.2.2.tgz", + "integrity": "sha512-psnnFhNY+49SXzdTDpHwnySMTDtHYDP9rxMx1Xb1UVE1JaxwuI0YLrylt+Zv0boGczmwol8afxZw2Z9TnSSocg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/dbusmenugtk3-0.4": { + "version": "0.4.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/dbusmenugtk3-0.4/-/dbusmenugtk3-0.4-0.4.0-3.2.2.tgz", + "integrity": "sha512-WlxmTH924sRjvwwUgvW58JaMmoF/i3FeMgVK9+nfye6oRjDWK/6/C36mGVdrdHonCD5iV9rQGGXoeXzAyaDFtQ==", + "dev": true, + "dependencies": { + "@girs/atk-1.0": "^2.45.1-3.2.2", + "@girs/cairo-1.0": "^1.0.0-3.2.2", + "@girs/dbusmenu-0.4": "^0.4.0-3.2.2", + "@girs/freetype2-2.0": "^2.0.0-3.2.2", + "@girs/gdk-3.0": "^3.24.39-3.2.2", + "@girs/gdkpixbuf-2.0": "^2.0.0-3.2.2", + "@girs/gio-2.0": "^2.77.0-3.2.2", + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2", + "@girs/gmodule-2.0": "^2.0.0-3.2.2", + "@girs/gobject-2.0": "^2.77.0-3.2.2", + "@girs/gtk-3.0": "^3.24.39-3.2.2", + "@girs/harfbuzz-0.0": "^7.1.0-3.2.2", + "@girs/pango-1.0": "^1.51.0-3.2.2", + "@girs/xlib-2.0": "^2.0.0-3.2.2" + } + }, + "node_modules/@girs/dbusmenugtk3-0.4/node_modules/@girs/gobject-2.0": { + "version": "2.77.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.77.0-3.2.2.tgz", + "integrity": "sha512-psnnFhNY+49SXzdTDpHwnySMTDtHYDP9rxMx1Xb1UVE1JaxwuI0YLrylt+Zv0boGczmwol8afxZw2Z9TnSSocg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/freetype2-2.0": { + "version": "2.0.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/freetype2-2.0/-/freetype2-2.0-2.0.0-3.2.2.tgz", + "integrity": "sha512-hOTMDj+3BAGXY8E9PUZQrj0acAfcO7QMWu/NeH9ZGYtIWC/ITIru/mhKjn7DnLjCq2No5V4DwXCQRsYrUaNhTA==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/gobject-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/freetype2-2.0/node_modules/@girs/gobject-2.0": { + "version": "2.77.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.77.0-3.2.2.tgz", + "integrity": "sha512-psnnFhNY+49SXzdTDpHwnySMTDtHYDP9rxMx1Xb1UVE1JaxwuI0YLrylt+Zv0boGczmwol8afxZw2Z9TnSSocg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/gdk-3.0": { + "version": "3.24.39-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gdk-3.0/-/gdk-3.0-3.24.39-3.2.2.tgz", + "integrity": "sha512-nZ6DUQ/UfcW2y3ZtE1pfhBgerUkacXYpCuHJB2cp2moWHt82/w5H7zsUSr43rSzQqkFZCPQOsjUSX0VAJQfYTw==", + "dev": true, + "dependencies": { + "@girs/cairo-1.0": "^1.0.0-3.2.2", + "@girs/freetype2-2.0": "^2.0.0-3.2.2", + "@girs/gdkpixbuf-2.0": "^2.0.0-3.2.2", + "@girs/gio-2.0": "^2.77.0-3.2.2", + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2", + "@girs/gmodule-2.0": "^2.0.0-3.2.2", + "@girs/gobject-2.0": "^2.77.0-3.2.2", + "@girs/harfbuzz-0.0": "^7.1.0-3.2.2", + "@girs/pango-1.0": "^1.51.0-3.2.2" + } + }, + "node_modules/@girs/gdk-3.0/node_modules/@girs/gobject-2.0": { + "version": "2.77.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.77.0-3.2.2.tgz", + "integrity": "sha512-psnnFhNY+49SXzdTDpHwnySMTDtHYDP9rxMx1Xb1UVE1JaxwuI0YLrylt+Zv0boGczmwol8afxZw2Z9TnSSocg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/gdkpixbuf-2.0": { + "version": "2.0.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gdkpixbuf-2.0/-/gdkpixbuf-2.0-2.0.0-3.2.2.tgz", + "integrity": "sha512-QMqryx8+SGKhmGl7liWJZRJUT9gqkO6nWXd1sK4yrJIPOQ7coS4b+FRE2unEiigg4O2OUQ2ASsx98ymWQSl5gw==", + "dev": true, + "dependencies": { + "@girs/gio-2.0": "^2.77.0-3.2.2", + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2", + "@girs/gmodule-2.0": "^2.0.0-3.2.2", + "@girs/gobject-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/gdkpixbuf-2.0/node_modules/@girs/gobject-2.0": { + "version": "2.77.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.77.0-3.2.2.tgz", + "integrity": "sha512-psnnFhNY+49SXzdTDpHwnySMTDtHYDP9rxMx1Xb1UVE1JaxwuI0YLrylt+Zv0boGczmwol8afxZw2Z9TnSSocg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/gio-2.0": { + "version": "2.77.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gio-2.0/-/gio-2.0-2.77.0-3.2.2.tgz", + "integrity": "sha512-AwxseNiPYXcPo5piyBc3Vb/+7ednxZgj2fcqOgys6Hmp40FrhNJphr4et87UBT1MOTA4sb4fyJNsSdQ2y9dfYQ==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2", + "@girs/gobject-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/gio-2.0/node_modules/@girs/gobject-2.0": { + "version": "2.77.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.77.0-3.2.2.tgz", + "integrity": "sha512-psnnFhNY+49SXzdTDpHwnySMTDtHYDP9rxMx1Xb1UVE1JaxwuI0YLrylt+Zv0boGczmwol8afxZw2Z9TnSSocg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/gjs": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@girs/gjs/-/gjs-3.2.6.tgz", + "integrity": "sha512-PY1i3RzkTw+kp/OKalPg5O6BHEiBq82PPq41GDivlkbrWcY1fX4UqcdjXBU7L0mRFd2po8ciVW9J0/yheyXXIg==", + "dev": true, + "dependencies": { + "@girs/glib-2.0": "^2.78.0-3.2.6", + "@girs/gobject-2.0": "^2.78.0-3.2.6" + } + }, + "node_modules/@girs/gjs/node_modules/@girs/glib-2.0": { + "version": "2.78.0-3.2.6", + "resolved": "https://registry.npmjs.org/@girs/glib-2.0/-/glib-2.0-2.78.0-3.2.6.tgz", + "integrity": "sha512-grdCdAH+mfdzoz5iMNKsvu+BSaJWaCdLcMyoa0tq/+Rz84D/2GmLslyomjFXzA7Xr6BrIXOzgHaTuRrCZNtnmw==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.6", + "@girs/gobject-2.0": "^2.78.0-3.2.6" + } + }, + "node_modules/@girs/gjs/node_modules/@girs/gobject-2.0": { + "version": "2.78.0-3.2.6", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.78.0-3.2.6.tgz", + "integrity": "sha512-Yyy+hTpczMgkdgVADnSt4idEa29ZKFIbQTHjZutsUkn2kF3fxQMD7fQUpr03d0DSXY7gLKMwDtXq4XkH4cy0lg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.6", + "@girs/glib-2.0": "^2.78.0-3.2.6" + } + }, + "node_modules/@girs/glib-2.0": { + "version": "2.77.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/glib-2.0/-/glib-2.0-2.77.0-3.2.2.tgz", + "integrity": "sha512-cFWgYKKBR58+er7MOYTFcws5MHEQUD74VaGUEBLUTjFh9EsyIXOOcaU+Z6cteObGDo9ZYdlr8RBAdKI8H18sqQ==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/gobject-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/glib-2.0/node_modules/@girs/gobject-2.0": { + "version": "2.77.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.77.0-3.2.2.tgz", + "integrity": "sha512-psnnFhNY+49SXzdTDpHwnySMTDtHYDP9rxMx1Xb1UVE1JaxwuI0YLrylt+Zv0boGczmwol8afxZw2Z9TnSSocg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/gmodule-2.0": { + "version": "2.0.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gmodule-2.0/-/gmodule-2.0-2.0.0-3.2.2.tgz", + "integrity": "sha512-OMtRsap1T73OvlN+8zX//tHyUFmPCqCykqGl9rZzeBI2CkjFYVczj48XYA4NEtQzSaVds3ERrTzRC+o7mlAAxg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2", + "@girs/gobject-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/gmodule-2.0/node_modules/@girs/gobject-2.0": { + "version": "2.77.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.77.0-3.2.2.tgz", + "integrity": "sha512-psnnFhNY+49SXzdTDpHwnySMTDtHYDP9rxMx1Xb1UVE1JaxwuI0YLrylt+Zv0boGczmwol8afxZw2Z9TnSSocg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/gobject-2.0": { + "version": "2.76.1-3.2.3", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.76.1-3.2.3.tgz", + "integrity": "sha512-9X35d1ZRO4xY9b0iOm51MwjfbgvOGQtNs2A9IWcSlaoI4LB5mCRlPlQ1UFhpqcbbmdrL+Cce/0p3F36x5rn/dg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.3", + "@girs/glib-2.0": "^2.76.1-3.2.3" + } + }, + "node_modules/@girs/gobject-2.0/node_modules/@girs/glib-2.0": { + "version": "2.76.1-3.2.3", + "resolved": "https://registry.npmjs.org/@girs/glib-2.0/-/glib-2.0-2.76.1-3.2.3.tgz", + "integrity": "sha512-pY/ZE2WPco9E8Cz5+wTqxEOdVpipEQBRDJXVd/KQCoRjTSvgoMLLEE8B84W0LgOgR8ns99XtGZrf0U0y4qFqyA==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.3", + "@girs/gobject-2.0": "^2.76.1-3.2.3" + } + }, + "node_modules/@girs/gtk-3.0": { + "version": "3.24.39-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gtk-3.0/-/gtk-3.0-3.24.39-3.2.2.tgz", + "integrity": "sha512-s12hGKHGM+aHD6ESOP0RhWaCV17ls6gIHLdtIMxFkHqV/2G146jowfl92c5IAzOgD7mS5ZvUmVRNrW4idY1BUQ==", + "dev": true, + "dependencies": { + "@girs/atk-1.0": "^2.45.1-3.2.2", + "@girs/cairo-1.0": "^1.0.0-3.2.2", + "@girs/freetype2-2.0": "^2.0.0-3.2.2", + "@girs/gdk-3.0": "^3.24.39-3.2.2", + "@girs/gdkpixbuf-2.0": "^2.0.0-3.2.2", + "@girs/gio-2.0": "^2.77.0-3.2.2", + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2", + "@girs/gmodule-2.0": "^2.0.0-3.2.2", + "@girs/gobject-2.0": "^2.77.0-3.2.2", + "@girs/harfbuzz-0.0": "^7.1.0-3.2.2", + "@girs/pango-1.0": "^1.51.0-3.2.2", + "@girs/xlib-2.0": "^2.0.0-3.2.2" + } + }, + "node_modules/@girs/gtk-3.0/node_modules/@girs/gobject-2.0": { + "version": "2.77.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.77.0-3.2.2.tgz", + "integrity": "sha512-psnnFhNY+49SXzdTDpHwnySMTDtHYDP9rxMx1Xb1UVE1JaxwuI0YLrylt+Zv0boGczmwol8afxZw2Z9TnSSocg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/gvc-1.0": { + "version": "1.0.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gvc-1.0/-/gvc-1.0-1.0.0-3.2.2.tgz", + "integrity": "sha512-I34tMaebFH8xhHp5vLt6n2LWqg7CG6czIivfc4DT7vcXcq7/hOTd28SsXlN3XPIcVHfyNSSJXu2Bh+X2AC2wWQ==", + "dev": true, + "dependencies": { + "@girs/gio-2.0": "^2.77.0-3.2.2", + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2", + "@girs/gobject-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/gvc-1.0/node_modules/@girs/gobject-2.0": { + "version": "2.77.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.77.0-3.2.2.tgz", + "integrity": "sha512-psnnFhNY+49SXzdTDpHwnySMTDtHYDP9rxMx1Xb1UVE1JaxwuI0YLrylt+Zv0boGczmwol8afxZw2Z9TnSSocg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/harfbuzz-0.0": { + "version": "7.1.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/harfbuzz-0.0/-/harfbuzz-0.0-7.1.0-3.2.2.tgz", + "integrity": "sha512-++9wuNUtNiv89iALaOOtCCA8jdb2SDlIjeBP4aKSn3RdGWi/awxh74AG/RK57UbvYR0gB7U/hx/eRceNJMId0A==", + "dev": true, + "dependencies": { + "@girs/freetype2-2.0": "^2.0.0-3.2.2", + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2", + "@girs/gobject-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/harfbuzz-0.0/node_modules/@girs/gobject-2.0": { + "version": "2.77.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.77.0-3.2.2.tgz", + "integrity": "sha512-psnnFhNY+49SXzdTDpHwnySMTDtHYDP9rxMx1Xb1UVE1JaxwuI0YLrylt+Zv0boGczmwol8afxZw2Z9TnSSocg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/nm-1.0": { + "version": "1.43.1-3.1.0", + "resolved": "https://registry.npmjs.org/@girs/nm-1.0/-/nm-1.0-1.43.1-3.1.0.tgz", + "integrity": "sha512-2jawCPFAFlBmlsQ0334+SIYZJ1zXiHClU0PRiPZPAuOx+NzIpvAjEjprynrwFHwZ2azjmSjFp5AQ/wTTiDLJ/g==", + "dev": true, + "dependencies": { + "@girs/gio-2.0": "^2.76.1-3.1.0", + "@girs/gjs": "^3.1.0", + "@girs/glib-2.0": "^2.76.1-3.1.0", + "@girs/gobject-2.0": "^2.76.1-3.1.0" + } + }, + "node_modules/@girs/nm-1.0/node_modules/@girs/gio-2.0": { + "version": "2.76.1-3.2.3", + "resolved": "https://registry.npmjs.org/@girs/gio-2.0/-/gio-2.0-2.76.1-3.2.3.tgz", + "integrity": "sha512-6SK2z2YsZrxdoumXW7taI1S2HIBvWcFoKWAot0A5coMskJOnt6HnNxIMTBbN5YhkOs855YHqfaLYeNNU3Y3M2A==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.3", + "@girs/glib-2.0": "^2.76.1-3.2.3", + "@girs/gobject-2.0": "^2.76.1-3.2.3" + } + }, + "node_modules/@girs/nm-1.0/node_modules/@girs/glib-2.0": { + "version": "2.76.1-3.2.3", + "resolved": "https://registry.npmjs.org/@girs/glib-2.0/-/glib-2.0-2.76.1-3.2.3.tgz", + "integrity": "sha512-pY/ZE2WPco9E8Cz5+wTqxEOdVpipEQBRDJXVd/KQCoRjTSvgoMLLEE8B84W0LgOgR8ns99XtGZrf0U0y4qFqyA==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.3", + "@girs/gobject-2.0": "^2.76.1-3.2.3" + } + }, + "node_modules/@girs/pango-1.0": { + "version": "1.51.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/pango-1.0/-/pango-1.0-1.51.0-3.2.2.tgz", + "integrity": "sha512-wnbGnSz69V+FlUeJ07gVqx7wCCWDPutuyD/zlle4Qr45Hi1JoPrvK8w/DLNlCFF0RP8k1Ya/fY1ck2ku2uQZ0w==", + "dev": true, + "dependencies": { + "@girs/cairo-1.0": "^1.0.0-3.2.2", + "@girs/freetype2-2.0": "^2.0.0-3.2.2", + "@girs/gio-2.0": "^2.77.0-3.2.2", + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2", + "@girs/gobject-2.0": "^2.77.0-3.2.2", + "@girs/harfbuzz-0.0": "^7.1.0-3.2.2" + } + }, + "node_modules/@girs/pango-1.0/node_modules/@girs/gobject-2.0": { + "version": "2.77.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.77.0-3.2.2.tgz", + "integrity": "sha512-psnnFhNY+49SXzdTDpHwnySMTDtHYDP9rxMx1Xb1UVE1JaxwuI0YLrylt+Zv0boGczmwol8afxZw2Z9TnSSocg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/xlib-2.0": { + "version": "2.0.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/xlib-2.0/-/xlib-2.0-2.0.0-3.2.2.tgz", + "integrity": "sha512-xRzMSIni3ho5RaYsKXOIGMFNGNMu/xYkMe1w8VwF+MrCeDky5GBRFcsv7p9Dzpy2q6S/LN6wuXp+I4H3DZ1aJA==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/gobject-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@girs/xlib-2.0/node_modules/@girs/gobject-2.0": { + "version": "2.77.0-3.2.2", + "resolved": "https://registry.npmjs.org/@girs/gobject-2.0/-/gobject-2.0-2.77.0-3.2.2.tgz", + "integrity": "sha512-psnnFhNY+49SXzdTDpHwnySMTDtHYDP9rxMx1Xb1UVE1JaxwuI0YLrylt+Zv0boGczmwol8afxZw2Z9TnSSocg==", + "dev": true, + "dependencies": { + "@girs/gjs": "^3.2.2", + "@girs/glib-2.0": "^2.77.0-3.2.2" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@stylistic/eslint-plugin": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-1.4.0.tgz", + "integrity": "sha512-DtPiS4jr7m+A2nlcn8Ls4LEsOj1KC8x+KvAmoUI+nTcnin4Hkb8/I9Vteuu2CFLyVmlnKIQhrL5JC/xUEMyE9w==", + "dev": true, + "dependencies": { + "@stylistic/eslint-plugin-js": "1.4.0", + "@stylistic/eslint-plugin-jsx": "1.4.0", + "@stylistic/eslint-plugin-ts": "1.4.0" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@stylistic/eslint-plugin-js": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.4.0.tgz", + "integrity": "sha512-cANyn4ECWu8kxPmBM4K/Q4WocD3JbA0POmGbA2lJ4tynPE8jGyKpfP8SZj6BIidXV0pkyqvxEfaKppB4D16UsA==", + "dev": true, + "dependencies": { + "acorn": "^8.11.2", + "escape-string-regexp": "^4.0.0", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "graphemer": "^1.4.0" + } + }, + "node_modules/@stylistic/eslint-plugin-jsx": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-1.4.0.tgz", + "integrity": "sha512-MB5MW8HnRm0nAeUpgVzr4NOzLtxWYBIBtW9iDXopykl1ZJOm/0LlSFlsw9wsXd4Zqarkow6IrV18HcZ0Hc06yQ==", + "dev": true, + "dependencies": { + "@stylistic/eslint-plugin-js": "^1.4.0", + "estraverse": "^5.3.0" + } + }, + "node_modules/@stylistic/eslint-plugin-ts": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-1.4.0.tgz", + "integrity": "sha512-eNEC0MufXfe2v9fW+g5yDzMMcws80cn1gKIt9CaLVjUuWnwCdY4SG1hUtDfEpBCTNBZgG/LKKls15dSa1x++0g==", + "dev": true, + "dependencies": { + "@stylistic/eslint-plugin-js": "1.4.0", + "@typescript-eslint/utils": "^6.11.0", + "graphemer": "^1.4.0" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/scope-manager": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.12.0.tgz", + "integrity": "sha512-5gUvjg+XdSj8pcetdL9eXJzQNTl3RD7LgUiYTl8Aabdi8hFkaGSYnaS6BLc0BGNaDH+tVzVwmKtWvu0jLgWVbw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.12.0", + "@typescript-eslint/visitor-keys": "6.12.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/types": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.12.0.tgz", + "integrity": "sha512-MA16p/+WxM5JG/F3RTpRIcuOghWO30//VEOvzubM8zuOOBYXsP+IfjoCXXiIfy2Ta8FRh9+IO9QLlaFQUU+10Q==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.12.0.tgz", + "integrity": "sha512-vw9E2P9+3UUWzhgjyyVczLWxZ3GuQNT7QpnIY3o5OMeLO/c8oHljGc8ZpryBMIyympiAAaKgw9e5Hl9dCWFOYw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.12.0", + "@typescript-eslint/visitor-keys": "6.12.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/utils": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.12.0.tgz", + "integrity": "sha512-LywPm8h3tGEbgfyjYnu3dauZ0U7R60m+miXgKcZS8c7QALO9uWJdvNoP+duKTk2XMWc7/Q3d/QiCuLN9X6SWyQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.12.0", + "@typescript-eslint/types": "6.12.0", + "@typescript-eslint/typescript-estree": "6.12.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.12.0.tgz", + "integrity": "sha512-rg3BizTZHF1k3ipn8gfrzDXXSFKyOEB5zxYXInQ6z0hUvmQlhaZQzK+YmHmNViMA9HzW5Q9+bPPt90bU6GQwyw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.12.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", + "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==", + "dev": true + }, + "node_modules/@types/minimist": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.4.tgz", + "integrity": "sha512-Kfe/D3hxHTusnPNRbycJE1N77WHDsdS4AjUYIzlDzhDrS47NrwuL3YW4VITxwR7KCVpzwgy4Rbj829KSSQmwXQ==", + "dev": true, + "peer": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.3.tgz", + "integrity": "sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg==", + "dev": true, + "peer": true + }, + "node_modules/@types/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.1.tgz", + "integrity": "sha512-w0tiiRc9I4S5XSXXrMHOWgHgxbrBn1Ro+PmiYhSg2ZVdxrAJtQgzU5o2m1BfP6UOn7Vxcc6152vFjQfmZR4xEg==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.9.1", + "@typescript-eslint/type-utils": "6.9.1", + "@typescript-eslint/utils": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.1.tgz", + "integrity": "sha512-C7AK2wn43GSaCUZ9do6Ksgi2g3mwFkMO3Cis96kzmgudoVaKyt62yNzJOktP0HDLb/iO2O0n2lBOzJgr6Q/cyg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.9.1", + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/typescript-estree": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.1.tgz", + "integrity": "sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.1.tgz", + "integrity": "sha512-eh2oHaUKCK58qIeYp19F5V5TbpM52680sB4zNSz29VBQPTWIlE/hCj5P5B1AChxECe/fmZlspAWFuRniep1Skg==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.9.1", + "@typescript-eslint/utils": "6.9.1", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", + "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.1.tgz", + "integrity": "sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.1.tgz", + "integrity": "sha512-L1T0A5nFdQrMVunpZgzqPL6y2wVreSyHhKGZryS6jrEN7bD9NplVAyMryUhXsQ4TWLnZmxc2ekar/lSGIlprCA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.9.1", + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/typescript-estree": "6.9.1", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", + "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.9.1", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.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==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz", + "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==", + "dev": true, + "peer": true, + "dependencies": { + "camelcase": "^6.3.0", + "map-obj": "^4.1.0", + "quick-lru": "^5.1.1", + "type-fest": "^1.2.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true, + "peer": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "peer": true, + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.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.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-functions-list": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.1.tgz", + "integrity": "sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12 || >=16" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "peer": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz", + "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "peer": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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==", + "dev": true, + "peer": true + }, + "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==", + "dev": true, + "peer": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.52.0.tgz", + "integrity": "sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.52.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "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==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "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.4" + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "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==", + "dev": true, + "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": "3.1.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", + "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "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==" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "peer": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "peer": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "peer": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", + "dev": true, + "peer": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "peer": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "peer": 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==", + "dev": true, + "peer": true + }, + "node_modules/is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dev": true, + "peer": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "peer": true, + "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==", + "dev": true + }, + "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==", + "dev": true, + "peer": true + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "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==", + "dev": true, + "peer": true + }, + "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==", + "dev": true + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/known-css-properties": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.29.0.tgz", + "integrity": "sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==", + "dev": true, + "peer": true + }, + "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==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "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==", + "dev": true, + "peer": true + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true, + "peer": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true, + "peer": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true, + "peer": true + }, + "node_modules/meow": { + "version": "10.1.5", + "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.5.tgz", + "integrity": "sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/minimist": "^1.2.2", + "camelcase-keys": "^7.0.0", + "decamelize": "^5.0.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.2", + "read-pkg-up": "^8.0.0", + "redent": "^4.0.0", + "trim-newlines": "^4.0.2", + "type-fest": "^1.2.2", + "yargs-parser": "^20.2.9" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "peer": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "peer": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "peer": true, + "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-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true, + "peer": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true + }, + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", + "dev": true + }, + "node_modules/postcss-safe-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "node_modules/postcss-scss": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz", + "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-scss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.4.29" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "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==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-6.0.0.tgz", + "integrity": "sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==", + "dev": true, + "peer": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^3.0.2", + "parse-json": "^5.2.0", + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-8.0.0.tgz", + "integrity": "sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==", + "dev": true, + "peer": true, + "dependencies": { + "find-up": "^5.0.0", + "read-pkg": "^6.0.0", + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/redent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-4.0.0.tgz", + "integrity": "sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==", + "dev": true, + "peer": true, + "dependencies": { + "indent-string": "^5.0.0", + "strip-indent": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "peer": true, + "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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "peer": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "peer": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true, + "peer": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "peer": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz", + "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==", + "dev": true, + "peer": true + }, + "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==", + "dev": true, + "peer": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", + "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", + "dev": true, + "peer": true, + "dependencies": { + "min-indent": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==", + "dev": true, + "peer": true + }, + "node_modules/stylelint": { + "version": "15.11.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.11.0.tgz", + "integrity": "sha512-78O4c6IswZ9TzpcIiQJIN49K3qNoXTM8zEJzhaTE/xRTCZswaovSEVIa/uwbOltZrk16X4jAxjaOhzz/hTm1Kw==", + "dev": true, + "peer": true, + "dependencies": { + "@csstools/css-parser-algorithms": "^2.3.1", + "@csstools/css-tokenizer": "^2.2.0", + "@csstools/media-query-list-parser": "^2.1.4", + "@csstools/selector-specificity": "^3.0.0", + "balanced-match": "^2.0.0", + "colord": "^2.9.3", + "cosmiconfig": "^8.2.0", + "css-functions-list": "^3.2.1", + "css-tree": "^2.3.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.1", + "fastest-levenshtein": "^1.0.16", + "file-entry-cache": "^7.0.0", + "global-modules": "^2.0.0", + "globby": "^11.1.0", + "globjoin": "^0.1.4", + "html-tags": "^3.3.1", + "ignore": "^5.2.4", + "import-lazy": "^4.0.0", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.29.0", + "mathml-tag-names": "^2.1.3", + "meow": "^10.1.5", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.28", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^6.0.0", + "postcss-selector-parser": "^6.0.13", + "postcss-value-parser": "^4.2.0", + "resolve-from": "^5.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "style-search": "^0.1.0", + "supports-hyperlinks": "^3.0.0", + "svg-tags": "^1.0.0", + "table": "^6.8.1", + "write-file-atomic": "^5.0.1" + }, + "bin": { + "stylelint": "bin/stylelint.mjs" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + } + }, + "node_modules/stylelint-config-recommended": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-13.0.0.tgz", + "integrity": "sha512-EH+yRj6h3GAe/fRiyaoO2F9l9Tgg50AOFhaszyfov9v6ayXJ1IkSHwTxd7lB48FmOeSGDPLjatjO11fJpmarkQ==", + "dev": true, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "stylelint": "^15.10.0" + } + }, + "node_modules/stylelint-config-recommended-scss": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-13.0.0.tgz", + "integrity": "sha512-7AmMIsHTsuwUQm7I+DD5BGeIgCvqYZ4BpeYJJpb1cUXQwrJAKjA+GBotFZgUEGP8lAM+wmd91ovzOi8xfAyWEw==", + "dev": true, + "dependencies": { + "postcss-scss": "^4.0.7", + "stylelint-config-recommended": "^13.0.0", + "stylelint-scss": "^5.1.0" + }, + "peerDependencies": { + "postcss": "^8.3.3", + "stylelint": "^15.10.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + } + } + }, + "node_modules/stylelint-config-standard": { + "version": "34.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-34.0.0.tgz", + "integrity": "sha512-u0VSZnVyW9VSryBG2LSO+OQTjN7zF9XJaAJRX/4EwkmU0R2jYwmBSN10acqZisDitS0CLiEiGjX7+Hrq8TAhfQ==", + "dev": true, + "dependencies": { + "stylelint-config-recommended": "^13.0.0" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "stylelint": "^15.10.0" + } + }, + "node_modules/stylelint-config-standard-scss": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard-scss/-/stylelint-config-standard-scss-11.0.0.tgz", + "integrity": "sha512-fGE79NBOLg09a9afqGH/guJulRULCaQWWv4cv1v2bMX92B+fGb0y56WqIguwvFcliPmmUXiAhKrrnXilIeXoHA==", + "dev": true, + "dependencies": { + "stylelint-config-recommended-scss": "^13.0.0", + "stylelint-config-standard": "^34.0.0" + }, + "peerDependencies": { + "postcss": "^8.3.3", + "stylelint": "^15.10.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + } + } + }, + "node_modules/stylelint-scss": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-5.2.1.tgz", + "integrity": "sha512-ZoTJUM85/qqpQHfEppjW/St//8s6p9Qsg8deWlYlr56F9iUgC9vXeIDQvH4odkRRJLTLFQzYMALSOFCQ3MDkgw==", + "dev": true, + "dependencies": { + "known-css-properties": "^0.28.0", + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-selector-parser": "^6.0.13", + "postcss-value-parser": "^4.2.0" + }, + "peerDependencies": { + "stylelint": "^14.5.1 || ^15.0.0" + } + }, + "node_modules/stylelint-scss/node_modules/known-css-properties": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.28.0.tgz", + "integrity": "sha512-9pSL5XB4J+ifHP0e0jmmC98OGC1nL8/JjS+fi6mnTlIf//yt/MfVLtKg7S6nCtj/8KTcWX7nRlY0XywoYY1ISQ==", + "dev": true + }, + "node_modules/stylelint/node_modules/balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true, + "peer": true + }, + "node_modules/stylelint/node_modules/file-entry-cache": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-7.0.1.tgz", + "integrity": "sha512-uLfFktPmRetVCbHe5UPuekWrQ6hENufnA46qEGbfACkK5drjTTdQYUragRgMjHldcbYG+nslUerqMPjbBSHXjQ==", + "dev": true, + "peer": true, + "dependencies": { + "flat-cache": "^3.1.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/stylelint/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", + "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true, + "peer": true + }, + "node_modules/table": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "dev": true, + "peer": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "peer": true + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/trim-newlines": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.1.1.tgz", + "integrity": "sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ts-api-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "dev": true, + "engines": { + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "peer": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "peer": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } + } } diff --git a/modules/ags/config/package.json b/modules/ags/config/package.json index c6a18d35..3af6a5d3 100644 --- a/modules/ags/config/package.json +++ b/modules/ags/config/package.json @@ -1,15 +1,18 @@ { - "name": "ags", - "version": "0.0.0", - "main": "app.ts", - "dependencies": { - "astal": "https://gitpkg.vercel.app/Aylur/astal/lang/gjs/src?4820a3e37cc8eb81db6ed991528fb23472a8e4de", - "@eslint/js": "9.26.0", - "@stylistic/eslint-plugin": "4.2.0", - "eslint": "9.26.0", - "eslint-plugin-jsdoc": "50.6.17", - "fzf": "0.5.2", - "jiti": "2.4.2", - "typescript-eslint": "8.32.1" - } + "main": "config.js", + "dependencies": { + "fzf": "^0.5.2" + }, + "devDependencies": { + "eslint": "^8.52.0", + "@typescript-eslint/eslint-plugin": "^6.9.1", + "@typescript-eslint/parser": "^6.9.1", + "stylelint-config-standard-scss": "^11.0.0", + "@stylistic/eslint-plugin": "^1.4.0", + "@girs/dbusmenugtk3-0.4": "^0.4.0-3.2.0", + "@girs/gobject-2.0": "^2.76.1-3.2.3", + "@girs/gtk-3.0": "^3.24.39-3.2.2", + "@girs/gvc-1.0": "^1.0.0-3.1.0", + "@girs/nm-1.0": "^1.43.1-3.1.0" + } } diff --git a/modules/ags/config/scss/binto-widgets/applauncher.scss b/modules/ags/config/scss/binto-widgets/applauncher.scss new file mode 100644 index 00000000..6ba509db --- /dev/null +++ b/modules/ags/config/scss/binto-widgets/applauncher.scss @@ -0,0 +1,118 @@ +.applauncher { + all: unset; + border: 2px solid $contrast-bg; + background-color: $bg; + color: #f8f8f2; + padding: 2px; + + * { + font-size: 16px; + } + + list, row { + all: unset; + } + + .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: 10px; + padding-bottom: 0; + min-width: 900px; + min-height: 650px; + + scrollbar, scrollbar * { + all: unset; + } + + scrollbar.vertical { + transition: 200ms; + background-color: rgba(23, 23, 23, 0.3); + margin: 20px 0; + + &: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; + border-radius: 9px; + + label { + transition: 200ms; + + &.title { + margin-top: 20px; + color: #f8f8f2; + } + + &.description { + color: rgba(238, 238, 238, 0.7); + } + } + + image { + transition: 200ms; + margin: 0 8px; + } + + &:active { + background-color: rgba($contrast-bg, 0.5); + box-shadow: inset 0 0 0 3px rgba(238, 238, 238, 0.03); + } + } + + *:selected, .app:hover, .app:focus { + * { + font-weight: unset; + } + + label.title { + color: $contrast-bg; + } + + image { + -gtk-icon-shadow: 2px 2px $contrast-bg; + } + } +} diff --git a/modules/ags/config/scss/binto-widgets/bar.scss b/modules/ags/config/scss/binto-widgets/bar.scss new file mode 100644 index 00000000..414b626f --- /dev/null +++ b/modules/ags/config/scss/binto-widgets/bar.scss @@ -0,0 +1,50 @@ +.bar { + .clock, .notif-panel { + padding: 4.5px 7px; + background-color: $bgfull; + } + + .sys-tray { + menubar { + background-color: $bgfull; + padding: 2.5px; + } + + menuitem { + image { color: #CBA6F7; } + padding: 0 2px; + + * { + font-size: 25px; + } + } + } + + .current-window { + padding-right: 7px; + background-color: $bgfull; + } +} + +.razer { + padding: 0 5px; + background: $bgfull; + + .low { + color: $red; + } + + .medium { + color: $yellow; + } + + .high { + color: $green; + } + + image { + padding-right: 5px; + font-size: 22px; + color: white; + } +} diff --git a/modules/ags/config/scss/binto-widgets/notification-center.scss b/modules/ags/config/scss/binto-widgets/notification-center.scss new file mode 100644 index 00000000..1d5ebb6e --- /dev/null +++ b/modules/ags/config/scss/binto-widgets/notification-center.scss @@ -0,0 +1,108 @@ +.notification-center { + min-height: 700px; + min-width: 524px; + background: $bg; + padding: 0; + + * { + font-size: 16px; + } + + .header { + padding: 10px; + margin-top: 22px; + margin-bottom: 9px; + + label { + font-size: 22px; + } + + .clear { + box { + all: unset; + transition: 200ms; + color: #eee; + background-color: #664C90; + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + padding: 4.5px 9px; + } + + &:hover box { + 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 { + 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; + 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/modules/ags/config/scss/binto-widgets/notification.scss b/modules/ags/config/scss/binto-widgets/notification.scss new file mode 100644 index 00000000..9a4a1a5a --- /dev/null +++ b/modules/ags/config/scss/binto-widgets/notification.scss @@ -0,0 +1,206 @@ +$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; + 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 { + margin-right: 9px; + } + + .icon.img { + border: 1px solid rgba(238, 238, 238, 0.03); + } + + .actions { + button { + all: unset; + transition: all 500ms; + background-color: $background-color-3; + box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03); + 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; + background-color: $background-color-5; + background-image: none; + box-shadow: none; + margin-left: 9px; + 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-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/modules/ags/config/scss/binto-widgets/osd.scss b/modules/ags/config/scss/binto-widgets/osd.scss new file mode 100644 index 00000000..26ecdb4c --- /dev/null +++ b/modules/ags/config/scss/binto-widgets/osd.scss @@ -0,0 +1,40 @@ +.osd { + padding: 12px 20px; + background: rgba(40, 42, 54, 0.8); + border: 2px solid $contrast-bg; + + label { + min-width: 170px; + } + + progressbar:disabled { + opacity: 0.5; + } + + progressbar { + min-height: 6px; + min-width: 170px; + border-radius: 999px; + background: transparent; + border: none; + + trough { + background: #363847; + min-height: inherit; + border: none; + } + + progress { + background: #79659f; + min-height: inherit; + border: none; + } + } + + image { + font-size: 2rem; + color: white; + margin-left: -0.4rem; + margin-right: 0.8rem; + } +} diff --git a/modules/ags/config/scss/binto-widgets/powermenu.scss b/modules/ags/config/scss/binto-widgets/powermenu.scss new file mode 100644 index 00000000..ba8fa1b8 --- /dev/null +++ b/modules/ags/config/scss/binto-widgets/powermenu.scss @@ -0,0 +1,34 @@ +.powermenu { + background-color: $bg; + color: $fg; + padding: 10px; + font-family: "MesloLGS NF"; + + /* font-family: Iosevka Nerd Font; */ + font-size: 70px; + border: 2px solid $contrast-bg; + + label { + min-width: 140px; + min-height: 130px; + } + + .button { + margin: 5px 10px; + min-width: 80px; + transition: all ease .2s; + &:hover { background-color: $bg-secondary; } + &:active { background-color: $bg-secondary; } + + .content { + padding: 0 15px; + } + } + .shutdown { color: $red; } + .reboot { color: $magenta; } + .logout { color: $yellow; } +} + +.powermenu-clickhandler { + background-color: black; +} diff --git a/modules/ags/config/scss/binto.scss b/modules/ags/config/scss/binto.scss new file mode 100644 index 00000000..034e6bb4 --- /dev/null +++ b/modules/ags/config/scss/binto.scss @@ -0,0 +1,17 @@ +window, +button, +eventbox, +box, +progressbar, +trough, +undershoot { + all: unset; +} + +@import "./common"; +@import './binto-widgets/applauncher'; +@import './binto-widgets/bar'; +@import './binto-widgets/notification'; +@import './binto-widgets/notification-center'; +@import './binto-widgets/osd'; +@import './binto-widgets/powermenu'; diff --git a/modules/ags/config/scss/common.scss b/modules/ags/config/scss/common.scss new file mode 100644 index 00000000..580d5d36 --- /dev/null +++ b/modules/ags/config/scss/common.scss @@ -0,0 +1,33 @@ +$darkbg: #0b0d16; +$bg: rgba(40, 42, 54, 0.8); // rgba(69, 71, 90, 0.3); #0d0f18; +$bgfull: rgb(40, 42, 54); +$contrast-bg: rgba(189, 147, 249, 0.8); +$contrast-bg-full: rgba(189, 147, 249, 1); +$bg-secondary: rgba(#382c4a, 0.8); +$bg-secondary-alt: #a5b6cf; +$fg: #a5b6cf; +$fg-dim: #a5b6cf; +$watermelon: #dd6777; + +// Aliases +$background: $bg; +$background-secondary: $bg-secondary; +$background-secondary-alt: $bg-secondary-alt; +$foreground: $fg; +$foreground-dim: $fg-dim; + +$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/scss/wim-widgets/applauncher.scss b/modules/ags/config/scss/wim-widgets/applauncher.scss new file mode 100644 index 00000000..b12f1911 --- /dev/null +++ b/modules/ags/config/scss/wim-widgets/applauncher.scss @@ -0,0 +1,118 @@ +.applauncher { + all: unset; + border: 2px solid $contrast-bg; + border-radius: 25px; + background-color: $bg; + color: #f8f8f2; + padding: 2px; + + * { + font-size: 16px; + } + + list, row { + all: unset; + } + + .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: 10px; + padding-bottom: 0; + min-width: 700px; + min-height: 450px; + + scrollbar, scrollbar * { + all: unset; + } + + scrollbar.vertical { + transition: 200ms; + background-color: rgba(23, 23, 23, 0.3); + margin: 20px 0; + + &: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; + border-radius: 9px; + + label { + transition: 200ms; + + &.title { + color: #f8f8f2; + } + + &.description { + color: rgba(238, 238, 238, 0.7); + } + } + + image { + transition: 200ms; + margin: 0 8px; + } + + &:active { + background-color: rgba($contrast-bg, 0.5); + box-shadow: inset 0 0 0 3px rgba(238, 238, 238, 0.03); + } + } + + *:selected, .app:hover, .app:focus { + * { + font-weight: unset; + } + + label.title { + color: $contrast-bg; + } + + image { + -gtk-icon-shadow: 2px 2px $contrast-bg; + } + } +} diff --git a/modules/ags/config/scss/wim-widgets/date.scss b/modules/ags/config/scss/wim-widgets/date.scss new file mode 100644 index 00000000..4cf7c1e4 --- /dev/null +++ b/modules/ags/config/scss/wim-widgets/date.scss @@ -0,0 +1,75 @@ +.date { + background-color: $bg; + color: $fg; + border-radius: 30px; + border: 2px solid $contrast-bg; +} + +.timebox { + margin: 30px 0; + + .time-container { + .content { + font-weight: bolder; + font-size: 60px; + } + + .divider { + margin: 8px 15px; + padding: 0 1px; + background: linear-gradient($red, $magenta, $blue, $cyan); + } + } + + .date-container { + margin-top: 2px; + } +} + +.cal-box { + border-radius: 30px; + padding: 0 1rem .2rem; + color: $fg; + background-color: $bgfull; + border-bottom: 2px solid $contrast-bg; + border-top: 2px solid $contrast-bg; + margin: 0 12px 18px; + + .cal { + font-size: 20px; + background-color: inherit; + padding: .5rem .10rem 0; + margin-left: 10px; + border-radius: 30px; + + & > * { + border: solid 0 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/modules/ags/config/scss/wim-widgets/notification-center.scss b/modules/ags/config/scss/wim-widgets/notification-center.scss new file mode 100644 index 00000000..262c77c4 --- /dev/null +++ b/modules/ags/config/scss/wim-widgets/notification-center.scss @@ -0,0 +1,114 @@ +.notification-center { + min-height: 700px; + min-width: 524px; + background: $bg; + border-radius: 30px; + border-top-right-radius: 0; + border: 2px solid $contrast-bg; + padding: 0; + + * { + font-size: 16px; + } + + .header { + padding: 10px; + margin-top: 22px; + margin-bottom: 9px; + + label { + font-size: 22px; + } + + .clear { + box { + 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 { + 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 { + 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; + border-radius: 30px; + border-top: 2px solid $contrast-bg; + 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/modules/ags/config/scss/wim-widgets/notification.scss b/modules/ags/config/scss/wim-widgets/notification.scss new file mode 100644 index 00000000..61759c67 --- /dev/null +++ b/modules/ags/config/scss/wim-widgets/notification.scss @@ -0,0 +1,210 @@ +$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; + margin: 9px 9px 0; + border: 2px solid $contrast-bg; + 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; + 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; + 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-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/modules/ags/config/scss/wim-widgets/osd.scss b/modules/ags/config/scss/wim-widgets/osd.scss new file mode 100644 index 00000000..335da1bb --- /dev/null +++ b/modules/ags/config/scss/wim-widgets/osd.scss @@ -0,0 +1,43 @@ +.osd { + padding: 12px 20px; + border-radius: 999px; + background: rgba(40, 42, 54, 0.8); + border: 2px solid $contrast-bg; + + label { + min-width: 170px; + } + + progressbar:disabled { + opacity: 0.5; + } + + progressbar { + min-height: 6px; + min-width: 170px; + 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; + } + } + + image { + font-size: 2rem; + color: white; + margin-left: -0.4rem; + margin-right: 0.8rem; + } +} diff --git a/modules/ags/config/scss/wim-widgets/osk.scss b/modules/ags/config/scss/wim-widgets/osk.scss new file mode 100644 index 00000000..f5e32777 --- /dev/null +++ b/modules/ags/config/scss/wim-widgets/osk.scss @@ -0,0 +1,95 @@ +.thingy { + border-radius: 2rem 2rem 0 0; + min-height: 2.7rem; + min-width: 20rem; + + .settings { + padding: 0.5rem; + + .button { + background-color: $bgfull; + border: 0.1rem solid $darkbg; + border-radius: 0.7rem; + padding: 0.3rem; + + &.toggled { + background-color: $contrast-bg; + } + } + } +} + +.osk { + padding-top: 4px; + border-radius: 10px 10px 0; + + .side { + .key { + &:active label { + background-color: $contrast-bg; + } + + label { + background-color: $bg; + border: 0.08rem solid $darkbg; + border-radius: 0.7rem; + min-height: 3rem; + + transition: background-color 0.2s ease-in-out, + border-color 0.2s ease-in-out; + + &.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; + } + + &.active { + background-color: $darkbg; + } + + &.altgr { + border: 0.08rem solid blue; + } + } + } + + &.right-side { + .key .mod { + &.Ctrl { + min-width: 2.4rem; + } + } + } + + &.left-side { + .key .mod { + &.Alt { + min-width: 3rem; + } + + &.Ctrl { + min-width: 4rem; + } + } + } + } +} diff --git a/modules/ags/config/scss/wim-widgets/player.scss b/modules/ags/config/scss/wim-widgets/player.scss new file mode 100644 index 00000000..2772b8fd --- /dev/null +++ b/modules/ags/config/scss/wim-widgets/player.scss @@ -0,0 +1,117 @@ +.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 $contrast-bg; + border-bottom: 2px solid $contrast-bg; + 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 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 { + 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/scss/wim-widgets/powermenu.scss b/modules/ags/config/scss/wim-widgets/powermenu.scss new file mode 100644 index 00000000..9cee5890 --- /dev/null +++ b/modules/ags/config/scss/wim-widgets/powermenu.scss @@ -0,0 +1,37 @@ +.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 $contrast-bg; + + label { + min-width: 140px; + min-height: 130px; + } + + .button { + margin: 5px 10px; + border-radius: 12px; + min-width: 80px; + transition: all ease .2s; + &:hover { background-color: $bg-secondary; } + &:active { background-color: $bg-secondary; } + + .content { + border-radius: 4px; + padding: 0 15px; + } + } + .shutdown { color: $red; } + .reboot { color: $magenta; } + .logout { color: $yellow; } +} + +.powermenu-clickhandler { + background-color: black; +} diff --git a/modules/ags/config/scss/wim-widgets/quick-settings.scss b/modules/ags/config/scss/wim-widgets/quick-settings.scss new file mode 100644 index 00000000..40b9d7a9 --- /dev/null +++ b/modules/ags/config/scss/wim-widgets/quick-settings.scss @@ -0,0 +1,182 @@ +.quick-settings { + font-size: 30px; + min-width: 500px; + padding: 0; + background-color: $bg; + border-radius: 30px 0 30px 30px; + border: 2px solid $contrast-bg; +} + +.title { + font-size: 22px; + margin-top: 30px; +} + +.grid-label { + font-size: 30px; + margin-left: 15px; + margin-right: 10px; + min-width: 50px; + transition: color 0.3s ease-in-out; +} + +.scrolled-indicator { + margin: 5px 0; +} + +.menu { + margin: 10px; + padding: 0; + border: 1.5px solid $contrast-bg; + border-radius: 10px; + font-size: 12px; + + scrolledwindow { + padding: 3px; + } + + row { + padding: 0; + margin: 0; + } + + .menu-item { + margin: 5px; + + label { + font-size: 16px; + margin-left: 5px; + } + + image { + font-size: 20px; + } + } +} + +.sub-label { + font-size: 14px; + padding: 3px; + border: 2px solid $contrast-bg; + border-radius: 10px 20px 20px 10px; + min-width: 106px; + background: #1b1b1b; + margin-top: 5px; +} + +.grid-chev { + margin-left: 10px; + margin-right: 12px; + font-size: 25px; + + transition: -gtk-icon-transform 0.3s ease-in-out; +} + +.button-grid { + font-size: 10px; + min-width: 440px; + background-color: $bgfull; + border-top: 2px solid $contrast-bg; + border-bottom: 2px solid $contrast-bg; + border-radius: 15px; + padding: 10px 15px; +} + +.grid-button { + min-height: 65px; + min-width: 70px; +} + +.left-part { + background: #1b1b1b; + border-top-left-radius: 15px; + border-bottom-left-radius: 15px; + border-left: 2px solid $contrast-bg; + border-top: 2px solid $contrast-bg; + border-bottom: 2px solid $contrast-bg; + 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 $contrast-bg; + border-top: 2px solid $contrast-bg; + border-bottom: 2px solid $contrast-bg; + transition: all 0.5s ease-in-out; +} + +.right-part:hover, .right-part:active { + color: $contrast-bg; + border: 2px solid $contrast-bg; + border-top-left-radius: 7px; + border-bottom-left-radius: 7px; + transition: all 0.5s ease-in-out; +} + +.left-part:hover, .left-part:active { + color: $contrast-bg; + border: 2px solid $contrast-bg; + 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 $contrast-bg; + border-bottom: 2px solid $contrast-bg; + border-radius: 15px; + margin-top: 30px; + margin-bottom: 20px; + + .slider-label { + font-size: 30px; + min-width: 40px; + margin-right: -20px; + } + + .slider { + min-height: 55px; + + scale { + min-width: 400px; + margin-left: 18px; + margin-right: 20px; + + highlight { + margin: 0; + 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%; + transition: background-color 0.5s ease-in-out; + } + + slider:hover { + background-color: #303240; + transition: background-color 0.5s ease-in-out; + } + } + } +} diff --git a/modules/ags/config/scss/wim-widgets/systray.scss b/modules/ags/config/scss/wim-widgets/systray.scss new file mode 100644 index 00000000..f83b83f4 --- /dev/null +++ b/modules/ags/config/scss/wim-widgets/systray.scss @@ -0,0 +1,30 @@ +.sys-tray { + padding: 5px; + background-color: $bg; + border-radius: 80px; + border: 2px solid $bg-secondary; + transition: background-color 0.5s ease-in-out, + border 0.5s ease-in-out; + + menuitem { + image { color: #CBA6F7; } + background-color: transparent; + padding: 0 2px; + border-radius: 100%; + transition: all 0.5s ease-in-out; + + &:hover { + border-radius: 100%; + transition: all 0.5s ease-in-out; + } + + * { + font-size: 25px; + border-radius: 10px; + } + } + + menubar { + background-color: transparent; + } +} diff --git a/modules/ags/config/scss/wim-widgets/traybuttons.scss b/modules/ags/config/scss/wim-widgets/traybuttons.scss new file mode 100644 index 00000000..d0847db3 --- /dev/null +++ b/modules/ags/config/scss/wim-widgets/traybuttons.scss @@ -0,0 +1,117 @@ +.bar { + margin: 5px; +} + +.osk-toggle, +.tablet-toggle, +.heart-toggle { + font-size: 28px; + min-height: 40px; + min-width: 53px; +} + +.heart-toggle { + font-size: 28px; + min-height: 40px; + color: #CBA6F7; +} + +.notif-panel { + font-size: 20px; + min-height: 37px; + min-width: 105px; +} + +.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 $bg-secondary; + 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 $contrast-bg; + 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: 0 15px; +} + +.audio, +.bluetooth, +.brightness, +.keyboard { + padding: 0 10px; + font-size: 20px; + margin-right: -10px; +} + +.network { + padding: 0 10px; + font-size: 20px; +} + +.bg-text { + color: $bg; + font-weight: bold; +} + +.battery { + padding: 0 10px; + font-size: 20px; + + .battery-indicator { + &.charging { + color: green; + } + + &.charged { + // TODO: charged battery style + } + + &.low { + color: red; + } + } + + icon { + .charging { + // TODO: charging battery style + } + + .discharging { + // TODO: discharging battery style + } + } + + label { + font-size: 20px; + } +} + +tooltip { + background: rgba(0,0,0, 0.6); + border-radius: 5px; +} diff --git a/modules/ags/config/scss/wim-widgets/workspaces.scss b/modules/ags/config/scss/wim-widgets/workspaces.scss new file mode 100644 index 00000000..f54e4fd4 --- /dev/null +++ b/modules/ags/config/scss/wim-widgets/workspaces.scss @@ -0,0 +1,31 @@ +.workspaces { + background-color: $bg; + border-radius: 80px; + border: 2px solid $bg-secondary; + padding: 3px 12px; +} + +.button { + margin: 0 2.5px; + min-height: 22px; + min-width: 22px; + border-radius: 100%; + border: 2px solid transparent; +} + +.occupied { + border: 2px solid $bg; + background: $contrast-bg; + transition: background-color 0.6s ease-in-out; +} + +.urgent { + border: 2px solid $bg; + background: red; + transition: background-color 0.6s ease-in-out; +} + +.active { + border: 2px solid #50fa7b; + transition: margin-left 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); +} diff --git a/modules/ags/config/scss/wim.scss b/modules/ags/config/scss/wim.scss new file mode 100644 index 00000000..fdc0460f --- /dev/null +++ b/modules/ags/config/scss/wim.scss @@ -0,0 +1,23 @@ +window, +button, +eventbox, +box, +progressbar, +trough, +undershoot { + all: unset; +} + +@import "./common"; +@import "./wim-widgets/powermenu"; +@import "./wim-widgets/traybuttons"; +@import "./wim-widgets/workspaces"; +@import "./wim-widgets/systray"; +@import "./wim-widgets/notification-center"; +@import "./wim-widgets/notification"; +@import "./wim-widgets/date"; +@import "./wim-widgets/quick-settings"; +@import "./wim-widgets/player"; +@import "./wim-widgets/applauncher"; +@import "./wim-widgets/osd"; +@import "./wim-widgets/osk"; diff --git a/modules/ags/config/services/brightness.ts b/modules/ags/config/services/brightness.ts index 4d68b25c..93b26901 100644 --- a/modules/ags/config/services/brightness.ts +++ b/modules/ags/config/services/brightness.ts @@ -1,27 +1,74 @@ -import { execAsync, interval } from 'astal'; -import GObject, { register, property } from 'astal/gobject'; +const { exec, execAsync } = Utils; - -const SCREEN_ICONS: Record<number, string> = { +const KBD = 'tpacpi::kbd_backlight'; +const INTERVAL = 500; +const SCREEN_ICONS = { 90: 'display-brightness-high-symbolic', 70: 'display-brightness-medium-symbolic', 20: 'display-brightness-low-symbolic', 5: 'display-brightness-off-symbolic', }; -const INTERVAL = 500; +class Brightness extends Service { + static { + Service.register(this, { + screen: ['float'], + kbd: ['float'], + caps: ['int'], + }, { + 'screen-icon': ['string', 'rw'], + 'caps-icon': ['string', 'rw'], + }); + } -@register() -export default class Brightness extends GObject.Object { - declare private _kbd: string | undefined; - declare private _caps: string | undefined; + #kbd = 0; + #kbdMax = 0; + #screen = 0; + #screenIcon = 'display-brightness-symbolic'; + #capsName = 'input0::capslock'; + #caps = 0; + #capsIcon = 'caps-lock-symbolic'; - declare private _screen: number; + get capsName() { + return this.#capsName; + } + + set capsName(value: string) { + this.#capsName = value; + } + + get kbd() { + return this.#kbd; + } - @property(Number) get screen() { - return this._screen; - }; + return this.#screen; + } + + get screenIcon() { + return this.#screenIcon; + } + + get caps() { + return this.#caps; + } + + get capsIcon() { + return this.#capsIcon; + } + + set kbd(value) { + if (value < 0 || value > this.#kbdMax) { + return; + } + + execAsync(`brightnessctl -d ${KBD} s ${value} -q`) + .then(() => { + this.#kbd = value; + this.emit('kbd', this.#kbd); + }) + .catch(console.error); + } set screen(percent) { if (percent < 0) { @@ -32,144 +79,73 @@ export default class Brightness extends GObject.Object { percent = 1; } - percent = parseFloat(percent.toFixed(2)); - execAsync(`brightnessctl s ${percent * 100}% -q`) .then(() => { - this._screen = percent; - this.notify('screen'); - this._getScreenIcon(); + this.#screen = percent; + this.#getScreenIcon(); + this.emit('screen', this.#screen); }) .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 } = {}) { + constructor() { 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'); - })(); + this.#monitorKbdState(); + this.#kbdMax = Number(exec(`brightnessctl -d ${KBD} m`)); + this.#caps = Number(exec(`bash -c brightnessctl -d ${this.#capsName} g`)); + this.#screen = Number(exec('brightnessctl g')) / + Number(exec('brightnessctl m')); } - catch (_e) { - console.error('missing dependency: brightnessctl'); + catch (error) { + console.error('missing dependancy: 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; + #getScreenIcon() { + const brightness = this.#screen * 100; + // eslint-disable-next-line for (const threshold of [4, 19, 69, 89]) { if (brightness > threshold + 1) { - this._screenIcon = SCREEN_ICONS[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`) + fetchCapsState() { + execAsync(`brightnessctl -d ${this.#capsName} g`) .then((out) => { - this._capsLevel = Number(out); - this._capsIcon = this._capsLevel ? + this.#caps = Number(out); + this.#capsIcon = this.#caps ? 'caps-lock-symbolic' : 'capslock-disabled-symbolic'; this.notify('caps-icon'); - this.notify('caps-level'); + this.emit('caps', this.#caps); }) .catch(logError); } + + #monitorKbdState() { + const interval = setInterval(() => { + execAsync(`brightnessctl -d ${KBD} g`).then( + (out) => { + if (parseInt(out) !== this.#kbd) { + this.#kbd = parseInt(out); + this.emit('kbd', this.#kbd); + + return this.#kbd; + } + }, + ).catch(() => { + interval.destroy(); + }); + }, INTERVAL); + } } + +const brightnessService = new Brightness(); + +export default brightnessService; diff --git a/modules/ags/config/services/gpu-screen-recorder.ts b/modules/ags/config/services/gpu-screen-recorder.ts index 7b7251d7..da11429a 100644 --- a/modules/ags/config/services/gpu-screen-recorder.ts +++ b/modules/ags/config/services/gpu-screen-recorder.ts @@ -1,105 +1,72 @@ -import { execAsync, subprocess } from 'astal'; -import GObject, { register } from 'astal/gobject'; - -import { notifySend } from '../lib'; +const { execAsync, subprocess } = Utils; +const Notifications = await Service.import('notifications'); const APP_NAME = 'gpu-screen-recorder'; +const START_APP_ID = 2345; const ICON_NAME = 'nvidia'; -@register() -export default class GpuScreenRecorder extends GObject.Object { - private _lastNotifID: number | undefined; - public constructor() { +class GSR extends Service { + static { + Service.register(this, {}, {}); + } + + #appID = START_APP_ID; + + constructor() { super(); - try { - subprocess( - ['gsr-start'], - (path) => { - if (!this._lastNotifID) { - console.error('[GpuScreenRecorder] ID of warning notif not found'); + subprocess( + ['gsr-start'], + (path) => { + Notifications.getNotification(this.#appID)?.close(); - setTimeout(() => { - this._onSaved(path); - }, 1000); - } - else { - this._onSaved(path); - } - }, - () => { /**/ }, + const notifId = Notifications.Notify( + APP_NAME, + ++this.#appID, + ICON_NAME, + 'Replay Saved', + `Saved to ${path}`, + ['folder', 'Open Folder', 'video', 'Open Video'], + {}, + Notifications.popupTimeout, + ); + + Notifications.getNotification(notifId)?.connect( + 'invoked', + (_, actionId: string) => { + if (actionId === 'folder') { + execAsync([ + 'xdg-open', + path.substring(0, path.lastIndexOf('/')), + ]).catch(print); + } + + else if (actionId === 'video') { + execAsync(['xdg-open', path]).catch(print); + } + }, + ); + }, + logError, + ); + } + + saveReplay() { + execAsync(['gpu-save-replay']).then(() => { + Notifications.Notify( + APP_NAME, + this.#appID, + ICON_NAME, + 'Saving Replay', + 'Last 20 minutes', + [], + {}, + Notifications.popupTimeout, ); - } - 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), - }, - ], - }); + }).catch(logError); } } + +export default GSR; 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/pointers.ts b/modules/ags/config/services/pointers.ts new file mode 100644 index 00000000..4c422300 --- /dev/null +++ b/modules/ags/config/services/pointers.ts @@ -0,0 +1,231 @@ +const Hyprland = await Service.import('hyprland'); +const { subprocess } = Utils; + +const ON_RELEASE_TRIGGERS = [ + 'released', + 'TOUCH_UP', + 'HOLD_END', +]; +const ON_CLICK_TRIGGERS = [ + 'pressed', + 'TOUCH_DOWN', +]; + +// Types +import { PopupWindow } from 'global-types'; +import { Subprocess } from 'types/@girs/gio-2.0/gio-2.0.cjs'; +type Layer = { + address: string; + x: number; + y: number; + w: number; + h: number; + namespace: string; +}; +type Levels = { + 0?: Array<Layer> | null; + 1?: Array<Layer> | null; + 2?: Array<Layer> | null; + 3?: Array<Layer> | null; +}; +type Layers = { + levels: Levels; +}; +type CursorPos = { + x: number; + y: number; +}; + + +class Pointers extends Service { + static { + Service.register(this, { + 'proc-started': ['boolean'], + 'proc-destroyed': ['boolean'], + 'device-fetched': ['boolean'], + 'new-line': ['string'], + 'released': ['string'], + 'clicked': ['string'], + }); + } + + #process = null as Subprocess | null; + #lastLine = ''; + #pointers = [] as Array<string>; + + get process() { + return this.#process; + } + + get lastLine() { + return this.#lastLine; + } + + get pointers() { + return this.#pointers; + } + + constructor() { + super(); + this.#initAppConnection(); + } + + 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))) { + this.#lastLine = output; + Pointers.detectClickedOutside('released'); + this.emit('released', output); + this.emit('new-line', output); + } + + if (ON_CLICK_TRIGGERS.some((p) => output.includes(p))) { + this.#lastLine = output; + Pointers.detectClickedOutside('clicked'); + this.emit('clicked', output); + this.emit('new-line', output); + } + }, + ); + this.emit('proc-started', true); + } + + killProc() { + if (this.#process) { + this.#process.force_exit(); + this.#process = null; + this.emit('proc-destroyed', true); + } + } + + #initAppConnection() { + App.connect('window-toggled', () => { + const anyVisibleAndClosable = + (App.windows as Array<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(); + } + }); + } + + static detectClickedOutside(clickStage: string) { + const toClose = ((App.windows as Array<PopupWindow>)).some((w) => { + const closable = ( + w.close_on_unfocus && + w.close_on_unfocus === clickStage + ); + + return w.visible && closable; + }); + + if (!toClose) { + return; + } + + Hyprland.messageAsync('j/layers').then((response) => { + const layers = JSON.parse(response) as { Layers: Layers }; + + Hyprland.messageAsync('j/cursorpos').then((res) => { + const pos = JSON.parse(res) as CursorPos; + + Object.values(layers).forEach((key) => { + const overlayLayer = key.levels['3']; + + if (overlayLayer) { + const noCloseWidgetsNames = [ + 'bar-0', + 'bar-1', + 'bar-2', + 'bar-3', + 'osk', + ]; + + const getNoCloseWidgets = (names: Array<string>) => { + const arr = [] as Array<Layer>; + + names.forEach((name) => { + arr.push( + overlayLayer.find( + (n) => n.namespace === 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.windows.some((win) => + win.name === n.namespace)) { + window = (App + .getWindow(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.closeWindow(w.namespace); + } + }, + ); + } + } + }); + }).catch(print); + }).catch(print); + } +} + +export default new Pointers(); diff --git a/modules/ags/config/services/tablet.ts b/modules/ags/config/services/tablet.ts index f00f481a..cd526c10 100644 --- a/modules/ags/config/services/tablet.ts +++ b/modules/ags/config/services/tablet.ts @@ -1,174 +1,125 @@ -import { execAsync, subprocess } from 'astal'; -import GObject, { register, property, signal } from 'astal/gobject'; +const Hyprland = await Service.import('hyprland'); +const { execAsync, subprocess } = Utils; -import { hyprMessage } from '../lib'; +import TouchGestures from './touch-gestures.ts'; -/* Types */ -import AstalIO from 'gi://AstalIO'; -type RotationName = 'normal' | 'right-up' | 'bottom-up' | 'left-up'; - - -const ROTATION_MAP: Record<RotationName, 0 | 1 | 2 | 3> = { +const ROTATION_MAP = { '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; +// Types +import { Subprocess } from 'types/@girs/gio-2.0/gio-2.0.cjs'; - private _currentMode: 'laptop' | 'tablet' = 'laptop'; - - @property(String) - get currentMode() { - return this._currentMode; +class Tablet extends Service { + static { + Service.register(this, { + 'device-fetched': ['boolean'], + 'autorotate-started': ['boolean'], + 'autorotate-destroyed': ['boolean'], + 'inputs-blocked': ['boolean'], + 'inputs-unblocked': ['boolean'], + 'laptop-mode': ['boolean'], + 'tablet-mode': ['boolean'], + 'mode-toggled': ['boolean'], + 'osk-toggled': ['boolean'], + }); } - set currentMode(val) { - this._currentMode = val; + #tabletMode = false; + #oskState = false; + #autorotate = null as Subprocess | null; + #blockedInputs = null as Subprocess | null; - 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'); + get tabletMode() { + return this.#tabletMode; } - - private _oskState = false; - - @property(Boolean) get oskState() { - return this._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'); + set oskState(value: boolean) { + this.#oskState = value; + this.emit('osk-toggled', this.#oskState); } - 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) { + #blockInputs() { + if (this.#blockedInputs) { 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', + 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); + this.emit('inputs-blocked', true); } - private _unblockInputs() { - if (this._blockedInputs) { - this._blockedInputs.kill(); - this._blockedInputs = null; - - this.emit('inputs-changed', false); + #unblockInputs() { + if (this.#blockedInputs) { + this.#blockedInputs.force_exit(); + this.#blockedInputs = null; + this.emit('inputs-unblocked', true); } } + setTabletMode() { + execAsync(['brightnessctl', '-d', 'tpacpi::kbd_backlight', 's', '0']) + .catch(print); - public toggleMode() { - if (this.currentMode === 'laptop') { - this.currentMode = 'tablet'; - } - else if (this.currentMode === 'tablet') { - this.currentMode = 'laptop'; - } + this.startAutorotate(); + this.#blockInputs(); + + this.#tabletMode = true; + this.emit('tablet-mode', true); + this.emit('mode-toggled', true); } + setLaptopMode() { + execAsync(['brightnessctl', '-d', 'tpacpi::kbd_backlight', 's', '2']) + .catch(print); - public startAutorotate() { - if (this._autorotate) { + this.killAutorotate(); + this.#unblockInputs(); + + this.#tabletMode = false; + this.emit('laptop-mode', true); + this.emit('mode-toggled', true); + } + + toggleMode() { + if (this.#tabletMode) { + this.setLaptopMode(); + } + else { + this.setTabletMode(); + } + + this.emit('mode-toggled', true); + } + + startAutorotate() { + if (this.#autorotate) { return; } - this._autorotate = subprocess( + this.#autorotate = subprocess( ['monitor-sensor'], (output) => { if (output.includes('orientation changed')) { - const index = output.split(' ').at(-1) as RotationName | undefined; + const index = output.split(' ').at(-1); if (!index) { return; @@ -176,38 +127,39 @@ export default class Tablet extends GObject.Object { const orientation = ROTATION_MAP[index]; - hyprMessage( + Hyprland.messageAsync( `keyword monitor ${SCREEN},transform,${orientation}`, ).catch(print); const batchRotate = DEVICES.map((dev) => `keyword device:${dev}:transform ${orientation}; `); - hyprMessage(`[[BATCH]] ${batchRotate.flat()}`); + Hyprland.messageAsync(`[[BATCH]] ${batchRotate.flat()}`); + + if (TouchGestures.gestureDaemon) { + TouchGestures.killDaemon(); + TouchGestures.startDaemon(); + } } }, ); - - this.emit('autorotate-changed', true); + this.emit('autorotate-started', true); } - public killAutorotate() { - if (this._autorotate) { - this._autorotate.kill(); - this._autorotate = null; - - this.emit('autorotate-changed', false); + killAutorotate() { + if (this.#autorotate) { + this.#autorotate.force_exit(); + this.#autorotate = null; + this.emit('autorotate-destroyed', true); } } - - private static _default: InstanceType<typeof Tablet> | undefined; - - public static get_default() { - if (!Tablet._default) { - Tablet._default = new Tablet(); - } - - return Tablet._default; + toggleOsk() { + this.#oskState = !this.#oskState; + this.emit('osk-toggled', this.#oskState); } } + +const tabletService = new Tablet(); + +export default tabletService; diff --git a/modules/ags/config/services/touch-gestures.ts b/modules/ags/config/services/touch-gestures.ts new file mode 100644 index 00000000..5b0b3935 --- /dev/null +++ b/modules/ags/config/services/touch-gestures.ts @@ -0,0 +1,143 @@ +const { subprocess } = Utils; + +const SCREEN = '/dev/input/by-path/platform-AMDI0010\:00-event'; + +const GESTURE_VERIF = [ + 'LR', // Left to Right + 'RL', // Right to Left + 'DU', // Down to Up + 'UD', // Up to Down + 'DLUR', // Down to Left to Up to Right (clockwise motion from Down) + 'DRUL', // Down to Right to Up to Left (counter-clockwise from Down) + 'URDL', // Up to Right to Down to Left (clockwise motion from Up) + 'ULDR', // Up to Left to Down to Right (counter-clockwise from Up) +]; +const EDGE_VERIF = [ + '*', // Any + 'N', // None + 'L', // Left + 'R', // Right + 'T', // Top + 'B', // Bottom + 'TL', // Top left + 'TR', // Top right + 'BL', // Bottom left + 'BR', // Bottom right +]; +const DISTANCE_VERIF = [ + '*', // Any + 'S', // Short + 'M', // Medium + 'L', // Large +]; + +// Types +import { Subprocess } from 'types/@girs/gio-2.0/gio-2.0.cjs'; + + +// TODO: add actmode param +// TODO: support multiple daemons for different thresholds +class TouchGestures extends Service { + static { + Service.register(this, { + 'daemon-started': ['boolean'], + 'daemon-destroyed': ['boolean'], + }); + } + + #gestures = new Map(); + #gestureDaemon = null as Subprocess | null; + + get gestures() { + return this.#gestures; + } + + get gestureDaemon() { + return this.#gestureDaemon; + } + + addGesture({ + name, + nFingers = '1', + gesture, + edge = '*', + distance = '*', + command, + }) { + gesture = String(gesture).toUpperCase(); + if (!GESTURE_VERIF.includes(gesture)) { + logError('Wrong gesture id'); + + return; + } + + edge = String(edge).toUpperCase(); + if (!EDGE_VERIF.includes(edge)) { + logError('Wrong edge id'); + + return; + } + + distance = String(distance).toUpperCase(); + if (!DISTANCE_VERIF.includes(distance)) { + logError('Wrong distance id'); + + return; + } + + if (typeof command !== 'string') { + globalThis[name] = command; + command = `ags -r "${name}()"`; + } + + this.#gestures.set(name, [ + '-g', + `${nFingers},${gesture},${edge},${distance},${command}`, + ]); + + if (this.#gestureDaemon) { + this.killDaemon(); + } + this.startDaemon(); + } + + startDaemon() { + if (this.#gestureDaemon) { + return; + } + + let command = [ + 'lisgd', '-d', SCREEN, + // Orientation + '-o', '0', + // Threshold of gesture recognized + '-t', '125', + // Leniency of gesture angle + '-r', '25', + // Timeout time + '-m', '3200', + ]; + + this.#gestures.forEach((gesture) => { + command = command.concat(gesture); + }); + + this.#gestureDaemon = subprocess( + command, + () => { /**/ }, + ); + this.emit('daemon-started', true); + } + + killDaemon() { + if (this.#gestureDaemon) { + this.#gestureDaemon.force_exit(); + this.#gestureDaemon = null; + this.emit('daemon-destroyed', true); + } + } +} + +const touchGesturesService = new TouchGestures(); + +export default touchGesturesService; 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/ts/applauncher/app-item.ts b/modules/ags/config/ts/applauncher/app-item.ts new file mode 100644 index 00000000..3db5d14a --- /dev/null +++ b/modules/ags/config/ts/applauncher/app-item.ts @@ -0,0 +1,68 @@ +const { Box, Icon, Label } = Widget; +const { lookUpIcon } = Utils; + +import CursorBox from '../misc/cursorbox.ts'; + +// Types +import { Application } from 'types/service/applications.ts'; + + +export default (app: Application) => { + const icon = Icon({ size: 42 }); + const iconString = app.app.get_string('Icon'); + + if (app.icon_name) { + if (lookUpIcon(app.icon_name)) { + icon.icon = app.icon_name; + } + else if (iconString && iconString !== 'nix-snowflake') { + icon.icon = iconString; + } + else { + icon.icon = ''; + } + } + + const textBox = Box({ + vertical: true, + vpack: 'start', + + children: [ + Label({ + class_name: 'title', + label: app.name, + xalign: 0, + truncate: 'end', + }), + + Label({ + class_name: 'description', + label: app.description || '', + wrap: true, + xalign: 0, + justification: 'left', + }), + + Label(), + ], + }); + + return CursorBox({ + hexpand: true, + class_name: 'app', + + attribute: { app }, + + on_primary_click_release: () => { + App.closeWindow('win-applauncher'); + app.launch(); + }, + + child: Box({ + children: [ + icon, + textBox, + ], + }), + }); +}; diff --git a/modules/ags/config/ts/applauncher/main.ts b/modules/ags/config/ts/applauncher/main.ts new file mode 100644 index 00000000..c0844a3e --- /dev/null +++ b/modules/ags/config/ts/applauncher/main.ts @@ -0,0 +1,156 @@ +const Applications = await Service.import('applications'); +const { Box, Entry, Icon, Label, ListBox, Revealer, Scrollable } = Widget; + +import { Fzf, FzfResultItem } from 'fzf'; + +import PopupWindow from '../misc/popup.ts'; +import AppItem from './app-item.ts'; + +// Types +import { ListBoxRow } from 'types/@girs/gtk-3.0/gtk-3.0.cjs'; +import { Application } from 'types/service/applications.ts'; +import { AgsAppItem } from 'global-types'; + + +const Applauncher = (window_name = 'applauncher') => { + let fzfResults: FzfResultItem<Application>[]; + const list = ListBox(); + + const setSort = (text: string) => { + const fzf = new Fzf(Applications.list, { + selector: (app) => app.name + app.executable, + + tiebreakers: [ + (a, b) => b.item.frequency - a.item.frequency, + ], + }); + + fzfResults = fzf.find(text); + list.set_sort_func((a, b) => { + const row1 = (a.get_children()[0] as AgsAppItem).attribute.app.name; + const row2 = (b.get_children()[0] as AgsAppItem).attribute.app.name; + + const s1 = fzfResults.find((r) => r.item.name === row1)?.score ?? 0; + const s2 = fzfResults.find((r) => r.item.name === row2)?.score ?? 0; + + return s1 - s2; + }); + }; + + const makeNewChildren = () => { + const rows = list.get_children() as ListBoxRow[]; + + rows.forEach((ch) => { + ch.destroy(); + }); + + const children = Applications.query('') + .flatMap((app) => AppItem(app)); + + children.forEach((ch) => { + list.add(ch); + }); + list.show_all(); + }; + + makeNewChildren(); + + const placeholder = Revealer({ + child: Label({ + label: " Couldn't find a match", + class_name: 'placeholder', + }), + }); + + const entry = Entry({ + // Set some text so on-change works the first time + text: '-', + hexpand: true, + + on_accept: ({ text }) => { + const appList = Applications.query(text || ''); + + if (appList[0]) { + App.closeWindow(`win-${window_name}`); + appList[0].launch(); + } + }, + + on_change: ({ text }) => { + if (text === null) { + return; + } + setSort(text); + let visibleApps = 0; + + const rows = list.get_children() as ListBoxRow[]; + + rows.forEach((row) => { + row.changed(); + + const item = (row.get_children()[0] as AgsAppItem); + + if (item.attribute.app) { + const isMatching = fzfResults.some((r) => { + return r.item.name === item.attribute.app.name; + }); + + row.visible = isMatching; + + if (isMatching) { + ++visibleApps; + } + } + }); + placeholder.reveal_child = visibleApps <= 0; + }, + }); + + return Box({ + class_name: 'applauncher', + vertical: true, + + setup: (self) => { + self.hook(App, (_, name, visible) => { + if (name !== `win-${window_name}`) { + return; + } + + entry.text = ''; + + if (visible) { + entry.grab_focus(); + } + else { + makeNewChildren(); + } + }); + }, + + children: [ + Box({ + class_name: 'header', + children: [ + Icon('preferences-system-search-symbolic'), + entry, + ], + }), + + Scrollable({ + hscroll: 'never', + vscroll: 'automatic', + child: Box({ + vertical: true, + children: [list, placeholder], + }), + }), + ], + }); +}; + +export default () => PopupWindow({ + name: 'applauncher', + transition: 'slide top', + keymode: 'on-demand', + content: Applauncher(), +}); diff --git a/modules/ags/config/ts/bar/binto.ts b/modules/ags/config/ts/bar/binto.ts new file mode 100644 index 00000000..b6e3b7f0 --- /dev/null +++ b/modules/ags/config/ts/bar/binto.ts @@ -0,0 +1,59 @@ +const { Box, CenterBox } = Widget; + +import Separator from '../misc/separator.ts'; + +import BarRevealer from './fullscreen.ts'; + +import Clock from './items/clock.ts'; +import CurrentWindow from './items/current-window'; +import NotifButton from './items/notif-button.ts'; +import RazerStats from './items/razer-stats.ts'; +import SysTray from './items/systray.ts'; + +const PADDING = 20; + +export default () => BarRevealer({ + monitor: 1, + exclusivity: 'exclusive', + anchor: ['bottom', 'left', 'right'], + bar: Box({ + vertical: true, + children: [ + CenterBox({ + class_name: 'bar', + hexpand: true, + + start_widget: Box({ + hpack: 'start', + children: [ + Separator(PADDING), + + SysTray(), + + Separator(PADDING / 2 / 2), + + RazerStats(), + ], + }), + + center_widget: Box({ + children: [ + CurrentWindow(), + ], + }), + + end_widget: Box({ + hpack: 'end', + children: [ + NotifButton(), + Separator(PADDING / 2), + Clock(), + + Separator(PADDING), + ], + }), + }), + Separator(PADDING, { vertical: true }), + ], + }), +}); diff --git a/modules/ags/config/ts/bar/fullscreen.ts b/modules/ags/config/ts/bar/fullscreen.ts new file mode 100644 index 00000000..e74457fb --- /dev/null +++ b/modules/ags/config/ts/bar/fullscreen.ts @@ -0,0 +1,138 @@ +const Hyprland = await Service.import('hyprland'); +const { Box, EventBox, Revealer, Window } = Widget; + + +const FullscreenState = Variable({ + monitors: [] as number[], + clientAddrs: new Map() as Map<number, string>, +}); + +Hyprland.connect('event', (hyprObj) => { + const arrayEquals = (a1: unknown[], a2: unknown[]) => + a1.sort().toString() === a2.sort().toString(); + + const mapEquals = (m1: Map<number, string>, m2: Map<number, string>) => + m1.size === m2.size && + Array.from(m1.keys()).every((key) => m1.get(key) === m2.get(key)); + + const fs = FullscreenState.value; + const fsClients = hyprObj.clients.filter((c) => { + const mon = Hyprland.getMonitor(c.monitor); + + return c.fullscreen && + c.workspace.id === mon?.activeWorkspace.id; + }); + + const monitors = fsClients.map((c) => c.monitor); + const clientAddrs = new Map(fsClients.map((c) => [c.monitor, c.address])); + + const hasChanged = + !arrayEquals(monitors, fs.monitors) || + !mapEquals(clientAddrs, fs.clientAddrs); + + if (hasChanged) { + FullscreenState.setValue({ + monitors, + clientAddrs, + }); + } +}); + +export default ({ anchor, bar, monitor = 0, ...rest }) => { + const BarVisible = Variable(true); + + FullscreenState.connect('changed', (v) => { + BarVisible.setValue(!v.value.monitors.includes(monitor)); + }); + + const barCloser = Window({ + name: `bar-${monitor}-closer`, + visible: false, + monitor, + anchor: ['top', 'bottom', 'left', 'right'], + layer: 'overlay', + + child: EventBox({ + on_hover: () => { + barCloser.set_visible(false); + BarVisible.setValue(false); + }, + + child: Box({ + css: 'padding: 1px;', + }), + }), + }); + + // Hide bar instantly when out of focus + Hyprland.active.workspace.connect('changed', () => { + const addr = FullscreenState.value.clientAddrs.get(monitor); + + if (addr) { + const client = Hyprland.getClient(addr); + + if (client!.workspace.id !== Hyprland.active.workspace.id) { + BarVisible.setValue(false); + barCloser.visible = false; + } + } + }); + + const buffer = Box({ + css: 'min-height: 10px', + visible: BarVisible.bind().as((v) => !v), + }); + + const vertical = anchor.includes('left') && anchor.includes('right'); + const isBottomOrLeft = ( + anchor.includes('left') && anchor.includes('right') && anchor.includes('bottom') + ) || ( + anchor.includes('top') && anchor.includes('bottom') && anchor.includes('left') + ); + + let transition: 'slide_up' | 'slide_down' | 'slide_left' | 'slide_right'; + + if (vertical) { + transition = isBottomOrLeft ? 'slide_up' : 'slide_down'; + } + else { + transition = isBottomOrLeft ? 'slide_right' : 'slide_left'; + } + + const barWrap = Revealer({ + reveal_child: BarVisible.bind(), + transition, + child: bar, + }); + + return Window({ + name: `bar-${monitor}`, + layer: 'overlay', + monitor, + margins: [-1, -1, -1, -1], + anchor, + ...rest, + + attribute: { + barCloser, + }, + + child: EventBox({ + child: Box({ + css: 'min-height: 1px; padding: 1px;', + hexpand: true, + hpack: 'fill', + vertical, + + children: isBottomOrLeft ? + [buffer, barWrap] : + [barWrap, buffer], + }), + }).on('enter-notify-event', () => { + if (!BarVisible.value) { + barCloser.visible = true; + BarVisible.setValue(true); + } + }), + }); +}; diff --git a/modules/ags/config/ts/bar/hovers/audio.ts b/modules/ags/config/ts/bar/hovers/audio.ts new file mode 100644 index 00000000..cffa56a4 --- /dev/null +++ b/modules/ags/config/ts/bar/hovers/audio.ts @@ -0,0 +1,21 @@ +const Audio = await Service.import('audio'); +const { Label, Icon } = Widget; + +import { SpeakerIcon } from '../../misc/audio-icons.ts'; +import HoverRevealer from './hover-revealer.ts'; + + +export default () => HoverRevealer({ + class_name: 'audio', + + icon: Icon({ + icon: SpeakerIcon.bind(), + }), + + label: Label().hook(Audio, (self) => { + if (Audio.speaker?.volume) { + self.label = + `${Math.round(Audio.speaker?.volume * 100)}%`; + } + }, 'speaker-changed'), +}); diff --git a/modules/ags/config/ts/bar/hovers/bluetooth.ts b/modules/ags/config/ts/bar/hovers/bluetooth.ts new file mode 100644 index 00000000..fe6a5a1a --- /dev/null +++ b/modules/ags/config/ts/bar/hovers/bluetooth.ts @@ -0,0 +1,26 @@ +const Bluetooth = await Service.import('bluetooth'); +const { Label, Icon } = Widget; + +import HoverRevealer from './hover-revealer.ts'; + + +export default () => HoverRevealer({ + class_name: 'bluetooth', + + icon: Icon().hook(Bluetooth, (self) => { + if (Bluetooth.enabled) { + self.icon = Bluetooth.connected_devices[0] ? + Bluetooth.connected_devices[0].icon_name : + 'bluetooth-active-symbolic'; + } + else { + self.icon = 'bluetooth-disabled-symbolic'; + } + }), + + label: Label().hook(Bluetooth, (self) => { + self.label = Bluetooth.connected_devices[0] ? + `${Bluetooth.connected_devices[0]}` : + 'Disconnected'; + }, 'notify::connected-devices'), +}); diff --git a/modules/ags/config/ts/bar/hovers/brightness.ts b/modules/ags/config/ts/bar/hovers/brightness.ts new file mode 100644 index 00000000..74b936db --- /dev/null +++ b/modules/ags/config/ts/bar/hovers/brightness.ts @@ -0,0 +1,17 @@ +const { Icon, Label } = Widget; + +import Brightness from '../../../services/brightness.ts'; +import HoverRevealer from './hover-revealer.ts'; + + +export default () => HoverRevealer({ + class_name: 'brightness', + + icon: Icon({ + icon: Brightness.bind('screenIcon'), + }), + + label: Label().hook(Brightness, (self) => { + self.label = `${Math.round(Brightness.screen * 100)}%`; + }, 'screen'), +}); diff --git a/modules/ags/config/ts/bar/hovers/hover-revealer.ts b/modules/ags/config/ts/bar/hovers/hover-revealer.ts new file mode 100644 index 00000000..b01102e1 --- /dev/null +++ b/modules/ags/config/ts/bar/hovers/hover-revealer.ts @@ -0,0 +1,42 @@ +const { Box, Revealer } = Widget; + +import Separator from '../../misc/separator.ts'; +import CursorBox from '../../misc/cursorbox.ts'; + + +export default ({ + class_name, + icon, + label, + spacing = 5, +}) => { + const hoverRevLabel = Revealer({ + transition: 'slide_right', + + child: Box({ + + children: [ + Separator(spacing), + + label, + ], + }), + }); + + const widget = CursorBox({ + on_hover: () => { + hoverRevLabel.reveal_child = true; + }, + + child: Box({ + class_name, + + children: [ + icon, + hoverRevLabel, + ], + }), + }); + + return widget; +}; diff --git a/modules/ags/config/ts/bar/hovers/keyboard-layout.ts b/modules/ags/config/ts/bar/hovers/keyboard-layout.ts new file mode 100644 index 00000000..4faa2abc --- /dev/null +++ b/modules/ags/config/ts/bar/hovers/keyboard-layout.ts @@ -0,0 +1,54 @@ +const Hyprland = await Service.import('hyprland'); +const { Icon, Label } = Widget; + +import HoverRevealer from './hover-revealer.ts'; + +const DEFAULT_KB = 'at-translated-set-2-keyboard'; + +// Types +import { Keyboard, LabelGeneric } from 'global-types'; + + +const getKbdLayout = (self: LabelGeneric, _: 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 + Hyprland.messageAsync('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); + } +}; + +export default () => HoverRevealer({ + class_name: 'keyboard', + spacing: 4, + + icon: Icon({ + icon: 'input-keyboard-symbolic', + size: 20, + }), + label: Label({ css: 'font-size: 20px;' }) + .hook(Hyprland, getKbdLayout, 'keyboard-layout'), +}); diff --git a/modules/ags/config/ts/bar/hovers/network.ts b/modules/ags/config/ts/bar/hovers/network.ts new file mode 100644 index 00000000..0280a8ff --- /dev/null +++ b/modules/ags/config/ts/bar/hovers/network.ts @@ -0,0 +1,37 @@ +const Network = await Service.import('network'); +const { Label, Icon } = Widget; + +import HoverRevealer from './hover-revealer.ts'; + + +export default () => HoverRevealer({ + class_name: 'network', + + icon: Icon().hook(Network, (self) => { + if (Network.wifi.internet === 'connected' || + Network.wifi.internet === 'connecting') { + self.icon = Network.wifi.icon_name; + } + else if (Network.wired.internet === 'connected' || + Network.wired.internet === 'connecting') { + self.icon = Network.wired.icon_name; + } + else { + self.icon = Network.wifi.icon_name; + } + }), + + label: Label().hook(Network, (self) => { + if (Network.wifi.internet === 'connected' || + Network.wifi.internet === 'connecting') { + self.label = Network.wifi.ssid || 'Unknown'; + } + else if (Network.wired.internet === 'connected' || + Network.wired.internet === 'connecting') { + self.label = 'Connected'; + } + else { + self.label = 'Disconnected'; + } + }), +}); diff --git a/modules/ags/config/ts/bar/items/battery.ts b/modules/ags/config/ts/bar/items/battery.ts new file mode 100644 index 00000000..d2662313 --- /dev/null +++ b/modules/ags/config/ts/bar/items/battery.ts @@ -0,0 +1,30 @@ +const Battery = await Service.import('battery'); +const { Label, Icon, Box } = Widget; + +import Separator from '../../misc/separator.ts'; + +const LOW_BATT = 20; +const SPACING = 5; + + +export default () => Box({ + class_name: 'toggle-off battery', + + children: [ + Icon({ + class_name: 'battery-indicator', + icon: Battery.bind('icon_name'), + }).hook(Battery, (self) => { + self.toggleClassName('charging', Battery.charging); + self.toggleClassName('charged', Battery.charged); + self.toggleClassName('low', Battery.percent < LOW_BATT); + }), + + Separator(SPACING), + + Label({ + label: Battery.bind('percent') + .transform((v) => `${v}%`), + }), + ], +}); diff --git a/modules/ags/config/ts/bar/items/cal-opener.ts b/modules/ags/config/ts/bar/items/cal-opener.ts new file mode 100644 index 00000000..e8b764d7 --- /dev/null +++ b/modules/ags/config/ts/bar/items/cal-opener.ts @@ -0,0 +1,19 @@ +import CursorBox from '../../misc/cursorbox.ts'; +import Clock from './clock'; + + +export default () => CursorBox({ + class_name: 'toggle-off', + + on_primary_click_release: () => App.toggleWindow('win-calendar'), + + setup: (self) => { + self.hook(App, (_, windowName, visible) => { + if (windowName === 'win-calendar') { + self.toggleClassName('toggle-on', visible); + } + }); + }, + + child: Clock(), +}); diff --git a/modules/ags/config/ts/bar/items/clock.ts b/modules/ags/config/ts/bar/items/clock.ts new file mode 100644 index 00000000..296f4807 --- /dev/null +++ b/modules/ags/config/ts/bar/items/clock.ts @@ -0,0 +1,16 @@ +const { Label } = Widget; +const { new_now_local } = imports.gi.GLib.DateTime; + + +export default () => Label({ class_name: 'clock' }) + .poll(1000, (self) => { + const time = new_now_local(); + + const dayName = time.format('%a. '); + const dayNum = time.get_day_of_month(); + const date = time.format(' %b. %H:%M'); + + if (dayNum && dayName && date) { + self.label = dayName + dayNum + date; + } + }); diff --git a/modules/ags/config/ts/bar/items/current-window.ts b/modules/ags/config/ts/bar/items/current-window.ts new file mode 100644 index 00000000..56dbb105 --- /dev/null +++ b/modules/ags/config/ts/bar/items/current-window.ts @@ -0,0 +1,34 @@ +const Applications = await Service.import('applications'); +const Hyprland = await Service.import('hyprland'); +const { Box, Icon, Label } = Widget; + +import Separator from '../../misc/separator.ts'; + +const SPACING = 8; + + +export default () => Box({ + class_name: 'current-window', + + children: [ + Separator(SPACING / 2), + + Icon({ size: 30 }) + .hook(Hyprland.active.client, (self) => { + const app = Applications + .query(Hyprland.active.client.class)[0]; + + self.icon = app?.icon_name || ''; + }), + + Separator(SPACING), + + Label({ + css: 'color: #CBA6F7; font-size: 18px', + truncate: 'end', + label: Hyprland.active.client.bind('title'), + }), + ], +}).hook(Hyprland.active.client, (self) => { + self.visible = Hyprland.active.client.title !== ''; +}); diff --git a/modules/ags/config/ts/bar/items/heart.ts b/modules/ags/config/ts/bar/items/heart.ts new file mode 100644 index 00000000..d942b5ab --- /dev/null +++ b/modules/ags/config/ts/bar/items/heart.ts @@ -0,0 +1,26 @@ +const { Label } = Widget; + +import CursorBox from '../../misc/cursorbox.ts'; +import Persist from '../../misc/persist.ts'; + +const HeartState = Variable(''); + +Persist({ + name: 'heart', + gobject: HeartState, + prop: 'value', + condition: '', + whenFalse: '', +}); + + +export default () => CursorBox({ + on_primary_click_release: () => { + HeartState.setValue(HeartState.value === '' ? '' : ''); + }, + + child: Label({ + class_name: 'heart-toggle', + label: HeartState.bind(), + }), +}); diff --git a/modules/ags/config/ts/bar/items/notif-button.ts b/modules/ags/config/ts/bar/items/notif-button.ts new file mode 100644 index 00000000..6221790b --- /dev/null +++ b/modules/ags/config/ts/bar/items/notif-button.ts @@ -0,0 +1,60 @@ +const Notifications = await Service.import('notifications'); +const { Box, CenterBox, Icon, Label } = Widget; + +import CursorBox from '../../misc/cursorbox.ts'; +import Separator from '../../misc/separator.ts'; + +const SPACING = 4; + +// Types +import { PopupWindow } from 'global-types'; + + +export default () => CursorBox({ + class_name: 'toggle-off', + + on_primary_click_release: (self) => { + (App.getWindow('win-notification-center') as PopupWindow) + .set_x_pos( + self.get_allocation(), + 'right', + ); + + App.toggleWindow('win-notification-center'); + }, + + setup: (self) => { + self.hook(App, (_, windowName, visible) => { + if (windowName === 'win-notification-center') { + self.toggleClassName('toggle-on', visible); + } + }); + }, + + child: CenterBox({ + class_name: 'notif-panel', + + center_widget: Box({ + children: [ + Icon().hook(Notifications, (self) => { + if (Notifications.dnd) { + self.icon = 'notification-disabled-symbolic'; + } + else if (Notifications.notifications.length > 0) { + self.icon = 'notification-new-symbolic'; + } + else { + self.icon = 'notification-symbolic'; + } + }), + + Separator(SPACING), + + Label({ + label: Notifications.bind('notifications') + .transform((n) => String(n.length)), + }), + ], + }), + }), +}); diff --git a/modules/ags/config/ts/bar/items/osk-toggle.ts b/modules/ags/config/ts/bar/items/osk-toggle.ts new file mode 100644 index 00000000..76f8383b --- /dev/null +++ b/modules/ags/config/ts/bar/items/osk-toggle.ts @@ -0,0 +1,23 @@ +const { Label } = Widget; + +import Tablet from '../../../services/tablet.ts'; +import CursorBox from '../../misc/cursorbox.ts'; + + +export default () => CursorBox({ + class_name: 'toggle-off', + + on_primary_click_release: () => Tablet.toggleOsk(), + + setup: (self) => { + self.hook(Tablet, () => { + self.toggleClassName('toggle-on', Tablet.oskState); + }, 'osk-toggled'); + }, + + child: Label({ + class_name: 'osk-toggle', + xalign: 0.6, + label: ' ', + }), +}); diff --git a/modules/ags/config/ts/bar/items/quick-settings.ts b/modules/ags/config/ts/bar/items/quick-settings.ts new file mode 100644 index 00000000..7c8d0123 --- /dev/null +++ b/modules/ags/config/ts/bar/items/quick-settings.ts @@ -0,0 +1,79 @@ +const { Box, Icon } = Widget; + +import Audio from '../hovers/audio.ts'; +import Bluetooth from '../hovers/bluetooth.ts'; +import Brightness from '../hovers/brightness.ts'; +import KeyboardLayout from '../hovers/keyboard-layout.ts'; +import Network from '../hovers/network.ts'; + +import CursorBox from '../../misc/cursorbox.ts'; +import Separator from '../../misc/separator.ts'; + +const SPACING = 4; + +// Types +import { PopupWindow } from 'global-types'; + + +export default () => { + const hoverRevealers = [ + KeyboardLayout(), + + Brightness(), + + Audio(), + + Bluetooth(), + + Network(), + ]; + + return CursorBox({ + class_name: 'toggle-off', + + on_primary_click_release: (self) => { + (App.getWindow('win-quick-settings') as PopupWindow) + .set_x_pos( + self.get_allocation(), + 'right', + ); + + App.toggleWindow('win-quick-settings'); + }, + + setup: (self) => { + self.hook(App, (_, windowName, visible) => { + if (windowName === 'win-quick-settings') { + self.toggleClassName('toggle-on', visible); + } + }); + }, + + attribute: { + hoverRevealers: hoverRevealers.map((rev) => { + const box = rev.child; + + return box.children[1]; + }), + }, + on_hover_lost: (self) => { + self.attribute.hoverRevealers.forEach((rev) => { + rev.reveal_child = false; + }); + }, + + child: Box({ + class_name: 'quick-settings-toggle', + vertical: false, + children: [ + Separator(SPACING), + + ...hoverRevealers, + + Icon('nixos-logo-symbolic'), + + Separator(SPACING), + ], + }), + }); +}; diff --git a/modules/ags/config/ts/bar/items/razer-stats.ts b/modules/ags/config/ts/bar/items/razer-stats.ts new file mode 100644 index 00000000..267f4ca8 --- /dev/null +++ b/modules/ags/config/ts/bar/items/razer-stats.ts @@ -0,0 +1,93 @@ +import { execAsync, interval } from 'resource:///com/github/Aylur/ags/utils.js'; + +const { Box, Icon, Label } = Widget; + +const RAZER_POLL = 10000; +const LOW_BATT = 20; + +const RazerBat = Variable({ + battery: 0, + charging: false, + sleeping: false, + disconnected: true, +}); + + +const fetchInfo = () => { + execAsync([ + 'bash', + '-c', + "polychromatic-cli -n 'Razer Naga Pro (Wired)' -k" + + ' || ' + + "polychromatic-cli -n 'Razer Naga Pro (Wireless)' -k", + + ]).then((out) => { + const batteryMatches = out.split('\n') + .filter((i) => i.includes('Battery'))[0] + .match(/[0-9]+/); + + let sleeping = false; + let battery = batteryMatches !== null ? + parseInt(batteryMatches[0]) : + 0; + + // Don't set to zero when in sleep mode + if (battery === 0 && RazerBat.value.battery > 10) { + battery = RazerBat.value.battery; + sleeping = true; + } + + // If 'Wireless' isn't in the logs it means the cmd found 'Wired' + const charging = !out.includes('Wireless'); + + RazerBat.value = { + battery, + charging, + sleeping, + disconnected: false, + }; + }).catch(() => { + RazerBat.value.disconnected = true; + }); +}; + +interval(RAZER_POLL, fetchInfo); + +export default () => { + const percentage = Label({ vpack: 'center' }); + + const icon = Icon({ hpack: 'start' }) + .hook(RazerBat, (self) => { + const v = RazerBat.value; + + percentage.visible = !(v.disconnected || v.charging); + percentage.label = `${v.battery}%`; + + self.icon = v.disconnected ? + 'content-loading-symbolic' : + 'mouse-razer-symbolic'; + self.setCss( + v.disconnected || v.charging ? + 'margin-right: -5px;' : + '', + ); + + self.toggleClassName( + 'high', + v.battery > 66, + ); + self.toggleClassName( + 'medium', + v.battery > LOW_BATT && v.battery <= 66, + ); + self.toggleClassName( + 'low', + v.battery <= LOW_BATT, + ); + }); + + return Box({ + class_name: 'razer', + children: [icon, percentage], + }); +}; diff --git a/modules/ags/config/ts/bar/items/systray.ts b/modules/ags/config/ts/bar/items/systray.ts new file mode 100644 index 00000000..88a69790 --- /dev/null +++ b/modules/ags/config/ts/bar/items/systray.ts @@ -0,0 +1,92 @@ +const SystemTray = await Service.import('systemtray'); + +const { timeout } = Utils; +const { Box, Icon, MenuItem, MenuBar, Revealer } = Widget; + +import Separator from '../../misc/separator.ts'; + +const REVEAL_DURATION = 500; +const SPACING = 12; + +// Types +import { TrayItem } from 'types/service/systemtray.ts'; + + +const SysTrayItem = (item: TrayItem) => { + if (item.id === 'spotify-client') { + return; + } + + return MenuItem({ + submenu: item.menu, + tooltip_markup: item.bind('tooltip_markup'), + + child: Revealer({ + transition: 'slide_right', + transition_duration: REVEAL_DURATION, + + child: Icon({ size: 24 }).bind('icon', item, 'icon'), + }), + }); +}; + +const SysTray = () => MenuBar({ + attribute: { items: new Map() }, + + setup: (self) => { + self + .hook(SystemTray, (_, id) => { + const item = SystemTray.getItem(id); + + if (self.attribute.items.has(id) || !item) { + return; + } + + const w = SysTrayItem(item); + + // Early return if item is in blocklist + if (!w) { + return; + } + + self.attribute.items.set(id, w); + self.add(w); + self.show_all(); + + w.child.reveal_child = true; + }, 'added') + + .hook(SystemTray, (_, id) => { + if (!self.attribute.items.has(id)) { + return; + } + + self.attribute.items.get(id).child.reveal_child = false; + timeout(REVEAL_DURATION, () => { + self.attribute.items.get(id).destroy(); + self.attribute.items.delete(id); + }); + }, 'removed'); + }, +}); + +export default () => { + const systray = SysTray(); + + return Revealer({ + transition: 'slide_right', + + child: Box({ + children: [ + Box({ + class_name: 'sys-tray', + children: [systray], + }), + + Separator(SPACING), + ], + }), + }).hook(SystemTray, (self) => { + self.reveal_child = systray.get_children().length > 0; + }); +}; diff --git a/modules/ags/config/ts/bar/items/tablet-toggle.ts b/modules/ags/config/ts/bar/items/tablet-toggle.ts new file mode 100644 index 00000000..80d67957 --- /dev/null +++ b/modules/ags/config/ts/bar/items/tablet-toggle.ts @@ -0,0 +1,24 @@ +const { Box, Label } = Widget; + +import Tablet from '../../../services/tablet.ts'; +import CursorBox from '../../misc/cursorbox.ts'; + + +export default () => CursorBox({ + class_name: 'toggle-off', + + on_primary_click_release: () => Tablet.toggleMode(), + + setup: (self) => { + self.hook(Tablet, () => { + self.toggleClassName('toggle-on', Tablet.tabletMode); + }, 'mode-toggled'); + }, + + child: Box({ + class_name: 'tablet-toggle', + vertical: false, + children: [Label(' ')], + }), + +}); diff --git a/modules/ags/config/ts/bar/items/workspaces.ts b/modules/ags/config/ts/bar/items/workspaces.ts new file mode 100644 index 00000000..b7ca7c23 --- /dev/null +++ b/modules/ags/config/ts/bar/items/workspaces.ts @@ -0,0 +1,179 @@ +const Hyprland = await Service.import('hyprland'); + +const { timeout } = Utils; +const { Box, Overlay, Revealer } = Widget; + +import CursorBox from '../../misc/cursorbox.ts'; + +const URGENT_DURATION = 1000; + +// Types +import { + BoxGeneric, + EventBoxGeneric, + OverlayGeneric, + RevealerGeneric, + Workspace, +} from 'global-types'; + + +const Workspace = ({ id }: { id: number }) => { + return Revealer({ + transition: 'slide_right', + attribute: { id }, + + child: CursorBox({ + tooltip_text: `${id}`, + + on_primary_click_release: () => { + Hyprland.messageAsync(`dispatch workspace ${id}`); + }, + + child: Box({ + vpack: 'center', + class_name: 'button', + + setup: (self) => { + const update = ( + _: BoxGeneric, + addr: string | undefined, + ) => { + const workspace = Hyprland.getWorkspace(id); + const occupied = workspace && workspace.windows > 0; + + self.toggleClassName('occupied', occupied); + + if (!addr) { + return; + } + + // Deal with urgent windows + const client = Hyprland.getClient(addr); + const isThisUrgent = client && + client.workspace.id === id; + + if (isThisUrgent) { + self.toggleClassName('urgent', true); + + // Only show for a sec when urgent is current workspace + if (Hyprland.active.workspace.id === id) { + timeout(URGENT_DURATION, () => { + self.toggleClassName('urgent', false); + }); + } + } + }; + + self + .hook(Hyprland, update) + + // Deal with urgent windows + .hook(Hyprland, update, 'urgent-window') + + .hook(Hyprland.active.workspace, () => { + if (Hyprland.active.workspace.id === id) { + self.toggleClassName('urgent', false); + } + }); + }, + }), + }), + }); +}; + +export default () => { + const L_PADDING = 16; + const WS_WIDTH = 30; + + const updateHighlight = (self: BoxGeneric) => { + const currentId = Hyprland.active.workspace.id; + + const indicators = (((self.get_parent() as OverlayGeneric) + .child as EventBoxGeneric) + .child as BoxGeneric) + .children as Workspace[]; + + const currentIndex = indicators + .findIndex((w) => w.attribute.id === currentId); + + if (currentIndex < 0) { + return; + } + + self.setCss(`margin-left: ${L_PADDING + (currentIndex * WS_WIDTH)}px`); + }; + + const highlight = Box({ + vpack: 'center', + hpack: 'start', + class_name: 'button active', + + }).hook(Hyprland.active.workspace, updateHighlight); + + const widget = Overlay({ + pass_through: true, + overlays: [highlight], + child: CursorBox({ + child: Box({ + class_name: 'workspaces', + + attribute: { workspaces: [] as Workspace[] }, + + setup: (self) => { + const refresh = () => { + (self.children as RevealerGeneric[]) + .forEach((rev) => { + rev.reveal_child = false; + }); + + self.attribute.workspaces + .forEach((ws) => { + ws.reveal_child = true; + }); + }; + + const updateWorkspaces = () => { + Hyprland.workspaces.forEach((ws) => { + const currentWs = + (self.children as Workspace[]) + .find((ch) => ch.attribute.id === ws.id); + + if (!currentWs && ws.id > 0) { + self.add(Workspace({ id: ws.id })); + } + }); + self.show_all(); + + // Make sure the order is correct + self.attribute.workspaces.forEach((workspace, i) => { + (workspace.get_parent() as BoxGeneric) + .reorder_child(workspace, i); + }); + }; + + self.hook(Hyprland, () => { + self.attribute.workspaces = + (self.children as Workspace[]) + .filter((ch) => { + return Hyprland.workspaces.find((ws) => { + return ws.id === ch.attribute.id; + }); + }) + .sort((a, b) => + a.attribute.id - b.attribute.id); + + updateWorkspaces(); + refresh(); + + // Make sure the highlight doesn't go too far + const TEMP_TIMEOUT = 10; + + timeout(TEMP_TIMEOUT, () => updateHighlight(highlight)); + }); + }, + }), + }), + }); + + return widget; +}; diff --git a/modules/ags/config/ts/bar/wim.ts b/modules/ags/config/ts/bar/wim.ts new file mode 100644 index 00000000..7c188a0d --- /dev/null +++ b/modules/ags/config/ts/bar/wim.ts @@ -0,0 +1,80 @@ +const { CenterBox, Box } = Widget; + +import Separator from '../misc/separator.ts'; + +import Battery from './items/battery.ts'; +import Clock from './items/cal-opener.ts'; +import CurrentWindow from './items/current-window.ts'; +import Heart from './items/heart.ts'; +import NotifButton from './items/notif-button.ts'; +import OskToggle from './items/osk-toggle.ts'; +import QsToggle from './items/quick-settings.ts'; +import SysTray from './items/systray.ts'; +import TabletToggle from './items/tablet-toggle.ts'; +import Workspaces from './items/workspaces.ts'; + +import BarRevealer from './fullscreen.ts'; + +const SPACING = 12; + + +export default () => BarRevealer({ + anchor: ['top', 'left', 'right'], + exclusivity: 'exclusive', + bar: CenterBox({ + css: 'margin: 5px 5px 5px 5px', + class_name: 'bar', + + start_widget: Box({ + hpack: 'start', + children: [ + + OskToggle(), + + Separator(SPACING), + + TabletToggle(), + + Separator(SPACING), + + SysTray(), + + Workspaces(), + + Separator(SPACING), + + CurrentWindow(), + + ], + }), + + center_widget: Box({ + children: [ + Separator(SPACING), + + Clock(), + + Separator(SPACING), + ], + }), + + end_widget: Box({ + hpack: 'end', + children: [ + Heart(), + + Separator(SPACING), + + Battery(), + + Separator(SPACING), + + NotifButton(), + + Separator(SPACING), + + QsToggle(), + ], + }), + }), +}); diff --git a/modules/ags/config/ts/corners/main.ts b/modules/ags/config/ts/corners/main.ts new file mode 100644 index 00000000..921e4c74 --- /dev/null +++ b/modules/ags/config/ts/corners/main.ts @@ -0,0 +1,52 @@ +const { Window } = Widget; + +import RoundedCorner from './screen-corners.ts'; + + +const TopLeft = () => Window({ + name: 'cornertl', + layer: 'overlay', + exclusivity: 'ignore', + anchor: ['top', 'left'], + visible: true, + click_through: true, + child: RoundedCorner('topleft'), +}); + +const TopRight = () => Window({ + name: 'cornertr', + layer: 'overlay', + exclusivity: 'ignore', + anchor: ['top', 'right'], + visible: true, + click_through: true, + child: RoundedCorner('topright'), +}); + +const BottomLeft = () => Window({ + name: 'cornerbl', + layer: 'overlay', + exclusivity: 'ignore', + anchor: ['bottom', 'left'], + visible: true, + click_through: true, + child: RoundedCorner('bottomleft'), +}); + +const BottomRight = () => Window({ + name: 'cornerbr', + layer: 'overlay', + exclusivity: 'ignore', + anchor: ['bottom', 'right'], + visible: true, + click_through: true, + child: RoundedCorner('bottomright'), +}); + + +export default () => [ + TopLeft(), + TopRight(), + BottomLeft(), + BottomRight(), +]; diff --git a/modules/ags/config/ts/corners/screen-corners.ts b/modules/ags/config/ts/corners/screen-corners.ts new file mode 100644 index 00000000..16ed64e5 --- /dev/null +++ b/modules/ags/config/ts/corners/screen-corners.ts @@ -0,0 +1,79 @@ +const { Box, DrawingArea } = Widget; + +const { Gtk } = imports.gi; + +export default ( + place = 'top left', + css = 'background-color: black;', +) => Box({ + hpack: place.includes('left') ? 'start' : 'end', + vpack: place.includes('top') ? 'start' : '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'}; + `, + child: DrawingArea({ + css: ` + border-radius: 18px; + border-width: 0.068rem; + ${css} + `, + setup: (widget) => { + let r = widget.get_style_context() + .get_property('border-radius', Gtk.StateFlags.NORMAL); + + widget.set_size_request(r, r); + widget.connect('draw', (_, cr) => { + const c = widget.get_style_context() + .get_property('background-color', Gtk.StateFlags.NORMAL); + + r = widget.get_style_context() + .get_property('border-radius', Gtk.StateFlags.NORMAL); + + const borderColor = widget.get_style_context() + .get_property('color', Gtk.StateFlags.NORMAL); + + // You're going to write border-width: something anyway + const borderWidth = widget.get_style_context() + .get_border(Gtk.StateFlags.NORMAL).left; + + widget.set_size_request(r, r); + + switch (place) { + case 'topleft': + cr.arc(r, r, r, Math.PI, 3 * Math.PI / 2); + cr.lineTo(0, 0); + break; + + case 'topright': + cr.arc(0, r, r, 3 * Math.PI / 2, 2 * Math.PI); + cr.lineTo(r, 0); + break; + + case 'bottomleft': + cr.arc(r, 0, r, Math.PI / 2, Math.PI); + cr.lineTo(0, r); + break; + + case 'bottomright': + cr.arc(0, 0, r, 0, Math.PI / 2); + cr.lineTo(r, r); + break; + } + + cr.closePath(); + cr.setSourceRGBA(c.red, c.green, c.blue, c.alpha); + cr.fill(); + cr.setLineWidth(borderWidth); + cr.setSourceRGBA(borderColor.red, + borderColor.green, + borderColor.blue, + borderColor.alpha); + cr.stroke(); + }); + }, + }), +}); diff --git a/modules/ags/config/ts/date.ts b/modules/ags/config/ts/date.ts new file mode 100644 index 00000000..23f4ff15 --- /dev/null +++ b/modules/ags/config/ts/date.ts @@ -0,0 +1,102 @@ +const { Box, Calendar, Label } = Widget; + +const { new_now_local } = imports.gi.GLib.DateTime; + +import PopupWindow from './misc/popup.ts'; + + +const Divider = () => Box({ + class_name: 'divider', + vertical: true, +}); + +const Time = () => Box({ + class_name: 'timebox', + vertical: true, + + children: [ + Box({ + class_name: 'time-container', + hpack: 'center', + vpack: 'center', + + children: [ + Label({ + class_name: 'content', + label: 'hour', + setup: (self) => { + self.poll(1000, () => { + self.label = new_now_local().format('%H') || ''; + }); + }, + }), + + Divider(), + + Label({ + class_name: 'content', + label: 'minute', + setup: (self) => { + self.poll(1000, () => { + self.label = new_now_local().format('%M') || ''; + }); + }, + }), + + ], + }), + + Box({ + class_name: 'date-container', + hpack: 'center', + + child: Label({ + css: 'font-size: 20px', + label: 'complete date', + + setup: (self) => { + self.poll(1000, () => { + const time = new_now_local(); + + const dayNameMonth = time.format('%A, %B '); + const dayNum = time.get_day_of_month(); + const date = time.format(', %Y'); + + if (dayNum && dayNameMonth && date) { + self.label = dayNameMonth + dayNum + date; + } + }); + }, + }), + }), + + ], +}); + +const CalendarWidget = () => Box({ + class_name: 'cal-box', + + child: Calendar({ + show_day_names: true, + show_heading: true, + class_name: 'cal', + }), +}); + +const TOP_MARGIN = 6; + +export default () => PopupWindow({ + name: 'calendar', + anchor: ['top'], + margins: [TOP_MARGIN, 0, 0, 0], + + content: Box({ + class_name: 'date', + vertical: true, + + children: [ + Time(), + CalendarWidget(), + ], + }), +}); diff --git a/modules/ags/config/ts/media-player/gesture.ts b/modules/ags/config/ts/media-player/gesture.ts new file mode 100644 index 00000000..b4ad7271 --- /dev/null +++ b/modules/ags/config/ts/media-player/gesture.ts @@ -0,0 +1,167 @@ +const { timeout } = Utils; +const { Box, EventBox, Overlay } = Widget; + +const { Gtk } = imports.gi; + +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 +import { + CenterBoxGeneric, + Gesture, + OverlayGeneric, + PlayerBox, +} from 'global-types'; + + +export default ({ + setup = () => {/**/}, + ...props +}: Gesture) => { + const widget = EventBox(); + const gesture = Gtk.GestureDrag.new(widget); + + // Have empty PlayerBox to define the size of the widget + const emptyPlayer = Box({ + class_name: 'player', + attribute: { empty: true }, + }); + + const content = Overlay({ + ...props, + attribute: { + players: new Map(), + setup: false, + dragging: false, + + includesWidget: (playerW: OverlayGeneric) => { + return content.overlays.find((w) => w === playerW); + }, + + showTopOnly: () => content.overlays.forEach((over) => { + over.visible = over === content.overlays.at(-1); + }), + + moveToTop: (player: CenterBoxGeneric) => { + player.visible = true; + content.reorder_overlay(player, -1); + timeout(ANIM_DURATION, () => { + content.attribute.showTopOnly(); + }); + }, + }, + + child: emptyPlayer, + + setup: (self) => { + setup(self); + + self + .hook(gesture, (_, realGesture) => { + if (realGesture) { + self.overlays.forEach((over) => { + over.visible = true; + }); + } + else { + self.attribute.showTopOnly(); + } + + // Don't allow gesture when only one player + if (self.overlays.length <= 1) { + return; + } + + self.attribute.dragging = true; + let offset = gesture.get_offset()[1]; + const playerBox = self.overlays.at(-1) as PlayerBox; + + if (!offset) { + return; + } + + // Slide right + if (offset >= 0) { + playerBox.setCss(` + margin-left: ${offset}px; + margin-right: -${offset}px; + ${playerBox.attribute.bgStyle} + `); + } + + // Slide left + else { + offset = Math.abs(offset); + playerBox.setCss(` + margin-left: -${offset}px; + margin-right: ${offset}px; + ${playerBox.attribute.bgStyle} + `); + } + }, 'drag-update') + + + .hook(gesture, () => { + // Don't allow gesture when only one player + if (self.overlays.length <= 1) { + return; + } + + self.attribute.dragging = false; + const offset = gesture.get_offset()[1]; + + const playerBox = self.overlays.at(-1) as PlayerBox; + + // If crosses threshold after letting go, slide away + if (offset && Math.abs(offset) > MAX_OFFSET) { + // Disable inputs during animation + widget.sensitive = false; + + // Slide away right + if (offset >= 0) { + playerBox.setCss(` + ${TRANSITION} + margin-left: ${OFFSCREEN}px; + margin-right: -${OFFSCREEN}px; + opacity: 0.7; ${playerBox.attribute.bgStyle} + `); + } + + // Slide away left + else { + playerBox.setCss(` + ${TRANSITION} + margin-left: -${OFFSCREEN}px; + margin-right: ${OFFSCREEN}px; + opacity: 0.7; ${playerBox.attribute.bgStyle} + `); + } + + timeout(ANIM_DURATION, () => { + // Put the player in the back after anim + self.reorder_overlay(playerBox, 0); + // Recenter player + playerBox.setCss(playerBox.attribute.bgStyle); + + widget.sensitive = true; + + self.attribute.showTopOnly(); + }); + } + else { + // Recenter with transition for animation + playerBox.setCss(`${TRANSITION} + ${playerBox.attribute.bgStyle}`); + } + }, 'drag-end'); + }, + }); + + widget.add(content); + + return widget; +}; diff --git a/modules/ags/config/ts/media-player/mpris.ts b/modules/ags/config/ts/media-player/mpris.ts new file mode 100644 index 00000000..ee7f6f60 --- /dev/null +++ b/modules/ags/config/ts/media-player/mpris.ts @@ -0,0 +1,473 @@ +const Mpris = await Service.import('mpris'); + +const { Button, Icon, Label, Stack, Slider, CenterBox, Box } = Widget; +const { execAsync, lookUpIcon, readFileAsync } = Utils; + +import Separator from '../misc/separator.ts'; +import CursorBox from '../misc/cursorbox.ts'; + +const ICON_SIZE = 32; + +const icons = { + mpris: { + fallback: 'audio-x-generic-symbolic', + shuffle: { + enabled: '', + disabled: '', + }, + loop: { + none: '', + track: '', + playlist: '', + }, + playing: ' ', + paused: ' ', + stopped: ' ', + prev: '', + next: '', + }, +}; + +// Types +import { MprisPlayer } from 'types/service/mpris.ts'; +import { Variable as Var } from 'types/variable'; + +import { + AgsWidget, + CenterBoxPropsGeneric, + Colors, + PlayerBox, + PlayerButtonType, + PlayerDrag, + PlayerOverlay, +} from 'global-types'; + + +export const CoverArt = ( + player: MprisPlayer, + colors: Var<Colors>, + props: CenterBoxPropsGeneric, +) => CenterBox({ + ...props, + vertical: true, + + attribute: { + bgStyle: '', + player, + }, + + setup: (self: PlayerBox) => { + // Give temp cover art + readFileAsync(player.cover_path).catch(() => { + if (!colors.value && !player.track_cover_url) { + colors.setValue({ + imageAccent: '#6b4fa2', + buttonAccent: '#ecdcff', + buttonText: '#25005a', + hoverAccent: '#d4baff', + }); + + self.attribute.bgStyle = ` + background: radial-gradient(circle, + rgba(0, 0, 0, 0.4) 30%, + ${(colors as Var<Colors>).value.imageAccent}), + rgb(0, 0, 0); + background-size: cover; + background-position: center; + `; + self.setCss(self.attribute.bgStyle); + } + }); + + self.hook(player, () => { + execAsync(['bash', '-c', `[[ -f "${player.cover_path}" ]] && + coloryou "${player.cover_path}" | grep -v Warning`]) + .then((out) => { + if (!Mpris.players.find((p) => player === p)) { + return; + } + + colors.setValue(JSON.parse(out)); + + self.attribute.bgStyle = ` + background: radial-gradient(circle, + rgba(0, 0, 0, 0.4) 30%, + ${colors.value.imageAccent}), + url("${player.cover_path}"); + background-size: cover; + background-position: center; + `; + + if (!(self.get_parent() as PlayerDrag) + .attribute.dragging) { + self.setCss(self.attribute.bgStyle); + } + }).catch((err) => { + if (err !== '') { + print(err); + } + }); + }); + }, +}); + +export const TitleLabel = (player: MprisPlayer) => Label({ + xalign: 0, + max_width_chars: 40, + truncate: 'end', + justification: 'left', + class_name: 'title', + label: player.bind('track_title'), +}); + +export const ArtistLabel = (player: MprisPlayer) => Label({ + xalign: 0, + max_width_chars: 40, + truncate: 'end', + justification: 'left', + class_name: 'artist', + label: player.bind('track_artists') + .transform((a) => a.join(', ') || ''), +}); + + +export const PlayerIcon = (player: MprisPlayer, overlay: PlayerOverlay) => { + const playerIcon = ( + p: MprisPlayer, + widget?: PlayerOverlay, + playerBox?: PlayerBox, + ) => CursorBox({ + tooltip_text: p.identity || '', + + on_primary_click_release: () => { + if (widget && playerBox) { + widget.attribute.moveToTop(playerBox); + } + }, + + child: Icon({ + class_name: widget ? 'position-indicator' : 'player-icon', + size: widget ? 0 : ICON_SIZE, + + setup: (self) => { + self.hook(p, () => { + self.icon = lookUpIcon(p.entry) ? + p.entry : + icons.mpris.fallback; + }); + }, + }), + }); + + return Box().hook(Mpris, (self) => { + const grandPa = self.get_parent()?.get_parent() as AgsWidget; + + if (!grandPa) { + return; + } + + const thisIndex = overlay.overlays + .indexOf(grandPa); + + self.children = (overlay.overlays as PlayerBox[]) + .map((playerBox, i) => { + self.children.push(Separator(2)); + + return i === thisIndex ? + playerIcon(player) : + playerIcon(playerBox.attribute.player, overlay, playerBox); + }) + .reverse(); + }); +}; + +const { Gdk } = imports.gi; +const display = Gdk.Display.get_default(); + +export const PositionSlider = ( + player: MprisPlayer, + colors: Var<Colors>, +) => Slider({ + class_name: 'position-slider', + vpack: 'center', + hexpand: true, + draw_value: false, + + on_change: ({ value }) => { + player.position = player.length * value; + }, + + setup: (self) => { + const update = () => { + if (!self.dragging) { + self.visible = player.length > 0; + if (player.length > 0) { + self.value = player.position / player.length; + } + } + }; + + self + .poll(1000, () => update()) + .hook(player, () => update(), 'position') + .hook(colors, () => { + if (colors.value) { + const c = colors.value; + + self.setCss(` + highlight { background-color: ${c.buttonAccent}; } + slider { background-color: ${c.buttonAccent}; } + slider:hover { background-color: ${c.hoverAccent}; } + trough { background-color: ${c.buttonText}; } + `); + } + }) + + // OnClick + .on('button-press-event', () => { + if (!display) { + return; + } + self.window.set_cursor(Gdk.Cursor.new_from_name( + display, + 'grabbing', + )); + }) + + // OnRelease + .on('button-release-event', () => { + if (!display) { + return; + } + self.window.set_cursor(Gdk.Cursor.new_from_name( + display, + 'pointer', + )); + }) + + // OnHover + .on('enter-notify-event', () => { + if (!display) { + return; + } + self.window.set_cursor(Gdk.Cursor.new_from_name( + display, + 'pointer', + )); + self.toggleClassName('hover', true); + }) + + // OnHoverLost + .on('leave-notify-event', () => { + self.window.set_cursor(null); + self.toggleClassName('hover', false); + }); + }, +}); + +const PlayerButton = ({ + player, + colors, + children = {}, + onClick, + prop, +}: PlayerButtonType) => CursorBox({ + child: Button({ + attribute: { hovered: false }, + child: Stack({ children }), + + on_primary_click_release: () => player[onClick](), + + on_hover: (self) => { + self.attribute.hovered = true; + + if (prop === 'playBackStatus' && colors.value) { + const c = colors.value; + + Object.values(children).forEach((ch: AgsWidget) => { + ch.setCss(` + background-color: ${c.hoverAccent}; + color: ${c.buttonText}; + min-height: 40px; + min-width: 36px; + margin-bottom: 1px; + margin-right: 1px; + `); + }); + } + }, + + on_hover_lost: (self) => { + self.attribute.hovered = false; + if (prop === 'playBackStatus' && colors.value) { + const c = colors.value; + + Object.values(children).forEach((ch: AgsWidget) => { + ch.setCss(` + background-color: ${c.buttonAccent}; + color: ${c.buttonText}; + min-height: 42px; + min-width: 38px; + `); + }); + } + }, + + setup: (self) => { + self + .hook(player, () => { + self.child.shown = `${player[prop]}`; + }) + .hook(colors, () => { + if (!Mpris.players.find((p) => player === p)) { + return; + } + + if (colors.value) { + const c = colors.value; + + if (prop === 'playBackStatus') { + if (self.attribute.hovered) { + Object.values(children) + .forEach((ch: AgsWidget) => { + ch.setCss(` + background-color: ${c.hoverAccent}; + color: ${c.buttonText}; + min-height: 40px; + min-width: 36px; + margin-bottom: 1px; + margin-right: 1px; + `); + }); + } + else { + Object.values(children) + .forEach((ch: AgsWidget) => { + ch.setCss(` + background-color: ${c.buttonAccent}; + color: ${c.buttonText}; + min-height: 42px; + min-width: 38px; + `); + }); + } + } + else { + self.setCss(` + * { color: ${c.buttonAccent}; } + *:hover { color: ${c.hoverAccent}; } + `); + } + } + }); + }, + }), +}); + +export const ShuffleButton = ( + player: MprisPlayer, + colors: Var<Colors>, +) => PlayerButton({ + player, + colors, + children: { + true: Label({ + class_name: 'shuffle enabled', + label: icons.mpris.shuffle.enabled, + }), + false: Label({ + class_name: 'shuffle disabled', + label: icons.mpris.shuffle.disabled, + }), + }, + onClick: 'shuffle', + prop: 'shuffleStatus', +}); + +export const LoopButton = ( + player: MprisPlayer, + colors: Var<Colors>, +) => PlayerButton({ + player, + colors, + children: { + None: Label({ + class_name: 'loop none', + label: icons.mpris.loop.none, + }), + Track: Label({ + class_name: 'loop track', + label: icons.mpris.loop.track, + }), + Playlist: Label({ + class_name: 'loop playlist', + label: icons.mpris.loop.playlist, + }), + }, + onClick: 'loop', + prop: 'loopStatus', +}); + +export const PlayPauseButton = ( + player: MprisPlayer, + colors: Var<Colors>, +) => PlayerButton({ + player, + colors, + children: { + Playing: Label({ + class_name: 'pausebutton playing', + label: icons.mpris.playing, + }), + Paused: Label({ + class_name: 'pausebutton paused', + label: icons.mpris.paused, + }), + Stopped: Label({ + class_name: 'pausebutton stopped paused', + label: icons.mpris.stopped, + }), + }, + onClick: 'playPause', + prop: 'playBackStatus', +}); + +export const PreviousButton = ( + player: MprisPlayer, + colors: Var<Colors>, +) => PlayerButton({ + player, + colors, + children: { + true: Label({ + class_name: 'previous', + label: icons.mpris.prev, + }), + false: Label({ + class_name: 'previous', + label: icons.mpris.prev, + }), + }, + onClick: 'previous', + prop: 'canGoPrev', +}); + +export const NextButton = ( + player: MprisPlayer, + colors: Var<Colors>, +) => PlayerButton({ + player, + colors, + children: { + true: Label({ + class_name: 'next', + label: icons.mpris.next, + }), + false: Label({ + class_name: 'next', + label: icons.mpris.next, + }), + }, + onClick: 'next', + prop: 'canGoNext', +}); diff --git a/modules/ags/config/ts/media-player/player.ts b/modules/ags/config/ts/media-player/player.ts new file mode 100644 index 00000000..500f44e7 --- /dev/null +++ b/modules/ags/config/ts/media-player/player.ts @@ -0,0 +1,201 @@ +const Mpris = await Service.import('mpris'); + +const { Box, CenterBox } = Widget; + +import * as mpris from './mpris.ts'; +import PlayerGesture from './gesture.ts'; +import Separator from '../misc/separator.ts'; + +const FAVE_PLAYER = 'org.mpris.MediaPlayer2.spotify'; +const SPACING = 8; + +// Types +import { MprisPlayer } from 'types/service/mpris.ts'; +import { Variable as Var } from 'types/variable'; +import { Colors, PlayerBox, PlayerOverlay } from 'global-types'; + + +const Top = ( + player: MprisPlayer, + overlay: PlayerOverlay, +) => Box({ + class_name: 'top', + hpack: 'start', + vpack: 'start', + + children: [ + mpris.PlayerIcon(player, overlay), + ], +}); + +const Center = ( + player: MprisPlayer, + colors: Var<Colors>, +) => Box({ + class_name: 'center', + + children: [ + CenterBox({ + vertical: true, + + start_widget: Box({ + class_name: 'metadata', + vertical: true, + hpack: 'start', + vpack: 'center', + hexpand: true, + + children: [ + mpris.TitleLabel(player), + mpris.ArtistLabel(player), + ], + }), + }), + + CenterBox({ + vertical: true, + + center_widget: mpris.PlayPauseButton(player, colors), + }), + + ], +}); + +const Bottom = ( + player: MprisPlayer, + colors: Var<Colors>, +) => Box({ + class_name: 'bottom', + + children: [ + mpris.PreviousButton(player, colors), + Separator(SPACING), + + mpris.PositionSlider(player, colors), + Separator(SPACING), + + mpris.NextButton(player, colors), + Separator(SPACING), + + mpris.ShuffleButton(player, colors), + Separator(SPACING), + + mpris.LoopButton(player, colors), + ], +}); + +const PlayerBox = ( + player: MprisPlayer, + colors: Var<Colors>, + overlay: PlayerOverlay, +) => { + const widget = mpris.CoverArt(player, colors, { + class_name: `player ${player.name}`, + 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: PlayerOverlay) => { + self + .hook(Mpris, (_, bus_name) => { + const players = self.attribute.players; + + if (players.has(bus_name)) { + return; + } + + // Sometimes the signal doesn't give the bus_name + if (!bus_name) { + const player = Mpris.players.find((p) => { + return !players.has(p.bus_name); + }); + + if (player) { + bus_name = player.bus_name; + } + else { + return; + } + } + + // Get the one on top so we can move it up later + const previousFirst = self.overlays.at(-1) as PlayerBox; + + // Make the new player + const player = Mpris.getPlayer(bus_name); + const colorsVar = Variable({ + imageAccent: '#6b4fa2', + buttonAccent: '#ecdcff', + buttonText: '#25005a', + hoverAccent: '#d4baff', + }); + + if (!player) { + return; + } + + players.set( + bus_name, + PlayerBox(player, colorsVar, self), + ); + self.overlays = Array.from(players.values()) + .map((widget) => widget) as PlayerBox[]; + + const includes = self.attribute + .includesWidget(previousFirst); + + // Select favorite player at startup + const attrs = self.attribute; + + if (!attrs.setup && players.has(FAVE_PLAYER)) { + attrs.moveToTop(players.get(FAVE_PLAYER)); + attrs.setup = true; + } + + // Move previousFirst on top again + else if (includes) { + attrs.moveToTop(previousFirst); + } + }, 'player-added') + + .hook(Mpris, (_, bus_name) => { + const players = self.attribute.players; + + if (!bus_name || !players.has(bus_name)) { + return; + } + + // Get the one on top so we can move it up later + const previousFirst = self.overlays.at(-1) as PlayerBox; + + // Remake overlays without deleted one + players.delete(bus_name); + self.overlays = Array.from(players.values()) + .map((widget) => widget) as PlayerBox[]; + + // Move previousFirst on top again + const includes = self.attribute + .includesWidget(previousFirst); + + if (includes) { + self.attribute.moveToTop(previousFirst); + } + }, 'player-closed'); + }, + }); + + return Box({ + class_name: 'media', + child: content, + }); +}; diff --git a/modules/ags/config/ts/misc/audio-icons.ts b/modules/ags/config/ts/misc/audio-icons.ts new file mode 100644 index 00000000..fbbd7e05 --- /dev/null +++ b/modules/ags/config/ts/misc/audio-icons.ts @@ -0,0 +1,57 @@ +const Audio = await Service.import('audio'); + +const speakerIcons = { + 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 micIcons = { + 67: 'audio-input-microphone-high-symbolic', + 34: 'audio-input-microphone-medium-symbolic', + 1: 'audio-input-microphone-low-symbolic', + 0: 'audio-input-microphone-muted-symbolic', +}; + + +export const SpeakerIcon = Variable(''); +Audio.connect('speaker-changed', () => { + if (!Audio.speaker) { + return; + } + + if (Audio.speaker.stream?.is_muted) { + SpeakerIcon.setValue(speakerIcons[0]); + } + else { + const vol = Audio.speaker.volume * 100; + + for (const threshold of [-1, 0, 33, 66, 100]) { + if (vol > threshold + 1) { + SpeakerIcon.setValue(speakerIcons[threshold + 1]); + } + } + } +}); + +export const MicIcon = Variable(''); +Audio.connect('microphone-changed', () => { + if (!Audio.microphone) { + return; + } + + if (Audio.microphone.stream?.is_muted) { + MicIcon.setValue(micIcons[0]); + } + else { + const vol = Audio.microphone.volume * 100; + + for (const threshold of [-1, 0, 33, 66]) { + if (vol > threshold + 1) { + MicIcon.setValue(micIcons[threshold + 1]); + } + } + } +}); diff --git a/modules/ags/config/ts/misc/background-fade.ts b/modules/ags/config/ts/misc/background-fade.ts new file mode 100644 index 00000000..a990cdec --- /dev/null +++ b/modules/ags/config/ts/misc/background-fade.ts @@ -0,0 +1,15 @@ +const { Window } = Widget; + + +export default () => Window({ + name: 'bg-gradient', + layer: 'background', + exclusivity: 'ignore', + anchor: ['top', 'bottom', 'left', 'right'], + css: ` + background-image: -gtk-gradient (linear, + left top, left bottom, + from(rgba(0, 0, 0, 0.5)), + to(rgba(0, 0, 0, 0))); + `, +}); diff --git a/modules/ags/config/ts/misc/closer.ts b/modules/ags/config/ts/misc/closer.ts new file mode 100644 index 00000000..a3d7e0ae --- /dev/null +++ b/modules/ags/config/ts/misc/closer.ts @@ -0,0 +1,13 @@ +// Types +import { PopupWindow } from 'global-types'; + + +export default () => { + (App.windows as Array<PopupWindow>) + .filter((w) => w && + w.close_on_unfocus && + w.close_on_unfocus !== 'stay') + .forEach((w) => { + App.closeWindow(w.name); + }); +}; diff --git a/modules/ags/config/ts/misc/cursorbox.ts b/modules/ags/config/ts/misc/cursorbox.ts new file mode 100644 index 00000000..747f2e7c --- /dev/null +++ b/modules/ags/config/ts/misc/cursorbox.ts @@ -0,0 +1,271 @@ +import Gtk from 'gi://Gtk?version=3.0'; +import Gdk from 'gi://Gdk?version=3.0'; + +// Types +import { BaseProps, Widget as AgsWidget } from 'types/widgets/widget'; +type EventHandler<Self> = (self: Self, event: Gdk.Event) => boolean | unknown; + +export type CursorBoxProps< + Child extends Gtk.Widget, + Attr = unknown, + Self = CursorBox<Child, Attr>, +> = BaseProps<Self, Gtk.EventBox.ConstructorProperties & { + child?: Child + on_hover?: EventHandler<Self> + on_hover_lost?: EventHandler<Self> + + on_scroll_up?: EventHandler<Self> + on_scroll_down?: EventHandler<Self> + + on_primary_click?: EventHandler<Self> + on_middle_click?: EventHandler<Self> + on_secondary_click?: EventHandler<Self> + + on_primary_click_release?: EventHandler<Self> + on_middle_click_release?: EventHandler<Self> + on_secondary_click_release?: EventHandler<Self> +}, Attr>; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export interface CursorBox<Child, Attr> extends AgsWidget<Attr> { } + + +export class CursorBox<Child extends Gtk.Widget, Attr> extends Gtk.EventBox { + static { + Widget.register(this, { + properties: { + 'on-clicked': ['jsobject', 'rw'], + + 'on-hover': ['jsobject', 'rw'], + 'on-hover-lost': ['jsobject', 'rw'], + + 'on-scroll-up': ['jsobject', 'rw'], + 'on-scroll-down': ['jsobject', 'rw'], + + 'on-primary-click': ['jsobject', 'rw'], + 'on-secondary-click': ['jsobject', 'rw'], + 'on-middle-click': ['jsobject', 'rw'], + + 'on-primary-click-release': ['jsobject', 'rw'], + 'on-secondary-click-release': ['jsobject', 'rw'], + 'on-middle-click-release': ['jsobject', 'rw'], + }, + }); + } + + constructor(props: CursorBoxProps<Child, Attr> = {}) { + super(props as Gtk.EventBox.ConstructorProperties); + this.add_events(Gdk.EventMask.SCROLL_MASK); + this.add_events(Gdk.EventMask.SMOOTH_SCROLL_MASK); + + // Gesture stuff + const gesture = Gtk.GestureLongPress.new(this); + + this.hook(gesture, () => { + const pointer = gesture.get_point(null); + const x = pointer[1]; + const y = pointer[2]; + + if ((!x || !y) || (x === 0 && y === 0)) { + return; + } + + this.#canRun.setValue(!( + x > this.get_allocated_width() || + y > this.get_allocated_height() + )); + }, 'end'); + + this.connect('enter-notify-event', (_, event: Gdk.Event) => { + this.set_state_flags(Gtk.StateFlags.PRELIGHT, false); + + if (!this.#display) { + return; + } + this.window.set_cursor(Gdk.Cursor.new_from_name( + this.#display, + this.#disabled.value ? + 'not-allowed' : + 'pointer', + )); + + return this.on_hover?.(this, event); + }); + + this.connect('leave-notify-event', (_, event: Gdk.Event) => { + this.unset_state_flags(Gtk.StateFlags.PRELIGHT); + + this.window.set_cursor(null); + + return this.on_hover_lost?.(this, event); + }); + + this.connect('button-press-event', (_, event: Gdk.Event) => { + this.set_state_flags(Gtk.StateFlags.ACTIVE, false); + if (this.#disabled.value) { + return; + } + + if (event.get_button()[1] === Gdk.BUTTON_PRIMARY) { + return this.on_primary_click?.(this, event); + } + + else if (event.get_button()[1] === Gdk.BUTTON_MIDDLE) { + return this.on_middle_click?.(this, event); + } + + else if (event.get_button()[1] === Gdk.BUTTON_SECONDARY) { + return this.on_secondary_click?.(this, event); + } + }); + + this.connect('button-release-event', (_, event: Gdk.Event) => { + this.unset_state_flags(Gtk.StateFlags.ACTIVE); + if (this.#disabled.value) { + return; + } + + if (event.get_button()[1] === Gdk.BUTTON_PRIMARY) { + // Every click, do a one shot connect to + // CanRun to wait for location of click + const id = this.#canRun.connect('changed', () => { + if (this.#canRun.value) { + this.on_primary_click_release?.(this, event); + } + + this.#canRun.disconnect(id); + }); + } + + else if (event.get_button()[1] === Gdk.BUTTON_MIDDLE) { + return this.on_middle_click_release?.(this, event); + } + + else if (event.get_button()[1] === Gdk.BUTTON_SECONDARY) { + return this.on_secondary_click_release?.(this, event); + } + }); + + this.connect('scroll-event', (_, event: Gdk.Event) => { + if (event.get_scroll_deltas()[2] < 0) { + return this.on_scroll_up?.(this, event); + } + + else if (event.get_scroll_deltas()[2] > 0) { + return this.on_scroll_down?.(this, event); + } + }); + + this.hook(this.#disabled, () => { + this.toggleClassName('disabled', this.#disabled.value); + }); + } + + #display = Gdk.Display.get_default(); + + // Make this variable to know if the function should + // be executed depending on where the click is released + #canRun = Variable(true); + #disabled = Variable(false); + + get disabled() { + return this.#disabled.value; + } + + set disabled(value: boolean) { + this.#disabled.setValue(value); + } + + get child() { + return super.child as Child; + } + + set child(child: Child) { + super.child = child; + } + + + get on_hover() { + return this._get('on-hover'); + } + + set on_hover(callback: EventHandler<this>) { + this._set('on-hover', callback); + } + + get on_hover_lost() { + return this._get('on-hover-lost'); + } + + set on_hover_lost(callback: EventHandler<this>) { + this._set('on-hover-lost', callback); + } + + get on_scroll_up() { + return this._get('on-scroll-up'); + } + + set on_scroll_up(callback: EventHandler<this>) { + this._set('on-scroll-up', callback); + } + + get on_scroll_down() { + return this._get('on-scroll-down'); + } + + set on_scroll_down(callback: EventHandler<this>) { + this._set('on-scroll-down', callback); + } + + get on_primary_click() { + return this._get('on-primary-click'); + } + + set on_primary_click(callback: EventHandler<this>) { + this._set('on-primary-click', callback); + } + + get on_middle_click() { + return this._get('on-middle-click'); + } + + set on_middle_click(callback: EventHandler<this>) { + this._set('on-middle-click', callback); + } + + get on_secondary_click() { + return this._get('on-secondary-click'); + } + + set on_secondary_click(callback: EventHandler<this>) { + this._set('on-secondary-click', callback); + } + + get on_primary_click_release() { + return this._get('on-primary-click-release'); + } + + set on_primary_click_release(callback: EventHandler<this>) { + this._set('on-primary-click-release', callback); + } + + get on_middle_click_release() { + return this._get('on-middle-click-release'); + } + + set on_middle_click_release(callback: EventHandler<this>) { + this._set('on-middle-click-release', callback); + } + + get on_secondary_click_release() { + return this._get('on-secondary-click-release'); + } + + set on_secondary_click_release(callback: EventHandler<this>) { + this._set('on-secondary-click-release', callback); + } +} + +export default <Child extends Gtk.Widget, Attr>( + props?: CursorBoxProps<Child, Attr>, +) => new CursorBox(props ?? {}); diff --git a/modules/ags/config/widgets/misc/persist.ts b/modules/ags/config/ts/misc/persist.ts similarity index 59% rename from modules/ags/config/widgets/misc/persist.ts rename to modules/ags/config/ts/misc/persist.ts index dd22f703..b6d7267a 100644 --- a/modules/ags/config/widgets/misc/persist.ts +++ b/modules/ags/config/ts/misc/persist.ts @@ -1,28 +1,35 @@ -import { execAsync, readFileAsync, timeout, GLib, type Variable } from 'astal'; +const { execAsync, readFileAsync, timeout } = Utils; +const { get_home_dir } = imports.gi.GLib; -const { get_home_dir } = GLib; +import GObject from 'types/@girs/gobject-2.0/gobject-2.0'; + +type Persist = { + name: string + gobject: GObject.Object + prop: string + condition?: boolean | string // If string, compare following props to this + whenTrue?: boolean | string + whenFalse?: boolean | string + signal?: string +}; -export default <T>({ +export default ({ name, - variable, + gobject, + prop, condition = true, whenTrue = condition, whenFalse = false, -}: { - name: string - variable: Variable<T> - condition?: boolean | string - whenTrue?: boolean | string - whenFalse?: boolean | string -}) => { + signal = 'changed', +}: Persist) => { const cacheFile = `${get_home_dir()}/.cache/ags/.${name}`; const stateCmd = () => ['bash', '-c', - `echo ${variable.get() === condition} > ${cacheFile}`]; + `echo ${gobject[prop] === condition} > ${cacheFile}`]; const monitorState = () => { - variable.subscribe(() => { + gobject.connect(signal, () => { execAsync(stateCmd()).catch(print); }); }; @@ -31,9 +38,7 @@ export default <T>({ .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); + gobject[prop] = JSON.parse(content) ? whenTrue : whenFalse; timeout(1000, () => { monitorState(); diff --git a/modules/ags/config/ts/misc/popup.ts b/modules/ags/config/ts/misc/popup.ts new file mode 100644 index 00000000..f29772c1 --- /dev/null +++ b/modules/ags/config/ts/misc/popup.ts @@ -0,0 +1,158 @@ +import Gtk from 'gi://Gtk?version=3.0'; +const Hyprland = await Service.import('hyprland'); + +const { Box, register } = Widget; +const { timeout } = Utils; + +// Types +import { Window } from 'resource:///com/github/Aylur/ags/widgets/window.js'; +import { Variable as Var } from 'types/variable'; + +import { + CloseType, + HyprTransition, + PopupWindowProps, +} from 'global-types'; + + +export class PopupWindow< + Child extends Gtk.Widget, + Attr, +> extends Window<Child, Attr> { + static { + register(this, { + properties: { + content: ['widget', 'rw'], + }, + }); + } + + #content: Var<Gtk.Widget>; + #close_on_unfocus: CloseType; + #transition: HyprTransition; + + get content() { + return this.#content.value; + } + + set content(value: Gtk.Widget) { + this.#content.setValue(value); + this.child.show_all(); + } + + get close_on_unfocus() { + return this.#close_on_unfocus; + } + + set close_on_unfocus(value: CloseType) { + this.#close_on_unfocus = value; + } + + get transition() { + return this.#transition; + } + + set transition(t: HyprTransition) { + this.#transition = t; + Hyprland.messageAsync(`keyword layerrule animation ${t}, ${this.name}`); + } + + constructor({ + transition = 'slide top', + transition_duration = 800, + on_open = () => {/**/}, + on_close = () => {/**/}, + + // Window props + name, + visible = false, + anchor = [], + layer = 'overlay', + attribute, + content = Box(), + blur = false, + close_on_unfocus = 'released', + ...rest + }: PopupWindowProps<Child, Attr>) { + const contentVar = Variable(Box() as Gtk.Widget); + + if (content) { + contentVar.setValue(content); + } + + super({ + ...rest, + name: `win-${name}`, + visible, + anchor, + layer, + attribute, + setup: () => { + const id = App.connect('config-parsed', () => { + // Add way to make window open on startup + if (visible) { + App.openWindow(`win-${name}`); + } + + // This connection should always run only once + App.disconnect(id); + }); + + if (blur) { + Hyprland.messageAsync('[[BATCH]] ' + + `keyword layerrule ignorealpha 0.97, win-${name}; ` + + `keyword layerrule blur, win-${name}`); + } + + Hyprland.messageAsync( + `keyword layerrule animation ${transition}, win-${name}`, + ); + }, + child: contentVar.bind(), + }); + + this.hook(App, (_, currentName, isOpen) => { + if (currentName === `win-${name}`) { + if (isOpen) { + on_open(this); + } + else { + timeout(Number(transition_duration), () => { + on_close(this); + }); + } + } + }); + + this.#content = contentVar; + this.#close_on_unfocus = close_on_unfocus; + this.#transition = transition; + } + + set_x_pos( + alloc: Gtk.Allocation, + side = 'right' as 'left' | 'right', + ) { + const width = this.get_display() + .get_monitor_at_point(alloc.x, alloc.y) + .get_geometry().width; + + this.margins = [ + this.margins[0], + + side === 'right' ? + (width - alloc.x - alloc.width) : + this.margins[1], + + this.margins[2], + + side === 'right' ? + this.margins[3] : + (alloc.x - alloc.width), + ]; + } +} + +export default <Child extends Gtk.Widget, Attr>( + props: PopupWindowProps<Child, Attr>, +) => new PopupWindow(props); diff --git a/modules/ags/config/ts/misc/separator.ts b/modules/ags/config/ts/misc/separator.ts new file mode 100644 index 00000000..cbdba272 --- /dev/null +++ b/modules/ags/config/ts/misc/separator.ts @@ -0,0 +1,13 @@ +const { Box } = Widget; + + +export default (size: number, { + vertical = false, + css = '', + ...props +} = {}) => { + return Box({ + css: `${vertical ? 'min-height' : 'min-width'}: ${size}px; ${css}`, + ...props, + }); +}; diff --git a/modules/ags/config/ts/notifications/base.ts b/modules/ags/config/ts/notifications/base.ts new file mode 100644 index 00000000..306590ea --- /dev/null +++ b/modules/ags/config/ts/notifications/base.ts @@ -0,0 +1,289 @@ +const Applications = await Service.import('applications'); +const Hyprland = await Service.import('hyprland'); +const Notifications = await Service.import('notifications'); + +const { Box, Icon, Label, Button } = Widget; +const { lookUpIcon } = Utils; + +const { GLib } = imports.gi; + +import Gesture from './gesture.ts'; +import CursorBox from '../misc/cursorbox.ts'; + +// Types +import { Notification as NotifObj } from 'types/service/notifications.ts'; +import { Client } from 'types/service/hyprland.ts'; +type NotificationWidget = { + notif: NotifObj + slideIn?: 'Left' | 'Right' + command?(): void +}; +import { + CursorBox as CBox, + EventBoxGeneric, + NotifGesture, +} from 'global-types'; + + +// Set Notifications settings +Notifications.popupTimeout = 5000; +Notifications.cacheActions = true; + +const setTime = (time: number) => { + return GLib.DateTime + .new_from_unix_local(time) + .format('%H:%M'); +}; + +const getDragState = (box: EventBoxGeneric) => (box + .get_parent() + ?.get_parent() + ?.get_parent() + ?.get_parent() + ?.get_parent() as NotifGesture) + ?.attribute.dragging; + + +const NotificationIcon = (notif: NotifObj) => { + let iconCmd = (box: CBox):void => { + if (!box) { + console.log(); + } + }; + + if (notif.app_entry && Applications.query(notif.app_entry).length > 0) { + const app = Applications.query(notif.app_entry)[0]; + + let wmClass = app.app.get_string('StartupWMClass'); + + if (app.app?.get_filename()?.includes('discord')) { + wmClass = 'discord'; + } + + if (wmClass != null) { + iconCmd = (box) => { + if (!getDragState(box)) { + if (wmClass === 'thunderbird') { + Hyprland.messageAsync('dispatch ' + + 'togglespecialworkspace thunder'); + } + else if (wmClass === 'Spotify') { + Hyprland.messageAsync('dispatch ' + + 'togglespecialworkspace spot'); + } + else { + Hyprland.messageAsync('j/clients').then((msg) => { + const clients = JSON.parse(msg) as Array<Client>; + const classes = [] as Array<string>; + + for (const key of clients) { + if (key.class) { + classes.push(key.class); + } + } + + if (wmClass && classes.includes(wmClass)) { + Hyprland.messageAsync('dispatch ' + + `focuswindow ^(${wmClass})`); + } + else { + Hyprland.messageAsync('dispatch workspace empty') + .then(() => { + app.launch(); + }); + } + }); + } + + globalThis.closeAll(); + } + }; + } + } + + if (notif.image) { + return CursorBox({ + on_primary_click_release: (self) => { + iconCmd(self); + }, + + child: Box({ + vpack: 'start', + hexpand: false, + class_name: 'icon img', + css: ` + background-image: url("${notif.image}"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + min-width: 78px; + min-height: 78px; + `, + }), + }); + } + + let icon = 'dialog-information-symbolic'; + + if (lookUpIcon(notif.app_icon)) { + icon = notif.app_icon; + } + + + if (notif.app_entry && lookUpIcon(notif.app_entry)) { + icon = notif.app_entry; + } + + + return CursorBox({ + on_primary_click_release: (self) => { + iconCmd(self); + }, + + child: Box({ + vpack: 'start', + hexpand: false, + class_name: 'icon', + css: ` + min-width: 78px; + min-height: 78px; + `, + children: [Icon({ + icon, + size: 58, + hpack: 'center', + hexpand: true, + vpack: 'center', + vexpand: true, + })], + }), + }); +}; + +// Make a variable to connect to for Widgets +// to know when there are notifs or not +export const HasNotifs = Variable(false); + +export const Notification = ({ + notif, + slideIn = 'Left', + command = () => {/**/}, +}: NotificationWidget) => { + if (!notif) { + return; + } + + const BlockedApps = [ + 'Spotify', + 'OpenRazer', + ]; + + if (BlockedApps.find((app) => app === notif.app_name)) { + notif.close(); + + return; + } + + HasNotifs.setValue(Notifications.notifications.length > 0); + + // Init notif + const notifWidget = Gesture({ + command, + slideIn, + id: notif.id, + }); + + // Add body to notif + (notifWidget.child as EventBoxGeneric).add(Box({ + class_name: `notification ${notif.urgency}`, + vexpand: false, + + // Notification + child: Box({ + vertical: true, + children: [ + + // Content + Box({ + children: [ + NotificationIcon(notif), + + Box({ + hexpand: true, + vertical: true, + children: [ + + // Top of Content + Box({ + children: [ + + // Title + Label({ + class_name: 'title', + xalign: 0, + justification: 'left', + hexpand: true, + max_width_chars: 24, + truncate: 'end', + wrap: true, + label: notif.summary, + use_markup: notif.summary + .startsWith('<'), + }), + + // Time + Label({ + class_name: 'time', + vpack: 'start', + label: setTime(notif.time), + }), + + // Close button + CursorBox({ + child: Button({ + class_name: 'close-button', + vpack: 'start', + + on_primary_click_release: () => + notif.close(), + + child: Icon('window-close' + + '-symbolic'), + }), + }), + ], + }), + + // Description + Label({ + class_name: 'description', + hexpand: true, + use_markup: true, + xalign: 0, + justification: 'left', + label: notif.body, + wrap: true, + }), + ], + }), + ], + }), + + // Actions + Box({ + class_name: 'actions', + children: notif.actions.map((action) => Button({ + class_name: 'action-button', + hexpand: true, + + on_primary_click_release: () => notif.invoke(action.id), + + child: Label(action.label), + })), + }), + ], + }), + })); + + return notifWidget; +}; diff --git a/modules/ags/config/ts/notifications/binto.ts b/modules/ags/config/ts/notifications/binto.ts new file mode 100644 index 00000000..975b30be --- /dev/null +++ b/modules/ags/config/ts/notifications/binto.ts @@ -0,0 +1,26 @@ +const { Window } = Widget; + +import NotifCenterWidget from './center.ts'; +import PopUpsWidget from './popup.ts'; + +import PopupWindow from '../misc/popup.ts'; + + +export const NotifPopups = () => Window({ + name: 'notifications', + anchor: ['bottom', 'left'], + layer: 'overlay', + monitor: 1, + + child: PopUpsWidget(), +}); + + +export const NotifCenter = () => PopupWindow({ + name: 'notification-center', + anchor: ['bottom', 'right'], + transition: 'slide bottom', + monitor: 1, + + content: NotifCenterWidget(), +}); diff --git a/modules/ags/config/ts/notifications/center.ts b/modules/ags/config/ts/notifications/center.ts new file mode 100644 index 00000000..73b25d1b --- /dev/null +++ b/modules/ags/config/ts/notifications/center.ts @@ -0,0 +1,167 @@ +const Notifications = await Service.import('notifications'); + +const { Label, Box, Icon, Scrollable, Revealer } = Widget; +const { timeout } = Utils; + +import { Notification, HasNotifs } from './base.ts'; +import CursorBox from '../misc/cursorbox.ts'; + +// Types +import { Notification as NotifObj } from 'resource:///com/github/Aylur/ags/service/notifications.js'; +import { BoxGeneric, NotifGesture } from 'global-types'; + + +const addNotif = (box: BoxGeneric, notif: NotifObj) => { + if (notif) { + const NewNotif = Notification({ + notif, + slideIn: 'Right', + command: () => notif.close(), + }); + + if (NewNotif) { + box.pack_end(NewNotif, false, false, 0); + box.show_all(); + } + } +}; + +const NotificationList = () => Box({ + vertical: true, + vexpand: true, + vpack: 'start', + visible: HasNotifs.bind(), + + setup: (self) => { + const initNotifId = 1337; + const delay = 2000; + + // Fix the no notif placement with a fake notif + Notifications.Notify('', initNotifId, '', '', '', [''], {}, 0); + setTimeout(() => { + Notifications.getNotification(initNotifId)?.close(); + }, delay); + + self + .hook(Notifications, (box, id) => { + // Handle cached notifs + if (box.children.length === 0) { + Notifications.notifications.forEach((n) => { + addNotif(box, n); + }); + } + + else if (id) { + const notifObj = Notifications.getNotification(id); + + if (notifObj) { + addNotif(box, notifObj); + } + } + }, 'notified') + + .hook(Notifications, (box, id) => { + const notif = (box.children as NotifGesture[]) + .find((ch) => ch.attribute.id === id); + + if (notif?.sensitive) { + notif.attribute.slideAway('Right'); + } + }, 'closed'); + }, +}); + +const ClearButton = () => CursorBox({ + class_name: 'clear', + + on_primary_click_release: () => { + Notifications.clear(); + timeout(1000, () => App.closeWindow('win-notification-center')); + }, + + setup: (self) => { + self.hook(HasNotifs, () => { + self.disabled = !HasNotifs.value; + }); + }, + + child: Box({ + + children: [ + Label('Clear '), + + Icon({ + setup: (self) => { + self.hook(Notifications, () => { + self.icon = Notifications.notifications.length > 0 ? + 'user-trash-full-symbolic' : + 'user-trash-symbolic'; + }); + }, + }), + ], + }), +}); + +const Header = () => Box({ + class_name: 'header', + children: [ + Label({ + label: 'Notifications', + hexpand: true, + xalign: 0, + }), + ClearButton(), + ], +}); + +const Placeholder = () => Revealer({ + transition: 'crossfade', + reveal_child: HasNotifs.bind() + .transform((v) => !v), + + child: Box({ + class_name: 'placeholder', + vertical: true, + vpack: 'center', + hpack: 'center', + vexpand: true, + hexpand: true, + + children: [ + Icon('notification-disabled-symbolic'), + Label('Your inbox is empty'), + ], + }), +}); + +export default () => Box({ + class_name: 'notification-center', + vertical: true, + children: [ + Header(), + + Box({ + class_name: 'notification-wallpaper-box', + + children: [ + Scrollable({ + class_name: 'notification-list-box', + hscroll: 'never', + vscroll: 'automatic', + + child: Box({ + class_name: 'notification-list', + vertical: true, + + children: [ + NotificationList(), + + Placeholder(), + ], + }), + }), + ], + }), + ], +}); diff --git a/modules/ags/config/ts/notifications/gesture.ts b/modules/ags/config/ts/notifications/gesture.ts new file mode 100644 index 00000000..f655ab20 --- /dev/null +++ b/modules/ags/config/ts/notifications/gesture.ts @@ -0,0 +1,223 @@ +const Notifications = await Service.import('notifications'); + +const { Box, EventBox } = Widget; +const { timeout } = Utils; + +import { HasNotifs } from './base.ts'; + +const { Gdk, Gtk } = imports.gi; +const display = Gdk.Display.get_default(); + +// Types +import { BoxGeneric } from 'global-types'; + +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 SQUEEZED = 'margin-bottom: -70px; margin-top: -70px;'; +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} + margin-top: 0px; + margin-bottom: 0px; + opacity: 0;`; +const squeezeLeft = `${TRANSITION} ${MAX_LEFT} ${SQUEEZED} opacity: 0;`; + +const slideRight = `${TRANSITION} ${MAX_RIGHT} + margin-top: 0px; + margin-bottom: 0px; + opacity: 0;`; +const squeezeRight = `${TRANSITION} ${MAX_RIGHT} ${SQUEEZED} opacity: 0;`; + +const defaultStyle = `${TRANSITION} margin: unset; opacity: 1;`; + + +export default ({ + id, + slideIn = 'Left', + command = () => {/**/}, + ...props +}) => { + const widget = EventBox({ + ...props, + + setup: (self) => { + self + // OnClick + .on('button-press-event', () => { + if (!display) { + return; + } + self.window.set_cursor(Gdk.Cursor.new_from_name( + display, + 'grabbing', + )); + }) + + // OnRelease + .on('button-release-event', () => { + if (!display) { + return; + } + self.window.set_cursor(Gdk.Cursor.new_from_name( + display, + 'grab', + )); + }) + + // OnHover + .on('enter-notify-event', () => { + if (!display) { + return; + } + self.window.set_cursor(Gdk.Cursor.new_from_name( + display, + 'grab', + )); + self.toggleClassName('hover', true); + if (!self.attribute.hovered) { + self.attribute.hovered = true; + } + }) + + // OnHoverLost + .on('leave-notify-event', () => { + self.window.set_cursor(null); + self.toggleClassName('hover', false); + + if (self.attribute.hovered) { + self.attribute.hovered = false; + } + }); + }, + + attribute: { + dragging: false, + hovered: false, + ready: false, + id, + + slideAway: (side: 'Left' | 'Right') => { + (widget.child as BoxGeneric) + .setCss(side === 'Left' ? slideLeft : slideRight); + + // Make it uninteractable + widget.sensitive = false; + + timeout(ANIM_DURATION - 100, () => { + // Reduce height after sliding away + (widget.child as BoxGeneric)?.setCss(side === 'Left' ? + squeezeLeft : + squeezeRight); + + timeout(ANIM_DURATION, () => { + // Kill notif and update HasNotifs after anim is done + command(); + + HasNotifs.setValue(Notifications + .notifications.length > 0); + + (widget.get_parent() as BoxGeneric)?.remove(widget); + }); + }); + }, + }, + }); + + const gesture = Gtk.GestureDrag.new(widget); + + widget.add(Box({ + css: squeezeLeft, + setup: (self) => { + self + // When dragging + .hook(gesture, () => { + let offset = gesture.get_offset()[1]; + + if (!offset || offset === 0) { + return; + } + + // Slide right + if (offset > 0) { + self.setCss(` + margin-top: 0px; margin-bottom: 0px; + opacity: 1; transition: none; + margin-left: ${offset}px; + margin-right: -${offset}px; + `); + } + + // Slide left + else { + offset = Math.abs(offset); + self.setCss(` + margin-top: 0px; margin-bottom: 0px; + opacity: 1; transition: none; + margin-right: ${offset}px; + margin-left: -${offset}px; + `); + } + + // Put a threshold on if a click is actually dragging + widget.attribute.dragging = + Math.abs(offset) > SLIDE_MIN_THRESHOLD; + + widget.cursor = 'grabbing'; + }, 'drag-update') + + // On drag end + .hook(gesture, () => { + // Make it slide in on init + if (!widget.attribute.ready) { + // Reverse of slideAway, so it started at squeeze, then we go to slide + self.setCss(slideIn === 'Left' ? + slideLeft : + slideRight); + + timeout(ANIM_DURATION, () => { + // Then we go to center + self.setCss(defaultStyle); + timeout(ANIM_DURATION, () => { + widget.attribute.ready = true; + }); + }); + + return; + } + + const offset = gesture.get_offset()[1]; + + if (!offset) { + return; + } + + // If crosses threshold after letting go, slide away + if (Math.abs(offset) > MAX_OFFSET) { + if (offset > 0) { + widget.attribute.slideAway('Right'); + } + else { + widget.attribute.slideAway('Left'); + } + } + else { + self.setCss(defaultStyle); + widget.cursor = 'grab'; + widget.attribute.dragging = false; + } + }, 'drag-end'); + }, + })); + + return widget; +}; diff --git a/modules/ags/config/ts/notifications/popup.ts b/modules/ags/config/ts/notifications/popup.ts new file mode 100644 index 00000000..253cd1d6 --- /dev/null +++ b/modules/ags/config/ts/notifications/popup.ts @@ -0,0 +1,77 @@ +const Notifications = await Service.import('notifications'); + +const { Box } = Widget; +const { interval } = Utils; + +const { GLib } = imports.gi; + +import { Notification } from './base.ts'; + +const DELAY = 2000; + +// Types +import { NotifGesture } from 'global-types'; + + +export default () => Box({ + vertical: true, + // Needed so it occupies space at the start + css: 'padding: 1px;', + + setup: (self) => { + const addPopup = (id: number) => { + if (!id) { + return; + } + + const notif = Notifications.getNotification(id); + + if (notif) { + const NewNotif = Notification({ + notif, + command: () => { + if (notif.popup) { + notif.dismiss(); + } + }, + }); + + if (NewNotif) { + // Use this instead of add to put it at the top + self.pack_end(NewNotif, false, false, 0); + self.show_all(); + } + } + }; + + const handleDismiss = (id: number, force = false) => { + const notif = (self.children as NotifGesture[]) + .find((ch) => ch.attribute.id === id); + + if (!notif) { + return; + } + + // If notif isn't hovered or was closed, slide away + if (!notif.attribute.hovered || force) { + notif.attribute.slideAway('Left'); + } + + // If notif is hovered, delay close + else if (notif.attribute.hovered) { + const intervalId = interval(DELAY, () => { + if (!notif.attribute.hovered && intervalId) { + notif.attribute.slideAway('Left'); + + GLib.source_remove(intervalId); + } + }); + } + }; + + self + .hook(Notifications, (_, id) => addPopup(id), 'notified') + .hook(Notifications, (_, id) => handleDismiss(id), 'dismissed') + .hook(Notifications, (_, id) => handleDismiss(id, true), 'closed'); + }, +}); diff --git a/modules/ags/config/ts/notifications/wim.ts b/modules/ags/config/ts/notifications/wim.ts new file mode 100644 index 00000000..3acc89e5 --- /dev/null +++ b/modules/ags/config/ts/notifications/wim.ts @@ -0,0 +1,25 @@ +const { Window } = Widget; + +import NotifCenterWidget from './center.ts'; +import PopUpsWidget from './popup.ts'; + +import PopupWindow from '../misc/popup.ts'; + + +export const NotifPopups = () => Window({ + name: 'notifications', + layer: 'overlay', + anchor: ['top', 'left'], + child: PopUpsWidget(), +}); + + +const TOP_MARGIN = 6; + +export const NotifCenter = () => PopupWindow({ + name: 'notification-center', + anchor: ['top', 'right'], + margins: [TOP_MARGIN, 0, 0, 0], + + content: NotifCenterWidget(), +}); diff --git a/modules/ags/config/ts/on-screen-keyboard/gesture.ts b/modules/ags/config/ts/on-screen-keyboard/gesture.ts new file mode 100644 index 00000000..e47e8db2 --- /dev/null +++ b/modules/ags/config/ts/on-screen-keyboard/gesture.ts @@ -0,0 +1,164 @@ +const Hyprland = await Service.import('hyprland'); + +const { execAsync, timeout } = Utils; + +const { Gtk } = imports.gi; + +import Tablet from '../../services/tablet.ts'; + +const KEY_N = 249; +const HIDDEN_MARGIN = 340; +const ANIM_DURATION = 700; + +// Types +import { OskWindow } from 'global-types'; + + +const releaseAllKeys = () => { + const keycodes = Array.from(Array(KEY_N).keys()); + + execAsync([ + 'ydotool', 'key', + ...keycodes.map((keycode) => `${keycode}:0`), + ]).catch(print); +}; + +export default (window: OskWindow) => { + const gesture = Gtk.GestureDrag.new(window); + + window.child.setCss(`margin-bottom: -${HIDDEN_MARGIN}px;`); + + let signals = [] as Array<number>; + + window.attribute = { + startY: null, + + setVisible: (state: boolean) => { + if (state) { + window.visible = true; + window.attribute.setSlideDown(); + + window.child.setCss(` + transition: margin-bottom 0.7s + cubic-bezier(0.36, 0, 0.66, -0.56); + margin-bottom: 0px; + `); + } + else { + timeout(ANIM_DURATION + 100 + 100, () => { + if (!Tablet.tabletMode) { + window.visible = false; + } + }); + releaseAllKeys(); + window.attribute.setSlideUp(); + + window.child.setCss(` + transition: margin-bottom 0.7s + cubic-bezier(0.36, 0, 0.66, -0.56); + margin-bottom: -${HIDDEN_MARGIN}px; + `); + } + }, + + killGestureSigs: () => { + signals.forEach((id) => { + gesture.disconnect(id); + }); + signals = []; + window.attribute.startY = null; + }, + + setSlideUp: () => { + window.attribute.killGestureSigs(); + + // Begin drag + signals.push( + gesture.connect('drag-begin', () => { + Hyprland.messageAsync('j/cursorpos').then((out) => { + window.attribute.startY = JSON.parse(out).y; + }); + }), + ); + + // Update drag + signals.push( + gesture.connect('drag-update', () => { + Hyprland.messageAsync('j/cursorpos').then((out) => { + if (!window.attribute.startY) { + return; + } + + const currentY = JSON.parse(out).y; + const offset = window.attribute.startY - currentY; + + if (offset < 0) { + return; + } + + window.child.setCss(` + margin-bottom: ${offset - HIDDEN_MARGIN}px; + `); + }); + }), + ); + + // End drag + signals.push( + gesture.connect('drag-end', () => { + window.child.setCss(` + transition: margin-bottom 0.5s ease-in-out; + margin-bottom: -${HIDDEN_MARGIN}px; + `); + }), + ); + }, + + setSlideDown: () => { + window.attribute.killGestureSigs(); + + // Begin drag + signals.push( + gesture.connect('drag-begin', () => { + Hyprland.messageAsync('j/cursorpos').then((out) => { + window.attribute.startY = JSON.parse(out).y; + }); + }), + ); + + // Update drag + signals.push( + gesture.connect('drag-update', () => { + Hyprland.messageAsync('j/cursorpos').then((out) => { + if (!window.attribute.startY) { + return; + } + + const currentY = JSON.parse(out).y; + const offset = window.attribute.startY - currentY; + + if (offset > 0) { + return; + } + + window.child.setCss(` + margin-bottom: ${offset}px; + `); + }); + }), + ); + + // End drag + signals.push( + gesture.connect('drag-end', () => { + window.child.setCss(` + transition: margin-bottom 0.5s ease-in-out; + margin-bottom: 0px; + `); + }), + ); + }, + }; + + return window; +}; diff --git a/modules/ags/config/widgets/on-screen-keyboard/keyboard-layouts.ts b/modules/ags/config/ts/on-screen-keyboard/keyboard-layouts.ts similarity index 99% rename from modules/ags/config/widgets/on-screen-keyboard/keyboard-layouts.ts rename to modules/ags/config/ts/on-screen-keyboard/keyboard-layouts.ts index c81f5f67..874f00e9 100644 --- a/modules/ags/config/widgets/on-screen-keyboard/keyboard-layouts.ts +++ b/modules/ags/config/ts/on-screen-keyboard/keyboard-layouts.ts @@ -1,4 +1,4 @@ -// keyboard is missing right Ctrl mod https://handwiki.org/wiki/images/4/41/KB_Canadian_Multilingual_Standard.svg +// TODO: right Ctrl https://handwiki.org/wiki/images/4/41/KB_Canadian_Multilingual_Standard.svg export const defaultOskLayout = 'qwerty_custom'; export const oskLayouts = { diff --git a/modules/ags/config/ts/on-screen-keyboard/keyboard.ts b/modules/ags/config/ts/on-screen-keyboard/keyboard.ts new file mode 100644 index 00000000..2cc688de --- /dev/null +++ b/modules/ags/config/ts/on-screen-keyboard/keyboard.ts @@ -0,0 +1,169 @@ +const { Box, CenterBox, Label, ToggleButton } = Widget; + +const { Gdk } = imports.gi; +const display = Gdk.Display.get_default(); + +import Separator from '../misc/separator.ts'; +import RoundedCorner from '../corners/screen-corners.ts'; +import Key from './keys.ts'; + +import { defaultOskLayout, oskLayouts } from './keyboard-layouts.ts'; +const keyboardLayout = defaultOskLayout; +const keyboardJson = oskLayouts[keyboardLayout]; + +const L_KEY_PER_ROW = [8, 7, 6, 6, 6, 4]; // eslint-disable-line +const COLOR = 'rgba(0, 0, 0, 0.3)'; +const SPACING = 4; + +// Types +import { BoxGeneric, OskWindow } from 'global-types'; + + +export default (window: OskWindow) => Box({ + vertical: true, + children: [ + CenterBox({ + hpack: 'center', + + start_widget: RoundedCorner('bottomright', ` + background-color: ${COLOR}; + `), + + center_widget: CenterBox({ + class_name: 'thingy', + css: `background: ${COLOR};`, + + center_widget: Box({ + hpack: 'center', + class_name: 'settings', + + children: [ + ToggleButton({ + class_name: 'button', + active: true, + vpack: 'center', + + setup: (self) => { + self + .on('toggled', () => { + self.toggleClassName( + 'toggled', + self.get_active(), + ); + window.exclusivity = self.get_active() ? + 'exclusive' : + 'normal'; + }) + + // OnHover + .on('enter-notify-event', () => { + if (!display) { + return; + } + self.window.set_cursor( + Gdk.Cursor.new_from_name( + display, + 'pointer', + ), + ); + self.toggleClassName('hover', true); + }) + + // OnHoverLost + .on('leave-notify-event', () => { + self.window.set_cursor(null); + self.toggleClassName('hover', false); + }); + }, + + child: Label('Exclusive'), + }), + ], + }), + }), + + end_widget: RoundedCorner('bottomleft', ` + background-color: ${COLOR}; + `), + }), + + CenterBox({ + css: `background: ${COLOR};`, + class_name: 'osk', + hexpand: true, + + start_widget: Box({ + class_name: 'left-side side', + hpack: 'start', + vertical: true, + + children: keyboardJson.keys.map((row, rowIndex) => { + const keys = [] as BoxGeneric[]; + + row.forEach((key, keyIndex) => { + if (keyIndex < L_KEY_PER_ROW[rowIndex]) { + keys.push(Key(key)); + } + }); + + return Box({ + vertical: true, + + children: [ + Box({ + class_name: 'row', + + children: [ + Separator(SPACING), + + ...keys, + ], + }), + + Separator(SPACING, { vertical: true }), + ], + }); + }), + }), + + center_widget: Box({ + hpack: 'center', + vpack: 'center', + + children: [ + ], + }), + + end_widget: Box({ + class_name: 'right-side side', + hpack: 'end', + vertical: true, + + children: keyboardJson.keys.map((row, rowIndex) => { + const keys = [] as BoxGeneric[]; + + row.forEach((key, keyIndex) => { + if (keyIndex >= L_KEY_PER_ROW[rowIndex]) { + keys.push(Key(key)); + } + }); + + return Box({ + vertical: true, + + children: [ + Box({ + hpack: 'end', + class_name: 'row', + + children: keys, + }), + + Separator(SPACING, { vertical: true }), + ], + }); + }), + }), + }), + ], +}); diff --git a/modules/ags/config/ts/on-screen-keyboard/keys.ts b/modules/ags/config/ts/on-screen-keyboard/keys.ts new file mode 100644 index 00000000..13cc8ef2 --- /dev/null +++ b/modules/ags/config/ts/on-screen-keyboard/keys.ts @@ -0,0 +1,254 @@ +import Brightness from '../../services/brightness.ts'; + +const { Box, EventBox, Label } = Widget; +const { execAsync } = Utils; + +const { Gdk, Gtk } = imports.gi; +const display = Gdk.Display.get_default(); + +import Separator from '../misc/separator.ts'; + +// Keep track of when a non modifier key +// is clicked to release all modifiers +const NormalClick = Variable(false); + +// 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('caps', (_, state) => { + Caps.setValue(state); +}); + +// Assume both shifts are the same for key.labelShift +const LShift = Variable(false); +const RShift = Variable(false); + +const Shift = Variable(false); + +LShift.connect('changed', () => { + Shift.setValue(LShift.value || RShift.value); +}); +RShift.connect('changed', () => { + Shift.setValue(LShift.value || RShift.value); +}); + +const SPACING = 4; +const LSHIFT_CODE = 42; +const LALT_CODE = 56; +const LCTRL_CODE = 29; + +// Types +import { Variable as Var } from 'types/variable.ts'; +type Key = { + keytype: string, + label: string, + labelShift?: string, + labelAltGr?: string, + shape: string, + keycode: number +}; + + +const ModKey = (key: Key) => { + let Mod: Var<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; + } + const label = Label({ + class_name: `mod ${key.label}`, + label: key.label, + }); + + const button = EventBox({ + class_name: 'key', + + on_primary_click_release: () => { + console.log('mod toggled'); + + execAsync(`ydotool key ${key.keycode}:${Mod.value ? 0 : 1}`); + + label.toggleClassName('active', !Mod.value); + Mod.setValue(!Mod.value); + }, + + setup: (self) => { + self + .hook(NormalClick, () => { + Mod.setValue(false); + + label.toggleClassName('active', false); + execAsync(`ydotool key ${key.keycode}:0`); + }) + + // OnHover + .on('enter-notify-event', () => { + if (!display) { + return; + } + self.window.set_cursor(Gdk.Cursor.new_from_name( + display, + 'pointer', + )); + self.toggleClassName('hover', true); + }) + + // OnHoverLost + .on('leave-notify-event', () => { + self.window.set_cursor(null); + self.toggleClassName('hover', false); + }); + }, + child: label, + }); + + return Box({ + children: [ + button, + Separator(SPACING), + ], + }); +}; + +const RegularKey = (key: Key) => { + const widget = EventBox({ + class_name: 'key', + + child: Label({ + class_name: `normal ${key.label}`, + label: key.label, + + setup: (self) => { + self + .hook(Shift, () => { + if (!key.labelShift) { + return; + } + + self.label = Shift.value ? key.labelShift : key.label; + }) + .hook(Caps, () => { + if (key.label === 'Caps') { + self.toggleClassName('active', Caps.value); + + return; + } + + if (!key.labelShift) { + return; + } + + if (key.label.match(/[A-Za-z]/)) { + self.label = Caps.value ? + key.labelShift : + key.label; + } + }) + .hook(AltGr, () => { + if (!key.labelAltGr) { + return; + } + + self.toggleClassName('altgr', AltGr.value); + self.label = AltGr.value ? key.labelAltGr : key.label; + }) + + // OnHover + .on('enter-notify-event', () => { + if (!display) { + return; + } + self.window.set_cursor(Gdk.Cursor.new_from_name( + display, + 'pointer', + )); + self.toggleClassName('hover', true); + }) + + // OnHoverLost + .on('leave-notify-event', () => { + self.window.set_cursor(null); + self.toggleClassName('hover', false); + }); + }, + }), + }); + + const gesture = Gtk.GestureLongPress.new(widget); + + gesture.delay_factor = 1.0; + + // Long press + widget.hook(gesture, () => { + const pointer = gesture.get_point(null); + const x = pointer[1]; + const y = pointer[2]; + + if ((!x || !y) || (x === 0 && y === 0)) { + return; + } + + console.log('Not implemented yet'); + + // TODO: popup menu for accents + }, 'pressed'); + + // OnPrimaryClickRelease + widget.hook(gesture, () => { + const pointer = gesture.get_point(null); + const x = pointer[1]; + const y = pointer[2]; + + if ((!x || !y) || (x === 0 && y === 0)) { + return; + } + + console.log('key clicked'); + + execAsync(`ydotool key ${key.keycode}:1`); + execAsync(`ydotool key ${key.keycode}:0`); + NormalClick.setValue(true); + }, 'cancelled'); + + return Box({ + children: [ + widget, + Separator(SPACING), + ], + }); +}; + +export default (key: Key) => key.keytype === 'normal' ? + RegularKey(key) : + ModKey(key); diff --git a/modules/ags/config/ts/on-screen-keyboard/main.ts b/modules/ags/config/ts/on-screen-keyboard/main.ts new file mode 100644 index 00000000..61449595 --- /dev/null +++ b/modules/ags/config/ts/on-screen-keyboard/main.ts @@ -0,0 +1,32 @@ +const { Window } = Widget; +const { execAsync } = Utils; + +import Tablet from '../../services/tablet.ts'; +import Gesture from './gesture.ts'; +import Keyboard from './keyboard.ts'; + +/* Types */ +import { OskWindow } from 'global-types'; + +// Start ydotool daemon +execAsync('ydotoold').catch(print); + +// Window +export default () => { + const window = Window({ + name: 'osk', + layer: 'overlay', + anchor: ['left', 'bottom', 'right'], + }) + .hook(Tablet, (self: OskWindow, state) => { + self.attribute.setVisible(state); + }, 'osk-toggled') + + .hook(Tablet, () => { + window.visible = !(!Tablet.tabletMode && !Tablet.oskState); + }, 'mode-toggled'); + + window.child = Keyboard(window); + + return Gesture(window); +}; diff --git a/modules/ags/config/ts/osd/ctor.ts b/modules/ags/config/ts/osd/ctor.ts new file mode 100644 index 00000000..8537bdeb --- /dev/null +++ b/modules/ags/config/ts/osd/ctor.ts @@ -0,0 +1,62 @@ +const { Box, Icon, ProgressBar } = Widget; + +const Y_POS = 80; + +// Types +import { ConnectFunc, OSD, OSDStack } from 'global-types'; + + +export default ({ name, icon, info }: OSD) => { + let connectFunc: ConnectFunc; + const status = info.widget ? + info.widget : + ProgressBar({ vpack: 'center' }); + + // Wrapper to get sliding up anim + const osd = Box({ + name, + css: `margin-bottom: ${Y_POS}px;`, + children: [ + // Actual OSD + Box({ + class_name: 'osd', + children: [ + Icon({ + hpack: 'start', + icon, + }), + status, + ], + }), + ], + }); + + // Handle requests to show the OSD + // Different wether it's a bar or static + if (info.logic) { + connectFunc = (self) => new Promise<void>((r) => { + if (info.logic && self) { + info.logic(self); + } + r(); + }).then(() => (osd.get_parent() as OSDStack)?.attribute?.popup(name)) + .catch(console.error); + } + else { + connectFunc = () => (osd.get_parent() as OSDStack) + ?.attribute?.popup(name); + } + + if (info.signal) { + if (typeof info.signal === 'string') { + status.hook(info.mod, connectFunc, info.signal); + } + else { + info.signal.forEach((sig) => { + status.hook(info.mod, connectFunc, sig); + }); + } + } + + return osd; +}; diff --git a/modules/ags/config/ts/osd/main.ts b/modules/ags/config/ts/osd/main.ts new file mode 100644 index 00000000..f584902d --- /dev/null +++ b/modules/ags/config/ts/osd/main.ts @@ -0,0 +1,78 @@ +const { timeout } = Utils; +const { Stack } = Widget; + +import PopupWindow from '../misc/popup.ts'; + +// Types +import { BoxGeneric } from 'global-types'; + +// Import all the OSDs as an array +const OSDList = [] as Array<() => BoxGeneric>; + +import * as Modules from './osds.ts'; +for (const osd in Modules) { + OSDList.push(Modules[osd]); +} // Array + +const HIDE_DELAY = 2000; +const transition_duration = 300; + + +const OSDs = () => { + const stack = Stack({ + transition: 'over_up_down', + transition_duration, + + attribute: { + popup: (osd: string) => { + if (!osd) { + // + } + }, + }, + }); + + // Send reference of stack to all children + stack.children = Object.fromEntries( + OSDList.map((osd) => { + const widget = osd(); + + return [widget.name, widget]; + }), + ); + + stack.show_all(); + + // Delay popup method so it + // doesn't show any OSDs at launch + timeout(1000, () => { + let count = 0; + + stack.attribute.popup = (osd: string) => { + ++count; + stack.shown = osd; + App.openWindow('win-osd'); + + timeout(HIDE_DELAY, () => { + --count; + + if (count === 0) { + App.closeWindow('win-osd'); + } + }); + }; + + globalThis['popup_osd'] = stack.attribute.popup; + }); + + return stack; +}; + +export default () => PopupWindow({ + name: 'osd', + anchor: ['bottom'], + exclusivity: 'ignore', + close_on_unfocus: 'stay', + transition: 'slide bottom', + content: OSDs(), +}); diff --git a/modules/ags/config/ts/osd/osds.ts b/modules/ags/config/ts/osd/osds.ts new file mode 100644 index 00000000..49ec96c7 --- /dev/null +++ b/modules/ags/config/ts/osd/osds.ts @@ -0,0 +1,96 @@ +const Audio = await Service.import('audio'); + +const { Label } = Widget; + +import OSD from './ctor.ts'; + +import Brightness from '../../services/brightness.ts'; +import { SpeakerIcon } from '../misc/audio-icons.ts'; +import { MicIcon } from '../misc/audio-icons.ts'; + +const AUDIO_MAX = 1.5; + + +export const SpeakerOSD = () => OSD({ + name: 'speaker', + icon: SpeakerIcon.bind(), + info: { + mod: Audio.speaker, + signal: ['notify::volume', 'notify::is-muted'], + + logic: (self) => { + if (!Audio.speaker) { + return; + } + + self.value = Audio.speaker ? + Audio.speaker.volume / AUDIO_MAX : + 0; + + self.sensitive = !Audio.speaker.stream?.is_muted; + }, + }, +}); + +export const ScreenBrightnessOSD = () => OSD({ + name: 'screen', + icon: Brightness.bind('screenIcon'), + info: { + mod: Brightness, + signal: 'screen', + + logic: (self) => { + self.value = Brightness.screen; + }, + }, +}); + +export const KbdBrightnessOSD = () => OSD({ + name: 'kbd', + icon: 'keyboard-brightness-symbolic', + info: { + mod: Brightness, + signal: 'kbd', + + logic: (self) => { + if (!self.value) { + self.value = Brightness.kbd / 2; + + return; + } + self.value = Brightness.kbd / 2; + self.sensitive = Brightness.kbd !== 0; + }, + }, +}); + +export const MicOSD = () => OSD({ + name: 'mic', + icon: MicIcon.bind(), + info: { + mod: Audio.microphone, + signal: ['notify::volume', 'notify::is-muted'], + + logic: (self) => { + if (!Audio.microphone) { + return; + } + + self.value = Audio.microphone ? Audio.microphone.volume : 0; + self.sensitive = !Audio.microphone.stream?.is_muted; + }, + }, +}); + +export const CapsLockOSD = () => OSD({ + name: 'caps', + icon: Brightness.bind('capsIcon'), + info: { + mod: Brightness, + signal: 'caps', + widget: Label({ + vpack: 'center', + label: 'Caps Lock', + }), + }, +}); diff --git a/modules/ags/config/ts/powermenu.ts b/modules/ags/config/ts/powermenu.ts new file mode 100644 index 00000000..055c142e --- /dev/null +++ b/modules/ags/config/ts/powermenu.ts @@ -0,0 +1,49 @@ +const Hyprland = await Service.import('hyprland'); + +const { CenterBox, Label } = Widget; +const { execAsync } = Utils; + +import PopupWindow from './misc/popup.ts'; +import CursorBox from './misc/cursorbox.ts'; + + +const PowermenuWidget = () => CenterBox({ + class_name: 'powermenu', + vertical: false, + + start_widget: CursorBox({ + class_name: 'shutdown button', + on_primary_click_release: () => execAsync(['systemctl', 'poweroff']) + .catch(print), + + child: Label({ + label: '襤', + }), + }), + + center_widget: CursorBox({ + class_name: 'reboot button', + on_primary_click_release: () => execAsync(['systemctl', 'reboot']) + .catch(print), + + child: Label({ + label: '勒', + }), + }), + + end_widget: CursorBox({ + class_name: 'logout button', + on_primary_click_release: () => Hyprland.messageAsync('dispatch exit') + .catch(print), + + child: Label({ + label: '', + }), + }), +}); + +export default () => PopupWindow({ + name: 'powermenu', + transition: 'slide bottom', + content: PowermenuWidget(), +}); diff --git a/modules/ags/config/ts/quick-settings/bluetooth.ts b/modules/ags/config/ts/quick-settings/bluetooth.ts new file mode 100644 index 00000000..acedfd8a --- /dev/null +++ b/modules/ags/config/ts/quick-settings/bluetooth.ts @@ -0,0 +1,213 @@ +const Bluetooth = await Service.import('bluetooth'); + +const { Box, Icon, Label, ListBox, Overlay, Revealer, Scrollable } = Widget; + +import CursorBox from '../misc/cursorbox.ts'; + +const SCROLL_THRESH_H = 200; +const SCROLL_THRESH_N = 7; + +// Types +import { ListBoxRow } from 'types/@girs/gtk-3.0/gtk-3.0.cjs'; +import { BluetoothDevice as BTDev } from 'types/service/bluetooth.ts'; +import { DeviceBox, ScrollableGeneric } from 'global-types'; + + +const BluetoothDevice = (dev: BTDev) => Box({ + class_name: 'menu-item', + + attribute: { dev }, + + children: [Revealer({ + reveal_child: true, + transition: 'slide_down', + + child: CursorBox({ + on_primary_click_release: () => dev.setConnection(true), + + child: Box({ + hexpand: true, + + children: [ + Icon({ + icon: dev.bind('icon_name'), + }), + + Label({ + label: dev.bind('name'), + }), + + Icon({ + icon: 'object-select-symbolic', + hexpand: true, + hpack: 'end', + + }).hook(dev, (self) => { + self.setCss(`opacity: ${dev.paired ? + '1' : + '0'}; + `); + }), + ], + }), + }), + })], +}); + +export const BluetoothMenu = () => { + const DevList = new Map(); + + const topArrow = Revealer({ + transition: 'slide_down', + + child: Icon({ + icon: 'down-large-symbolic', + class_name: 'scrolled-indicator', + size: 16, + css: '-gtk-icon-transform: rotate(180deg);', + }), + }); + + const bottomArrow = Revealer({ + transition: 'slide_up', + + child: Icon({ + icon: 'down-large-symbolic', + class_name: 'scrolled-indicator', + size: 16, + }), + }); + + return Overlay({ + pass_through: true, + + overlays: [ + Box({ + vpack: 'start', + hpack: 'center', + css: 'margin-top: 12px', + children: [topArrow], + }), + + Box({ + vpack: 'end', + hpack: 'center', + css: 'margin-bottom: 12px', + children: [bottomArrow], + }), + ], + + child: Box({ + class_name: 'menu', + + child: Scrollable({ + hscroll: 'never', + vscroll: 'never', + + setup: (self) => { + self.on('edge-reached', (_, pos) => { + // Manage scroll indicators + if (pos === 2) { + topArrow.reveal_child = false; + bottomArrow.reveal_child = true; + } + else if (pos === 3) { + topArrow.reveal_child = true; + bottomArrow.reveal_child = false; + } + }); + }, + + child: ListBox({ + setup: (self) => { + self.set_sort_func((a, b) => { + const bState = (b.get_children()[0] as DeviceBox) + .attribute.dev.paired; + + const aState = (a.get_children()[0] as DeviceBox) + .attribute.dev.paired; + + return bState - aState; + }); + + self.hook(Bluetooth, () => { + // Get all devices + const Devices = Bluetooth.devices.concat( + Bluetooth.connected_devices, + ); + + // Add missing devices + Devices.forEach((dev) => { + if (!DevList.has(dev) && dev.name) { + DevList.set(dev, BluetoothDevice(dev)); + + self.add(DevList.get(dev)); + self.show_all(); + } + }); + + // Delete ones that don't exist anymore + const difference = Array.from(DevList.keys()) + .filter((dev) => !Devices + .find((d) => dev === d) && + dev.name); + + difference.forEach((dev) => { + const devWidget = DevList.get(dev); + + if (devWidget) { + if (devWidget.toDestroy) { + devWidget.get_parent().destroy(); + DevList.delete(dev); + } + else { + devWidget.child.reveal_child = false; + devWidget.toDestroy = true; + } + } + }); + + // Start scrolling after a specified height + // is reached by the children + const height = Math.max( + self.get_parent()?.get_allocated_height() || 0, + SCROLL_THRESH_H, + ); + + const scroll = (self.get_parent() as ListBoxRow) + ?.get_parent() as ScrollableGeneric; + + if (scroll) { + const n_child = self.get_children().length; + + if (n_child > SCROLL_THRESH_N) { + scroll.vscroll = 'always'; + scroll.setCss(`min-height: ${height}px;`); + + // Make bottom scroll indicator appear only + // when first getting overflowing children + if (!(bottomArrow.reveal_child === true || + topArrow.reveal_child === true)) { + bottomArrow.reveal_child = true; + } + } + else { + scroll.vscroll = 'never'; + scroll.setCss(''); + topArrow.reveal_child = false; + bottomArrow.reveal_child = false; + } + } + + // Trigger sort_func + (self.get_children() as Array<ListBoxRow>) + .forEach((ch) => { + ch.changed(); + }); + }); + }, + }), + }), + }), + }); +}; diff --git a/modules/ags/config/ts/quick-settings/button-grid.ts b/modules/ags/config/ts/quick-settings/button-grid.ts new file mode 100644 index 00000000..401b182b --- /dev/null +++ b/modules/ags/config/ts/quick-settings/button-grid.ts @@ -0,0 +1,345 @@ +const Bluetooth = await Service.import('bluetooth'); +const Network = await Service.import('network'); + +const { Box, Icon, Label, Revealer } = Widget; +const { execAsync } = Utils; + +import { SpeakerIcon, MicIcon } from '../misc/audio-icons.ts'; +import CursorBox from '../misc/cursorbox.ts'; +import Separator from '../misc/separator.ts'; + +import { NetworkMenu } from './network.ts'; +import { BluetoothMenu } from './bluetooth.ts'; + +// Types +import GObject from 'types/@girs/gobject-2.0/gobject-2.0'; +import { Variable as Var } from 'types/variable.ts'; +import { + BoxGeneric, + IconGeneric, + LabelGeneric, + RevealerGeneric, +} from 'global-types'; +type IconTuple = [ + GObject.Object, + (self: IconGeneric) => void, + signal?: string, +]; +type IndicatorTuple = [ + GObject.Object, + (self: LabelGeneric) => void, + signal?: string, +]; +type GridButtonType = { + command?(): void + secondary_command?(): void + on_open?(menu: RevealerGeneric): void + icon: string | IconTuple + indicator?: IndicatorTuple + // @ts-expect-error me is lazy + menu?: Widget +}; + +const SPACING = 28; +const ButtonStates = [] as Array<Var<boolean>>; + + +const GridButton = ({ + command = () => {/**/}, + secondary_command = () => {/**/}, + on_open = () => {/**/}, + icon, + indicator, + menu, +}: GridButtonType) => { + const Activated = Variable(false); + + ButtonStates.push(Activated); + let iconWidget = Icon(); + let indicatorWidget = Label(); + + // Allow setting icon dynamically or statically + if (typeof icon === 'string') { + iconWidget = Icon({ + class_name: 'grid-label', + icon, + setup: (self) => { + self.hook(Activated, () => { + self.setCss(`color: ${Activated.value ? + 'rgba(189, 147, 249, 0.8)' : + 'unset'};`); + }); + }, + }); + } + else if (Array.isArray(icon)) { + iconWidget = Icon({ + class_name: 'grid-label', + setup: (self) => { + self + .hook(...icon) + .hook(Activated, () => { + self.setCss(`color: ${Activated.value ? + 'rgba(189, 147, 249, 0.8)' : + 'unset'};`); + }); + }, + }); + } + + if (indicator) { + indicatorWidget = Label({ + class_name: 'sub-label', + justification: 'left', + truncate: 'end', + max_width_chars: 12, + setup: (self) => { + self.hook(...indicator); + }, + }); + } + + if (menu) { + menu = Revealer({ + transition: 'slide_down', + child: menu, + reveal_child: Activated.bind(), + }); + } + + const widget = Box({ + vertical: true, + children: [ + Box({ + class_name: 'grid-button', + children: [ + + CursorBox({ + class_name: 'left-part', + + on_primary_click_release: () => { + if (Activated.value) { + secondary_command(); + } + else { + command(); + } + }, + + child: iconWidget, + }), + + CursorBox({ + class_name: 'right-part', + + on_primary_click_release: () => { + ButtonStates.forEach((state) => { + if (state !== Activated) { + state.setValue(false); + } + }); + Activated.setValue(!Activated.value); + }, + + on_hover: (self) => { + if (menu) { + const rowMenu = + ((((self.get_parent() as BoxGeneric) + ?.get_parent() as BoxGeneric) + ?.get_parent() as BoxGeneric) + ?.get_parent() as BoxGeneric) + ?.children[1] as BoxGeneric; + + const isSetup = (rowMenu + .get_children() as Array<BoxGeneric>) + .find((ch) => ch === menu); + + if (!isSetup) { + rowMenu.add(menu); + rowMenu.show_all(); + } + } + }, + + child: Icon({ + icon: 'down-large-symbolic', + class_name: 'grid-chev', + + setup: (self) => { + self.hook(Activated, () => { + let deg = 270; + + if (Activated.value) { + deg = menu ? 360 : 450; + on_open(menu); + } + self.setCss(` + -gtk-icon-transform: rotate(${deg}deg); + `); + }); + }, + }), + }), + + ], + }), + indicatorWidget, + ], + }); + + return widget; +}; + +const Row = ({ buttons }) => { + const child = Box({ + class_name: 'button-row', + hpack: 'center', + }); + + const widget = Box({ + vertical: true, + + children: [ + child, + Box({ vertical: true }), + ], + }); + + for (let i = 0; i < buttons.length; ++i) { + if (i === buttons.length - 1) { + child.add(buttons[i]); + } + else { + child.add(buttons[i]); + child.add(Separator(SPACING)); + } + } + + return widget; +}; + +const FirstRow = () => Row({ + buttons: [ + + GridButton({ + command: () => Network.toggleWifi(), + + secondary_command: () => { + // TODO: connection editor + }, + + icon: [Network, (self) => { + self.icon = Network.wifi?.icon_name; + }], + + indicator: [Network, (self) => { + self.label = Network.wifi?.ssid || Network.wired?.internet; + }], + + menu: NetworkMenu(), + on_open: () => Network.wifi.scan(), + }), + + // TODO: do vpn + GridButton({ + command: () => { + // + }, + + secondary_command: () => { + // + }, + + icon: 'airplane-mode-disabled-symbolic', + }), + + GridButton({ + command: () => Bluetooth.toggle(), + + secondary_command: () => { + // TODO: bluetooth connection editor + }, + + icon: [Bluetooth, (self) => { + if (Bluetooth.enabled) { + self.icon = Bluetooth.connected_devices[0] ? + Bluetooth.connected_devices[0].icon_name : + 'bluetooth-active-symbolic'; + } + else { + self.icon = 'bluetooth-disabled-symbolic'; + } + }], + + indicator: [Bluetooth, (self) => { + self.label = Bluetooth.connected_devices[0] ? + `${Bluetooth.connected_devices[0]}` : + 'Disconnected'; + }, 'notify::connected-devices'], + + menu: BluetoothMenu(), + on_open: (menu) => { + execAsync(`bluetoothctl scan ${menu.reveal_child ? + 'on' : + 'off'}`).catch(print); + }, + }), + + ], +}); + +const SecondRow = () => Row({ + buttons: [ + GridButton({ + command: () => { + execAsync(['pactl', 'set-sink-mute', + '@DEFAULT_SINK@', 'toggle']).catch(print); + }, + + secondary_command: () => { + execAsync(['bash', '-c', 'pavucontrol']) + .catch(print); + }, + + icon: [SpeakerIcon, (self) => { + self.icon = SpeakerIcon.value; + }], + }), + + GridButton({ + command: () => { + execAsync(['pactl', 'set-source-mute', + '@DEFAULT_SOURCE@', 'toggle']).catch(print); + }, + + secondary_command: () => { + execAsync(['bash', '-c', 'pavucontrol']) + .catch(print); + }, + + icon: [MicIcon, (self) => { + self.icon = MicIcon.value; + }], + }), + + // TODO: replace this with Rotation Toggle and move lock to a separate section + GridButton({ + command: () => { + execAsync(['lock']).catch(print); + }, + secondary_command: () => App.openWindow('win-powermenu'), + icon: 'system-lock-screen-symbolic', + }), + ], +}); + +export default () => Box({ + class_name: 'button-grid', + vertical: true, + hpack: 'center', + children: [ + FirstRow(), + Separator(10, { vertical: true }), + SecondRow(), + ], +}); diff --git a/modules/ags/config/ts/quick-settings/main.ts b/modules/ags/config/ts/quick-settings/main.ts new file mode 100644 index 00000000..6f5e1136 --- /dev/null +++ b/modules/ags/config/ts/quick-settings/main.ts @@ -0,0 +1,58 @@ +const { Box, Label, Revealer } = Widget; + +import ButtonGrid from './button-grid.ts'; +import SliderBox from './slider-box.ts'; +import Player from '../media-player/player.ts'; +import PopupWindow from '../misc/popup.ts'; +import ToggleButton from './toggle-button.ts'; + + +const QuickSettingsWidget = () => { + const rev = Revealer({ + transition: 'slide_down', + child: Player(), + }); + + return Box({ + class_name: 'qs-container', + vertical: true, + children: [ + + Box({ + class_name: 'quick-settings', + vertical: true, + children: [ + + Label({ + label: 'Control Center', + class_name: 'title', + hpack: 'start', + css: ` + margin-left: 20px; + margin-bottom: 30px; + `, + }), + + ButtonGrid(), + + SliderBox(), + + ToggleButton(rev), + + ], + }), + + rev, + + ], + }); +}; + +const TOP_MARGIN = 6; + +export default () => PopupWindow({ + name: 'quick-settings', + anchor: ['top', 'right'], + margins: [TOP_MARGIN, 0, 0, 0], + content: QuickSettingsWidget(), +}); diff --git a/modules/ags/config/ts/quick-settings/network.ts b/modules/ags/config/ts/quick-settings/network.ts new file mode 100644 index 00000000..3b8cc83e --- /dev/null +++ b/modules/ags/config/ts/quick-settings/network.ts @@ -0,0 +1,240 @@ +const Network = await Service.import('network'); + +const { Box, Icon, Label, ListBox, Overlay, Revealer, Scrollable } = Widget; +const { execAsync } = Utils; + +import CursorBox from '../misc/cursorbox.ts'; + +const SCROLL_THRESH_H = 200; +const SCROLL_THRESH_N = 7; + +// Types +import { APType, APBox, ScrollableGeneric } from 'global-types'; +import { ListBoxRow } from 'types/@girs/gtk-3.0/gtk-3.0.cjs'; + + +const AccessPoint = (ap: APType) => { + const widget = Box({ + class_name: 'menu-item', + attribute: { + ap: Variable(ap), + }, + }); + + + const child = Box({ + hexpand: true, + children: [ + Icon().hook(widget.attribute.ap, (self) => { + self.icon = widget.attribute.ap.value.iconName; + }), + + Label().hook(widget.attribute.ap, (self) => { + self.label = widget.attribute.ap.value.ssid || ''; + }), + + Icon({ + icon: 'object-select-symbolic', + hexpand: true, + hpack: 'end', + + setup: (self) => { + self.hook(Network, () => { + self.setCss( + `opacity: ${ + widget.attribute.ap.value.ssid === + Network.wifi.ssid ? + '1' : + '0' + }; + `, + ); + }); + }, + }), + ], + }); + + widget.add(Revealer({ + reveal_child: true, + transition: 'slide_down', + + child: CursorBox({ + on_primary_click_release: () => { + execAsync(`nmcli device wifi connect + ${widget.attribute.ap.value.bssid}`).catch(print); + }, + child, + }), + })); + + return widget; +}; + +export const NetworkMenu = () => { + const APList = new Map(); + + const topArrow = Revealer({ + transition: 'slide_down', + + child: Icon({ + icon: 'down-large-symbolic', + class_name: 'scrolled-indicator', + size: 16, + css: '-gtk-icon-transform: rotate(180deg);', + }), + }); + + const bottomArrow = Revealer({ + transition: 'slide_up', + + child: Icon({ + icon: 'down-large-symbolic', + class_name: 'scrolled-indicator', + size: 16, + }), + }); + + return Overlay({ + pass_through: true, + + overlays: [ + Box({ + vpack: 'start', + hpack: 'center', + css: 'margin-top: 12px', + children: [topArrow], + }), + + Box({ + vpack: 'end', + hpack: 'center', + css: 'margin-bottom: 12px', + children: [bottomArrow], + }), + ], + + child: Box({ + class_name: 'menu', + + child: Scrollable({ + hscroll: 'never', + vscroll: 'never', + + setup: (self) => { + self.on('edge-reached', (_, pos) => { + // Manage scroll indicators + if (pos === 2) { + topArrow.reveal_child = false; + bottomArrow.reveal_child = true; + } + else if (pos === 3) { + topArrow.reveal_child = true; + bottomArrow.reveal_child = false; + } + }); + }, + + child: ListBox({ + setup: (self) => { + self.set_sort_func((a, b) => { + const bState = (b.get_children()[0] as APBox) + .attribute.ap.value.strength; + + const aState = (a.get_children()[0] as APBox) + .attribute.ap.value.strength; + + return bState - aState; + }); + + self.hook(Network, () => { + // Add missing APs + const currentAPs = Network.wifi + ?.access_points as Array<APType>; + + currentAPs.forEach((ap) => { + if (ap.ssid !== 'Unknown') { + if (APList.has(ap.ssid)) { + const accesPoint = APList.get(ap.ssid) + .attribute.ap.value; + + if (accesPoint.strength < ap.strength) { + APList.get(ap.ssid).attribute + .ap.setValue(ap); + } + } + else { + APList.set(ap.ssid, AccessPoint(ap)); + + self.add(APList.get(ap.ssid)); + self.show_all(); + } + } + }); + + // Delete ones that don't exist anymore + const difference = Array.from(APList.keys()) + .filter((ssid) => !Network.wifi.access_points + .find((ap) => ap.ssid === ssid) && + ssid !== 'Unknown'); + + difference.forEach((ssid) => { + const apWidget = APList.get(ssid); + + if (apWidget) { + if (apWidget.toDestroy) { + apWidget.get_parent().destroy(); + APList.delete(ssid); + } + else { + apWidget.children[0] + .reveal_child = false; + apWidget.toDestroy = true; + } + } + }); + + // Start scrolling after a specified height + // is reached by the children + const height = Math.max( + self.get_parent()?.get_allocated_height() || 0, + SCROLL_THRESH_H, + ); + + const scroll = (self.get_parent() as ListBoxRow) + ?.get_parent() as ScrollableGeneric; + + if (scroll) { + const n_child = self.get_children().length; + + if (n_child > SCROLL_THRESH_N) { + scroll.vscroll = 'always'; + scroll.setCss(`min-height: ${height}px;`); + + // Make bottom scroll indicator appear only + // when first getting overflowing children + if (!(bottomArrow.reveal_child === true || + topArrow.reveal_child === true)) { + bottomArrow.reveal_child = true; + } + } + else { + scroll.vscroll = 'never'; + scroll.setCss(''); + topArrow.reveal_child = false; + bottomArrow.reveal_child = false; + } + } + + // Trigger sort_func + (self.get_children() as Array<ListBoxRow>) + .forEach((ch) => { + ch.changed(); + }); + }); + }, + }), + }), + }), + }); +}; diff --git a/modules/ags/config/ts/quick-settings/slider-box.ts b/modules/ags/config/ts/quick-settings/slider-box.ts new file mode 100644 index 00000000..1bf90585 --- /dev/null +++ b/modules/ags/config/ts/quick-settings/slider-box.ts @@ -0,0 +1,161 @@ +const Audio = await Service.import('audio'); + +const { Box, Slider, Icon } = Widget; + +const { Gdk } = imports.gi; +const display = Gdk.Display.get_default(); + +import Brightness from '../../services/brightness.ts'; +import { SpeakerIcon } from '../misc/audio-icons.ts'; + + +export default () => Box({ + class_name: 'slider-box', + vertical: true, + hpack: 'center', + children: [ + + Box({ + class_name: 'slider', + vpack: 'start', + hpack: 'center', + + children: [ + Icon({ + size: 26, + class_name: 'slider-label', + icon: SpeakerIcon.bind(), + }), + + Slider({ + vpack: 'center', + max: 0.999, + draw_value: false, + + on_change: ({ value }) => { + if (Audio.speaker) { + Audio.speaker.volume = value; + } + }, + + setup: (self) => { + self + .hook(Audio, () => { + self.value = Audio.speaker?.volume || 0; + }, 'speaker-changed') + + // OnClick + .on('button-press-event', () => { + if (!display) { + return; + } + self.window.set_cursor(Gdk.Cursor.new_from_name( + display, + 'grabbing', + )); + }) + + // OnRelease + .on('button-release-event', () => { + if (!display) { + return; + } + self.window.set_cursor(Gdk.Cursor.new_from_name( + display, + 'pointer', + )); + }) + + // OnHover + .on('enter-notify-event', () => { + if (!display) { + return; + } + self.window.set_cursor(Gdk.Cursor.new_from_name( + display, + 'pointer', + )); + self.toggleClassName('hover', true); + }) + + // OnHoverLost + .on('leave-notify-event', () => { + self.window.set_cursor(null); + self.toggleClassName('hover', false); + }); + }, + }), + ], + }), + + Box({ + class_name: 'slider', + vpack: 'start', + hpack: 'center', + + children: [ + Icon({ + class_name: 'slider-label', + icon: Brightness.bind('screenIcon'), + }), + + Slider({ + vpack: 'center', + draw_value: false, + + on_change: ({ value }) => { + Brightness.screen = value; + }, + + setup: (self) => { + self + .hook(Brightness, () => { + self.value = Brightness.screen; + }, 'screen') + + // OnClick + .on('button-press-event', () => { + if (!display) { + return; + } + self.window.set_cursor(Gdk.Cursor.new_from_name( + display, + 'grabbing', + )); + }) + + // OnRelease + .on('button-release-event', () => { + if (!display) { + return; + } + self.window.set_cursor(Gdk.Cursor.new_from_name( + display, + 'pointer', + )); + }) + + // OnHover + .on('enter-notify-event', () => { + if (!display) { + return; + } + self.window.set_cursor(Gdk.Cursor.new_from_name( + display, + 'pointer', + )); + self.toggleClassName('hover', true); + }) + + // OnHoverLost + .on('leave-notify-event', () => { + self.window.set_cursor(null); + self.toggleClassName('hover', false); + }); + }, + }), + ], + }), + + ], +}); diff --git a/modules/ags/config/ts/quick-settings/toggle-button.ts b/modules/ags/config/ts/quick-settings/toggle-button.ts new file mode 100644 index 00000000..2134349a --- /dev/null +++ b/modules/ags/config/ts/quick-settings/toggle-button.ts @@ -0,0 +1,66 @@ +const Mpris = await Service.import('mpris'); + +const { CenterBox, Icon, ToggleButton } = Widget; + +const { Gdk } = imports.gi; +const display = Gdk.Display.get_default(); + +// Types +import { RevealerGeneric } from 'global-types'; + + +export default (rev: RevealerGeneric) => { + const child = Icon({ + icon: 'down-large-symbolic', + class_name: 'arrow', + css: '-gtk-icon-transform: rotate(180deg);', + }); + + const button = CenterBox({ + center_widget: ToggleButton({ + setup: (self) => { + // Open at startup if there are players + const id = Mpris.connect('changed', () => { + self.set_active(Mpris.players.length > 0); + Mpris.disconnect(id); + }); + + self + .on('toggled', () => { + if (self.get_active()) { + child + .setCss('-gtk-icon-transform: rotate(0deg);'); + rev.reveal_child = true; + } + else { + child + .setCss('-gtk-icon-transform: rotate(180deg);'); + rev.reveal_child = false; + } + }) + + // OnHover + .on('enter-notify-event', () => { + if (!display) { + return; + } + self.window.set_cursor(Gdk.Cursor.new_from_name( + display, + 'pointer', + )); + self.toggleClassName('hover', true); + }) + + // OnHoverLost + .on('leave-notify-event', () => { + self.window.set_cursor(null); + self.toggleClassName('hover', false); + }); + }, + + child, + }), + }); + + return button; +}; diff --git a/modules/ags/config/ts/setup.ts b/modules/ags/config/ts/setup.ts new file mode 100644 index 00000000..287db148 --- /dev/null +++ b/modules/ags/config/ts/setup.ts @@ -0,0 +1,49 @@ +const Bluetooth = await Service.import('bluetooth'); + +import Brightness from '../services/brightness.ts'; +import Pointers from '../services/pointers.ts'; +import Tablet from '../services/tablet.ts'; +import TouchGestures from '../services/touch-gestures.ts'; + +import closeAll from './misc/closer.ts'; +import Persist from './misc/persist.ts'; + + +export default () => { + globalThis.Brightness = Brightness; + globalThis.Pointers = Pointers; + globalThis.Tablet = Tablet; + globalThis.closeAll = closeAll; + + Persist({ + name: 'bluetooth', + gobject: Bluetooth, + prop: 'enabled', + signal: 'notify::enabled', + }); + + TouchGestures.addGesture({ + name: 'openAppLauncher', + gesture: 'UD', + edge: 'T', + command: () => App.openWindow('win-applauncher'), + }); + + TouchGestures.addGesture({ + name: 'oskOn', + gesture: 'DU', + edge: 'B', + command: () => { + Tablet.oskState = true; + }, + }); + + TouchGestures.addGesture({ + name: 'oskOff', + gesture: 'UD', + edge: 'B', + command: () => { + Tablet.oskState = false; + }, + }); +}; diff --git a/modules/ags/config/tsconfig.json b/modules/ags/config/tsconfig.json index dd1cebcc..73b6a4b0 100644 --- a/modules/ags/config/tsconfig.json +++ b/modules/ags/config/tsconfig.json @@ -1,17 +1,24 @@ { - "$schema": "https://json.schemastore.org/tsconfig", "compilerOptions": { - "experimentalDecorators": true, - "jsx": "react-jsx", - "jsxImportSource": "astal/gtk3", - "lib": [ - "ES2022" - ], + "target": "ES2022", "module": "ES2022", - "moduleResolution": "Bundler", + "lib": ["ES2022"], "noEmit": true, - "skipLibCheck": true, + "allowImportingTsExtensions": true, + "allowJs": true, + "checkJs": true, "strict": true, - "target": "ES2022" + "noImplicitAny": false, + "baseUrl": ".", + "paths": { + "fzf": ["./node_modules/fzf/dist/types"], + }, + "typeRoots": [ + "./types", + "./global-types.d.ts", + "./node_modules", + ], + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true } } 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/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.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/config/wim.ts b/modules/ags/config/wim.ts new file mode 100644 index 00000000..aafdd1b0 --- /dev/null +++ b/modules/ags/config/wim.ts @@ -0,0 +1,36 @@ +import Setup from './ts/setup.ts'; +import AppLauncher from './ts/applauncher/main.ts'; +import Bar from './ts/bar/wim.ts'; +import BgFade from './ts/misc/background-fade.ts'; +import Calendar from './ts/date.ts'; +import Corners from './ts/corners/main.ts'; +import { NotifPopups, NotifCenter } from './ts/notifications/wim.ts'; +import OSD from './ts/osd/main.ts'; +import OSK from './ts/on-screen-keyboard/main.ts'; +import Powermenu from './ts/powermenu.ts'; +import QSettings from './ts/quick-settings/main.ts'; + + +App.config({ + icons: './icons', + + onConfigParsed: () => { + Setup(); + }, + + windows: () => [ + ...Corners(), + + AppLauncher(), + Calendar(), + NotifCenter(), + OSD(), + OSK(), + Powermenu(), + QSettings(), + + Bar(), + BgFade(), + NotifPopups(), + ], +}); diff --git a/modules/ags/default.nix b/modules/ags/default.nix index 98fbf8fd..bbdeb784 100644 --- a/modules/ags/default.nix +++ b/modules/ags/default.nix @@ -1,84 +1,133 @@ -# TODO: move everything to Gtk4 -self: { +{ + ags, + astal, config, - lib, pkgs, ... }: let - inherit (self.inputs) ags astal virtualkeyboard-adapter; - inherit (lib) hasPrefix mkIf removePrefix; + inherit (config.vars) mainUser hostName; - # 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; - }; - }; - }; + isTouchscreen = config.hardware.sensor.iio.enable; 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. + # Enable pam for ags and astal + security.pam.services.ags = {}; + security.pam.services.astal = {}; + + services.upower.enable = true; + + home-manager.users.${mainUser}.imports = [ + ags.homeManagerModules.default + astal.homeManagerModules.default + + ({ + config, + lib, + ... + }: let + symlink = config.lib.file.mkOutOfStoreSymlink; + inherit (lib) hasPrefix mdDoc optionals removePrefix; + + configJs = + /* + javascript + */ + '' + import { transpileTypeScript } from './js/utils.js'; + + export default (await transpileTypeScript('${hostName}')).default; ''; - } - ]; - # Machine config - security.pam.services.astal-auth = {}; - services.upower.enable = true; + agsConfigDir = "${removePrefix "/home/${mainUser}/" flakeDir}/modules/ags"; + in { + assertions = [ + { + assertion = hasPrefix "/home/${mainUser}/" flakeDir; + message = mdDoc '' + Your $FLAKE environment variable needs to point to a directory in + the main users' home to use the AGS module. + ''; + } + ]; - 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 + # Experimental Gtk4 ags + programs.astal = { + enable = true; + extraPackages = with pkgs; [ + libadwaita ]; }; - }; - home-manager.users.${cfgDesktop.user}.imports = [ - hmOpts - (import ./packages.nix self) - (import ./hyprland.nix self) - ]; - }; + programs.ags.enable = true; - # For accurate stack trace - _file = ./default.nix; + home = { + file = + { + # Astal symlinks. ${./astal}, types and config.js + ".config/astal".source = symlink "${flakeDir}/modules/ags/astal"; + "${agsConfigDir}/astal/types".source = "${config.programs.astal.finalPackage}/share/io.Aylur.Astal/types"; + "${agsConfigDir}/astal/config.js".text = configJs; + + # AGS symlinks. ${./config}, types and config.js + ".config/ags".source = symlink "${flakeDir}/modules/ags/config"; + "${agsConfigDir}/config/types".source = "${config.programs.ags.finalPackage}/share/com.github.Aylur.ags/types"; + "${agsConfigDir}/config/config.js".text = configJs; + } + // (import ./icons.nix {inherit pkgs agsConfigDir;}); + + packages = + [config.customPkgs.coloryou] + ++ (with pkgs; [ + # ags + dart-sass + bun + playerctl + + ## gui + pavucontrol # TODO: replace with ags widget + ]) + ++ (optionals isTouchscreen (with pkgs; [ + lisgd + ydotool + ])); + }; + + wayland.windowManager.hyprland = { + settings = { + animations = { + bezier = [ + "easeInOutBack, 0.68, -0.6, 0.32, 1.6" + ]; + + animation = [ + "fadeLayersIn, 0" + "fadeLayersOut, 1, 3000, default" + "layers, 1, 8, easeInOutBack, slide left" + ]; + }; + + layerrule = [ + "noanim, ^(?!win-).*" + ]; + + exec-once = [ + "ags" + "sleep 3; ags -r 'App.openWindow(\"win-applauncher\")'" + ]; + + bind = [ + "$mainMod SHIFT, E, exec, ags -t win-powermenu" + "$mainMod , D, exec, ags -t win-applauncher" + ]; + binde = [ + ## Brightness control + ", XF86MonBrightnessUp, exec, ags -r 'Brightness.screen += 0.05'" + ", XF86MonBrightnessDown, exec, ags -r 'Brightness.screen -= 0.05'" + ]; + bindn = [" , Escape, exec, ags -r 'closeAll()'"]; + bindr = ["CAPS, Caps_Lock, exec, ags -r 'Brightness.fetchCapsState()'"]; + }; + }; + }) + ]; } 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 08bc5a14..00000000 --- a/modules/ags/hyprland.nix +++ /dev/null @@ -1,215 +0,0 @@ -self: { - lib, - osConfig, - pkgs, - ... -}: let - inherit (self.lib.hypr) mkAnimation mkBezier mkBind mkLayerRule; - - inherit (lib) getExe 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 = getExe (pkgs.writeShellApplication { - name = "select-screenshot"; - runtimeInputs = with pkgs; [grim-hyprland satty slurp]; - text = '' - 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 index 56570e1e..b885efab 100644 --- a/modules/ags/icons.nix +++ b/modules/ags/icons.nix @@ -3,13 +3,20 @@ pkgs, ... }: { - "${agsConfigDir}/icons/down-large-symbolic.svg".source = pkgs.fetchurl { + "${agsConfigDir}/config/icons/mouse-razer-symbolic.svg".source = pkgs.fetchurl { + url = "https://raw.githubusercontent.com/bithatch/razer-icon-font/main/src/devices/mouse.svg"; + hash = "sha256-A1+eIp2VEFDyY23GIHKhbnByHXrnVS3QgIJ9sjjtuZw="; + }; + + "${agsConfigDir}/config/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 + "${agsConfigDir}/config/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> 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/arion/.template/compose.nix b/modules/arion/.template/compose.nix new file mode 100644 index 00000000..e88934d1 --- /dev/null +++ b/modules/arion/.template/compose.nix @@ -0,0 +1,9 @@ +{config, ...}: let + inherit (config.sops) secrets; + inherit (config.arion) rwDataDir; + + rwPath = rwDataDir + "/projectName"; +in { + arion.projects."projectName" = { + }; +} diff --git a/modules/docker/.template/images/image.nix b/modules/arion/.template/images/image.nix similarity index 62% rename from modules/docker/.template/images/image.nix rename to modules/arion/.template/images/image.nix index 152d9b12..5a212259 100644 --- a/modules/docker/.template/images/image.nix +++ b/modules/arion/.template/images/image.nix @@ -1,8 +1,8 @@ pkgs: -pkgs.dockerTools.pullImage rec { +pkgs.dockerTools.pullImage { imageName = "some/image/name"; imageDigest = ""; sha256 = ""; - finalImageName = imageName; + finalImageName = ""; finalImageTag = "latest"; } diff --git a/modules/arion/default.nix b/modules/arion/default.nix new file mode 100644 index 00000000..41da620f --- /dev/null +++ b/modules/arion/default.nix @@ -0,0 +1,129 @@ +{ + arion, + config, + lib, + pkgs, + ... +}: let + inherit + (lib) + filterAttrs + hasAttr + mapAttrs + mkEnableOption + mkForce + mkIf + mkOption + optionalAttrs + types + ; + + inherit (config.vars) mainUser; + + cfg = config.arion; +in { + imports = [arion.nixosModules.arion]; + + options.arion = { + enable = mkEnableOption (lib.mdDoc "My custom arion config layer module"); + + rwDataDir = mkOption { + default = "/var/lib/arion"; + type = types.str; + description = lib.mdDoc '' + Directory to place persistent data in + ''; + }; + + projects = mkOption { + default = {}; + description = lib.mdDoc '' + Declarative specification of docker-compose in nix. + ''; + type = types.attrs; + }; + }; + + config = mkIf cfg.enable { + users.extraUsers.${mainUser}.extraGroups = ["docker"]; + + virtualisation = { + docker = { + enable = true; + storageDriver = "btrfs"; + }; + + arion = { + backend = "docker"; + + projects = + mapAttrs (n: v: { + # https://docs.hercules-ci.com/arion/options + settings = { + enableDefaultNetwork = v.enableDefaultNetwork or true; + + networks = + optionalAttrs (hasAttr "networks" v) + v.networks; + + services = + mapAttrs (n': v': { + # https://github.com/hercules-ci/arion/issues/169#issuecomment-1301370634 + build.image = let + importImage = file: pkgs.callPackage file pkgs; + in + mkForce (importImage v'.image); + + service = + (filterAttrs (attrName: _: + attrName != "image" && attrName != "extraOptions") + v') + # By default set the container_name to the attrset's name + // (optionalAttrs (! hasAttr "container_name" v') { + container_name = n'; + }); + + out.service = + optionalAttrs + (hasAttr "extraOptions" v') + v'.extraOptions; + }) + v; + }; + }) + cfg.projects; + }; + }; + + # Script for updating the images of all images of a compose.nix file + environment.systemPackages = with pkgs; [ + (writeShellApplication { + name = "updateImages"; + + runtimeInputs = [ + (writeShellApplication { + name = "pullImage"; + runtimeInputs = [nix-prefetch-docker]; + text = '' + FILE="$1" + + IMAGE=$(sed -n 's/.*imageName = "\([^"]*\).*/\1/p' "$FILE") + TAG=$(sed -n 's/.*finalImageTag = "\([^"]*\).*/\1/p' "$FILE") + echo "$IMAGE $TAG" + + if ! grep "Locked" "$FILE"; then + PREFETCH=$(nix-prefetch-docker "$IMAGE" "$TAG") + echo -e "pkgs:\npkgs.dockerTools.pullImage $PREFETCH" > "$FILE" + fi + ''; + }) + ]; + + text = '' + DIR=''${1:-"."} + find "$DIR"/images -type f -exec pullImage {} \; + ''; + }) + ]; + }; +} diff --git a/modules/audio.nix b/modules/audio.nix new file mode 100644 index 00000000..fe7df897 --- /dev/null +++ b/modules/audio.nix @@ -0,0 +1,13 @@ +{nix-gaming, ...}: { + imports = [nix-gaming.nixosModules.pipewireLowLatency]; + + hardware.pulseaudio.enable = false; + + services.pipewire = { + enable = true; + alsa.enable = true; + jack.enable = true; + pulse.enable = true; + lowLatency.enable = true; + }; +} 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 fa903269..00000000 --- a/modules/base/default.nix +++ /dev/null @@ -1,153 +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"; - }; - }; - - environment.systemPackages = attrValues { - switch = pkgs.writeShellApplication { - name = "switch"; - text = '' - exec nh os switch --hostname ${config.networking.hostName} - ''; - }; - - # Peripherals - inherit - (pkgs) - hdparm - pciutils - usbutils - rar - ; - }; - - 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 - ''; - - 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 index 4242ad41..954238ba 100644 --- a/modules/borgbackup/default.nix +++ b/modules/borgbackup/default.nix @@ -1,44 +1,20 @@ -{ - 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" - ]; - } - ]; - }; + services.borgbackup = { + existingRepos = [ + { + name = "arion"; + authorizedKeys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPijoxuSwH9IrS4poewzHHwe64UoX4QY7Qix5VhEdqKR root@servivi" + ]; + } + { + name = "mc"; + 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 index a22f7c2d..849e01b4 100644 --- a/modules/borgbackup/module.nix +++ b/modules/borgbackup/module.nix @@ -4,12 +4,11 @@ pkgs, ... }: let - inherit (lib) mkIf mkOption types; - inherit (lib.lists) all any filter findSingle length; - inherit (lib.attrsets) attrValues hasAttr listToAttrs mapAttrs removeAttrs; + inherit (lib) all any attrValues length mapAttrs mkIf mkOption types; + inherit (builtins) listToAttrs removeAttrs; inherit (config.sops) secrets; - inherit (config.networking) hostName; + inherit (config.vars) hostName; cfg = config.services.borgbackup; in { @@ -27,11 +26,11 @@ in { }: { options = { paths = mkOption { - type = types.nullOr (types.coercedTo types.str lib.singleton (types.listOf types.str)); + type = with types; nullOr (coercedTo str lib.singleton (listOf str)); default = null; }; dumpCommand = mkOption { - type = types.nullOr types.path; + type = with types; nullOr path; default = null; }; repo = mkOption { @@ -104,7 +103,7 @@ in { default = []; }; readWritePaths = mkOption { - type = types.listOf types.path; + type = with types; listOf path; default = []; }; privateTmp = mkOption { @@ -178,20 +177,18 @@ in { }; existingRepos = mkOption { - type = types.listOf (types.submodule { - options = { - name = mkOption { - type = types.str; + type = with types; + listOf (submodule { + options = { + name = mkOption { + type = str; + }; + authorizedKeys = mkOption { + type = listOf str; + default = []; + }; }; - host = mkOption { - type = types.str; - }; - authorizedKeys = mkOption { - type = types.listOf types.str; - default = []; - }; - }; - }); + }); default = []; }; }; @@ -210,24 +207,20 @@ in { ]; services.borgbackup = let - backupDir = { - nos = "/data/borgbackups"; - servivi = "/home/backups"; - }; + backupDir = "/data/borgbackups"; in { repos = - mkIf (length cfg.existingRepos > 0) + mkIf (hostName == "nos" && length cfg.existingRepos > 0) (listToAttrs (map (r: { inherit (r) name; value = { authorizedKeysAppendOnly = r.authorizedKeys; - path = "${backupDir.${hostName}}/${r.name}"; + path = "${backupDir}/${r.name}"; }; }) - (filter (x: x.host == hostName) cfg.existingRepos))); + cfg.existingRepos)); jobs = mapAttrs (n: v: let - existingRepo = findSingle (x: x.name == v.repo) null null cfg.existingRepos; otherAttrs = removeAttrs v [ "environment" "paths" @@ -241,7 +234,7 @@ in { { environment = v.environment - // (mkIf (hasAttr "borg-ssh" secrets) { + // (mkIf (hostName != "nos") { BORG_RSH = "ssh -o 'StrictHostKeyChecking=no' -i ${secrets.borg-ssh.path}"; }); @@ -264,15 +257,12 @@ in { ''; repo = - if (hostName != existingRepo.host) - then "ssh://borg@${existingRepo.host}${backupDir.${existingRepo.host}}/${v.repo}" - else "${backupDir.${existingRepo.host}}/${v.repo}"; + if (hostName != "nos") + then "ssh://borg@nos${backupDir}/${v.repo}" + else "${backupDir}/${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/dconf.nix b/modules/dconf.nix new file mode 100644 index 00000000..7752b596 --- /dev/null +++ b/modules/dconf.nix @@ -0,0 +1,28 @@ +{config, ...}: let + inherit (config.vars) mainUser; +in { + programs = { + dconf.enable = true; + }; + + home-manager.users.${mainUser} = { + 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"; + }; + }; + }; +} 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 000cca25..00000000 --- a/modules/desktop/default.nix +++ /dev/null @@ -1,129 +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. - ''; - }; - - quickshell.enable = mkOption { - type = types.bool; - default = false; - description = '' - Whether we want to enable Quickshell 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 02580475..00000000 --- a/modules/desktop/environment/default.nix +++ /dev/null @@ -1,251 +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) - ../../quickshell - - ./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 776ac9ac..00000000 --- a/modules/desktop/environment/modules/packages.nix +++ /dev/null @@ -1,355 +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.homeModules.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 - hunspell - krename - ; - - # Apps - inherit - (pkgs) - gnome-calculator - 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/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/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/default.nix b/modules/docker/default.nix deleted file mode 100644 index 0fe33379..00000000 --- a/modules/docker/default.nix +++ /dev/null @@ -1,59 +0,0 @@ -self: { - config, - lib, - pkgs, - ... -}: let - inherit (lib) mkIf mkOption types; - inherit (config.sops) secrets; - - 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 {}) - ]; - nix.settings.extra-sandbox-paths = [secrets.docker.path]; - nixpkgs.overlays = [ - (final: prev: { - skopeo = pkgs.writeScriptBin "skopeo" ''exec ${prev.skopeo}/bin/skopeo "$@" --authfile=${secrets.docker.path}''; - }) - ]; - - 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 7ea80a81..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" &> /dev/null; 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/dolphin.nix b/modules/dolphin.nix new file mode 100644 index 00000000..7ea0b226 --- /dev/null +++ b/modules/dolphin.nix @@ -0,0 +1,49 @@ +{ + config, + pkgs, + ... +}: let + inherit (config.vars) mainUser; +in { + environment.systemPackages = with pkgs; [ + plasma5Packages.kio-admin + ]; + + # 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.dolphin}/bin/dolphin"; + }; + }; + + home-manager.users.${mainUser}.home.packages = with pkgs; + [] + ++ (with pkgs.plasma5Packages; [ + ark + kcharselect + kdenlive + okular + + # Dolphin & co + dolphin + dolphin-plugins + kdegraphics-thumbnailers + ffmpegthumbs + kio + kio-admin # needs to be both here and in system pkgs + kio-extras + kmime + ]) + ++ (with pkgs.gnome; [ + gnome-calculator + ]); +} 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/greetd/astal.nix b/modules/greetd/astal.nix new file mode 100644 index 00000000..4019ddd6 --- /dev/null +++ b/modules/greetd/astal.nix @@ -0,0 +1,54 @@ +{ + astal, + config, + pkgs, + ... +}: let + inherit (config.vars) mainUser; + hyprland = config.home-manager.users.${mainUser}.wayland.windowManager.hyprland.finalPackage; +in { + # Add home folder for home-manager to work + users.users.greeter = { + home = "/var/lib/greeter"; + createHome = true; + }; + + home-manager.users.greeter = { + imports = [ + astal.homeManagerModules.default + ../../home/theme + ]; + + programs.astal.enable = true; + + home = { + packages = [ + hyprland + pkgs.bun + pkgs.dart-sass + pkgs.swww + pkgs.gtk3 + pkgs.glib + ]; + + file = { + ".config/astal/.wallpaper".source = "${pkgs.dracula-theme}/wallpapers/waves.png"; + + ".config/astal" = { + source = ../ags/astal; + recursive = true; + }; + + ".config/astal/config.js".text = + /* + javascript + */ + '' + import { transpileTypeScript } from './js/utils.js'; + + export default (await transpileTypeScript('greeter')).default; + ''; + }; + }; + }; +} diff --git a/modules/greetd/default.nix b/modules/greetd/default.nix new file mode 100644 index 00000000..4dcefc07 --- /dev/null +++ b/modules/greetd/default.nix @@ -0,0 +1,45 @@ +{ + config, + lib, + pkgs, + ... +}: let + inherit (config.vars) mainUser; + inherit (import ./hyprland.nix {inherit config lib pkgs;}) hyprConf; + + # Nix stuff + isTouchscreen = config.hardware.sensor.iio.enable; + hyprland = config.home-manager.users.${mainUser}.wayland.windowManager.hyprland.finalPackage; +in { + imports = [./astal.nix]; + + services = { + xserver = { + displayManager = { + sessionPackages = [hyprland]; + }; + + libinput.enable = true; + wacom.enable = isTouchscreen; + }; + + greetd = { + enable = true; + settings = { + default_session = { + command = "Hyprland --config ${hyprConf}"; + user = "greeter"; + }; + + initial_session = { + command = "Hyprland"; + user = mainUser; + }; + }; + }; + }; + + # unlock GPG keyring on login + services.gnome.gnome-keyring.enable = true; + security.pam.services.greetd.enableGnomeKeyring = true; +} diff --git a/modules/greetd/hyprland.nix b/modules/greetd/hyprland.nix new file mode 100644 index 00000000..a4f09099 --- /dev/null +++ b/modules/greetd/hyprland.nix @@ -0,0 +1,99 @@ +{ + config, + lib, + pkgs, + ... +}: let + inherit + (lib) + boolToString + concatStringsSep + filterAttrs + hasPrefix + isAttrs + isBool + mapAttrsToList + optionalString + ; + inherit (config.vars) mainUser; + + inherit (import ./setupMonitors.nix {inherit config pkgs;}) setupMonitors; + + # Nix stuff + cfgHypr = config.home-manager.users.${mainUser}.wayland.windowManager.hyprland; + + devices = filterAttrs (n: v: hasPrefix "device:" n) cfgHypr.settings; + monitors = cfgHypr.settings.monitor; + inputs = cfgHypr.settings.input; + misc = cfgHypr.settings.misc; + + mkHyprBlock = attrs: + concatStringsSep "\n" (mapAttrsToList ( + n: v: + if (isAttrs v) + then '' + ${n} { + ${mkHyprBlock v} + } + '' + else if (isBool v) + then " ${n}=${boolToString v}" + else " ${n}=${toString v}" + ) + attrs); +in { + hyprConf = pkgs.writeText "greetd-hypr-config" ( + (optionalString config.nvidia.enable + /* + hyprlang + */ + '' + env = LIBVA_DRIVER_NAME,nvidia + env = XDG_SESSION_TYPE,wayland + env = GBM_BACKEND,nvidia-drm + env = __GLX_VENDOR_LIBRARY_NAME,nvidia + env = WLR_NO_HARDWARE_CURSORS,1 + '') + + (concatStringsSep "\n" (map (x: "monitor=${x}") monitors)) + + + /* + hyprlang + */ + '' + + misc { + ${mkHyprBlock misc} + } + + # Devices + ${mkHyprBlock devices} + + input { + ${mkHyprBlock inputs} + } + + '' + + + /* + hyprlang + */ + '' + env = XCURSOR_SIZE,24 + exec-once = hyprctl setcursor Dracula-cursors 24 + + general { + border_size = 0 + } + + decoration { + blur { + enabled = false + } + drop_shadow = false + } + + exec-once = ${setupMonitors} + exec-once = astal -b greeter &> /tmp/astal.log; hyprctl dispatch exit + '' + ); +} diff --git a/modules/desktop/manager/hyprland/setupMonitors.nix b/modules/greetd/setupMonitors.nix similarity index 66% rename from modules/desktop/manager/hyprland/setupMonitors.nix rename to modules/greetd/setupMonitors.nix index 063faeaa..4654ee2b 100644 --- a/modules/desktop/manager/hyprland/setupMonitors.nix +++ b/modules/greetd/setupMonitors.nix @@ -3,26 +3,15 @@ pkgs, ... }: let - inherit (pkgs.lib) getExe; - - cfg = config.roles.desktop; - - hyprland = - config - .home-manager - .users - .${cfg.user} - .wayland - .windowManager - .hyprland - .finalPackage; + inherit (config.vars) mainUser greetdDupe mainMonitor; + hyprland = config.home-manager.users.${mainUser}.wayland.windowManager.hyprland.finalPackage; # Show Regreet on all monitors dupeMonitors = pkgs.writeShellApplication { name = "dupeMonitors"; runtimeInputs = [hyprland pkgs.jq]; text = '' - main="${cfg.mainMonitor}" + main="${mainMonitor}" names="($(hyprctl -j monitors | jq -r '.[] .description'))" if [[ "$main" == "null" ]]; then @@ -40,14 +29,12 @@ 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; + if (mainMonitor != "null" && !greetdDupe) + then "hyprctl dispatch focusmonitor ${mainMonitor}" + else "${dupeMonitors}/bin/dupeMonitors"; } 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/desktop/environment/config/dolphinrc b/modules/hyprland/config/dolphinrc similarity index 87% rename from modules/desktop/environment/config/dolphinrc rename to modules/hyprland/config/dolphinrc index dbf5dd3e..edd21d11 100644 --- a/modules/desktop/environment/config/dolphinrc +++ b/modules/hyprland/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/modules/desktop/environment/config/kdeglobals b/modules/hyprland/config/kdeglobals similarity index 94% rename from modules/desktop/environment/config/kdeglobals rename to modules/hyprland/config/kdeglobals index 719dadad..b89e13de 100644 --- a/modules/desktop/environment/config/kdeglobals +++ b/modules/hyprland/config/kdeglobals @@ -4,7 +4,7 @@ TerminalApplication=foot [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 diff --git a/modules/desktop/environment/config/kiorc b/modules/hyprland/config/kiorc similarity index 100% rename from modules/desktop/environment/config/kiorc rename to modules/hyprland/config/kiorc diff --git a/modules/hyprland/config/mimeapps.list b/modules/hyprland/config/mimeapps.list new file mode 100644 index 00000000..6da8914d --- /dev/null +++ b/modules/hyprland/config/mimeapps.list @@ -0,0 +1,12 @@ +[Added Associations] +application/pdf=firefox.desktop; +text/x-java=nvim.desktop; +x-scheme-handler/mailto=userapp-Thunderbird-9ME591.desktop; +x-scheme-handler/mid=userapp-Thunderbird-9ME591.desktop; + +[Default Applications] +application/pdf=firefox.desktop; +message/rfc822=userapp-Thunderbird-9ME591.desktop +text/x-java=nvim.desktop; +x-scheme-handler/mailto=userapp-Thunderbird-9ME591.desktop +x-scheme-handler/mid=userapp-Thunderbird-9ME591.desktop diff --git a/modules/hyprland/config/neofetch/config.conf b/modules/hyprland/config/neofetch/config.conf new file mode 100644 index 00000000..8407209d --- /dev/null +++ b/modules/hyprland/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/modules/hyprland/config/swappy/config b/modules/hyprland/config/swappy/config new file mode 100644 index 00000000..05702a4d --- /dev/null +++ b/modules/hyprland/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/modules/hyprland/default.nix b/modules/hyprland/default.nix new file mode 100644 index 00000000..92eeb774 --- /dev/null +++ b/modules/hyprland/default.nix @@ -0,0 +1,200 @@ +{ + config, + hyprland, + pkgs, + lib, + ... +}: let + inherit (lib) concatStringsSep mkIf optionals; + inherit (config.vars) mainUser; + + cfg = config.programs.hyprland; +in { + # SYSTEM CONFIG + imports = [ + ../dconf.nix + + ./packages.nix + ./security.nix + ]; + + environment.sessionVariables = + { + GTK_USE_PORTAL = "1"; + } + // mkIf (!config.nvidia.enable) { + NIXOS_OZONE_WL = "1"; + }; + + services = { + dbus.enable = true; + gvfs.enable = true; + }; + + programs.hyprland = with hyprland.packages.${pkgs.system}; { + enable = true; + package = default.overrideAttrs (o: { + postFixup = '' + rm "$out/share/xdg-desktop-portal/hyprland-portals.conf" + + cat <<EOF > "$out/share/xdg-desktop-portal/hyprland-portals.conf" + [preferred] + default=hyprland;gtk + org.freedesktop.impl.portal.FileChooser=kde + EOF + ''; + }); + portalPackage = xdg-desktop-portal-hyprland; + }; + + xdg.portal.extraPortals = [ + pkgs.xdg-desktop-portal-kde + ]; + + # HOME-MANAGER CONFIG + home-manager.users.${mainUser} = { + imports = [ + ./hyprexpo.nix + ./hyprgrass.nix + ./inputs.nix + ./style.nix + ]; + + wayland.windowManager.hyprland = { + enable = true; + package = cfg.finalPackage; + + systemd.variables = ["-all"]; + + settings = { + env = let + gset = pkgs.gsettings-desktop-schemas; + in + [ + "XDG_DATA_DIRS, ${concatStringsSep ":" [ + "${gset}/share/gsettings-schemas/${gset.name}" + "${pkgs.gtk3}/share/gsettings-schemas/${pkgs.gtk3.name}" + "$XDG_DATA_DIRS" + ]}" + ] + ++ (optionals config.nvidia.enable [ + "LIBVA_DRIVER_NAME, nvidia" + "XDG_SESSION_TYPE, wayland" + "GBM_BACKEND, nvidia-drm" + "__GLX_VENDOR_LIBRARY_NAME, nvidia" + "WLR_NO_HARDWARE_CURSORS, 1" + ]); + + xwayland.force_zero_scaling = true; + monitor = [ + (concatStringsSep "," [ + "desc:Acer Technologies Acer K212HQL T3EAA0014201" + "1920x1080@60" + "840x1000, 1, transform, 3" + ]) + (concatStringsSep "," [ + "desc:BOE 0x0964" + "1920x1200@60" + "0x2920, 1" + ]) + (concatStringsSep "," [ + "desc:Samsung Electric Company C27JG5x HTOM100586" + "2560x1440@60" + "1920x120, 1" + ]) + (concatStringsSep "," [ + "desc:GIGA-BYTE TECHNOLOGY CO. LTD. G27QC 0x00000B1D" + "2560x1440@165" + "1920x1560, 1" + ]) + ]; + + "$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" + + ",XF86AudioMute, exec, pactl set-sink-mute @DEFAULT_SINK@ toggle" + ",XF86AudioMicMute, exec, pactl set-source-mute @DEFAULT_SOURCE@ toggle" + ]; + + binde = [ + ",XF86AudioRaiseVolume, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+ & ags -r 'popup_osd(\"speaker\")' &" + ",XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- & ags -r 'popup_osd(\"speaker\")' &" + ]; + + # Mouse Binds + bindm = [ + "$mainMod, mouse:272, movewindow" + "$mainMod, mouse:273, resizewindow" + ]; + + misc = { + disable_hyprland_logo = true; + disable_splash_rendering = true; + vfr = true; + }; + + dwindle = { + smart_split = true; + special_scale_factor = 0.8; + }; + }; + }; + + # libs + home.packages = with pkgs; [ + # tools + bluez-tools + brightnessctl + pulseaudio + alsa-utils + p7zip # for reshade + + qt5.qtwayland + qt6.qtwayland + libayatana-appindicator + xdg-utils + evtest + glib + xorg.xrandr + libinput + xclip + libnotify + ]; + }; +} diff --git a/modules/hyprland/hyprexpo.nix b/modules/hyprland/hyprexpo.nix new file mode 100644 index 00000000..c775a8c8 --- /dev/null +++ b/modules/hyprland/hyprexpo.nix @@ -0,0 +1,28 @@ +{ + hypr-official-plugins, + pkgs, + ... +}: { + wayland.windowManager.hyprland = { + plugins = [hypr-official-plugins.packages.${pkgs.system}.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, 4 fingers + gesture_distance = 300; # how far is the "max" + gesture_positive = true; # positive = swipe down. Negative = swipe up. + }; + }; + + bind = [ + "ALT, tab, hyprexpo:expo, toggle" # can be: toggle, off/disable or on/enable + ]; + }; + }; +} diff --git a/modules/hyprland/hyprgrass.nix b/modules/hyprland/hyprgrass.nix new file mode 100644 index 00000000..cada6e1a --- /dev/null +++ b/modules/hyprland/hyprgrass.nix @@ -0,0 +1,41 @@ +{ + osConfig, + hyprgrass, + lib, + pkgs, + ... +}: let + inherit (lib) optionalAttrs; + + isTouchscreen = osConfig.hardware.sensor.iio.enable; +in + optionalAttrs isTouchscreen { + wayland.windowManager.hyprland = { + plugins = [hyprgrass.packages.${pkgs.system}.default]; + + 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; + + experimental = { + # 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 + send_cancel = 0; + }; + }; + }; + + gestures = { + workspace_swipe = true; + workspace_swipe_fingers = 3; + workspace_swipe_cancel_ratio = 0.15; + }; + }; + }; + } diff --git a/modules/hyprland/hyprlock.nix b/modules/hyprland/hyprlock.nix new file mode 100644 index 00000000..c9611e80 --- /dev/null +++ b/modules/hyprland/hyprlock.nix @@ -0,0 +1,59 @@ +{ + config, + hyprlock, + lib, + ... +}: let + inherit (lib) optionalString; + inherit (config.vars) mainMonitor; + + monitor = optionalString (mainMonitor != null) mainMonitor; +in { + imports = [hyprlock.homeManagerModules.default]; + + programs.hyprlock = { + enable = true; + general = { + hide_cursor = false; + }; + + backgrounds = [ + { + path = "screenshot"; + blur_size = 5; + blur_passes = 2; + vibrancy_darkness = 0.0; + brightness = 1.0; + } + ]; + + input-fields = [ + { + inherit monitor; + fade_on_empty = false; + outer_color = "rgba(10, 10, 10, 1.0)"; + inner_color = "rgb(151515)"; + font_color = "rgba(240, 240, 240, 1.0)"; # This is the dot color + capslock_color = "rgba(171, 12, 8, 1.0)"; + placeholder_text = ''<span foreground="##cccccc" style="italic">Input Password...</span>''; + } + ]; + + labels = [ + { + inherit monitor; + text = "$TIME"; + font_size = 80; + font_family = "Ubuntu Mono"; + position.y = 240; + shadow_passes = 3; + } + { + inherit monitor; + text = "<i> Groovy </i>"; + font_family = "Ubuntu Mono"; + shadow_passes = 3; + } + ]; + }; +} diff --git a/modules/hyprland/inputs.nix b/modules/hyprland/inputs.nix new file mode 100644 index 00000000..95214526 --- /dev/null +++ b/modules/hyprland/inputs.nix @@ -0,0 +1,54 @@ +{ + lib, + osConfig, + ... +}: let + inherit (lib) optionals; + inherit (osConfig.services.xserver) xkb; + inherit (osConfig.vars) mainMonitor; + + nagaProNames = [ + # Wireless + "razer-razer-naga-pro" + + # Wired (it always changes) + "razer-razer-naga-pro-1" + "razer-naga-pro" + "razer-naga-pro-1" + "razer-naga-pro-2" + "razer-naga-pro-3" + ]; + nagaConf = name: { + inherit name; + sensitivity = 0; + accel_profile = "flat"; + }; +in { + wayland.windowManager.hyprland = { + settings = { + device = map (d: (nagaConf d)) nagaProNames; + + input = { + kb_layout = xkb.layout; + kb_variant = xkb.variant; + follow_mouse = true; + + touchpad = { + natural_scroll = true; + disable_while_typing = false; + }; + }; + + bind = [ + ",XF86AudioPlay, exec, playerctl play-pause" + ",XF86AudioStop, exec, playerctl stop" + ",XF86AudioNext, exec, playerctl next" + ",XF86AudioPrev, exec, playerctl previous" + ]; + + exec-once = + optionals (! isNull mainMonitor) + ["hyprctl dispatch focusmonitor ${mainMonitor}"]; + }; + }; +} diff --git a/modules/hyprland/packages.nix b/modules/hyprland/packages.nix new file mode 100644 index 00000000..ca85075b --- /dev/null +++ b/modules/hyprland/packages.nix @@ -0,0 +1,132 @@ +{ + config, + lib, + pkgs, + ... +}: let + inherit (lib) makeLibraryPath optionalString; + inherit (config.vars) mainUser; + flakeDir = config.environment.variables.FLAKE; +in { + imports = [../dolphin.nix]; + + programs.kdeconnect.enable = true; + + home-manager.users.${mainUser} = { + imports = [ + ../../home/foot.nix + ../../home/mpv + ../../home/obs.nix + ../../home/wezterm + ../../home/wofi + + ({config, ...}: let + symlink = config.lib.file.mkOutOfStoreSymlink; + configDir = "${flakeDir}/modules/hyprland/config"; + in { + xdg.configFile = { + "dolphinrc".source = symlink "${configDir}/dolphinrc"; + "kdeglobals".source = symlink "${configDir}/kdeglobals"; + "kiorc".source = symlink "${configDir}/kiorc"; + "mimeapps.list".source = symlink "${configDir}/mimeapps.list"; + "neofetch".source = symlink "${configDir}/neofetch"; + "swappy".source = symlink "${configDir}/swappy"; + }; + }) + ]; + + home.packages = with pkgs; [ + # School + xournalpp + virt-manager + libreoffice-fresh # TODO: declarative conf? + hunspell + hunspellDicts.en_CA + config.customPkgs.rars-flatlaf + + # Apps + thunderbird # TODO: use programs.thunderbird + protonmail-bridge + spotifywm + photoqt + nextcloud-client + jellyfin-media-player + prismlauncher-qt5 + + # tools + wl-color-picker + wl-clipboard + cliphist + grim + slurp + swappy + + /* + Discord themes for Vencord + https://markchan0225.github.io/RoundedDiscord/RoundedDiscord.theme.css + https://raw.githubusercontent.com/dracula/BetterDiscord/master/Dracula_Official.theme.css + */ + (symlinkJoin { + name = "discord"; + paths = [ + (discord.override { + withOpenASAR = true; + withVencord = true; + }) + ]; + buildInputs = [makeWrapper]; + postBuild = '' + wrapProgram $out/bin/Discord ${optionalString config.nvidia.enable + ''--prefix LD_LIBRARY_PATH : "${makeLibraryPath [ + addOpenGLRunpath.driverLink + libglvnd + ]}"''} \ + --add-flags "--enable-features=UseOzonePlatform,WebRTCPipeWireCapturer --ozone-platform=wayland" + ''; + }) + ]; + + wayland.windowManager.hyprland = { + settings = { + exec-once = [ + "${config.programs.kdeconnect.package}/libexec/kdeconnectd" + "kdeconnect-indicator" + + "wl-paste --watch cliphist store" + + "sleep 3; nextcloud --background" + "sleep 3; protonmail-bridge --noninteractive --log-level info" + + "[workspace special:thunder silent] thunderbird" + "[workspace special:spot silent] spotify" + ]; + + windowrule = [ + "noborder,^(wofi)$" + "tile,^(libreoffice)$" + "float,^(org.gnome.Calculator)$" + + "float,^(com.nextcloud.desktopclient.nextcloud)$" + "move cursor -15 -10,^(com.nextcloud.desktopclient.nextcloud)$" + "size 400 581,^(com.nextcloud.desktopclient.nextcloud)$" + + "workspace special:thunder silent,^(thunderbird)$" + "workspace special:spot silent,^(Spotify)$" + ]; + + bind = [ + "$mainMod, Q, exec, foot" + + # Clipboard History + "$mainMod, V, exec, killall -r wofi || cliphist list | wofi --dmenu | cliphist decode | wl-copy" + + ",Print, exec, grim -g \"$(slurp)\" - | swappy -f -" + "$mainMod SHIFT, C, exec, wl-color-picker" + + "$mainMod, T, togglespecialworkspace, thunder" + "$mainMod, S, togglespecialworkspace, spot" + ]; + }; + }; + }; +} diff --git a/modules/hyprland/security.nix b/modules/hyprland/security.nix new file mode 100644 index 00000000..8f42b78d --- /dev/null +++ b/modules/hyprland/security.nix @@ -0,0 +1,71 @@ +{ + config, + hypridle, + lib, + pkgs, + ... +}: let + inherit (lib) mkIf; + inherit (config.vars) mainUser; + + isLaptop = config.services.logind.lidSwitch == "lock"; +in { + imports = [ + ../greetd + ]; + + security.pam.services.hyprlock = {}; + services.gnome.gnome-keyring.enable = true; + + home-manager.users.${mainUser} = let + hmCfg = config.home-manager.users.${mainUser}; + lockPkg = pkgs.writeShellApplication { + name = "lock"; + runtimeInputs = [ + hmCfg.programs.ags.finalPackage + hmCfg.programs.hyprlock.package + ]; + text = '' + ags -r 'Tablet.setLaptopMode()' + hyprlock + ''; + }; + in { + imports = [ + ./hyprlock.nix + hypridle.homeManagerModules.default + ]; + + home.packages = with pkgs; [ + gnome.seahorse + ]; + + services.hypridle = mkIf isLaptop { + enable = true; + lockCmd = "${lockPkg}/bin/lock"; + }; + + 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,^(org.kde.polkit-kde-authentication-agent-1)$" + "size 741 288,^(org.kde.polkit-kde-authentication-agent-1)$" + "center,^(org.kde.polkit-kde-authentication-agent-1)$" + + # For GParted auth + "size 741 288,^(org.kde.ksshaskpass)$" + "move cursor -370 -144,^(org.kde.ksshaskpass)$" + ]; + + bind = [ + "$mainMod, L, exec, ${lockPkg}/bin/lock" + ]; + }; + }; + }; +} diff --git a/modules/hyprland/style.nix b/modules/hyprland/style.nix new file mode 100644 index 00000000..31bd4088 --- /dev/null +++ b/modules/hyprland/style.nix @@ -0,0 +1,37 @@ +{ + config, + pkgs, + ... +}: let + inherit (config.vars) configDir; +in { + imports = [../../home/theme]; + + home.packages = with pkgs; [swww]; + + wayland.windowManager.hyprland = { + settings = { + env = ["XCURSOR_SIZE, 24"]; + + exec-once = [ + "hyprctl setcursor Dracula-cursors 24" + "sleep 0.1 && swww init --no-cache && swww img -t none ${pkgs.dracula-theme}/wallpapers/waves.png" + ]; + + windowrule = [ + "size 1231 950,title:^(Open Folder)$" + "float,title:^(Open Folder)$" + + "size 1231 950,title:^(Open File)$" + "float,title:^(Open File)$" + ]; + + layerrule = [ + "noanim, selection" + ]; + + # This file should only be used for theming + source = ["${configDir}/hypr/main.conf"]; + }; + }; +} diff --git a/modules/kmscon.nix b/modules/kmscon.nix new file mode 100644 index 00000000..b1fd1386 --- /dev/null +++ b/modules/kmscon.nix @@ -0,0 +1,16 @@ +{config, ...}: let + inherit (config.services.xserver) xkb; +in { + services.kmscon = { + enable = true; + hwRender = false; + # FIXME: https://github.com/Aetf/kmscon/issues/18 // Icons not rendering properly + extraOptions = builtins.concatStringsSep " " [ + "--font-size 12.5" + "--font-dpi 170" + "--xkb-layout ${xkb.layout}" + "--xkb-variant ${xkb.variant}" + "--font-name 'JetBrainsMono Nerd Font'" + ]; + }; +} 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.nix b/modules/nvidia.nix new file mode 100644 index 00000000..4d798860 --- /dev/null +++ b/modules/nvidia.nix @@ -0,0 +1,102 @@ +{ + config, + lib, + pkgs, + ... +}: let + inherit (lib) mdDoc mkIf mkEnableOption mkOption optionals types; + + cfg = config.nvidia; +in { + options.nvidia = { + enable = mkEnableOption (mdDoc "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 { + # Enable OpenGL + hardware.opengl = { + enable = true; + driSupport = true; + driSupport32Bit = true; + + extraPackages = with pkgs; [ + vaapiVdpau + libvdpau-va-gl + nvidia-vaapi-driver + ]; + extraPackages32 = with pkgs; [vaapiVdpau]; + }; + + services.xserver.videoDrivers = ["nvidia"]; + + hardware.nvidia = { + modesetting.enable = true; + + # Enable the Nvidia settings menu, + # accessible via `nvidia-settings`. + nvidiaSettings = cfg.enableNvidiaSettings; + + # Nvidia power management. Experimental, and can cause sleep/suspend to fail. + powerManagement = { + enable = false; + + # Fine-grained power management. Turns off GPU when not in use. + # Experimental and only works on modern Nvidia GPUs (Turing or newer). + finegrained = false; + }; + + open = cfg.enableWayland; + + package = with config.boot.kernelPackages.nvidiaPackages; + if !cfg.enableWayland + then stable + else let + rcu_patch = pkgs.fetchpatch { + url = "https://github.com/gentoo/gentoo/raw/c64caf53/x11-drivers/nvidia-drivers/files/nvidia-drivers-470.223.02-gpl-pfn_valid.patch"; + hash = "sha256-eZiQQp2S/asE7MfGvfe6dA/kdCvek9SYa/FFGp24dVg="; + }; + in + # Keep the driver version at 535.xx.xx for Wayland desktop + # games stutter on more recent versions + # https://github.com/NixOS/nixpkgs/blob/e256f39bec8e01808c0a3e411d961cbced3f4e09/pkgs/os-specific/linux/nvidia-x11/default.nix#L70 + mkDriver rec { + version = "535.43.28"; + persistencedVersion = "535.98"; + settingsVersion = "535.98"; + sha256_64bit = "sha256-ic7r3MPp65fdEwqDRyc0WiKonL5eF6KZUpfD/C3vYaU="; + openSha256 = "sha256-a5iccyISHheOfTwpsrz6puqrVhgzYWFvNlykVG3+PVc="; + settingsSha256 = "sha256-jCRfeB1w6/dA27gaz6t5/Qo7On0zbAPIi74LYLel34s="; + persistencedSha256 = "sha256-WviDU6B50YG8dO64CGvU3xK8WFUX8nvvVYm/fuGyroM="; + url = "https://developer.nvidia.com/downloads/vulkan-beta-${lib.concatStrings (lib.splitVersion version)}-linux"; + + patches = [rcu_patch]; + }; + }; + + environment.systemPackages = with pkgs; ([ + libva-utils + nvidia-vaapi-driver + nvtopPackages.nvidia + pciutils + vdpauinfo + ] + ++ optionals cfg.enableCUDA [cudaPackages.cudatoolkit]); + + boot.kernelModules = optionals cfg.enableCUDA ["nvidia-uvm"]; + }; +} 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.nix b/modules/plymouth.nix new file mode 100644 index 00000000..18571e38 --- /dev/null +++ b/modules/plymouth.nix @@ -0,0 +1,27 @@ +{pkgs, ...}: { + 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" + ]; + + plymouth = { + enable = true; + themePackages = [pkgs.dracula-theme]; + theme = "dracula"; + }; + }; +} 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/printer.nix b/modules/printer.nix new file mode 100644 index 00000000..43fd5fd6 --- /dev/null +++ b/modules/printer.nix @@ -0,0 +1,11 @@ +{pkgs, ...}: { + services = { + # Enable CUPS to print documents. + printing = { + enable = true; + drivers = with pkgs; [ + hplip + ]; + }; + }; +} diff --git a/modules/quickshell/config/.envrc b/modules/quickshell/config/.envrc deleted file mode 100644 index 3cd98c4c..00000000 --- a/modules/quickshell/config/.envrc +++ /dev/null @@ -1 +0,0 @@ -use flake "$FLAKE#qml" diff --git a/modules/quickshell/config/.qmlformat.ini b/modules/quickshell/config/.qmlformat.ini deleted file mode 100644 index 47f522b7..00000000 --- a/modules/quickshell/config/.qmlformat.ini +++ /dev/null @@ -1,8 +0,0 @@ -[General] -FunctionsSpacing=true -IndentWidth=4 -MaxColumnWidth=-1 -NewlineType=native -NormalizeOrder=true -ObjectsSpacing=true -UseTabs=false diff --git a/modules/quickshell/config/.qmllint.ini b/modules/quickshell/config/.qmllint.ini deleted file mode 100644 index 1756e578..00000000 --- a/modules/quickshell/config/.qmllint.ini +++ /dev/null @@ -1,42 +0,0 @@ -[General] -DisableDefaultImports=false -MaxWarnings=-1 - -[Warnings] -AccessSingletonViaObject=warning -AttachedPropertyReuse=disable -BadSignalHandlerParameters=warning -CompilerWarnings=disable -Deprecated=warning -DuplicatePropertyBinding=warning -DuplicatedName=warning -ImportFailure=warning -IncompatibleType=warning -InheritanceCycle=warning -InvalidLintDirective=warning -LintPluginWarnings=disable -MissingProperty=warning -MissingType=warning -MultilineStrings=info -NonListProperty=warning -PrefixedImportType=warning -PropertyAliasCycles=warning -Quick.Anchors=warning -Quick.AttachedPropertyReuse=disable -Quick.AttachedPropertyType=warning -Quick.ControlsAttachedPropertyReuse=disable -Quick.ControlsNativeCustomize=warning -Quick.LayoutsPositioning=warning -Quick.PropertyChangesParsed=warning -Quick.UnexpectedVarType=warning -ReadOnlyProperty=warning -RequiredProperty=warning -RestrictedType=warning -TopLevelComponent=warning -UncreatableType=disable -UnqualifiedAccess=warning -UnresolvedType=warning -UnusedImports=info -UseProperFunction=warning -VarUsedBeforeDeclaration=warning -WithStatement=warning diff --git a/modules/quickshell/config/Components/RoundCorner/RoundCorner.qml b/modules/quickshell/config/Components/RoundCorner/RoundCorner.qml deleted file mode 100644 index ac0f7c0b..00000000 --- a/modules/quickshell/config/Components/RoundCorner/RoundCorner.qml +++ /dev/null @@ -1,61 +0,0 @@ -import QtQuick - -Item { - id: root - - enum Corner { - TopLeft, - TopRight, - BottomLeft, - BottomRight - } - - property color color: "black" - property int corner: RoundCorner.Corner.TopLeft - - property int size: 15 - - height: size - width: size - - onColorChanged: { - canvas.requestPaint(); - } - - Canvas { - id: canvas - - anchors.fill: parent - antialiasing: true - - onPaint: { - var ctx = getContext("2d"); - var r = root.size; - - ctx.beginPath(); - - switch (root.corner) { - case RoundCorner.Corner.TopLeft: - ctx.arc(r, r, r, Math.PI, 3 * Math.PI / 2); - ctx.lineTo(0, 0); - break; - case RoundCorner.Corner.TopRight: - ctx.arc(0, r, r, 3 * Math.PI / 2, 2 * Math.PI); - ctx.lineTo(r, 0); - break; - case RoundCorner.Corner.BottomLeft: - ctx.arc(r, 0, r, Math.PI / 2, Math.PI); - ctx.lineTo(0, r); - break; - case RoundCorner.Corner.BottomRight: - ctx.arc(0, 0, r, 0, Math.PI / 2); - ctx.lineTo(r, r); - break; - } - - ctx.closePath(); - ctx.fillStyle = root.color; - ctx.fill(); - } - } -} diff --git a/modules/quickshell/config/Config/Theme/Theme.qml b/modules/quickshell/config/Config/Theme/Theme.qml deleted file mode 100644 index 4e6129c6..00000000 --- a/modules/quickshell/config/Config/Theme/Theme.qml +++ /dev/null @@ -1,93 +0,0 @@ -import QtQuick - -Item { - id: dracula - - readonly property color accentBg: '#bd93f9' - readonly property color accentFg: '#f8f8f2' - readonly property color cardBg: Qt.rgba(255, 255, 255, 0.08) - readonly property color cardFg: dracula.accentFg - readonly property color cardShade: Qt.rgba(0, 0, 0, 0.36) - readonly property color colorBlack: '#151720' - readonly property color colorBlue: '#86aaec' - readonly property color colorBlue1: '#99c1f1' - readonly property color colorBlue2: '#62a0ea' - readonly property color colorBlue3: '#3584e4' - readonly property color colorBlue4: '#1c71d8' - readonly property color colorBlue5: '#1a5fb4' - readonly property color colorBrown1: '#cdab8f' - readonly property color colorBrown2: '#b5835a' - readonly property color colorBrown3: '#986a44' - readonly property color colorBrown4: '#865e3c' - readonly property color colorBrown5: '#63452c' - readonly property color colorCyan: '#93cee9' - readonly property color colorDark1: '#77767b' - readonly property color colorDark2: '#5e5c64' - readonly property color colorDark3: '#3d3846' - readonly property color colorDark4: '#241f31' - readonly property color colorDark5: '#000000' - readonly property color colorDimBlack: '#1a1c25' - readonly property color colorGreen: '#90ceaa' - readonly property color colorGreen1: '#8ff0a4' - readonly property color colorGreen2: '#57e389' - readonly property color colorGreen3: '#33d17a' - readonly property color colorGreen4: '#2ec27e' - readonly property color colorGreen5: '#26a269' - readonly property color colorJavacafeBlue: '#86aaec' - readonly property color colorJavacafeMagenta: '#c296eb' - readonly property color colorLight1: 'white' - readonly property color colorLight2: '#f6f5f4' - readonly property color colorLight3: '#deddda' - readonly property color colorLight4: '#c0bfbc' - readonly property color colorLight5: '#9a9996' - readonly property color colorLightBlack: '#262831' - readonly property color colorMagenta: '#c296eb' - readonly property color colorOrange1: '#ffbe6f' - readonly property color colorOrange2: '#ffa348' - readonly property color colorOrange3: '#ff7800' - readonly property color colorOrange4: '#e66100' - readonly property color colorOrange5: '#c64600' - readonly property color colorPurple: '#c296eb' - readonly property color colorPurple1: '#dc8add' - readonly property color colorPurple2: '#c061cb' - readonly property color colorPurple3: '#9141ac' - readonly property color colorPurple4: '#813d9c' - readonly property color colorPurple5: '#613583' - readonly property color colorRed: '#dd6777' - readonly property color colorRed1: '#f66151' - readonly property color colorRed2: '#ed333b' - readonly property color colorRed3: '#e01b24' - readonly property color colorRed4: '#c01c28' - readonly property color colorRed5: '#a51d2d' - readonly property color colorYellow: '#ecd3a0' - readonly property color colorYellow1: '#f9f06b' - readonly property color colorYellow2: '#f8e45c' - readonly property color colorYellow3: '#f6d32d' - readonly property color colorYellow4: '#f5c211' - readonly property color colorYellow5: '#e5a50a' - readonly property color darkWindowBg: '#21232D' - readonly property color destructiveBg: dracula.errorBg - readonly property color destructiveFg: dracula.accentFg - readonly property color dialogBg: dracula.windowBg - readonly property color dialogFg: dracula.accentFg - readonly property color errorBg: '#ff5555' - readonly property color errorFg: dracula.accentFg - readonly property color headerbarBackdrop: dracula.windowBg - readonly property color headerbarBg: dracula.windowBg - readonly property color headerbarBorder: 'white' - readonly property color headerbarFg: dracula.accentFg - readonly property color headerbarShade: Qt.rgba(0, 0, 0, 0.36) - readonly property color lightWindowBg: '#333643' - readonly property color popoverBg: dracula.windowBg - readonly property color popoverFg: dracula.accentFg - readonly property color scrollbarOutline: Qt.rgba(0, 0, 0, 0.5) - readonly property color shade: '#383838' - readonly property color successBg: '#50fa7b' - readonly property color successFg: dracula.accentFg - readonly property color viewBg: dracula.windowBg - readonly property color viewFg: dracula.accentFg - readonly property color warningBg: '#f1fa8c' - readonly property color warningFg: Qt.rgba(0, 0, 0, 0.8) - readonly property color windowBg: '#282a36' - readonly property color windowFg: dracula.accentFg -} diff --git a/modules/quickshell/config/Services/DateTime/DateTime.qml b/modules/quickshell/config/Services/DateTime/DateTime.qml deleted file mode 100644 index abcc2f56..00000000 --- a/modules/quickshell/config/Services/DateTime/DateTime.qml +++ /dev/null @@ -1,49 +0,0 @@ -pragma Singleton -pragma ComponentBehavior: Bound -import QtQuick -import Quickshell -import Quickshell.Io - -Singleton { - property string time: Qt.formatDateTime(clock.date, "ddd. d MMM. h:mm AP") - property string uptime: "0h, 0m" - - SystemClock { - id: clock - - precision: SystemClock.Minutes - } - - Timer { - interval: 10 - repeat: true - running: true - - onTriggered: { - fileUptime.reload(); - const textUptime = fileUptime.text(); - const uptimeSeconds = Number(textUptime.split(" ")[0] ?? 0); - - // Convert seconds to days, hours, and minutes - const days = Math.floor(uptimeSeconds / 86400); - const hours = Math.floor((uptimeSeconds % 86400) / 3600); - const minutes = Math.floor((uptimeSeconds % 3600) / 60); - - // Build the formatted uptime string - let formatted = ""; - if (days > 0) - formatted += `${days}d`; - if (hours > 0) - formatted += `${formatted ? ", " : ""}${hours}h`; - if (minutes > 0 || !formatted) - formatted += `${formatted ? ", " : ""}${minutes}m`; - DateTime.uptime = formatted; - } - } - - FileView { - id: fileUptime - - path: "/proc/uptime" - } -} diff --git a/modules/quickshell/config/Widgets/Bar/Bar.qml b/modules/quickshell/config/Widgets/Bar/Bar.qml deleted file mode 100644 index 6f781fdc..00000000 --- a/modules/quickshell/config/Widgets/Bar/Bar.qml +++ /dev/null @@ -1,113 +0,0 @@ -import Quickshell -import QtQuick -import QtQuick.Controls -import QtQuick.Layouts - -import "../../Components/RoundCorner" -import "../../Config/Theme" -import "../../Services/DateTime" - -PanelWindow { - id: toplevel - - color: "transparent" - exclusiveZone: bar.height - - Theme { - id: theme - - } - - anchors { - left: true - right: true - top: true - } - - Rectangle { - id: bar - - color: theme.windowBg - height: 50 - - anchors { - left: parent.left - right: parent.right - } - - RoundButton { - id: button - - anchors.centerIn: parent - radius: 5 - - background: Rectangle { - id: background - - anchors.centerIn: parent - color: { - if (button.down) { - return theme.windowBg; - } else if (button.hovered) { - return theme.lightWindowBg; - } else { - return theme.darkWindowBg; - } - } - height: clockText.height + 0.4 * clockText.height - opacity: enabled ? 1 : 0.3 - radius: 5 - width: clockText.width + 0.1 * clockText.width - - Behavior on color { - ColorAnimation { - duration: 200 - target: background - } - } - } - contentItem: Text { - id: clockText - - anchors.centerIn: parent - color: theme.windowFg - renderType: Text.NativeRendering - text: DateTime.time - - font { - pointSize: 16 - weight: 500 - } - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - } - } - } - - RowLayout { - spacing: bar.width - leftCorner.width - rightCorner.width - - anchors { - left: parent.left - right: parent.right - top: bar.bottom - } - - RoundCorner { - id: leftCorner - - color: theme.windowBg - corner: RoundCorner.Corner.TopLeft - } - - RoundCorner { - id: rightCorner - - color: theme.windowBg - corner: RoundCorner.Corner.TopRight - } - } -} diff --git a/modules/quickshell/config/Widgets/ScreenCorners/ScreenCorners.qml b/modules/quickshell/config/Widgets/ScreenCorners/ScreenCorners.qml deleted file mode 100644 index ab5f0934..00000000 --- a/modules/quickshell/config/Widgets/ScreenCorners/ScreenCorners.qml +++ /dev/null @@ -1,60 +0,0 @@ -import QtQuick -import QtQuick.Controls -import Quickshell -import Quickshell.Wayland - -import "../../Components/RoundCorner" - -Scope { - id: screenCorners - - readonly property Toplevel activeWindow: ToplevelManager.activeToplevel - - Variants { - model: Quickshell.screens - - PanelWindow { - property var modelData - - WlrLayershell.layer: WlrLayer.Overlay - WlrLayershell.namespace: "quickshell:screenCorners" - color: "transparent" - exclusionMode: ExclusionMode.Ignore - screen: modelData - - mask: Region { - } - - anchors { - bottom: true - left: true - right: true - top: true - } - - RoundCorner { - anchors.left: parent.left - anchors.top: parent.top - corner: RoundCorner.Corner.TopLeft - } - - RoundCorner { - anchors.right: parent.right - anchors.top: parent.top - corner: RoundCorner.Corner.TopRight - } - - RoundCorner { - anchors.bottom: parent.bottom - anchors.left: parent.left - corner: RoundCorner.Corner.BottomLeft - } - - RoundCorner { - anchors.bottom: parent.bottom - anchors.right: parent.right - corner: RoundCorner.Corner.BottomRight - } - } - } -} diff --git a/modules/quickshell/config/shell.qml b/modules/quickshell/config/shell.qml deleted file mode 100644 index d427071b..00000000 --- a/modules/quickshell/config/shell.qml +++ /dev/null @@ -1,13 +0,0 @@ -import Quickshell -import QtQuick - -import "./Widgets/Bar" -import "./Widgets/ScreenCorners" - -ShellRoot { - Bar { - } - - ScreenCorners { - } -} diff --git a/modules/quickshell/default.nix b/modules/quickshell/default.nix deleted file mode 100644 index 16ee01c6..00000000 --- a/modules/quickshell/default.nix +++ /dev/null @@ -1,41 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) hasPrefix mkIf removePrefix; - - # Configs - cfgDesktop = config.roles.desktop; - flakeDir = config.environment.variables.FLAKE; - - qsConfigDir = "${removePrefix "/home/${cfgDesktop.user}/" flakeDir}/modules/quickshell/config"; -in { - config = mkIf cfgDesktop.quickshell.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 my quickshell module. - ''; - } - ]; - - # Machine config - environment.systemPackages = [ - (pkgs.writeShellApplication { - name = "quickshell"; - runtimeInputs = [pkgs.quickshell]; - text = '' - if [ "$#" == 0 ]; then - exec qs --path ~/${qsConfigDir} - else - exec qs "$@" - fi - ''; - }) - ]; - }; -} diff --git a/modules/razer.nix b/modules/razer.nix new file mode 100644 index 00000000..a2cd5ab3 --- /dev/null +++ b/modules/razer.nix @@ -0,0 +1,35 @@ +{ + config, + lib, + pkgs, + ... +}: let + inherit (config.vars) mainUser; + inherit (lib) mkIf; + + cfgHypr = + config + .home-manager + .users + .${mainUser} + .wayland + .windowManager + .hyprland; +in { + hardware.openrazer = { + enable = true; + users = [mainUser]; + }; + + environment.systemPackages = with pkgs; [ + openrazer-daemon + polychromatic + ]; + + # HOME-MANAGER CONFIG + home-manager.users.${mainUser} = { + wayland.windowManager.hyprland = mkIf (cfgHypr.enable) { + settings.exec-once = ["polychromatic-tray-applet"]; + }; + }; +} 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/sshd.nix b/modules/sshd.nix new file mode 100644 index 00000000..e0334fc2 --- /dev/null +++ b/modules/sshd.nix @@ -0,0 +1,21 @@ +{config, ...}: let + inherit (config.vars) mainUser; +in { + services = { + openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + PermitRootLogin = "no"; + }; + }; + }; + + users.users.${mainUser} = { + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPE39uk52+NIDLdHeoSHIEsOUUFRzj06AGn09z4TUOYm matt@OP9" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICr2+CpqXNMLsjgbrYyIwTKhlVSiIYol1ghBPzLmUpKl matt@binto" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJGbLu+Gb7PiyNgNXMHemaQLnKixebx1/4cdJGna9OQp matt@wim" + ]; + }; +} diff --git a/modules/tailscale.nix b/modules/tailscale.nix new file mode 100644 index 00000000..7ae644cc --- /dev/null +++ b/modules/tailscale.nix @@ -0,0 +1,37 @@ +{config, ...}: let + inherit (config.vars) hostName mainUser; +in { + services = { + tailscale = { + enable = true; + # TODO: add authKeyFile to get extraUpFlags to work + # https://github.com/juanfont/headscale/issues/1550 + # https://github.com/juanfont/headscale/blob/main/docs/running-headscale-linux-manual.md#register-machine-using-a-pre-authenticated-key + # https://www.reddit.com/r/NixOS/comments/18kz1nb/tailscale_extraupflags_not_working/ + extraUpFlags = [ + "--login-server https://headscale.nelim.org" + "--operator=matt" + ]; + }; + }; + + home-manager.users.${mainUser} = { + 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}'"; + + # Cluster nodes + thingone = "ssh -t matt@thingone 'tmux -2u new -At ${hostName}'"; + thingtwo = "ssh -t matt@thingtwo 'tmux -2u new -At ${hostName}'"; + }; + }; +} 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/overlays/README.md b/overlays/README.md deleted file mode 100644 index 3879794e..00000000 --- a/overlays/README.md +++ /dev/null @@ -1,15 +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. | -| `forced` | Overrides packages from third party flakes that don't offer overlays. | -| `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 8db84dce..00000000 --- a/overlays/default.nix +++ /dev/null @@ -1,72 +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. - ''; - - forced = - overlay - (import ./forced self) - '' - Overrides packages from third party flakes that don't offer overlays. - ''; - - 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/forced/default.nix b/overlays/forced/default.nix deleted file mode 100644 index 4dc76ad4..00000000 --- a/overlays/forced/default.nix +++ /dev/null @@ -1,15 +0,0 @@ -self: final: prev: let - inherit (self.inputs) quickshell; - - overrideAll = self.lib.overrideAll final; -in { - quickshell = overrideAll quickshell.packages.${final.system}.default { - gitRev = quickshell.rev; - - buildStdenv = final.clangStdenv; - - debug = false; - withI3 = false; - withX11 = false; - }; -} diff --git a/overlays/misc-fixes/default.nix b/overlays/misc-fixes/default.nix deleted file mode 100644 index 90cf4aae..00000000 --- a/overlays/misc-fixes/default.nix +++ /dev/null @@ -1,24 +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; - }); - - # normal electron has a lot of cache misses for me - electron = final.electron-bin; -} diff --git a/overlays/nix-version/default.nix b/overlays/nix-version/default.nix deleted file mode 100644 index 3f802594..00000000 --- a/overlays/nix-version/default.nix +++ /dev/null @@ -1,51 +0,0 @@ -self: {nix ? null}: final: prev: let - inherit (builtins) mapAttrs replaceStrings; - inherit (final.lib) generateSplicesForMkScope versions; - inherit (self.inputs) nix-eval-jobs nix-fast-build; - - nullCheck = n: v: - if nix == null - then prev.${n} - else v; - - overrideAll = self.lib.overrideAll final; -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 a1ae4798..00000000 --- a/packages/README.md +++ /dev/null @@ -1,27 +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 | -| `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 | -| `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 ecbaa54e..00000000 --- a/packages/default.nix +++ /dev/null @@ -1,58 +0,0 @@ -{ - inputs, - mkVersion, - ... -}: (final: prev: { - selfPackages = { - coloryou = final.python3Packages.callPackage ./coloryou {}; - - gpu-screen-recorder = final.callPackage ./gpu-screen-recorder { - inherit (inputs) gpu-screen-recorder-src; - }; - - homepage = final.callPackage ./homepage {}; - - jdownloader-cli = final.callPackage ./jdownloader-cli {}; - - jmusicbot = final.callPackage ./jmusicbot {}; - - 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/default.nix b/packages/gpu-screen-recorder/default.nix deleted file mode 100644 index ebc04e28..00000000 --- a/packages/gpu-screen-recorder/default.nix +++ /dev/null @@ -1,24 +0,0 @@ -{ - callPackage, - gpu-screen-recorder-src, - ... -}: let - gpu-screen-recorder = callPackage ./gpu-screen-recorder.nix { - inherit gpu-screen-recorder-src; - }; - - gsr-kms-server = callPackage ./gsr-kms-server.nix { - inherit gpu-screen-recorder-src; - }; - - gsr-dbus-server = callPackage ./gsr-dbus-server.nix { - inherit gpu-screen-recorder-src; - }; -in - gpu-screen-recorder.overrideAttrs (o: { - passthru = - o.passthru or {} - // { - inherit gsr-kms-server gsr-dbus-server; - }; - }) diff --git a/packages/gpu-screen-recorder/generic.nix b/packages/gpu-screen-recorder/generic.nix deleted file mode 100644 index e784db70..00000000 --- a/packages/gpu-screen-recorder/generic.nix +++ /dev/null @@ -1,119 +0,0 @@ -{ - # params - pname, - description, - # 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 (pname == "gsr-kms-server") - # 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 = - optionalString (pname == "gsr-kms-server") - # bash - '' - rm $out/bin/{gpu-screen-recorder,gsr-dbus-server} - '' - + optionalString (pname == "gpu-screen-recorder") - # bash - '' - rm $out/bin/{gsr-kms-server,gsr-dbus-server} - '' - + optionalString (pname == "gsr-dbus-server") - # bash - '' - rm $out/bin/{gpu-screen-recorder,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-dbus-server.nix b/packages/gpu-screen-recorder/gsr-dbus-server.nix deleted file mode 100644 index 006ad8a4..00000000 --- a/packages/gpu-screen-recorder/gsr-dbus-server.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ - callPackage, - gpu-screen-recorder-src, - ... -}: -callPackage ./generic.nix { - pname = "gsr-dbus-server"; - inherit gpu-screen-recorder-src; - - description = '' - Small program to move dbus code to a separate process to allow gpu-screen-recorder to - use cap_sys_nice for better recording performance on AMD. - ''; -} 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 1e2d3672..00000000 --- a/packages/gpu-screen-recorder/gsr-kms-server.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ - callPackage, - gpu-screen-recorder-src, - ... -}: -callPackage ./generic.nix { - pname = "gsr-kms-server"; - 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 4cda83ff..00000000 --- a/packages/homepage/default.nix +++ /dev/null @@ -1,89 +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.2.0"; - - src = fetchFromGitHub { - owner = "gethomepage"; - repo = "homepage"; - rev = "v${finalAttrs.version}"; - hash = "sha256-B6hgQWAILfZNRFN4APX/3T2LcVj2FQPS/CAUdUA+drU="; - }; - - pnpmDeps = pnpm.fetchDeps { - inherit (finalAttrs) pname version src; - hash = "sha256-1WsiSG+dZVpd28bBjf3EYn95sxMCXsQPd27/otWW0nI="; - }; - - 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 - ''; - - 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/jdownloader-cli/default.nix b/packages/jdownloader-cli/default.nix deleted file mode 100644 index 477811f7..00000000 --- a/packages/jdownloader-cli/default.nix +++ /dev/null @@ -1,45 +0,0 @@ -{ - lib, - buildGoModule, - fetchFromGitHub, - installShellFiles, - ... -}: let - pname = "jdownloader-cli"; - version = "1.0.3"; - mainProgram = "jdcli"; -in - buildGoModule { - inherit pname version; - - src = fetchFromGitHub { - owner = "rkosegi"; - repo = pname; - rev = "v${version}"; - hash = "sha256-/qGV+v+Id5C7kTlvcolQmhRf6oHRHBoVXyd5YX0pxhE="; - }; - - 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/komf/default.nix b/packages/komf/default.nix deleted file mode 100644 index f49da76e..00000000 --- a/packages/komf/default.nix +++ /dev/null @@ -1,74 +0,0 @@ -{ - # nix build inputs - lib, - stdenv, - fetchFromGitHub, - makeWrapper, - # deps - gradle_8, - jdk17_headless, - ... -}: let - pname = "komf"; - version = "1.3.0"; - - jdk = jdk17_headless; - gradle = gradle_8.override {java = jdk;}; -in - stdenv.mkDerivation (finalAttrs: { - inherit pname version; - - # TODO: make PR - src = fetchFromGitHub { - # owner = "Snd-R"; - owner = "matt1432"; - repo = pname; - # tag = version; - rev = "f6865e6fd1f84d584c8fbb9adeefd8c245c8567e"; - hash = "sha256-7P2HoXcANAB9si/fQc6+QEaOdvJEcS8vIGce9KQea9o="; - }; - - gradleFlags = ["-Dorg.gradle.java.home=${jdk}"]; - - gradleBuildTask = ":komf-app:shadowjar"; - gradleUpdateTask = finalAttrs.gradleBuildTask; - - # nix build .#komf.mitmCache.updateScript --no-link --print-out-paths - mitmCache = gradle.fetchDeps { - pkg = finalAttrs.finalPackage; - data = ./deps.json; - silent = false; - useBwrap = false; - }; - - nativeBuildInputs = [ - gradle - makeWrapper - ]; - buildInputs = [ - jdk - ]; - - installPhase = '' - runHook preInstall - - mkdir -p $out/{bin,share/komf} - cp komf-app/build/libs/*.jar $out/share/komf/komf.jar - - makeWrapper ${jdk}/bin/java $out/bin/${pname} \ - --add-flags "-jar $out/share/komf/komf.jar" \ - --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/komf/deps.json b/packages/komf/deps.json deleted file mode 100644 index 6b1265bf..00000000 --- a/packages/komf/deps.json +++ /dev/null @@ -1,2061 +0,0 @@ -{ - "!comment": "This is a nixpkgs Gradle dependency lockfile. For more details, refer to the Gradle section in the nixpkgs manual.", - "!version": 1, - "https://dl.google.com/dl/android/maven2": { - "androidx/databinding#databinding-common/8.7.3": { - "jar": "sha256-Zsq4JjnawPbCQzRkwJOwdNYIxLuIfsOKm4vErJgSZzI=", - "pom": "sha256-n+PDSKMnWP7DyJbrWleh9jyiuJXePYZ1E7Zx4e4iDqQ=" - }, - "androidx/databinding#databinding-compiler-common/8.7.3": { - "jar": "sha256-skMcu+ONCjHgAbfDT1L2mjI/yexXO2r+WJPaztWrMoU=", - "pom": "sha256-HHunhKp5zc9OfMtUmGdZgEpo+oz4v/sy0FOP6gwd1Rc=" - }, - "com/android#signflinger/8.7.3": { - "jar": "sha256-wdyixoNjTuGilCmPnHF5V4r2qG4IC9xA+WGRW8XIFC8=", - "pom": "sha256-/EbBXN+8shna1dluzsd0AikmzP+ZMmOEO+srUyup2h8=" - }, - "com/android#zipflinger/8.7.3": { - "jar": "sha256-gd1IVhilCaMjWSm56xMJHYhEUmYd5s5aRcw4scVVQhw=", - "pom": "sha256-eoR+FAkDQ1VYyEcDqQpS+1SGyLdn4MixrOkTVUsqW5g=" - }, - "com/android/databinding#baseLibrary/8.7.3": { - "jar": "sha256-eUETcJ2rIbBsJis3lec8twj7rK5hcV80Nh4a9iN6GHA=", - "pom": "sha256-3t+hkSFIJf8+NUON0wcZMMYfF/g3hz626xvpwqQ97J4=" - }, - "com/android/library#com.android.library.gradle.plugin/8.7.3": { - "pom": "sha256-eo+bqKjZnZBI29ySvJZ9O/dcioHNgoIXceEyktO55fI=" - }, - "com/android/tools#annotations/31.7.3": { - "jar": "sha256-slmV+nsiDTX7uOMl3wcfgpFpG/uv+XNMmOOPRewqc+4=", - "pom": "sha256-IggjjUccCrksasegWaCp7INdWuE5Kq8Lsk5FW3D9a0s=" - }, - "com/android/tools#common/31.7.3": { - "jar": "sha256-q7Wy8olUrAnc+10ZLjVa9BI2yDN6/AixaqGtwOiuv2M=", - "pom": "sha256-fWLfKNC8mKnW3l3Vz5pStYe59NOORrAiqY/KqXLgwMM=" - }, - "com/android/tools#dvlib/31.7.3": { - "jar": "sha256-j9NJWi67ULGqyxtDYtxKRxuHRiwersQ2kbtW+JXpxjY=", - "pom": "sha256-/u38iQ67+yMC/G83ZefB/V0/SBsTdC8nrbYArwRze7Y=" - }, - "com/android/tools#repository/31.7.3": { - "jar": "sha256-FpwueneqMJeIedv4swQ2ZxFlhy/L392mxzWq3bZxA0A=", - "pom": "sha256-/KvwRMRUxajJlJ6d7Flu9eqhvvBDsOEaLBlUspjH2wQ=" - }, - "com/android/tools#sdk-common/31.7.3": { - "jar": "sha256-T6RKfZZ13xPaYU3uUS35CtPkMI0K3bMurZn1fOWPZ18=", - "pom": "sha256-qixXwckc96kRBeDOS73akUUdNka2fZHRVpVdvPTIwdM=" - }, - "com/android/tools#sdklib/31.7.3": { - "jar": "sha256-Cj9wl6SgCzhARreDtwU6WewL2SJWq4S6pr2AeqAoWLM=", - "pom": "sha256-a/777V0ro1SwxNEVT6YIbnSBDSZdfOD5gdpRS4c1kS4=" - }, - "com/android/tools/analytics-library#crash/31.7.3": { - "jar": "sha256-zKl6wpoTKb0xCj6DK25X9GIn5QGqUpwApj3yF8XX30E=", - "pom": "sha256-Y2k1CO6e1TLmb+4Skpna+6kaD41RZMGXS+IqWvLm34c=" - }, - "com/android/tools/analytics-library#protos/31.7.3": { - "jar": "sha256-aSz5gTlf4XGi8in/cMxswd354iYbKOrdoiadZuVQl4Y=", - "pom": "sha256-OULGcsqFS4Ql6JllHPAj9imcYkgXxSCYA0pOXkImS7Q=" - }, - "com/android/tools/analytics-library#shared/31.7.3": { - "jar": "sha256-yte7j5agR6XvehOxyDA0FCKenVByCWRuw7Y6ZIYeHOE=", - "pom": "sha256-XqiMevFXcLSVBzsH77c1WWVGL3JUnJk9+xnz7u2TCfI=" - }, - "com/android/tools/analytics-library#tracker/31.7.3": { - "jar": "sha256-4flUlzpHM/dgJ6X5b6RUctw8wi0nsdyT8/5qRqdWgb4=", - "pom": "sha256-1ag5OTcKdMumfmDfbPGnP3cwJWLCaxMbJikc2AX/iy8=" - }, - "com/android/tools/build#aapt2-proto/8.7.3-12006047": { - "jar": "sha256-sy99Syl1rJ7n8GBUwY8f6p2gRdwaYf9Dbs9UNIADYwI=", - "module": "sha256-vElUf3eyh2nNyoQZjS/s4dZZSikY0RyrPPSxu1eRXis=", - "pom": "sha256-u0XfDcUZLK+jKKGwxaxQJDjeJPM+jvQdyYNt2IzZ8Do=" - }, - "com/android/tools/build#aaptcompiler/8.7.3": { - "jar": "sha256-RwYuueVJfgdClGUo/ZPDiGdz3SM5BZMV9jFtXAXXza8=", - "module": "sha256-Pfe+D8ZksWVlQoGEyMu0DI8iMiojO0qCINu9bTmTU68=", - "pom": "sha256-yhzBgzCbhrtVFahbPJlUgg1jw50AHMdZCCoTGi0vfhY=" - }, - "com/android/tools/build#apksig/8.7.3": { - "jar": "sha256-wHDtE5RinXRkGqCQb2Cy/6Hud+Y2ah+TQ39ZcXsa64k=", - "pom": "sha256-pouibUpuejW77i/lFGYBRubCshcUa5wahrW1q62Zo8k=" - }, - "com/android/tools/build#apkzlib/8.7.3": { - "jar": "sha256-HBpn1vTxhkJ6wWbrqg3YZ/WV1RRPySUlKwX/udGhVrc=", - "pom": "sha256-fDrDehKu9BN7cxbt6jXl3zKmEEjYu6jdNJA7xIUxp90=" - }, - "com/android/tools/build#builder-model/8.7.3": { - "jar": "sha256-ABjH3SyraW4H8UC7HcjAsOyTtr8ZXpOHBDAQrIlNt9c=", - "module": "sha256-thR6gFeGPiAZR1wG9A7W9MHHU6kzTXU4RNgdNfEHXH8=", - "pom": "sha256-TeLf91xue+6OP/9JYo08LwfY0uriXkntj9pkwgM1ssU=" - }, - "com/android/tools/build#builder-test-api/8.7.3": { - "jar": "sha256-d43ZwX5VlAHIDbCOvKtny3c6Q95mV0F7QyCWDSlrm0A=", - "module": "sha256-6iyiLxBrb83jr26EH204l4KmkywivcgIT3vWLdyFLZU=", - "pom": "sha256-GKBnNBY92tqv7Vp8Gim4HwGV+yj12CogkU9UnszCNRU=" - }, - "com/android/tools/build#builder/8.7.3": { - "jar": "sha256-LQrANphsDyVrnzJ4EMJcHd5tWDmVZYDTKD4ODxRsuSY=", - "module": "sha256-iQxY1qte99ABTaqN3zj9W2iqStY8m7TdQl2jPqZAB7M=", - "pom": "sha256-9E/DMAcOdQDMrwmvaHWC2LSYq6oHD01qwzfLvR+MLY8=" - }, - "com/android/tools/build#bundletool/1.17.1": { - "jar": "sha256-OS/TsJm9grEWyHcquPxBOZhKkRCKZD+N/J7ilkiBitg=", - "pom": "sha256-fN0zdkTVI/5gz7YyQQxrf7fZgu7FMnDdvt/xwmMzVF0=" - }, - "com/android/tools/build#gradle-api/8.7.3": { - "jar": "sha256-hprfdeqPW+dneFD05w8iGkB+fvKJNMWLHY0esh1/ukU=", - "module": "sha256-OepMCIspW44jS5K3k2t3dlDnH7wg2ofe94LZiC43nX8=", - "pom": "sha256-HIaQJiRJI7kZvi/yI0ViZ6oFbYuUwmA8VZ9TS8bmSyM=" - }, - "com/android/tools/build#gradle-settings-api/8.7.3": { - "jar": "sha256-iocRuifg6LclvUuSsWsI0Oo2QTM2T90v2ba+BfKqhDg=", - "module": "sha256-MYEyOZi0ef+3B9x3tSpRxNiC3dHrRUcN34OTcDjMrk8=", - "pom": "sha256-ZNLS4K6Z8yIA0Hlvd2SsPes2fC7YhuuA5D+4D8T9gHI=" - }, - "com/android/tools/build#gradle/8.7.3": { - "jar": "sha256-q7T56SyYOL2ZiboFlo7IkhieFuI/Qq26LgY4Q9oEBw0=", - "module": "sha256-FvTIe08bezuZs9vCN9wP4sWmtqazFDukbko1sduZamU=", - "pom": "sha256-wQoZM9ibEaV1k9KGUw1/uYhPYq7Rr8Y5ChF7qmu3vkw=" - }, - "com/android/tools/build#manifest-merger/31.7.3": { - "jar": "sha256-8ablatvVV9a/NER6Yv9GgGQseZw5ekvBSoEla9lh5qs=", - "module": "sha256-93zlOCbQOzqLzZQPDDqyx+XcTfQE8EhY/Icksmr+dhw=", - "pom": "sha256-P5EszR/cRhV/9beBBi5ZfrrBQ66t/li8NFYiaSYE/vk=" - }, - "com/android/tools/build#transform-api/2.0.0-deprecated-use-gradle-api": { - "jar": "sha256-TeSj0F4cU0wtueRYi/NAgrsr0jLYq7lyfEMCkM4iV0A=", - "pom": "sha256-fGLzhW6KvKHXkleSXybBJmhpP12VkEBWu6yIYFz9hXU=" - }, - "com/android/tools/build/jetifier#jetifier-core/1.0.0-beta10": { - "jar": "sha256-Jqu0oTkn2QYhacUEyelP6A6a46T3tauIdasAdTapH14=", - "module": "sha256-8JF1iaQtJ2Fj8QBAq1hC6RiD3L2x1Iv9Hx/Kpywcp7c=", - "pom": "sha256-XJ1C5rfjXU2NAuCjIs8maTs+w2QrEHyPC+WnIdRaDG0=" - }, - "com/android/tools/build/jetifier#jetifier-processor/1.0.0-beta10": { - "jar": "sha256-xQZ6e5KCN6EnGl6ctXEOn4C0lzKTlFvFHjpMhk6kv+0=", - "module": "sha256-NsJVdrGZk982AXBSjMYrckbDd3bWFYFUpnzfj8LVjhM=", - "pom": "sha256-M7F/OWmJQEpJF0dIVpvI7fTjmmKkKjXOk9ylwOS6CEI=" - }, - "com/android/tools/ddms#ddmlib/31.7.3": { - "jar": "sha256-DX71OCP2ohuAfzmPDQOaXd4YS1jFWJYlYmykqj1hCO0=", - "pom": "sha256-0+dYGViVu1uhe0Br5b39hbk0V528U2szLRer/SgKmgY=" - }, - "com/android/tools/layoutlib#layoutlib-api/31.7.3": { - "jar": "sha256-mLrjb/BR4RTdTu9e/6gPvl5VKUT0IzzokhYNos2e6u0=", - "pom": "sha256-s9ld8hNWzmZtc826aillJMmv/zm9H/kVD9GdtYn5phI=" - }, - "com/android/tools/lint#lint-model/31.7.3": { - "jar": "sha256-n0wIehmRdFIdG8e4/wX/FIT3cPRRi3/Z9trmwmGILb0=", - "pom": "sha256-Lqpa42GJupKb53yniPVFmZQChfJdDBQiQa2Nf91EEio=" - }, - "com/android/tools/lint#lint-typedef-remover/31.7.3": { - "jar": "sha256-W09IUhXKTYbvIxn8OYtfIlHmL1RGvF/Q4AZTZI3d4xg=", - "pom": "sha256-ErBrHJ2XeHgf4jNo5yMXb2bw6XZBklWAougNL4cNLOk=" - }, - "com/android/tools/utp#android-device-provider-ddmlib-proto/31.7.3": { - "jar": "sha256-2p8/Pa4mVEyQZoVJWEdl1YVKh8Ql0s/ld80002AOoJc=", - "pom": "sha256-TKEqyOBl5PQAKdpLZoLIGZBEZOhStTqoF8yGhEJ5rko=" - }, - "com/android/tools/utp#android-device-provider-gradle-proto/31.7.3": { - "jar": "sha256-rSNCux1vlVY0AKMiST6hwinLk985RPEmG3OZ9xhJQEk=", - "pom": "sha256-89rOHUayZc2PgmTKeGFhIHPI22KZyZq9zmurrDn/dao=" - }, - "com/android/tools/utp#android-device-provider-profile-proto/31.7.3": { - "jar": "sha256-ENEAztXQg3FMHGi7uxC7N16FRvkqsOQhnA5KX/KYEV4=", - "pom": "sha256-ibF1CEo3zG84da9WhciII3T1bLbjvY3ET4l/XNxhQ+k=" - }, - "com/android/tools/utp#android-test-plugin-host-additional-test-output-proto/31.7.3": { - "jar": "sha256-OEUGlN5jKMLEy6aW+cBOzdXOaVI1X2jDoi+VQdHWVG8=", - "pom": "sha256-qodWHuOIALsRktVqPtxgRl2sbb+nOjRajMsUsPTolEc=" - }, - "com/android/tools/utp#android-test-plugin-host-apk-installer-proto/31.7.3": { - "jar": "sha256-VD62yNcrLtdFH46TnV2AiQVm8UvCa335yDR1BrJY164=", - "pom": "sha256-C40e2YLnqzbpWKY7yXXlsxqY9sa6b5L8r8IsaSu0oI8=" - }, - "com/android/tools/utp#android-test-plugin-host-coverage-proto/31.7.3": { - "jar": "sha256-77TXAUqqc1UkagfC5DeiIx+yUlQP8bzmhyyI3I2onRI=", - "pom": "sha256-TdzGtt9MkgcQNa4T+YDgX5vS5uO2zAU+CecLHVNzsbM=" - }, - "com/android/tools/utp#android-test-plugin-host-emulator-control-proto/31.7.3": { - "jar": "sha256-rt7F7EYn2JjMzfQtgDjbIOukSVdTxT0bCzeHNEkcr18=", - "pom": "sha256-ontLxj8vc/eltbV3XTgQg/rdHSD7/uBxKnEwuINJrt0=" - }, - "com/android/tools/utp#android-test-plugin-host-logcat-proto/31.7.3": { - "jar": "sha256-kSkCS9jjg1O8o+sm39jjYo4FjVfW6dhFH/w18BZ1HmM=", - "pom": "sha256-GuVOX5PNbg0Pj0/i5BzP7rP57Zlswh6ndJQg6/miPYM=" - }, - "com/android/tools/utp#android-test-plugin-host-retention-proto/31.7.3": { - "jar": "sha256-PbjtOO9JtpTK6kZq4i47Ns7clVezWJ0OB8DN2DKUWRw=", - "pom": "sha256-02L49Q+9HN7o3JL3ny6QGrgpcNXU4JoZrheUbFbAiEw=" - }, - "com/android/tools/utp#android-test-plugin-result-listener-gradle-proto/31.7.3": { - "jar": "sha256-y99xvKYOFMMOeyz0uQ8PCj6ME498rdh0sNnArgguAnQ=", - "pom": "sha256-Y+Uvd4WIRAvG2qmqMVia6fUrP6WyittRDHOfD/S40rw=" - }, - "com/google/testing/platform#core-proto/0.0.9-alpha02": { - "jar": "sha256-bYqJBndBUPQ6j60IymTiXGBww5vYpvwTslk/KJJC/pU=", - "pom": "sha256-J855WUJ6L/7kjQ/rRRKKPzbMQX7YqCKvoigiyPWliyU=" - } - }, - "https://plugins.gradle.org/m2": { - "app/cash/sqldelight#app.cash.sqldelight.gradle.plugin/2.0.2": { - "pom": "sha256-xI4eHTquSFcUqPmVqfwmIE3v0FJXhyJaRotJQfOPKwk=" - }, - "app/cash/sqldelight#core/2.0.2": { - "jar": "sha256-CfmuoBaSufgcVm1dw1RF4C8/6H/uO6zaQt4UYXQeQY4=", - "module": "sha256-ubO5UrQfVLVtOMwTVu6spkaECMg9LdcmWuJvTx2ixHk=", - "pom": "sha256-2HosGaOmef+nDNHe8pOrENlYiOjxlbMmhWTg4A6FmXo=" - }, - "app/cash/sqldelight#dialect-api/2.0.2": { - "jar": "sha256-O8jKnSyT2pb5pov3hhVk53UcpL17nJBV8ThLM52zL8Q=", - "module": "sha256-mQILmwYxc4kmMRq9mRGy5OiurYmJyDQPUkfYv/6X+Wk=", - "pom": "sha256-OXXuzXTyjyCTjLsN9bNCR4GVjxBt8oHFHbGtZECHHo0=" - }, - "app/cash/sqldelight#gradle-plugin/2.0.2": { - "jar": "sha256-zsOdiMdifvSOal4xcaDR7eAJDXq7DOK6ZkNg/tXiR9U=", - "module": "sha256-yDnQ4pMUS17zHZpnWPVdrpm8bBIDpJPwI/+yZmvOZJ0=", - "pom": "sha256-FVM3pAl20fds+Cf7Y/d3G9hYUDe04dl9sOe3CZ7MU0E=" - }, - "app/cash/sqldelight#migrations/2.0.2": { - "jar": "sha256-sLEBhNJMldR5KtJXEK99TmzmHEdAShaSnebRA58q5HY=", - "module": "sha256-PM3qLGRw8zvMVHkdx+NbZGZI8XTnfNnOSRGcsaYAz7w=", - "pom": "sha256-tzscVpxOC6XXv9Q6afbc+oLxKelpDpc6XTWphJW9HeM=" - }, - "com/alecstrong/sql/psi#core/0.4.9": { - "jar": "sha256-oQY2Xymv+JgfU9Fq1Iz5LZxYYz8ryXCMZ7TeB2FFGf0=", - "module": "sha256-j0kf/wuD3vJn1n+e29IaMspCvRsfdDip4eSue94vNL8=", - "pom": "sha256-95ZPG0a91j5AIgNvbDyImHMTqMkmjq4VXOTUhBoNF5w=" - }, - "com/alecstrong/sql/psi#environment/0.4.9": { - "jar": "sha256-/Vj4xjvQ6m/4VzNt9+Z1F9k8B7zainF+lXVU0eXxBqE=", - "module": "sha256-vOTPGccfqlxmffo8cood10Jma8f/1nEIBZVHd118kXU=", - "pom": "sha256-q/La0eTVD0NnA3hKsXKiE6WrpXf6lolUmQmYWmWJ5Yo=" - }, - "com/fasterxml#oss-parent/38": { - "pom": "sha256-yD+PRd/cqNC2s2YcYLP4R4D2cbEuBvka1dHBodH5Zug=" - }, - "com/fasterxml#oss-parent/50": { - "pom": "sha256-9dpV3XuI+xcMRoAdF3dKZS+y9FgftbHQpfyGqhgrhXc=" - }, - "com/fasterxml#oss-parent/58": { - "pom": "sha256-VnDmrBxN3MnUE8+HmXpdou+qTSq+Q5Njr57xAqCgnkA=" - }, - "com/fasterxml/jackson#jackson-bom/2.17.2": { - "pom": "sha256-H0crC8IATVz0IaxIhxQX+EGJ5481wElxg4f9i0T7nzI=" - }, - "com/fasterxml/jackson#jackson-parent/2.17": { - "pom": "sha256-rubeSpcoOwQOQ/Ta1XXnt0eWzZhNiSdvfsdWc4DIop0=" - }, - "com/fasterxml/woodstox#woodstox-core/6.5.1": { - "jar": "sha256-ySjWBmXGQV+xw5d1z5XPxE9/RYDPWrAbHDgOv/12iH8=", - "pom": "sha256-SDllThaxcU509Rq8s3jYNWgUq49NUnPR3S8c6KOQrdw=" - }, - "com/google/android#annotations/4.1.1.4": { - "jar": "sha256-unNOHoTAnWFa9qCdMwNLTwRC+Hct7BIO+zdthqVlrhU=", - "pom": "sha256-5LtUdTw2onoOXXAVSlA0/t2P6sQoIpUDS/1IPWx6rng=" - }, - "com/google/api/grpc#proto-google-common-protos/2.17.0": { - "jar": "sha256-TvH+DDJ/wVIdHXU7CxxKh1pUvRTr3tOv/wyjlTILbqk=", - "pom": "sha256-PwKBU6WFxZ9Viz5Dp8mAmmAai7XpEGHWxlj/+iTLjiY=" - }, - "com/google/auto#auto-parent/6": { - "pom": "sha256-BfdAxmSBZdsAz2GN1WwgDEcl41jm1U9YU+C+wVc06go=" - }, - "com/google/auto/value#auto-value-annotations/1.6.2": { - "jar": "sha256-tIsE3bpA6KwzvwNvBvxDmV/FCEvZS9qs6AfOJ9O+o/s=", - "pom": "sha256-HHbNRi/JbnqpbccM6C8NVAY9bfFts1ycfZzA0amdP/8=" - }, - "com/google/auto/value#auto-value-parent/1.6.2": { - "pom": "sha256-J7ZAyCF59c/2IAnAtyAz2bxg9g6ZAqZoAidLf+N/yBw=" - }, - "com/google/code/findbugs#jsr305/3.0.2": { - "jar": "sha256-dmrSoHg/JoeWLIrXTO7MOKKLn3Ki0IXuQ4t4E+ko0Mc=", - "pom": "sha256-GYidvfGyVLJgGl7mRbgUepdGRIgil2hMeYr+XWPXjf4=" - }, - "com/google/code/gson#gson-parent/2.10.1": { - "pom": "sha256-QkjgiCQmxhUYI4XWCGw+8yYudplXGJ4pMGKAuFSCuDM=" - }, - "com/google/code/gson#gson-parent/2.11.0": { - "pom": "sha256-issfO3Km8CaRasBzW62aqwKT1Sftt7NlMn3vE6k2e3o=" - }, - "com/google/code/gson#gson/2.10.1": { - "pom": "sha256-0rEVY09cCF20ucn/wmWOieIx/b++IkISGhzZXU2Ujdc=" - }, - "com/google/code/gson#gson/2.11.0": { - "jar": "sha256-V5KNblpu3rKr03cKj5W6RNzkXzsjt6ncKzCcWBVSp4s=", - "pom": "sha256-wOVHvqmYiI5uJcWIapDnYicryItSdTQ90sBd7Wyi42A=" - }, - "com/google/crypto/tink#tink/1.7.0": { - "jar": "sha256-iJcKRWoIukxmsBsj5YRsoQlcwU5Uy0g2Pl0uFaEwcwg=", - "pom": "sha256-Ku41I3FfjyzRCyYDyNGeVhrHWDELfiyYU5RtLF57S/c=" - }, - "com/google/dagger#dagger/2.28.3": { - "jar": "sha256-8d0j+K40qOkTZnI5kerQ1kmdGj6RY85VDCALAtdqhys=", - "pom": "sha256-JlupWajhPDoGEz8EtTkWnBAY2v/U0z9TxFOrTLOG9XA=" - }, - "com/google/errorprone#error_prone_annotations/2.11.0": { - "pom": "sha256-AmHKAfLS6awq4uznXULFYyOzhfspS2vJQ/Yu9Okt3wg=" - }, - "com/google/errorprone#error_prone_annotations/2.18.0": { - "pom": "sha256-kgE1eX3MpZF7WlwBdkKljTQKTNG80S9W+JKlZjvXvdw=" - }, - "com/google/errorprone#error_prone_annotations/2.27.0": { - "jar": "sha256-JMkjNyxY410LnxagKJKbua7cd1IYZ8J08r0HNd9bofU=", - "pom": "sha256-TKWjXWEjXhZUmsNG0eNFUc3w/ifoSqV+A8vrJV6k5do=" - }, - "com/google/errorprone#error_prone_annotations/2.3.1": { - "pom": "sha256-PtzmtxG6No7+Frm3qssCFPvWSEFMublllTouftiagZo=" - }, - "com/google/errorprone#error_prone_parent/2.11.0": { - "pom": "sha256-goPwy0TGJKedMwtv2AuLinFaaLNoXJqVHD3oN9RUBVE=" - }, - "com/google/errorprone#error_prone_parent/2.18.0": { - "pom": "sha256-R/Iumce/RmOR3vFvg3eYXl07pvW7z2WFNkSAVRPhX60=" - }, - "com/google/errorprone#error_prone_parent/2.27.0": { - "pom": "sha256-+oGCnQSVWd9pJ/nJpv1rvQn4tQ5tRzaucsgwC2w9dlQ=" - }, - "com/google/errorprone#error_prone_parent/2.3.1": { - "pom": "sha256-dnUl2agRKc0IGWg4KYAzYye+QWKx4iUaGCkR2qczwSM=" - }, - "com/google/flatbuffers#flatbuffers-java/1.12.0": { - "jar": "sha256-P4wIi03QSphYch8uFiUIyU2w3Yb5YeMG7mPvLtqHG/c=", - "pom": "sha256-yyJrr1RiYHcPIegVKmqoi6FSMNc591DfSA8qZo1D4Os=" - }, - "com/google/guava#failureaccess/1.0.1": { - "jar": "sha256-oXHuTHNN0tqDfksWvp30Zhr6typBra8x64Tf2vk2yiY=", - "pom": "sha256-6WBCznj+y6DaK+lkUilHyHtAopG1/TzWcqQ0kkEDxLk=" - }, - "com/google/guava#guava-parent/26.0-android": { - "pom": "sha256-+GmKtGypls6InBr8jKTyXrisawNNyJjUWDdCNgAWzAQ=" - }, - "com/google/guava#guava-parent/32.0.1-jre": { - "pom": "sha256-Q+0ONrNT9B5et1zXVmZ8ni35fO8G6xYGaWcVih0DTSo=" - }, - "com/google/guava#guava/32.0.1-jre": { - "jar": "sha256-vX+iJ1kfuFCWd9DREiz5UVjzuKn0VlP1goHYefbcSMU=", - "pom": "sha256-QsJX9/c203ezGv7u6XirJtcwzXCvYN3nZi4YI1LiSCo=" - }, - "com/google/guava#listenablefuture/9999.0-empty-to-avoid-conflict-with-guava": { - "jar": "sha256-s3KgN9QjCqV/vv/e8w/WEj+cDC24XQrO0AyRuXTzP5k=", - "pom": "sha256-GNSx2yYVPU5VB5zh92ux/gXNuGLvmVSojLzE/zi4Z5s=" - }, - "com/google/j2objc#j2objc-annotations/1.3": { - "pom": "sha256-X6yoJLoRW+5FhzAzff2y/OpGui/XdNQwTtvzD6aj8FU=" - }, - "com/google/j2objc#j2objc-annotations/2.8": { - "jar": "sha256-8CqV+hpele2z7YWf0Pt99wnRIaNSkO/4t03OKrf01u0=", - "pom": "sha256-N/h3mLGDhRE8kYv6nhJ2/lBzXvj6hJtYAMUZ1U2/Efg=" - }, - "com/google/jimfs#jimfs-parent/1.1": { - "pom": "sha256-xxVVdR5X4O+RKHDorJYlrnglAqalucGcz4OyqX2LJr0=" - }, - "com/google/jimfs#jimfs/1.1": { - "jar": "sha256-xIKOKNfAqTCvk4dRCzutp9qlwE18Jadce4sIHxwlfd0=", - "pom": "sha256-76huXNki8XtHL9/K5XI02NSsPhSLYlBzffzkVK96ekQ=" - }, - "com/google/protobuf#protobuf-bom/3.22.3": { - "pom": "sha256-E6Mt+53m/Bw8P3r1Pk1cd/130rR2uuOLdLdYHN7i5lU=" - }, - "com/google/protobuf#protobuf-java-util/3.22.3": { - "jar": "sha256-xhX3aHncXDA+TfW5Smr6OVNAWMdUXbLUg/2V2fY8i/4=", - "pom": "sha256-tEcBsGoGSGXsm1YUqT6eKPrdfU38S0YPIcgZ71Pb4tY=" - }, - "com/google/protobuf#protobuf-java/3.22.3": { - "jar": "sha256-WdOI6motLXaujv/3/U0MYMbw9GTD06ub6OWt0JKXVwg=", - "pom": "sha256-GG6nlBUPW0Kup+xgQd83PR2KioMWJPWKVd67YEPscxI=" - }, - "com/google/protobuf#protobuf-parent/3.22.3": { - "pom": "sha256-OZEz1/b1eTTddsSxjoY0j0JFMhCNr0oByPgguGZfCSk=" - }, - "com/googlecode/juniversalchardet#juniversalchardet/1.0.3": { - "jar": "sha256-dXv+kGGTuLZR553CbNZ9a1XQdwos37A4FZFQT3edSnY=", - "pom": "sha256-eEY5mzXHzWQqmzoADD4tYtBOs3pFR7aTPMixi8wvCGs=" - }, - "com/gradleup/shadow#com.gradleup.shadow.gradle.plugin/8.3.5": { - "pom": "sha256-bc9S5Y+1rG4aD6CVCbfashy3iqlLV3opZThgchAXjKY=" - }, - "com/gradleup/shadow#shadow-gradle-plugin/8.3.5": { - "jar": "sha256-VOCN0gqCd14zF6RyWhpeTsixscDzRt5wKknZ7UgVtzU=", - "module": "sha256-+kwoQEsU00woznA078s3q513u//7O6xbyLf7BGqtliI=", - "pom": "sha256-cIF5r4UBl3extKmnI2gPYIX67YERrJFJYeZ1S0lEG6k=" - }, - "com/squareup#javapoet/1.10.0": { - "jar": "sha256-IO9LguQ/98ZSKBohMTzzuUEJJGet0/pzUJwm9pae/as=", - "pom": "sha256-FpA0CiIiefLLrfNz6Igm+iD388w+wCUvNoGP7TJwGrE=" - }, - "com/squareup#javawriter/2.5.0": { - "jar": "sha256-/PsJ+w6gqpfTz+fqeSOYCBNI5GjxJrNgPLOAPyQBl/A=", - "pom": "sha256-4avX8RFs9eDFmUdpPiGJII7JQpayozlMlZ41EdOZp7A=" - }, - "com/squareup#kotlinpoet-jvm/1.16.0": { - "jar": "sha256-QaUGgk2kMMDlQ6AjJD6uiNuhiIrPJVuZmlHaLb78C8g=", - "module": "sha256-oD1zFaTG1WtNUZVh4fmPaFpQL0gilGN6jC7Te/b91C0=", - "pom": "sha256-h4x1iYdBvdiA7403aLPRK4P9Tzt25GHht5fIZ5gsoA8=" - }, - "com/squareup#kotlinpoet/1.16.0": { - "module": "sha256-AvPdM8OE9EQ4lqajsHcE/1axLf5eMqEOfqMmaueJT1M=", - "pom": "sha256-yFb0sTRO8oA4x3rbK5fH3BxJggvQXbwc/WwUasuPPg0=" - }, - "com/squareup/moshi#moshi/1.15.1": { - "jar": "sha256-RqERj+H8EnI6V1yUEz/Ik23MeNP4hzwOcKBV3p5YYaY=", - "module": "sha256-Zx9TVaun2f6mS+FONx/ClcNNq/hy0hCSS/DbQpHW73Q=", - "pom": "sha256-C4GbZHlZ52n2+7F+rZvm4F/tDCYRtFT1gAoIbC9IdjA=" - }, - "com/squareup/okhttp3#okhttp/4.12.0": { - "jar": "sha256-sQUAgbFLt6On5VpNPvAbXc+rxFO0VzpPwBl2cZHV9OA=", - "module": "sha256-YH4iD/ghW5Kdgpu/VPMyiU8UWbTXlZea6vy8wc6lTPM=", - "pom": "sha256-fHNwQKlBlSLnxQzAJ0FqcP58dinlKyGZNa3mtBGcfTg=" - }, - "com/squareup/okio#okio-jvm/3.7.0": { - "jar": "sha256-2LNa3Ch2j0OuWv5qfRqiqHi6UeC5ak8wiBHzsfWxPlU=", - "module": "sha256-b64CAbCuSKGWBt4Ab/6YQtjQ/CoeQ04Hhc7Ni3Wr5HQ=", - "pom": "sha256-d07LnSsHlLT7J+eeCHYMpWC39U+qlRm5GDxn/rRfLJc=" - }, - "com/squareup/okio#okio/3.6.0": { - "module": "sha256-akesUDZOZZhFlAH7hvm2z832N7mzowRbHMM8v0xAghg=", - "pom": "sha256-rrO3CiTBA+0MVFQfNfXFEdJ85gyuN2pZbX1lNpf4zJU=" - }, - "com/squareup/okio#okio/3.7.0": { - "module": "sha256-88rgCfC2yEL7vFLOd1QsGdGdVu6ZpeVVZH8Lr8nVDPo=", - "pom": "sha256-H2KMRSg726uM4DwHps+3akeLjdrhgL2PNKusJz5Id24=" - }, - "com/squareup/retrofit2#converter-moshi/2.11.0": { - "jar": "sha256-2/rp294LYeXFZxZIyNn9SG766a0H1XPtAb0N5GiNmyw=", - "module": "sha256-8jl8dvQPuHPUydGvgwtEolty75gpsCYJnikTB4uN8z4=", - "pom": "sha256-MB/EqjCHlmkS/fQEko2EOtcUPO8wm3fuVeD+srWoyBU=" - }, - "com/squareup/retrofit2#converter-scalars/2.11.0": { - "jar": "sha256-ZH1+gaxh7t9pG6adgvDVaFCHq/DVj+fYa2Q9AoCNqRE=", - "module": "sha256-SaqPyhyulzzMqBdmncrXltVqeQ7UdQnweTMHdc8zJnQ=", - "pom": "sha256-s9ShAXMYUHQencArE1u4FRHlM0wUe74tqtL1afVmNkU=" - }, - "com/squareup/retrofit2#retrofit/2.11.0": { - "jar": "sha256-n0+7znByhYT77tONQGHzbUR36JvKdLTirIrraBmw/kM=", - "module": "sha256-6bsuIBhEyI5HUGJPkRSmNUtRtwlItE1ca0qU6M0HCoE=", - "pom": "sha256-3iKB4huk2YSrrxPcBn84C8WBaXBoxlaKu5uZjZ13cF4=" - }, - "com/sun/activation#all/1.2.0": { - "pom": "sha256-HYUY46x1MqEE5Pe+d97zfJguUwcjxr2z1ncIzOKwwsQ=" - }, - "com/sun/activation#all/1.2.1": { - "pom": "sha256-NgiDv2RIbs7xYbjygvZQNTbdGmcNU6Coccj7IBcOZ5U=" - }, - "com/sun/activation#javax.activation/1.2.0": { - "jar": "sha256-mTMCsWzXBW8h53nMV30XWoELtJAO9zzY+/K1D5KLqc4=", - "pom": "sha256-+Hm26UWFTGkAsNvuHIOE16s95+FX/XrISTdAXEFtKl4=" - }, - "com/sun/istack#istack-commons-runtime/3.0.8": { - "jar": "sha256-T/q7Br5FSgXkOY4gx3+itjCNS4jfvvfKMKdrW31VBe8=", - "pom": "sha256-wuAU00y4TtKH0GSYbEXDBaQSQiinM37M9sQh0U1wjxw=" - }, - "com/sun/istack#istack-commons/3.0.8": { - "pom": "sha256-oPBRfoUS8PvMe4KVwS9lZqPQwthtZVY53GYu+MDH6+U=" - }, - "com/sun/xml/bind#jaxb-bom-ext/2.3.2": { - "pom": "sha256-Gn3sKyfn4FV0TNuM8bkN70/Uc6zRuATv8JgTk1iVm9c=" - }, - "com/sun/xml/bind/mvn#jaxb-parent/2.3.2": { - "pom": "sha256-IN1tw0q3VJrEDaHYLpIiLsQ0etDsDLEY72xXA77VOhg=" - }, - "com/sun/xml/bind/mvn#jaxb-runtime-parent/2.3.2": { - "pom": "sha256-sk+NUfGEpovBuG1IwOPP7+shpE7eHF9zA8WK4EiFM+w=" - }, - "com/sun/xml/bind/mvn#jaxb-txw-parent/2.3.2": { - "pom": "sha256-tV0++psVj0g6MOkseMy2APkzFHM9CJ66m3RDbwGzFKQ=" - }, - "com/sun/xml/fastinfoset#FastInfoset/1.2.16": { - "jar": "sha256-BW86HhRECfIe0Wr8JoBfWOmiHz/OFUPELUAHGdJQxRE=", - "pom": "sha256-4UfSWKtuZpH3BZmpUkAObmx1WPjJwCjb4b4jF4MI6DA=" - }, - "com/sun/xml/fastinfoset#fastinfoset-project/1.2.16": { - "pom": "sha256-kFgkJa3B9AtBNi2vuVFzkxIlrKpeeWINXmvVL2Rikro=" - }, - "com/vanniktech#central-portal/0.30.0": { - "jar": "sha256-8VybicRPV4cOThd6sK+u9xbHrYwJhzJmwtAuGh7fhu8=", - "module": "sha256-1rl7bLb3gsnA7RPI001F0dilTN2P4fPOLL5tXPscwpw=", - "pom": "sha256-nuEIXixMif6Jvn099IX0TFoIIuw8u5zmUoQtjQ9Z0lc=" - }, - "com/vanniktech#gradle-maven-publish-plugin/0.30.0": { - "jar": "sha256-byC0TTthYaeFv25+5PmHM9kXIbJmzoIQNsE21T8uSkg=", - "module": "sha256-7P66Xja6oxnc5IWGt5W2IF3K4KPI4lDtnUEyX6I3Zkc=", - "pom": "sha256-s7lK4JAD1t2n5vnABYUzoZdRo2b6/iwkxuNyY2HvsxU=" - }, - "com/vanniktech#nexus/0.30.0": { - "jar": "sha256-ewSXzGMMYxZdtBLhDCpo9k/4yLuu7JxnYxkzwlBzNEw=", - "module": "sha256-nqVJjdIldR6Q/sKM/xhkoutkkeA7HIQEhC492hvdu+w=", - "pom": "sha256-A99wmKpz2ZU3hI47gsMmisXwxF0wkKrjmJw/mjFQads=" - }, - "com/vanniktech/maven/publish#com.vanniktech.maven.publish.gradle.plugin/0.30.0": { - "pom": "sha256-JswhKPKkM3FnGR/kD986hZEBSpp5e2gO3uAzKq4y6ik=" - }, - "commons-codec#commons-codec/1.10": { - "pom": "sha256-vbjbcBLREqbj6o/bfFELMA2Z7/CBnSfd26nEM5fqTPs=" - }, - "commons-codec#commons-codec/1.11": { - "jar": "sha256-5ZnVMY6Xqkj0ITaikn5t+k6Igd/w5sjjEJ3bv/Ude30=", - "pom": "sha256-wecUDR3qj981KLwePFRErAtUEpcxH0X5gGwhPsPumhA=" - }, - "commons-io#commons-io/2.13.0": { - "jar": "sha256-Zx6qOWiNrC/6pGRbPJmAri0OokceSual2hmc0VriNmY=", - "pom": "sha256-2z/tZMLhd06/1rGnSQN3MrFJuREd1+a5hfCN2lVHBDk=" - }, - "commons-io#commons-io/2.17.0": { - "jar": "sha256-SqTKSPPf0wt4Igt4gdjLk+rECT7JQ2G2vvqUh5mKVQs=", - "pom": "sha256-SEqTn/9TELjLXGuQKcLc8VXT+TuLjWKF8/VrsroJ/Ek=" - }, - "commons-logging#commons-logging/1.2": { - "jar": "sha256-2t3qHqC+D1aXirMAa4rJKDSv7vvZt+TmMW/KV98PpjY=", - "pom": "sha256-yRq1qlcNhvb9B8wVjsa8LFAIBAKXLukXn+JBAHOfuyA=" - }, - "io/grpc#grpc-api/1.57.0": { - "jar": "sha256-jSw4Qpn4Tuiqf2cPAOfLJrh+IxzzCRR0MHsyt2kQ9xw=", - "pom": "sha256-w/BUp8iGFkfQpVglsKlJ9E/PycZPR5CD2WgTgUxQJhI=" - }, - "io/grpc#grpc-context/1.57.0": { - "jar": "sha256-lT/KzYL1MeabduODT1gwutTCKuhBROBY1x3ICnQwJ10=", - "pom": "sha256-qyZOgr+2q4lfYBavizzERJWryB52nDD6WprgrRa+bMY=" - }, - "io/grpc#grpc-core/1.57.0": { - "jar": "sha256-O+5IxzvExbVb7Xm+DkhK3ya6Vr675XmN2/NHFO8eHOo=", - "pom": "sha256-gYQEX1eR4Azyzbz16IRq/Uj1z35aTzj7W4MDx7Lv5Vs=" - }, - "io/grpc#grpc-netty/1.57.0": { - "jar": "sha256-gdQ/LU7Rj6NBvYQKNzXxQDpwB0oEbhV+J/Z5tyG0ya0=", - "pom": "sha256-7Z3917HtQ1avs8XRQH3ttjTIYC+0EEebSArYwROe4Xs=" - }, - "io/grpc#grpc-protobuf-lite/1.57.0": { - "jar": "sha256-LFB8AtmBuEohdj1E4Jr08nmIHdPiW+MID2NhJYYH8Zg=", - "pom": "sha256-sCO+cAiElIn2Uu7/df0P4aqckF9nHTROFtqv3fkhgZ0=" - }, - "io/grpc#grpc-protobuf/1.57.0": { - "jar": "sha256-SfmG1OqxJhD9ukpokPylLV62U1mJFv24Y6Nm1eKO7Pc=", - "pom": "sha256-wNy4xn/QHapjJW8Pi2jTcHzrfKhc2qt6PGw/9GDhPdE=" - }, - "io/grpc#grpc-stub/1.57.0": { - "jar": "sha256-bm7hQVOfoU2fpHn39RFgVUREPH4BHnjic8+UaKoYMGA=", - "pom": "sha256-bURZSHxiHf8xUQqIgpBjYx6RXS3Md01xkoQYEW5ZqI0=" - }, - "io/netty#netty-buffer/4.1.93.Final": { - "jar": "sha256-AHx9nDeN8C05BWfQ1931Qv/dsCG3MT2/UCOSET/6uwg=", - "pom": "sha256-g/vFTitzuG1Vsgj2GNGioVaRDsFG9+zldWUAe3UK3Xg=" - }, - "io/netty#netty-codec-http/4.1.93.Final": { - "jar": "sha256-2s94znirLSlXAyXbTNJFHqWJY5gH3pWIGg+nFVqea1U=", - "pom": "sha256-o9r/8HG20oToBj2WhD3iu4PPO4iergzJ4K22SlejG4I=" - }, - "io/netty#netty-codec-http2/4.1.93.Final": { - "jar": "sha256-2WzAkEWhNBxtR0lDUqomO4e3L7HS6p7KFhqnOCC/6Ls=", - "pom": "sha256-CEQztC1UH3rEtZKH3SUyhc/aOj1l3nLnNou37D02cnE=" - }, - "io/netty#netty-codec-socks/4.1.93.Final": { - "jar": "sha256-DqR7W6I8odqOuRRsj8dVwScUFGM7Hivizh33ZLoP/yo=", - "pom": "sha256-jNgW7ZkalGBBurTLJL2cjkHuBpJRJRHy2DzvU462Bdc=" - }, - "io/netty#netty-codec/4.1.93.Final": { - "jar": "sha256-mQw3gWjcY2TG/1aXAfTy8SL//omYs+GJ66TE2GjtEIQ=", - "pom": "sha256-Gc3tJnoHDf8avJ0Cm1UvrSYqzBq6XGxnsiePyhE6Jqs=" - }, - "io/netty#netty-common/4.1.93.Final": { - "jar": "sha256-RDuzFlmfsW47rrovtYiBgU1/8LevF2/nbjgHGm6G+MA=", - "pom": "sha256-QtiDsT6zjKv1SWFkYsXzMfUzO/DI/JIVdE+DwBgKT2s=" - }, - "io/netty#netty-handler-proxy/4.1.93.Final": { - "jar": "sha256-KsX3+++gtz73g4iQaTRNVRVQWhSyMDvmk8UALEht8rQ=", - "pom": "sha256-bcUNoOZ/WXgSh0+B6qRUBPfQdrgZnqkIiTKoXBthAkU=" - }, - "io/netty#netty-handler/4.1.93.Final": { - "jar": "sha256-Tl9WOuFO1xM4GBbVgvX8/QYVrvspIDSGzft4LYoAoCs=", - "pom": "sha256-hKFSXKwLR1nvrvKZekf+Gbm1ZC+Sc/oP1YoudsegWf4=" - }, - "io/netty#netty-parent/4.1.93.Final": { - "pom": "sha256-sQnLdvN1/tuKnvdaxYBjFw3rfqLd0CT0Zv723GXN/O4=" - }, - "io/netty#netty-resolver/4.1.93.Final": { - "jar": "sha256-5Zdwtm6Bgi5dERrE5UTX6wxUPgooX1JijlOUGs2O11k=", - "pom": "sha256-WzUMPJHp5V0py+aM/k7yEWzB8DKGd+v59hW6twgsefQ=" - }, - "io/netty#netty-transport-native-unix-common/4.1.93.Final": { - "jar": "sha256-d0FlocTbqssX+cGtZms1aaallxWugo58PUdwP0eaU+c=", - "pom": "sha256-Fbwltn/wpJJysnDvK4z/1iAFfKFssp3/etVmGtyirhI=" - }, - "io/netty#netty-transport/4.1.93.Final": { - "jar": "sha256-paeAGbwc1D28PHt83TgBkSyibR9Jj7VgUU/uSXhkupY=", - "pom": "sha256-DdYqDrPLHqABpNBCbk9cCN8ccNkmVnW/+lxYNhNCLUM=" - }, - "io/perfmark#perfmark-api/0.26.0": { - "jar": "sha256-t9I+k6NFN84zJwgmmg0UBHiKW14ZSegvVTX85Rs+qVs=", - "module": "sha256-MdgyMyR0zkgVD1uuADNDMZE28zav0QdqKJApMZ4+qXo=", - "pom": "sha256-ft7khhbhe2Epfq46gutIOoXlbSVnkpN4qkbzCpUDIto=" - }, - "jakarta/activation#jakarta.activation-api/1.2.1": { - "jar": "sha256-iwoPUvqLBcVDGSGgY+2GbvqkHa3y46fuPhlh8rDZZFs=", - "pom": "sha256-QlhcsH3afyOqBOteCUAGGUSiRqZ609FpQvvlaf8DzTE=" - }, - "jakarta/platform#jakarta.jakartaee-bom/9.1.0": { - "pom": "sha256-35jgJmIZ/buCVigm15o6IHdqi6Aqp4fw8HZaU4ZUyKQ=" - }, - "jakarta/platform#jakartaee-api-parent/9.1.0": { - "pom": "sha256-p3AsSHAmgCeEtXl7YjMKi41lkr8PRzeyXGel6sgmWcA=" - }, - "jakarta/xml/bind#jakarta.xml.bind-api-parent/2.3.2": { - "pom": "sha256-FaVbfVN8n5lwrq0o0q+XwFn2X/YQL3a70p8SR92Kbfs=" - }, - "jakarta/xml/bind#jakarta.xml.bind-api/2.3.2": { - "jar": "sha256-aRVjBAeb3u2fwK47OTifGbPMS6REO8gFCJlTlOrXQuo=", - "pom": "sha256-tTeziNurTMBpC50vsMdBJNZyUxc0VnrPblMTDqsTGtY=" - }, - "javax/annotation#javax.annotation-api/1.3.2": { - "jar": "sha256-4EulGVvNVV3JVlD3zGFNFR5LzVLSmhC4qiGX86uJq5s=", - "pom": "sha256-RqSiUcpAbnjkhT16K66DKChEpJkoUUOe6aHyNxbwa5c=" - }, - "javax/inject#javax.inject/1": { - "jar": "sha256-kcdwRKUMSBY2wy2Rb9ickRinIZU5BFLIEGUID5V95/8=", - "pom": "sha256-lD4SsQBieARjj6KFgFoKt4imgCZlMeZQkh6/5GIai/o=" - }, - "net/java#jvnet-parent/1": { - "pom": "sha256-KBRAgRJo5l2eJms8yJgpfiFOBPCXQNA4bO60qJI9Y78=" - }, - "net/java#jvnet-parent/3": { - "pom": "sha256-MPV4nvo53b+WCVqto/wSYMRWH68vcUaGcXyy3FBJR1o=" - }, - "net/java/dev/jna#jna-platform/5.6.0": { - "jar": "sha256-ns6ovysbOZY5OdGLcEZO72DFCP7Ygg+dyroMNVGOq/c=", - "pom": "sha256-G+s1y0GE5skGp+Murr2FLdPaCiY5YumRNKuUWDI5Tig=" - }, - "net/java/dev/jna#jna/5.6.0": { - "jar": "sha256-VVfiNaiqL5dm1dxgnWeUjyqIMsLXls6p7x1svgs7fq8=", - "pom": "sha256-X+gbAlWXjyRhbTexBgi3lJil8wc+HZsgONhzaoMfJgg=" - }, - "net/sf/jopt-simple#jopt-simple/4.9": { - "jar": "sha256-JsWFbpVLX4ZNt28TuGkZtZxu7Pn9kwuWuqiIRia68vU=", - "pom": "sha256-evfi2LJLR5jwTCt9okyfvRt1V7TgF8IFRIFWWRYHkJI=" - }, - "net/sf/kxml#kxml2/2.3.0": { - "jar": "sha256-8mTdn3mh/eEM5ezFMiHv8kvkyTMcgwt9UvLwintjPeI=", - "pom": "sha256-Mc5gb06VGJNimbsNJ8l4+mHhhf0d58mHT+lZpT40poU=" - }, - "org/apache#apache/13": { - "pom": "sha256-/1E9sDYf1BI3vvR4SWi8FarkeNTsCpSW+BEHLMrzhB0=" - }, - "org/apache#apache/15": { - "pom": "sha256-NsLy+XmsZ7RQwMtIDk6br2tA86aB8iupaSKH0ROa1JQ=" - }, - "org/apache#apache/18": { - "pom": "sha256-eDEwcoX9R1u8NrIK4454gvEcMVOx1ZMPhS1E7ajzPBc=" - }, - "org/apache#apache/21": { - "pom": "sha256-rxDBCNoBTxfK+se1KytLWjocGCZfoq+XoyXZFDU3s4A=" - }, - "org/apache#apache/23": { - "pom": "sha256-vBBiTgYj82V3+sVjnKKTbTJA7RUvttjVM6tNJwVDSRw=" - }, - "org/apache#apache/29": { - "pom": "sha256-PkkDcXSCC70N9jQgqXclWIY5iVTCoGKR+mH3J6w1s3c=" - }, - "org/apache#apache/31": { - "pom": "sha256-VV0MnqppwEKv+SSSe5OB6PgXQTbTVe6tRFIkRS5ikcw=" - }, - "org/apache#apache/33": { - "pom": "sha256-14vYUkxfg4ChkKZSVoZimpXf5RLfIRETg6bYwJI6RBU=" - }, - "org/apache/ant#ant-launcher/1.10.15": { - "jar": "sha256-XIVRmQMHoDIzbZjdrtVJo5ponwfU1Ma5UGAb8is9ahs=", - "pom": "sha256-ea+EKil53F/gAivAc8SYgQ7q2DvGKD7t803E3+MNrJU=" - }, - "org/apache/ant#ant-parent/1.10.15": { - "pom": "sha256-SYhPGHPFEHzCN/QoXER3R5uwgEvwc3OUgBsI114rvrA=" - }, - "org/apache/ant#ant/1.10.15": { - "jar": "sha256-djrNpKaViMnqiBepUoUf8ML8S/+h0IHCVl3EB/KdV5Q=", - "pom": "sha256-R4DmHoeBbu4fIdGE7Jl7Zfk9tfS5BCwXitsp4j50JdY=" - }, - "org/apache/commons#commons-compress/1.21": { - "jar": "sha256-auz9VFlyillWAc+gcljRMZcv/Dm0kutIvdWWV3ovJEo=", - "pom": "sha256-Z1uwI8m+7d4yMpSZebl0Kl/qlGKApVobRi1Mp4AQiM0=" - }, - "org/apache/commons#commons-parent/34": { - "pom": "sha256-Oi5p0G1kHR87KTEm3J4uTqZWO/jDbIfgq2+kKS0Et5w=" - }, - "org/apache/commons#commons-parent/35": { - "pom": "sha256-cJihq4M27NTJ3CHLvKyGn4LGb2S4rE95iNQbT8tE5Jo=" - }, - "org/apache/commons#commons-parent/42": { - "pom": "sha256-zTE0lMZwtIPsJWlyrxaYszDlmPgHACNU63ZUefYEsJw=" - }, - "org/apache/commons#commons-parent/52": { - "pom": "sha256-ddvo806Y5MP/QtquSi+etMvNO18QR9VEYKzpBtu0UC4=" - }, - "org/apache/commons#commons-parent/58": { - "pom": "sha256-LUsS4YiZBjq9fHUni1+pejcp2Ah4zuy2pA2UbpwNVZA=" - }, - "org/apache/commons#commons-parent/74": { - "pom": "sha256-gOthsMh/3YJqBpMTsotnLaPxiFgy2kR7Uebophl+fss=" - }, - "org/apache/groovy#groovy-bom/4.0.22": { - "module": "sha256-Ul0/SGvArfFvN+YAL9RlqygCpb2l9MZWf778copo5mY=", - "pom": "sha256-Hh9rQiKue/1jMgA+33AgGDWZDb1GEGsWzduopT4832U=" - }, - "org/apache/httpcomponents#httpclient/4.5.14": { - "jar": "sha256-yLx+HFGm1M5y9A0uu6vxxLaL/nbnMhBLBDgbSTR46dY=", - "pom": "sha256-8YNVr0z4CopO8E69dCpH6Qp+rwgMclsgldvE/F2977c=" - }, - "org/apache/httpcomponents#httpcomponents-client/4.5.14": { - "pom": "sha256-W60d5PEBRHZZ+J0ImGjMutZKaMxQPS1lQQtR9pBKoGE=" - }, - "org/apache/httpcomponents#httpcomponents-client/4.5.6": { - "pom": "sha256-sEK0HyOR7bANNff05Qmu0hI2SMHSRs5Y0Pe5Bcn+H3M=" - }, - "org/apache/httpcomponents#httpcomponents-core/4.4.16": { - "pom": "sha256-8tdaLC1COtGFOb8hZW1W+IpAkZRKZi/K8VnVrig9t/c=" - }, - "org/apache/httpcomponents#httpcomponents-parent/10": { - "pom": "sha256-yq+WfZSvshdT82CCxghiBr0fSIJf9ZaTLM66crZdOfo=" - }, - "org/apache/httpcomponents#httpcomponents-parent/11": { - "pom": "sha256-qQH4exFcVQcMfuQ+//Y+IOewLTCvJEOuKSvx9OUy06o=" - }, - "org/apache/httpcomponents#httpcore/4.4.16": { - "jar": "sha256-bJs90UKgncRo4jrTmq1vdaDyuFElEERp8CblKkdORk8=", - "pom": "sha256-PLrYSbNdrP5s7DGtraLGI8AmwyYRQbDSbux+OZxs1/o=" - }, - "org/apache/httpcomponents#httpmime/4.5.6": { - "jar": "sha256-CysRAsGNPH4Fp3IUubdQGm9gVhdK5WBODiVndu2nVT4=", - "pom": "sha256-37/W/+KnhMqYF8RjZap/ileDILgFveOdb1WgsJ2KqMo=" - }, - "org/apache/logging#logging-parent/11.3.0": { - "pom": "sha256-pcmFtW/hxYQzOTtQkabznlufeFGN2PySE0aQWZtk19A=" - }, - "org/apache/logging/log4j#log4j-api/2.24.1": { - "jar": "sha256-bne7Ip/I3K8JA4vutekDCyLp4BtRtFiwGDzmaevMku8=", - "pom": "sha256-IzAaISnUEAiZJfSvQa7LUlhKPcxFJoI+EyNOyst+c+M=" - }, - "org/apache/logging/log4j#log4j-bom/2.24.1": { - "pom": "sha256-vGPPsrS5bbS9cwyWLoJPtpKMuEkCwUFuR3q1y3KwsNM=" - }, - "org/apache/logging/log4j#log4j-core/2.24.1": { - "jar": "sha256-ALzziEcsqApocBQYF2O2bXdxd/Isu/F5/WDhsaybybA=", - "pom": "sha256-JyQstBek3xl47t/GlYtFyJgg+WzH9NFtH0gr/CN24M0=" - }, - "org/apache/logging/log4j#log4j/2.24.1": { - "pom": "sha256-+NcAm1Rl2KhT0QuEG8Bve3JnXwza71OoDprNFDMkfto=" - }, - "org/apache/maven#maven-api-meta/4.0.0-alpha-9": { - "jar": "sha256-MsT1yturaAw0lS+ctXBFehODzOxMmlewOSYH1xkcaUk=", - "pom": "sha256-2ePDXW/aysuNGLn2QoYJDH/65yjWbLJq9aJmgZUNvnk=" - }, - "org/apache/maven#maven-api-xml/4.0.0-alpha-9": { - "jar": "sha256-KbJijQ8CgRlxWRaEnBnu1FsyzcZ+sTVReYxzr6SqI9Y=", - "pom": "sha256-N2bjAzOTTJIvUlj6M0uHXyi7ABJ/8D3vANl/KlOnrps=" - }, - "org/apache/maven#maven-api/4.0.0-alpha-9": { - "pom": "sha256-ZYvglXcymzX5TemWdb8O/HI26ZYbXHhfMyqkfyKUcfA=" - }, - "org/apache/maven#maven-bom/4.0.0-alpha-9": { - "pom": "sha256-4EfSnTUI/yd6Wsk1u5J/NUkQLMbTec5a4p4pYzeE0Rw=" - }, - "org/apache/maven#maven-parent/41": { - "pom": "sha256-di/N1M6GIcX6Ciz2SVrSaXKoCT60Mqo+QCvC1OJQDFM=" - }, - "org/apache/maven#maven-xml-impl/4.0.0-alpha-9": { - "jar": "sha256-JucCuIHVeuTuiNAsAJQLpkBjcF7mkgWuiVi/g5qLBrE=", - "pom": "sha256-us0USYVzbUMmuuRChHM78eMTKX3NolNGTkYpsddoGPc=" - }, - "org/apache/maven#maven/4.0.0-alpha-9": { - "pom": "sha256-5QzZ/zefQ3H3/ywsrFF5YfPS9n7fgJCHU8e9UGuRPX4=" - }, - "org/apfloat#apfloat-parent/1.10.1": { - "pom": "sha256-rHDBL+cJtXDurKOZT4NbpGnnJaWbvjYRDTpBImHgUt8=" - }, - "org/apfloat#apfloat/1.10.1": { - "jar": "sha256-oUgPVg83NV9sBFjFI72kZljaTNPiPMZOMJ/tzXsHgro=", - "pom": "sha256-hhppAMWT7SJoYA3RdxPseJHZM8oBnTlQm0bzGBJ0Xcs=" - }, - "org/bitbucket/b_c#jose4j/0.9.5": { - "jar": "sha256-gI+zFm8+Z9rZgRwzECmrFoEkL9Urc1vD8z8oEWf8xy4=", - "pom": "sha256-utAkGAobRpy9lOXy2xKEG8rFRD2VRWB/Zzz95nfB2HI=" - }, - "org/bouncycastle#bcpkix-jdk18on/1.77": { - "jar": "sha256-Gsf+jv1bLzjNwWW+WgZ1c0/kSAjauScHIB8DpTXW8bg=", - "pom": "sha256-j7CSbwLixLLcUuR+uwk/kvHTu28UnCpcyl4qZI0sSY0=" - }, - "org/bouncycastle#bcprov-jdk18on/1.77": { - "jar": "sha256-2ruYwk1yybn1hWM9HfnFzVjZrTc9DNaBNn5qYDpJXVg=", - "pom": "sha256-rROCz80DvN2L4TkTwC9E/UadCnalPPLK71vhgK3DayM=" - }, - "org/bouncycastle#bcutil-jdk18on/1.77": { - "jar": "sha256-lHZzvLxajd4tL6aIpbdZjQym4qdKfqMM2T8E9rOtaPg=", - "pom": "sha256-Fj36ZjL/uSinBcqDciNQys6knM1iPOc2RaXMOw+p5ug=" - }, - "org/checkerframework#checker-qual/2.5.8": { - "pom": "sha256-M6xqDxNBrpZkfH1EZfSqPST+l9Jpe87izq5vyLXvLDw=" - }, - "org/checkerframework#checker-qual/3.33.0": { - "jar": "sha256-4xYlW7/Nn+UNFlMUuFq7KzPLKmapPEkdtkjkmKgsLeE=", - "module": "sha256-6FIddWJdQScsdn0mKhU6wWPMUFtmZEou9wX6iUn/tOU=", - "pom": "sha256-9VqSICenj92LPqFaDYv+P+xqXOrDDIaqivpKW5sN9gM=" - }, - "org/codehaus/mojo#animal-sniffer-annotations/1.23": { - "jar": "sha256-n/5Sa/Q6Y0jp2LM7nNb1gKf17tDPBVkTAH7aJj3pdNA=", - "pom": "sha256-VhDbBrczZBrLx6DEioDEAGnbYnutBD+MfI16+09qPSc=" - }, - "org/codehaus/mojo#animal-sniffer-parent/1.23": { - "pom": "sha256-a38FSrhqh/jiWZ81gIsJiZIuhrbKsTmIAhzRJkCktAQ=" - }, - "org/codehaus/mojo#mojo-parent/74": { - "pom": "sha256-FHIyWhbwsb2r7SH6SDk3KWSURhApTOJoGyBZ7cZU8rM=" - }, - "org/codehaus/plexus#plexus-utils/4.0.2": { - "jar": "sha256-iVcnTnX+LCeLFCjdFqDa7uHdOBUstu/4Fhd6wo/Mtpc=", - "pom": "sha256-UVHBO918w6VWlYOn9CZzkvAT/9MRXquNtfht5CCjZq8=" - }, - "org/codehaus/plexus#plexus-xml/4.0.4": { - "jar": "sha256-Bp54tTcQjcYSSmcHP8mYJkeR9rZJnpVaOOcrs+T+Gt8=", - "pom": "sha256-Ohb3yn7CRzFFtGHgpylREI1H4SThjIRMCFsaY3jGEVE=" - }, - "org/codehaus/plexus#plexus/18": { - "pom": "sha256-tD7onIiQueW8SNB5/LTETwgrUTklM1bcRVgGozw92P0=" - }, - "org/codehaus/woodstox#stax2-api/4.2.1": { - "jar": "sha256-Z4Vn5ItRpCxlxpnyZlOa09Z21LGlsK19iezoudV3JXk=", - "pom": "sha256-edpBDIwPRqP46K2zDWwkzNYGW272v96HvZfpiB6gouc=" - }, - "org/eclipse/ee4j#project/1.0.2": { - "pom": "sha256-dJWgenl+iOQ8O8GodCG9ix/FXjIpH6GOTjLYAx3chz8=" - }, - "org/eclipse/ee4j#project/1.0.5": { - "pom": "sha256-kWtHlNjYIgpZo/32pk2+eUrrIzleiIuBrjaptaLFkaY=" - }, - "org/eclipse/ee4j#project/1.0.7": { - "pom": "sha256-IFwDmkLLrjVW776wSkg+s6PPlVC9db+EJg3I8oIY8QU=" - }, - "org/glassfish/jaxb#jaxb-bom/2.3.2": { - "pom": "sha256-oQGLtUZ47Z9ayy96QITjhf9RAgH06dv1913GpnX2a+c=" - }, - "org/glassfish/jaxb#jaxb-runtime/2.3.2": { - "jar": "sha256-5uCh6J+2/3hieeagCC1c71LcLr5nBT0EGABzdlK0/Rs=", - "pom": "sha256-lEilrX+mimCD375PQsjIPggrkgKhBUAfxo6UTCZUizQ=" - }, - "org/glassfish/jaxb#txw2/2.3.2": { - "jar": "sha256-SmqfSDOI1GG4GqmijGhbi3TAWXmTvxiEsE7dvKlfSP4=", - "pom": "sha256-p53QAvsDgYP/KGomNb4uaMEDuH4OZHF9jUS/0Bf9M+o=" - }, - "org/jdom#jdom2/2.0.6": { - "jar": "sha256-E0XxG6YG0VYD1nQFUajCGUfAIVZAdw7GcnH+eL6pfPU=", - "pom": "sha256-R7I6ef4za3QbgkNMbgSdaBZSVuQF51wQkh/XL6imXY0=" - }, - "org/jdom#jdom2/2.0.6.1": { - "jar": "sha256-CyD0XjoP2PDRLNxTFrBndukCsTZdsAEYh2+RdcYPMCw=", - "pom": "sha256-VXleEBi4rmR7k3lnz4EKmbCFgsI3TnhzwShzTIyRS/M=" - }, - "org/jetbrains#annotations/13.0": { - "jar": "sha256-rOKhDcji1f00kl7KwD5JiLLA+FFlDJS4zvSbob0RFHg=", - "pom": "sha256-llrrK+3/NpgZvd4b96CzuJuCR91pyIuGN112Fju4w5c=" - }, - "org/jetbrains/intellij/deps#trove4j/1.0.20200330": { - "jar": "sha256-xf1yW/+rUYRr88d9sTg8YKquv+G3/i8A0j/ht98KQ50=", - "pom": "sha256-h3IcuqZaPJfYsbqdIHhA8WTJ/jh1n8nqEP/iZWX40+k=" - }, - "org/jetbrains/kotlin#fus-statistics-gradle-plugin/2.1.20": { - "module": "sha256-6NVkojvCA3s++xxbAP+3SuRPmXJFd+L8jYf/u8nLn7U=", - "pom": "sha256-oRA6cKb4/8EITdwIGyS6smpWRJcvnM0UG4mU2fUFRHg=" - }, - "org/jetbrains/kotlin#fus-statistics-gradle-plugin/2.1.20/gradle85": { - "jar": "sha256-ZnTyl1XTJq3cdWov3Kvyu2AvAABKDtLbZp2j306EgAY=" - }, - "org/jetbrains/kotlin#kotlin-build-statistics/2.1.20": { - "jar": "sha256-TSjxg6dsMKjKwg56P6hwVMLdHbiGSzyc04nhjdmX0x4=", - "pom": "sha256-OR9tc0uDTJG3qAHiI638c2tYDb3ODxOafkvUdknATKM=" - }, - "org/jetbrains/kotlin#kotlin-build-tools-api/2.1.20": { - "jar": "sha256-Uzw2yzYubtLRX1hzLn9MbSvtXJ1RebiXvEsJ0W1gU3c=", - "pom": "sha256-kn9h95cmHFnktTEDFNaf1KOrjvT3A596UyYHXEKkFzo=" - }, - "org/jetbrains/kotlin#kotlin-compiler-runner/2.1.20": { - "jar": "sha256-3jtUI9j7+G6ivRM01AG8SqhOKOxIlFlS0RwAsQsUArY=", - "pom": "sha256-xgNdI3KARTSALDfOVU6MjLqq6EUUp7rWzAlkJNjySUU=" - }, - "org/jetbrains/kotlin#kotlin-daemon-client/2.1.20": { - "jar": "sha256-NjCjAYLGNXDrUZrmWqqUGSF9utCBT+3kLI3ecERlpMY=", - "pom": "sha256-+qpgvkJw6RSbWUOSZjlhkr60f/XjpAmF3u3FTlkXItI=" - }, - "org/jetbrains/kotlin#kotlin-gradle-plugin-annotations/2.1.20": { - "jar": "sha256-sk9SbQ3++wKWrg9Ks2L51soCV3JcwnMIOprjN+ooJn0=", - "pom": "sha256-wKs06ffQCv3LIv0D5S6PhZpGR9lY4Lh7fQzSY0QWOlo=" - }, - "org/jetbrains/kotlin#kotlin-gradle-plugin-api/2.1.20": { - "jar": "sha256-fjYZlm/jid9IV59DsY8sCwc2llWZFTd8lELrqM+7+/Y=", - "module": "sha256-AsJsJlASRw1yrc3buCTSOOayieEAzUu/moJ1Cj1Jv8A=", - "pom": "sha256-t02/6klcg6xWRwS6qDmk56W3kRiMj3llbJwZ3XfeLxg=" - }, - "org/jetbrains/kotlin#kotlin-gradle-plugin-api/2.1.20/gradle85": { - "jar": "sha256-fjYZlm/jid9IV59DsY8sCwc2llWZFTd8lELrqM+7+/Y=" - }, - "org/jetbrains/kotlin#kotlin-gradle-plugin-idea-proto/2.1.20": { - "jar": "sha256-6vELILujkjoH+PsYL7jNVlaZ4Vfuc9Elma8fXKuiUEA=", - "pom": "sha256-PdYeaTbcUQBs5MN+/+Q+/hQAuEHgnsSx7kqU9rkZOCo=" - }, - "org/jetbrains/kotlin#kotlin-gradle-plugin-idea/2.1.20": { - "jar": "sha256-APb4Q6vJMNDGGrtOPjAsjRd2EpH5srwlhv4SsMuXXq0=", - "module": "sha256-td7wBfIpohsq1pJt9wjPhLqe+8TsGcY16/5baTcx2wg=", - "pom": "sha256-CjCxRdSY1H2yVdDUzWp3hMXx+QyL+YgsupWCKjvzMHA=" - }, - "org/jetbrains/kotlin#kotlin-gradle-plugin-model/2.1.20": { - "jar": "sha256-1jf7pHCzv3E7CmXmcXrV3QOocl/MlFMCiUc6smtC6Cs=", - "module": "sha256-WJm5fnqbFx5sBeVJziqbo8ddJZMVnUsrAVZkFLVoUWo=", - "pom": "sha256-18CRV8ehutuNrk6Jv54N9FRbBM0DqqQJZqJm87hG0sM=" - }, - "org/jetbrains/kotlin#kotlin-gradle-plugin/1.9.23": { - "module": "sha256-YL2BUHBNWByO6tTBlAh26LAor+ixS0lAEMUJIEclRKc=", - "pom": "sha256-TgznuA0cN7kRzb/kFf77ZdzvGCalGLF3vWAvlaloqMU=" - }, - "org/jetbrains/kotlin#kotlin-gradle-plugin/2.1.20": { - "module": "sha256-6Ue1RPTNCcFQr9h5G70yoxN92uMEWn1TlL6lCaq5bFc=", - "pom": "sha256-H2OowlwTZmlled2VLz639CoKSns/avaRpIIjEwb82sk=" - }, - "org/jetbrains/kotlin#kotlin-gradle-plugin/2.1.20/gradle85": { - "jar": "sha256-+wFuZDtY4Koq7IkRDq8U54s3aMFX8lQ0V5X9aqEEk+s=" - }, - "org/jetbrains/kotlin#kotlin-gradle-plugins-bom/1.9.23": { - "module": "sha256-1yNF4lW/IKOperXQEIa2CMXX0M8/Z3inHoXKy61BQlo=", - "pom": "sha256-2Ive7tm5RMrHGM3PKUD4FdgiXuzNIb7KB93QgfDSQow=" - }, - "org/jetbrains/kotlin#kotlin-gradle-plugins-bom/2.1.20": { - "module": "sha256-IF4RacYovsBfHVnkTTIJFSiun9U6fjPsVDvO/bEojeY=", - "pom": "sha256-Y5ymx2U+Gp2pXfKjuuJsy3AcA6/VjHl6tr9vJV9kwwE=" - }, - "org/jetbrains/kotlin#kotlin-klib-commonizer-api/2.1.20": { - "jar": "sha256-EyGYEVmGCVkEsMsB76rh2BJJZB75FJ4Fs0T4ZKrpdfQ=", - "pom": "sha256-LZayVvD8kesSvOtuR2HhPXAf8TU/BZL8VymI2uai0Zs=" - }, - "org/jetbrains/kotlin#kotlin-metadata-jvm/2.1.0": { - "jar": "sha256-uNOpJXS6HfxJvfIFJW0e3gZkFIyxUKti+qhyteG7RjI=", - "pom": "sha256-G8hTyAjj0o3D8Gf2Z/ZSSro0YWl6+VJu/et09Ulojdg=" - }, - "org/jetbrains/kotlin#kotlin-native-utils/2.1.20": { - "jar": "sha256-pyVic6u53yI1kk2A/dNtZ4tFhGfDB2xmhRxCQ3vdPGY=", - "pom": "sha256-1Gec6AsERY5fzL1pteMUvxwMFnmH4EOVRv3+z7U+M0Y=" - }, - "org/jetbrains/kotlin#kotlin-reflect/2.0.21": { - "jar": "sha256-OtL8rQwJ3cCSLeurRETWEhRLe0Zbdai7dYfiDd+v15k=", - "pom": "sha256-Aqt66rA8aPQBAwJuXpwnc2DLw2CBilsuNrmjqdjosEk=" - }, - "org/jetbrains/kotlin#kotlin-serialization/2.1.20": { - "module": "sha256-OMZPybedsk2Y415NutDvDjOxdsKXSTE8c7k6D5bCIgs=", - "pom": "sha256-Ffv0qiQBTCr6vmXjwzrY39LYocR8z5dsBbqKNqGou0I=" - }, - "org/jetbrains/kotlin#kotlin-serialization/2.1.20/gradle85": { - "jar": "sha256-rNawwcN18ocop1LMbI0itREnbFT1DZcb7UM957K9qjI=" - }, - "org/jetbrains/kotlin#kotlin-stdlib-jdk7/1.9.20": { - "jar": "sha256-xUUdZ6J/M6/QmRPGfhzro4l65wiEsk7w/3EVflW2CGU=", - "pom": "sha256-AS4cVe1q3kF7y4JBEuvqaCrWJd++4WCFw3nM+hT68DM=" - }, - "org/jetbrains/kotlin#kotlin-stdlib-jdk8/1.9.20": { - "jar": "sha256-+DP8yU8LscMbnni9S9p+oj9Xn/NAiuGpTi61dHCGoqs=", - "pom": "sha256-o7B96wkfKu1Z1lWYhPRPmc/135ufo1okvNa4sGnP9I0=" - }, - "org/jetbrains/kotlin#kotlin-stdlib/2.0.21": { - "jar": "sha256-8xzFPxBafkjAk2g7vVQ3Vh0SM5IFE3dLRwgFZBvtvAk=", - "module": "sha256-gf1tGBASSH7jJG7/TiustktYxG5bWqcpcaTd8b0VQe0=", - "pom": "sha256-/LraTNLp85ZYKTVw72E3UjMdtp/R2tHKuqYFSEA+F9o=" - }, - "org/jetbrains/kotlin#kotlin-tooling-core/2.1.20": { - "jar": "sha256-tPu1I+hmLUqEUbmjap5/1D9jfLDNapueNoFxlmXavY0=", - "pom": "sha256-PO8cS3yC7KjMAcMMrt0VSQWeZfL51BYsjJ13+6JBMXY=" - }, - "org/jetbrains/kotlin#kotlin-util-io/2.1.20": { - "jar": "sha256-gqOymmEdR85jSuLmxQnN4qhvlLI7hr4whk6z1Lj+jn4=", - "pom": "sha256-eSQnftICC4UQ1F8N0QgREmVoEDAH2D+ZcfwYRmC9hKM=" - }, - "org/jetbrains/kotlin#kotlin-util-klib-metadata/2.1.20": { - "jar": "sha256-8tXmhHFbkgtghJaObDPIuwWwtrl5GYAOLyIdlBgkDH0=", - "pom": "sha256-hCdVuVwx20vbks9tQshUGhcB+ivc8lIahwa8sDKgoZc=" - }, - "org/jetbrains/kotlin#kotlin-util-klib/2.1.20": { - "jar": "sha256-/3nFsObkLZIOuxx2uhDMLdvyJOgFZFqO6sreSRbiqs4=", - "pom": "sha256-ps3TjXdd/QfQe9FZ00LPegqWg4qH50guIgxjrtluEoA=" - }, - "org/jetbrains/kotlin/android#org.jetbrains.kotlin.android.gradle.plugin/2.1.20": { - "pom": "sha256-yWdpfrgyBcRRU8hteaZi8cS2agHN7p9/3Qe7k0ApoTU=" - }, - "org/jetbrains/kotlin/jvm#org.jetbrains.kotlin.jvm.gradle.plugin/2.1.20": { - "pom": "sha256-q8TDh14/l1U6F2qQ9ReI7A9ero4dJkI+qOvb+KpqF4Y=" - }, - "org/jetbrains/kotlin/multiplatform#org.jetbrains.kotlin.multiplatform.gradle.plugin/2.1.20": { - "pom": "sha256-V9ikuJwOk+iwmY7ijgUHkjDqf3kdEDs8sHOsn9V4HSc=" - }, - "org/jetbrains/kotlin/plugin/serialization#org.jetbrains.kotlin.plugin.serialization.gradle.plugin/2.1.20": { - "pom": "sha256-YjXePQABYjdcj3IvCO2hU/CQ4RoDW0qbi+fqxO8UX+Y=" - }, - "org/jetbrains/kotlinx#atomicfu-gradle-plugin/0.27.0": { - "jar": "sha256-+JC6ryI1yN6kPhn4z+YCESnR/Z0K8DL4HZHbXk8dz6s=", - "module": "sha256-+ZVGhecoTZD4P51zKBGXl6gNP8dKZX5x0NKjM1fFESA=", - "pom": "sha256-I1EtRWDRpL/Rm2h1wg9DE85ep20RhyUwI4yx58oxNDE=" - }, - "org/jetbrains/kotlinx#atomicfu-transformer/0.27.0": { - "jar": "sha256-Mun9/FpwR6fnVEc4/YmRFLUnp6RiTfhXAnsehwIAeOw=", - "module": "sha256-eKfmR1/c4aDr+A62Mk5w0km24a/CgrdQPcw8pCk+yMg=", - "pom": "sha256-CiaCvpkn5FD+21SnYt9RxyUXW8f7A8ckPWDy8ckBQrk=" - }, - "org/jetbrains/kotlinx#kotlinx-coroutines-bom/1.8.0": { - "pom": "sha256-Ejnp2+E5fNWXE0KVayURvDrOe2QYQuQ3KgiNz6i5rVU=" - }, - "org/jetbrains/kotlinx#kotlinx-coroutines-core-jvm/1.8.0": { - "jar": "sha256-mGCQahk3SQv187BtLw4Q70UeZblbJp8i2vaKPR9QZcU=", - "module": "sha256-/2oi2kAECTh1HbCuIRd+dlF9vxJqdnlvVCZye/dsEig=", - "pom": "sha256-pWM6vVNGfOuRYi2B8umCCAh3FF4LduG3V4hxVDSIXQs=" - }, - "org/jetbrains/kotlinx/atomicfu#org.jetbrains.kotlinx.atomicfu.gradle.plugin/0.27.0": { - "pom": "sha256-tyPM6LzdnbMq2rYi9Zaogflt1cb5yofwGZ80vHQn9Zo=" - }, - "org/jgrapht#jgrapht-core/1.5.2": { - "jar": "sha256-36WW6fDQg48bXoHdDNYOOnbCwpCsJaCgKf/eWM9eTBQ=", - "pom": "sha256-R+MlGXkdDQblxsiNqMUZgA9O/9M2x9bVYE/f10+Sf8o=" - }, - "org/jgrapht#jgrapht/1.5.2": { - "pom": "sha256-V4X+aGHRVM9tin5rwS2X+GcmxgA2g/AOW++4rAPy0sM=" - }, - "org/jheaps#jheaps/0.14": { - "jar": "sha256-SamJjaN1hlk4jxMzxTzK22+9FCp9GKp7GjNXcJBoQnk=", - "pom": "sha256-Fge2IOHytOGg9IkQELNJCx+0qD5xOsTTiwjcLGf6PlE=" - }, - "org/junit#junit-bom/5.10.1": { - "module": "sha256-IbCvz//i7LN3D16wCuehn+rulOdx+jkYFzhQ2ueAZ7c=", - "pom": "sha256-IcSwKG9LIAaVd/9LIJeKhcEArIpGtvHIZy+6qzN7w/I=" - }, - "org/junit#junit-bom/5.10.2": { - "module": "sha256-3iOxFLPkEZqP5usXvtWjhSgWaYus5nBxV51tkn67CAo=", - "pom": "sha256-Fp3ZBKSw9lIM/+ZYzGIpK/6fPBSpifqSEgckzeQ6mWg=" - }, - "org/junit#junit-bom/5.10.3": { - "module": "sha256-qnlAydaDEuOdiaZShaqa9F8U2PQ02FDujZPbalbRZ7s=", - "pom": "sha256-EJN9RMQlmEy4c5Il00cS4aMUVkHKk6w/fvGG+iX2urw=" - }, - "org/junit#junit-bom/5.11.0": { - "module": "sha256-9+2+Z/IgQnCMQQq8VHQI5cR29An1ViNqEXkiEnSi7S0=", - "pom": "sha256-5nRZ1IgkJKxjdPQNscj0ouiJRrNAugcsgL6TKivkZE0=" - }, - "org/junit#junit-bom/5.9.2": { - "module": "sha256-qxN7pajjLJsGa/kSahx23VYUtyS6XAsCVJdyten0zx8=", - "pom": "sha256-LtB9ZYRRMfUzaoZHbJpAVrWdC1i5gVqzZ5uw82819wU=" - }, - "org/junit#junit-bom/5.9.3": { - "module": "sha256-tAH9JZAeWCpSSqU0PEs54ovFbiSWHBBpvytLv87ka5M=", - "pom": "sha256-TQMpzZ5y8kIOXKFXJMv+b/puX9KIg2FRYnEZD9w0Ltc=" - }, - "org/jvnet/staxex#stax-ex/1.8.1": { - "jar": "sha256-IFIlSQVunlCqNe8LRFouR6U9Br4LCpRn1wTiSD/7BJo=", - "pom": "sha256-j8hPNs5tps6MiTtlOBmaf2mmmgcG2bF6PuajoJRS7tY=" - }, - "org/mockito#mockito-bom/4.11.0": { - "pom": "sha256-2FMadGyYj39o7V8YjN6pRQBq6pk+xd+eUk4NJ9YUkdo=" - }, - "org/mockito#mockito-bom/5.7.0": { - "pom": "sha256-dlcAW89JAw1nzF1S3rxm3xj0jVTbs+1GZ/1yWwZ5+6A=" - }, - "org/mozilla#rhino/1.7.10": { - "jar": "sha256-OOswAM9WuMdVnuVYhmp2juvL8lQXRSLWQEt/B491wtQ=", - "pom": "sha256-PHy6D12ldR1ipVZ2iXp64jaHx6Hi++HUdMW8Wka5+bM=" - }, - "org/ow2#ow2/1.5.1": { - "pom": "sha256-Mh3bt+5v5PU96mtM1tt0FU1r+kI5HB92OzYbn0hazwU=" - }, - "org/ow2/asm#asm-analysis/9.6": { - "pom": "sha256-+j+ZUCHP9PQTkwbmz/7uoHU5EGRA0psZzAanpjahOFA=" - }, - "org/ow2/asm#asm-analysis/9.7": { - "jar": "sha256-e8a8vCE3mUigyMRn+w+GQgbluBj2vAtUaHL1yflBVW8=", - "pom": "sha256-nDMIDry2Ma5Pd+ti7We/xAy4cujP0Fishj5EXB3Zc98=" - }, - "org/ow2/asm#asm-commons/9.6": { - "pom": "sha256-qYrkiVM0uvj/hr1mUWIQ29mgPxpuFeR92oKvz2tT13w=" - }, - "org/ow2/asm#asm-commons/9.7": { - "jar": "sha256-OJvCR5WOBJ/JoECNOYySxtNwwYA1EgOV1Muh2dkwS3o=", - "pom": "sha256-Ws7j7nJS7ZC4B0x1XQInh0malfr/+YrEpoUQfE2kCbQ=" - }, - "org/ow2/asm#asm-commons/9.7.1": { - "jar": "sha256-mlebVNKSrZvhcdQxP9RznGNVksK1rDpFm70QSc3exqA=", - "pom": "sha256-C/HTHaDJ+djtwvJ9u/279z8acVtyzS+ijz8ZWZTXStE=" - }, - "org/ow2/asm#asm-tree/9.6": { - "pom": "sha256-G8tIHX/Ba5VbtgygfIz6JCS87ni9xAW7oxx9b13C0RM=" - }, - "org/ow2/asm#asm-tree/9.7": { - "jar": "sha256-YvSzvENgRcGstcO6LY7FVuwzaQk9f10Gx0frBLVtUrE=", - "pom": "sha256-o06h4+QSjAEDjbQ8aXbojHec9a+EsFBdombf5pZWaOw=" - }, - "org/ow2/asm#asm-tree/9.7.1": { - "jar": "sha256-mSmIH1nra4QOhtVFcMd7Wc5yHRBObf16QJeJkcLTtB8=", - "pom": "sha256-E7kF9l5/1DynZ09Azao3Z5ukhYxsnZ+48Xp6/ZuqvJ4=" - }, - "org/ow2/asm#asm-util/9.6": { - "pom": "sha256-UsXB01dAR3nRqZtJqFv506CFAluFFstz2+93yK40AF4=" - }, - "org/ow2/asm#asm-util/9.7": { - "jar": "sha256-N6ZBTTZkGXPxrxBJN8ldbZIbLdtNYSxmxanysT/BQhE=", - "pom": "sha256-XQFNjIcNSHGCW9LdtVZ7Ie9trI7Ei7uNu0ZbCzor9FI=" - }, - "org/ow2/asm#asm/9.6": { - "pom": "sha256-ku7iS8PIQ+SIHUbB3WUFRx7jFC+s+0ZrQoz+paVsa2A=" - }, - "org/ow2/asm#asm/9.7": { - "jar": "sha256-rfRtXjSUC98Ujs3Sap7o7qlElqcgNP9xQQZrPupcTp0=", - "pom": "sha256-3gARXx2E86Cy7jpLb2GS0Gb4bRhdZ7nRUi8sgP6sXwA=" - }, - "org/ow2/asm#asm/9.7.1": { - "jar": "sha256-jK3UOsXrbQneBfrsyji5F6BAu5E5x+3rTMgcdAtxMoE=", - "pom": "sha256-cimwOzCnPukQCActnkVppR2FR/roxQ9SeEGu9MGwuqg=" - }, - "org/slf4j#slf4j-api/1.7.30": { - "pom": "sha256-fgdHdR6bZ+Gdy1IG8E6iLMA9JQxCJCZALq3QNRPywxQ=" - }, - "org/slf4j#slf4j-api/1.8.0-alpha2": { - "jar": "sha256-CcMB+ICGrfcF/ROqvSDMshSNjqZN+jx+SCtckJBGx5I=", - "pom": "sha256-q7TTRvEsRpktok1TctybilWE2+hXbAlUkpId+iFpsEo=" - }, - "org/slf4j#slf4j-parent/1.7.30": { - "pom": "sha256-EWR5VuSKDFv7OsM/bafoPzQQAraFfv0zWlBbaHvjS3U=" - }, - "org/slf4j#slf4j-parent/1.8.0-alpha2": { - "pom": "sha256-nWWHTIet1peG5j/+ncT025AuB86ODQmzlRqZ46ptLCg=" - }, - "org/slf4j#slf4j-simple/1.8.0-alpha2": { - "jar": "sha256-ObJOKXTUdzen28wQKUiyzOcb0wNUEKnRb5gRhQhgtcI=", - "pom": "sha256-rqEymqts7JmjCCpSzd/IKFTxEyjspEEpGkhMHUCuNCQ=" - }, - "org/sonatype/oss#oss-parent/7": { - "pom": "sha256-tR+IZ8kranIkmVV/w6H96ne9+e9XRyL+kM5DailVlFQ=" - }, - "org/sonatype/oss#oss-parent/9": { - "pom": "sha256-+0AmX5glSCEv+C42LllzKyGH7G8NgBgohcFO8fmCgno=" - }, - "org/springframework#spring-framework-bom/5.3.39": { - "module": "sha256-+ItA4qUDM7QLQvGB7uJyt17HXdhmbLFFvZCxW5fhg+M=", - "pom": "sha256-9tSBCT51dny6Gsfh2zj49pLL4+OHRGkzcada6yHGFIs=" - }, - "org/tensorflow#tensorflow-lite-metadata/0.1.0-rc2": { - "jar": "sha256-LComT4QkmMNtNNKnuRNCSQ2alihiyFuqwazVTsL8ptk=", - "pom": "sha256-mk9eVnQ2bBVskDkWYvA+18WXHWqmODLfdKJx2m/4LpY=" - }, - "org/vafer#jdependency/2.11": { - "jar": "sha256-zdoDAD+pVRMVpMw/wWPxhJXxkbSaj3CjquIy8Emn/dA=", - "pom": "sha256-2mymcCFlPxUMHVNDLKxApzkH0tkqjzR65eRAHk+iJ+c=" - } - }, - "https://repo.maven.apache.org/maven2": { - "app/cash/sqldelight#compiler-env/2.0.2": { - "jar": "sha256-d8KB+VOzDh06DHWEcNxAS3VM7R3zqUcwCwQSNCxex2c=", - "module": "sha256-PvQukPnM6R8+tVRTrIn+QCQUvJPGDUjhGr9nQb/3dnk=", - "pom": "sha256-NZqoVOlA/vTy1bV61hIcb12e69457m+/f+Ac8F4poPo=" - }, - "app/cash/sqldelight#dialect-api/2.0.2": { - "jar": "sha256-O8jKnSyT2pb5pov3hhVk53UcpL17nJBV8ThLM52zL8Q=", - "module": "sha256-mQILmwYxc4kmMRq9mRGy5OiurYmJyDQPUkfYv/6X+Wk=", - "pom": "sha256-OXXuzXTyjyCTjLsN9bNCR4GVjxBt8oHFHbGtZECHHo0=" - }, - "app/cash/sqldelight#jdbc-driver/2.0.2": { - "jar": "sha256-B28ayZJ9OpRKmMIrnHaMyppDzaq+pfvDQ69oJJ+7yyE=", - "module": "sha256-MC3h5Lq1rryQzRrNW1ytNlehKpVd5SHLuPBgzMaHAK4=", - "pom": "sha256-aHkkp7DuIn/NAGO9PedsMntS/S3Vwl73lBqWyhXwf/M=" - }, - "app/cash/sqldelight#migration-env/2.0.2": { - "jar": "sha256-PLWqybEjxL6OUf1uYXdCUv8r+L8Z23pe0k16eSHHq9Y=", - "module": "sha256-qhgLbwtTdePaS4Aj2v12QnvrMsXjoJOugYLTP2ujVyk=", - "pom": "sha256-gC15Yg0X09aT5Nn7tqNfdAa4vANby1jcMVLG7zwMGqQ=" - }, - "app/cash/sqldelight#runtime-jvm/2.0.2": { - "jar": "sha256-cRk2N4b+PvfWUJaxEWtp3dSBxtl32PsDlYaMgaoAKew=", - "module": "sha256-yQpgluBwIvye8yby1O8Qf+7PhbyY4k9xs54FiXKUYQM=", - "pom": "sha256-wQDPEUHQBMnHIhm+yDXESzUkA//6JeGJy3mAcMevef0=" - }, - "app/cash/sqldelight#runtime/2.0.2": { - "module": "sha256-yVLgLQycsuW3Bq8yynMHkqT5HXjH+tkdk2ks+fwcXW4=", - "pom": "sha256-WGR/Tkvpnkbo5kOgPqd6C7kbDVlRV+j+pq0xtFviNtI=" - }, - "app/cash/sqldelight#sqlite-3-18-dialect/2.0.2": { - "jar": "sha256-HsdEuG8LHmB0r8sYTNtsTe9V7iikejNyuJa10CX8TNE=", - "module": "sha256-LvIi+YR4PzE4JiN4U5H2dFBB3jHPYdo7JiJeBV04MiM=", - "pom": "sha256-IoyB145uVY/rL4wo2mu65HytnJEakC/MMIyeQU4jpKc=" - }, - "app/cash/sqldelight#sqlite-driver/2.0.2": { - "jar": "sha256-uodtxjq97kppilOVxqYvwGJYLLGBupuyA+l+VIuKpFw=", - "module": "sha256-64zeg2nRj0sbO28Mppl7oYkzof6q5kKCDC60EyllghI=", - "pom": "sha256-WO+t2LiopDUvqkD2weaqLsfBMCsSt2aXVcjy6ADt5kI=" - }, - "ch/qos/logback#logback-classic/1.5.18": { - "jar": "sha256-PhUz0DIfiBXu9GdQruARG0FVT5pGRMPE0tQEdEsJ9g8=", - "pom": "sha256-1VfNKrI95KR+zocGQhYqn5Rzn80LHDE+J4MlFO4gODM=" - }, - "ch/qos/logback#logback-core/1.5.18": { - "jar": "sha256-hROee1e0ZPjl42Mm3YExdki+0ZnMxPmM1CWF+NdXECc=", - "pom": "sha256-x3JHKX1dm7ngTpLUyC51xujqviRUNokvkRQzW4t5DIM=" - }, - "ch/qos/logback#logback-parent/1.5.18": { - "pom": "sha256-U8PiGxI7vTijAbQNDYFAlOrUehAj0h1hPMdI1w57nGk=" - }, - "co/touchlab#stately-common-jvm/2.1.0": { - "jar": "sha256-rc7T7i/7YwnVIhFAiuq0tJNKykh7+DeEttVmldDM/vk=", - "module": "sha256-YJS2xMuXA5JCw/EIMH79GzPs820C0K+0fFrOkrSzw9k=", - "pom": "sha256-4ISMJiYA1vwAs8yGb8gOEIaLtw3+v04z8j4Jz9AZzRQ=" - }, - "co/touchlab#stately-common/2.1.0": { - "module": "sha256-/oMWdYjY6aCDNdle6mvygMCDB/1pqenOFsd0YS1Kup0=", - "pom": "sha256-H6pUlNYJlHka+DKTatycqjVrUz8mZdaAzYF8nCZ8EaQ=" - }, - "co/touchlab#stately-concurrency-jvm/2.1.0": { - "jar": "sha256-hnOWdYkvscF9a9NtBTR+if8xOVdCG7AaRadDzndOjik=", - "module": "sha256-D6llZC4JLY+zolZcFCgQBFrzO3twXmXE7XGoGKxrB8U=", - "pom": "sha256-P1Zua2KFRGWBF0Ec2/FArsibPmuRM6fzHLC2Y97CKbQ=" - }, - "co/touchlab#stately-concurrency/2.1.0": { - "module": "sha256-El5bZc1Vi4mhXnZF/6zCbBvMBuQdrw45XdMKcJKo2Xw=", - "pom": "sha256-77jL8SXaldDjBfhpMKO0N5Ny3PtcWdnM6ZfN4M0yQVo=" - }, - "co/touchlab#stately-iso-collections-jvm/2.1.0": { - "jar": "sha256-noKqT7wxeF0yliwE+nCjwxDhC0tjxaFWBtFkr+cZhLA=", - "module": "sha256-QhqOq7ZqBwiPx3CY6F7vpXWK/gwDGYUO7bV+rBWuGSw=", - "pom": "sha256-5ItiuiCyFDX8BFbGDiGJfAVplrcT9PsjG8+ozcxYIpU=" - }, - "co/touchlab#stately-iso-collections/2.1.0": { - "module": "sha256-bbO4mkUSy56T/NVZL4jTe8ym5HVNrRR0owrLC6XTCLk=", - "pom": "sha256-vvGboPQo1pCz1o/ZJ7Z0fDILnmtIdOQ9+0bTWH65DmI=" - }, - "co/touchlab#stately-isolate-jvm/2.1.0": { - "jar": "sha256-ZV9oCPf9XdtiV6TU5prNxF/zhq6q3bw/XmSS0VjzsGk=", - "module": "sha256-T9BmNwJBF6vpW1Ugog7JNi0jIO40MkhKXUOuS77SG+w=", - "pom": "sha256-nyuNKaa5V8hHfqrhrVgniP6Qnj6k7QNqInVlNLGsL2o=" - }, - "co/touchlab#stately-isolate/2.1.0": { - "module": "sha256-ZgfswfI/Ha8/sgAYqATMS1VxQxFx/K5uo7IdyAwIC0Y=", - "pom": "sha256-UPqXBxobLVw6KjKTAJ3xacXu8tl2AFeGAX49OyEAMRM=" - }, - "co/touchlab#stately-strict-jvm/2.1.0": { - "jar": "sha256-WBBw2ygCy62B9ubi2dJJSDVEMVOzFEWNU6pDxoJgyfo=", - "module": "sha256-kqvZ5gAGmEz0eQqvhMedDzhChuMm7ODzkh9pPNoIm5Q=", - "pom": "sha256-erZPXDxtRt2hKlno4RY+DEpYooljd8X1olZVhhC+Aak=" - }, - "co/touchlab#stately-strict/2.1.0": { - "module": "sha256-x5MXricP6pt1sugRZxQjoG+C+ogkTPlG/3lZhbTwtwE=", - "pom": "sha256-FsSmQjGZoCtg7Q7PuzyvcImUdcO5ODT9Oyi4Bj6pb0A=" - }, - "com/alecstrong/sql/psi#core/0.4.9": { - "jar": "sha256-oQY2Xymv+JgfU9Fq1Iz5LZxYYz8ryXCMZ7TeB2FFGf0=", - "module": "sha256-j0kf/wuD3vJn1n+e29IaMspCvRsfdDip4eSue94vNL8=", - "pom": "sha256-95ZPG0a91j5AIgNvbDyImHMTqMkmjq4VXOTUhBoNF5w=" - }, - "com/charleskorn/kaml#kaml-jvm/0.77.1": { - "jar": "sha256-JhcSmsk0uMUVLm/GFiIkKICe3kRP5/qDIxkXvqFB6n8=", - "module": "sha256-4U0BAn9uIlTL2p1JAnnzrh97hTfBetwawWZ1vqJUHHE=", - "pom": "sha256-BixbTXu2t0stY7pWiHcIonViNqh6UTv+0cK4Hyjy72o=" - }, - "com/charleskorn/kaml#kaml/0.77.1": { - "module": "sha256-2WfiA66erKxEuHLVkeOfZ8bGjHVXxNhd3fAY3OwA8EY=", - "pom": "sha256-I4ZYrXrfMFfxWI5KzQQM8wRF8Mp/4vRKtDHApod+QKo=" - }, - "com/fasterxml#oss-parent/61": { - "pom": "sha256-NklRPPWX6RhtoIVZhqjFQ+Er29gF7e75wSTbVt0DZUQ=" - }, - "com/fasterxml/jackson#jackson-bom/2.18.0": { - "pom": "sha256-ut3oZMpztsoE3p9+5J5knhpeivj4x8FoLHRr5eI0xYc=" - }, - "com/fasterxml/jackson#jackson-parent/2.18": { - "pom": "sha256-Vp3ADWi05t993oVimeHANT+kC9rxI+DfVj7L7kFlhtk=" - }, - "com/fleeksoft/charset#charset-jvm/0.0.4": { - "jar": "sha256-re3xy9VXZfRvMWL6eEiFFtTc35WR2m2LBwmi3dEpUlU=", - "module": "sha256-H/XaVX1/tm3WmAydQc96TMrUqU2md3SDNfHSMRNFF5A=", - "pom": "sha256-+zFapyyBMg6Xnz8wCm07KV5GAudxcmn1tZF0VAq+Lfk=" - }, - "com/fleeksoft/charset#charset/0.0.4": { - "module": "sha256-8bXY5eR8Tollvp0gTOMdLlE9w81aBfmPWF2AhXvgA9k=", - "pom": "sha256-YXCsSJRewHyEaoChTrnppXHMaikrd7gppq+iYSaPa3Y=" - }, - "com/fleeksoft/io#io-core-jvm/0.0.4": { - "jar": "sha256-Rlx8it65BTg2jKFpXvz5ZN2N0f3C52wWzN6BjT1tXeQ=", - "module": "sha256-Usz3FiD7EhrIEWE0mmqP1bOlb5JbFatUnsFbq15WiIw=", - "pom": "sha256-W17HyAvMdRGg9eOjk2zWcTQbqC/cSlkW+vif39zDy0s=" - }, - "com/fleeksoft/io#io-core/0.0.4": { - "module": "sha256-+OMStyxRXigbASIDP9xuzbF7gKhz8bmdVTVEaj4ySBI=", - "pom": "sha256-86n5E1LLjL0YhBnK4gX3olGj9wKQ/D0V488rpInOZvM=" - }, - "com/fleeksoft/ksoup#ksoup-jvm/0.2.3": { - "jar": "sha256-38Ub5iUdhnLtTH77+itqQ1PH0e2aKnvvNGmByEUmtE8=", - "module": "sha256-b2EgirbZOyE8FPBAv6aW7+/eoEbGTVBU2jRPPMhDtIM=", - "pom": "sha256-8cDkE/E7FXwXv+Tfeso3iisB8RtY32Xs6aqfvk7gIR0=" - }, - "com/fleeksoft/ksoup#ksoup/0.2.3": { - "module": "sha256-eITMP8Vh/I7YkYjQBv6mxGdgrSytpPTONGI05v+mDxg=", - "pom": "sha256-ik5gOYqd/ulr0IabKFm1V3/KxUiH3GdEqqzQ7+SbV9o=" - }, - "com/google/code/gson#gson-parent/2.8.9": { - "pom": "sha256-sW4CbmNCfBlyrQ/GhwPsN5sVduQRuknDL6mjGrC7z/s=" - }, - "com/google/code/gson#gson/2.8.9": { - "jar": "sha256-05mSkYVd5JXJTHQ3YbirUXbP6r4oGlqw2OjUUyb9cD4=", - "pom": "sha256-r97W5qaQ+/OtSuZa2jl/CpCl9jCzA9G3QbnJeSb91N4=" - }, - "com/microsoft/signalr#signalr/8.0.5": { - "jar": "sha256-Red6lgO5CLbNUgayvs5mU5AvkpD3fnihoJqJI/RR8lc=", - "pom": "sha256-DefjfsQ8dQwJGvQcs3H7lzrRFOnJdZ0S5dnMpMGFd+8=" - }, - "com/squareup#kotlinpoet-jvm/1.16.0": { - "jar": "sha256-QaUGgk2kMMDlQ6AjJD6uiNuhiIrPJVuZmlHaLb78C8g=", - "module": "sha256-oD1zFaTG1WtNUZVh4fmPaFpQL0gilGN6jC7Te/b91C0=", - "pom": "sha256-h4x1iYdBvdiA7403aLPRK4P9Tzt25GHht5fIZ5gsoA8=" - }, - "com/squareup#kotlinpoet/1.16.0": { - "module": "sha256-AvPdM8OE9EQ4lqajsHcE/1axLf5eMqEOfqMmaueJT1M=", - "pom": "sha256-yFb0sTRO8oA4x3rbK5fH3BxJggvQXbwc/WwUasuPPg0=" - }, - "com/squareup/okhttp3#logging-interceptor/4.12.0": { - "jar": "sha256-8+jV8JA8JQwrVdL0f8/gCOgGNDhdqDhRYcemOq7Qx0w=", - "module": "sha256-LiFIzSE7T49U1m0FSKIoBX4fe2czLg+Xmxoc42sidqc=", - "pom": "sha256-MVkkh9X6euW87fZ4Bqy93Eh9zPROH9t/z3zlNkrPyFw=" - }, - "com/squareup/okhttp3#okhttp-sse/4.12.0": { - "jar": "sha256-v/T7yu96rC2RDU/0ba+qTm0V2hJ99rrJchbaRpQ6fUw=", - "module": "sha256-c+RIzK9gfU9gO4tuZmGHKk/6PCZBGTyLvE1r2h5Ww0I=", - "pom": "sha256-lKunzO96e5DcolIFhb8LEjNtyO+U1ZGWPu2sV3lnkzw=" - }, - "com/squareup/okhttp3#okhttp/4.12.0": { - "jar": "sha256-sQUAgbFLt6On5VpNPvAbXc+rxFO0VzpPwBl2cZHV9OA=", - "module": "sha256-YH4iD/ghW5Kdgpu/VPMyiU8UWbTXlZea6vy8wc6lTPM=", - "pom": "sha256-fHNwQKlBlSLnxQzAJ0FqcP58dinlKyGZNa3mtBGcfTg=" - }, - "com/squareup/okio#okio-jvm/3.10.2": { - "jar": "sha256-/Qp+dsZzHwDpILe8EcBdgjqTIEVDGt1Ujgld4CCmnt4=", - "module": "sha256-p4CkJMVx4odVASiuADMjVibf/iFsuNs7ICRkmWrZaPA=", - "pom": "sha256-AP000Iv0YxNiofVSLKpXyuKMosfpOS76My72Vs/anUM=" - }, - "com/squareup/okio#okio-jvm/3.11.0": { - "jar": "sha256-LSJUGhkvkBpFyVJ0Vn1pV6we1hPUnkHbTl5dhhOc8CI=", - "module": "sha256-AOYfaQETdeeCYvf1PnoKcfjro+ScCUHVI9tQfumvdQY=", - "pom": "sha256-GnMR4mRILliufUvE1wgIfIhIz+RGC3Zyv19Qs09RS6k=" - }, - "com/squareup/okio#okio/3.10.2": { - "module": "sha256-P94fn79yxsMm1eiktTL0/Z/aLdDLFEK8pODHl9FBI4c=", - "pom": "sha256-7lbAIUoPqfER2nExxVDo3ICvDL9WCVbBzNosZtdQa0E=" - }, - "com/squareup/okio#okio/3.11.0": { - "module": "sha256-lQBY+qz8BqADxPIBUt+FR0InnLNh4EJ1FNjE5DdA3ew=", - "pom": "sha256-ehJQ9xiWx+cJPIDhNvgl4dl4kjHyPaHHk8TirhKrjA0=" - }, - "com/squareup/okio#okio/3.6.0": { - "module": "sha256-akesUDZOZZhFlAH7hvm2z832N7mzowRbHMM8v0xAghg=", - "pom": "sha256-rrO3CiTBA+0MVFQfNfXFEdJ85gyuN2pZbX1lNpf4zJU=" - }, - "com/twelvemonkeys#twelvemonkeys/3.12.0": { - "pom": "sha256-ttCYdPvd2bslDReBepMe+OCTvBjnQob/BrBAVBmAxzA=" - }, - "com/twelvemonkeys/common#common-image/3.12.0": { - "jar": "sha256-YqOCHHJPrf2jRsHi2DsMUGoMQHS+JppSv04xksfdkrw=", - "pom": "sha256-Mvxj0YSlsUAz7Z6uKPTH91cL6IUMZ+80q1DIpb3qlX8=" - }, - "com/twelvemonkeys/common#common-io/3.12.0": { - "jar": "sha256-v6z+sCrKxH2/0fqwAC6uymVUfQQklJi2VDIMng/fZkc=", - "pom": "sha256-X7G3pgrtAmv+FsK7u0MDlUfe3Q1OYT6AEnuTtKLFY1k=" - }, - "com/twelvemonkeys/common#common-lang/3.12.0": { - "jar": "sha256-XGXlBLW2TYBoPg+nCh3RVN2D1N59o38h6VD1qcA7xm0=", - "pom": "sha256-nFFSKc9KTl73IdpjR/+hm5wCetXeEHmQWUBdf6MtjVI=" - }, - "com/twelvemonkeys/common#common/3.12.0": { - "pom": "sha256-2prJlYu3TvpH0EAuhjHAw4djh0qVMDcP9X8HMTLJVv8=" - }, - "com/twelvemonkeys/imageio#imageio-core/3.12.0": { - "jar": "sha256-NMb5G/OyF+0BFbzoKDI4+9AmRWKqaCtCJqOWDQ7emBU=", - "pom": "sha256-N9att80pHm9n9inza8bpGiV6VFjj7lgf7BJ/aZIYG3g=" - }, - "com/twelvemonkeys/imageio#imageio-jpeg/3.12.0": { - "jar": "sha256-/GL1198E0a8n3H5bdOpfk8I7EBMGTd1OdIedcJqdhZ4=", - "pom": "sha256-wvUpr7RBT5ksNy7InUwRucYqluw6jegRgFos1y1kP/4=" - }, - "com/twelvemonkeys/imageio#imageio-metadata/3.12.0": { - "jar": "sha256-eX0Ca2fQfm1esAoatTpVrKq2+Apxxe4yVXIJPrkMDKo=", - "pom": "sha256-kIUqjzz4kZBqjShwC8/EQ/EZd1iEbm7lZR1pHBNCrpw=" - }, - "com/twelvemonkeys/imageio#imageio-webp/3.12.0": { - "jar": "sha256-Q9xEfM/jTFxcb10xGQJw4fm/ZfYDddaXriqP9DNGhSY=", - "pom": "sha256-YciGwb7ZmY5w46JD9w11sWV7CIAgf+FdOgbEh7LhQfg=" - }, - "com/twelvemonkeys/imageio#imageio/3.12.0": { - "pom": "sha256-ZI62q9rpluXh0kjqy1Gk3LYD4uwnHK6Mjh8PnLpK+Pk=" - }, - "com/typesafe#config/1.4.3": { - "jar": "sha256-itpMGFznJBZxLWPgta/cXwCcDN9AXl8m7+zfFWql37Y=", - "pom": "sha256-tn6vqd0iD/h9ANumiACDpSlqXgxsAxA/XUuOHaEDD/M=" - }, - "commons-codec#commons-codec/1.17.1": { - "jar": "sha256-+fbLED8t3DyZqdgK2irnvwaFER/Wv/zLcgM9HaTm/yM=", - "pom": "sha256-f6DbTYFQ2vkylYuK6onuJKu00Y4jFqXeU1J4/BMVEqA=" - }, - "commons-io#commons-io/2.16.1": { - "jar": "sha256-9B97qs1xaJZEes6XWGIfYsHGsKkdiazuSI2ib8R3yE8=", - "pom": "sha256-V3fSkiUceJXASkxXAVaD7Ds1OhJIbJs+cXjpsLPDj/8=" - }, - "commons-io#commons-io/2.17.0": { - "jar": "sha256-SqTKSPPf0wt4Igt4gdjLk+rECT7JQ2G2vvqUh5mKVQs=", - "pom": "sha256-SEqTn/9TELjLXGuQKcLc8VXT+TuLjWKF8/VrsroJ/Ek=" - }, - "io/github/oshai#kotlin-logging-jvm/7.0.7": { - "jar": "sha256-w3P39MnvyFxPcPEVGfKht4eLwO11oyU2TQNK8/oh93Y=", - "module": "sha256-QO2e6r7AizgleZTXK0wOsvBwVYVzkPGaTvPjlX8Crw8=", - "pom": "sha256-22vD1rbK+1kdW7F3jJbFMPmFjR66+tJ8XJCBFVgdoho=" - }, - "io/github/oshai#kotlin-logging/7.0.7": { - "module": "sha256-rrIaCFb7kGYQIY4F3mNMhiZpkYXNL0/45Ecv6gbEEmw=", - "pom": "sha256-nd6+64dztqV7p9ivwI8LsJAeMkAJ9RdtpZsPGLzvrpU=" - }, - "io/github/pdvrieze/xmlutil#core-jvmcommon/0.91.0": { - "jar": "sha256-Kogf8aIThsLinqxawAKYADZVrrZ8For6DHr29QsdPas=", - "module": "sha256-X2vfhDqLVcw6uaDovSgxaJMzwQ8hKP/8Z3VjfSM3fJw=", - "pom": "sha256-sO4QvqFfvV+y6gylyehxjGs3xB29LiX2AuNAwP0msuI=" - }, - "io/github/pdvrieze/xmlutil#core/0.91.0": { - "module": "sha256-iAYWns8ZPjAIdClaXd35E8JGtsfrx6EpMWCBU0Swtd0=", - "pom": "sha256-/FejigXcfEthnxfi0F22c2oconOznLX84aAVbdc9Mrs=" - }, - "io/github/pdvrieze/xmlutil#serialization-jvm/0.91.0": { - "jar": "sha256-fSbBlLf9v6H5twr4mvg0YZzH5WYUelVjWL8SPyBhJ9g=", - "module": "sha256-HAYAi45jpIR4cb1KJz4Ooc9tIUp2G7T+ULmHS0mG3mM=", - "pom": "sha256-rZsnLeicDmExn9HuUrPFCzDnLhtUDjlC2zwh1y3nvSM=" - }, - "io/github/pdvrieze/xmlutil#serialization/0.91.0": { - "module": "sha256-KLmiTXkINUMzy9+rpkSADEnOz2jE9li1svwqVq4gPVA=", - "pom": "sha256-f7xPoiQGtT7aFomJ9UtQsgghxocIPP+/um1pU9dmPHs=" - }, - "io/github/reactivecircus/cache4k#cache4k-jvm/0.14.0": { - "jar": "sha256-AFawtCFJsLOuEFDFCmqddyw+66sPyIs6AOgHsqGgBms=", - "module": "sha256-xPewTXNix7g61pgLtO0AyhYTiS/9kZ3CexwtNeZRV+s=", - "pom": "sha256-xijqm3blZwxRnxf65AP64VG9YzRhUPstjs56KRUQvmo=" - }, - "io/github/reactivecircus/cache4k#cache4k/0.14.0": { - "module": "sha256-0w1VvLHRtgjT13QBNIipFT8J4KUZpZzqiT2JWzRBtNM=", - "pom": "sha256-0rcanG8PxQPNnr5u5KjxEFcQI3CQOHxH0/Fnc7xSXfo=" - }, - "io/github/snd-r#komga-client-jvm/0.8.1": { - "jar": "sha256-C7ium+EzxV5/fjCSHygNDk/Hx1pz3qa16Aih89ZaM1M=", - "module": "sha256-0gTMivRv0UL6azayopT7eaFUnkDIFhWYnQBe54wZ1CQ=", - "pom": "sha256-Qtk6sU39WnflgW09d+FC+vPkASUR91niPk2fjKLVFbo=" - }, - "io/github/snd-r#komga-client/0.8.1": { - "module": "sha256-XpzTjwE3R5kZFXjHXybDh2NW9ejjHX7tcgo2WCxlo7A=", - "pom": "sha256-pIibveg3Wg7VP2H0DIOcMyRMZnhXg+sOQdzsc/mY3rs=" - }, - "io/ktor#ktor-client-auth-jvm/3.1.2": { - "jar": "sha256-a9fF3bez+9cTtivnwCaxIfSJtVzzyCC3ukewW3p1JiY=", - "module": "sha256-u0Dok4Uu9qj3oXQ3VJNbiBF8qQsK9d3+ouPZ49LNGpg=", - "pom": "sha256-7b9gABUd0HxUY5Impvvg05XH3m3DgCPWA5tQpbePqEU=" - }, - "io/ktor#ktor-client-auth/3.1.2": { - "module": "sha256-xrJI2kwqdHI/rLJTjcBv3F7tKAi+cxDUEdQJ5XN3Tdo=", - "pom": "sha256-PcqNqh4NeXvdThuRFOaePWZh9O4vnVHYiyGVNuh8Wnc=" - }, - "io/ktor#ktor-client-content-negotiation-jvm/3.1.2": { - "jar": "sha256-dAss0mnfpKVTVs3mA3p4F0lBtIKnVUjoAQ+IKB8xptI=", - "module": "sha256-R3zomBtwrhJd7jEKsdDYnHyqrsrjIaIDW+ex77xlLDo=", - "pom": "sha256-XXx8lh/dUBX7hM2My2jc+BEFUDphnW/4wQoxRoEmmwQ=" - }, - "io/ktor#ktor-client-content-negotiation/3.1.2": { - "module": "sha256-bKRchaC6lVZfMiWuvvNl5+uvT7infSiUAEcDMXC2Lzw=", - "pom": "sha256-B5OzgHgdWTcbnRv9vRckREDWVSzzxn7od3BzbiakxXo=" - }, - "io/ktor#ktor-client-core-jvm/3.1.2": { - "jar": "sha256-6+fGebo+G16Ma6Wxwt2JWcZ/Jv3etgnnee/xd9boxQg=", - "module": "sha256-FnKDMXflgXZQrVbQrtK+oMSvOpgbAZthw2OLsLzJeG0=", - "pom": "sha256-fHMA6SdRZcGDb9ylkOISDgARY+va5ha7K8WjQUNblp4=" - }, - "io/ktor#ktor-client-core/3.1.2": { - "module": "sha256-Yq0wnFdFJQmUpZpzzDfA0KPbtTplF1ul0VHOHcwP4XY=", - "pom": "sha256-qiDsWjyuvdkVZRxeOUb5l5aRVkD2NmylJHqKxjZbEFM=" - }, - "io/ktor#ktor-client-encoding-jvm/3.1.2": { - "jar": "sha256-eKeGHHtFttqh4WdCAQdSyoyIfs9Sji5Tq+MzueTVFZM=", - "module": "sha256-HfIxNeL/b6RGBK/o1kwuPuxEiU2DETFNr4JG/OAHiPI=", - "pom": "sha256-csNFCyCX+5UzZLokBDpAPbYostoT3D5aWA48RiMHBLE=" - }, - "io/ktor#ktor-client-encoding/3.1.2": { - "module": "sha256-lL9R4n3w432fGKxcpOYKDt3qjnQIbfrM6+dIImaTjVU=", - "pom": "sha256-Ug7bp+ZSmV0XfItjkffTk4YbXRd+iW4mJ5GEKJAkpkc=" - }, - "io/ktor#ktor-client-okhttp-jvm/3.1.2": { - "jar": "sha256-R3lvlBay27vqBmsalfOilKzO4K/FioNrNrXTMDgDfZA=", - "module": "sha256-0OzT8u0QQQE9T9jLQGpqtK6T/Q5Oa3a7PKyCKK69WfA=", - "pom": "sha256-hPl8vOtb2d0MTPdeEMZTxQPfvVQC/9CGJdc24fCsrKw=" - }, - "io/ktor#ktor-client-okhttp/3.1.2": { - "module": "sha256-sk5tZQn5dglw51taWChYUOau2S1r0qfoDrtiW/TuoKs=", - "pom": "sha256-dJEqC7Yv3cp2SV0Oo36WXEBwf5GKjpvpnRBOXV/I/4w=" - }, - "io/ktor#ktor-events-jvm/3.1.2": { - "jar": "sha256-ZvgMmj04rjEwGCwe2iBhfEUZNlfWPWqvBUU0Tr+1kRE=", - "module": "sha256-2VXhTrl7C8klpYpUUPFuKP06SxOw4pGpozacSFcq1O0=", - "pom": "sha256-DD0TK9i8DWi8mhsYDhEyGiogX2YAO+/y5tWIUWWltgE=" - }, - "io/ktor#ktor-events/3.1.2": { - "module": "sha256-zCNnPeUfpwNdbTGjbqPmBSW8eXgxWH62Qbdg7QzhgGY=", - "pom": "sha256-2KZiJ7h5hEIIHJo7a4wCpHyfmYFlfM347TrR23Msd4w=" - }, - "io/ktor#ktor-http-cio-jvm/3.1.2": { - "jar": "sha256-T/GcEQ/Vd4xcGqNmZHgdH5/SkK8Zk6tWMoO5YRVpvFM=", - "module": "sha256-uwPweWBUeas6d3R7IKqu1ospB3VlEd3HpBlm07jS2t4=", - "pom": "sha256-NTLCYHe7jeNppkFFcUqP7BwY0uk8ffZ/Y81lQ+Gthb0=" - }, - "io/ktor#ktor-http-cio/3.1.2": { - "module": "sha256-GoQI1DE0XFRZwXQzp4dXO98q0MSKhF3x23EZscUXpeg=", - "pom": "sha256-ur0cAJKzJKB5IwQ1y4/iLloga2iUSJO8kGE2MO9xtaw=" - }, - "io/ktor#ktor-http-jvm/3.1.2": { - "jar": "sha256-ykYSGB96b0dZ6G0oGoHqucOsrNp4ijGhY1si8dBWwWo=", - "module": "sha256-oDFMPrgt1dLkKl4vpIdf0HQiL7csS6V5+PSeIAh/cbQ=", - "pom": "sha256-ZwKozhE2AxhCCljnjlVpx6O7guGFjxAPLOcMXPemmlE=" - }, - "io/ktor#ktor-http/3.1.2": { - "module": "sha256-vsKmzcm1BARxfP/X9MAUhiCC+37DH+ovZp5hfO2sKiI=", - "pom": "sha256-wtnv/1erfTa9JsAJxLZbgjw0Zuavym2xJJGEoMZV4IY=" - }, - "io/ktor#ktor-io-jvm/3.1.2": { - "jar": "sha256-szoNOusNuTYxkJyHNoBBNkW31AQeadG1yZuuzoB1J/Y=", - "module": "sha256-eqmaoqiUwvMw7VaKWSmkd13mlhbFIRdla6HRitnMDEo=", - "pom": "sha256-3FWhpZqyA9Zx0SRPWimqgAX3RweUxFfqXp3IVxpMI6c=" - }, - "io/ktor#ktor-io/3.1.2": { - "module": "sha256-WuOYj9Nnpsgp4EEg8uz46efG6zW/4vo3p5x2FGHo/8E=", - "pom": "sha256-QLweS6FxQJvUNyR5qIlCQzFT3x5CL0pKgtJt96OOdAY=" - }, - "io/ktor#ktor-network-jvm/3.1.2": { - "jar": "sha256-rEQzHpc22qmy+zk9iFqOI7Xfk0xOgjXBbBvD9eg33NM=", - "module": "sha256-768dVKqyVkgci1Rg6SDaePaZcXb856rAfs5//mkWlg4=", - "pom": "sha256-QDnfI6RnjDOWKbua57It1q9dLMqjYflnu5SN0ubzD9M=" - }, - "io/ktor#ktor-network/3.1.2": { - "module": "sha256-kPTc8badNU4osJR+0ObEu4TbaW1W7T7eQCdbDt+nG0I=", - "pom": "sha256-CLpyZm62hR5IgaVTJQGub456HLcRxli0QULOPbECOyY=" - }, - "io/ktor#ktor-serialization-jvm/3.1.2": { - "jar": "sha256-JOEoQIvzHiORBjGvDJdDK3EARLDA4W+6Qc8UW9wJv2g=", - "module": "sha256-UG5PTj6iQ8PTm6LwA3C29Hk6FNkDKznvnmP2Zk3YFSw=", - "pom": "sha256-97F+QLGEwuPaeJ3J06HDuZjuLRZDK1GaggpUR/qg+4Q=" - }, - "io/ktor#ktor-serialization-kotlinx-json-jvm/3.1.2": { - "jar": "sha256-oDI5uRNWELf/jMfS41wXBKh801u+TvzM3RqVvqpsWrw=", - "module": "sha256-aDCeyKClh2dll1wEXxNsuH5KLFy1mVdLkzwn1O9tMjc=", - "pom": "sha256-quFFmG4iMVWbeMLvZ2LgxjzeZRyhD/2HOs9LpsfRu2U=" - }, - "io/ktor#ktor-serialization-kotlinx-json/3.1.2": { - "module": "sha256-nZDriSmY3jbHiNgMLkmzQ6Ym4FPmWc5yqC7wmbu960o=", - "pom": "sha256-sXNRUzom89AElcUZbZRsesjbtuY+3RWOgoqbX8HMh14=" - }, - "io/ktor#ktor-serialization-kotlinx-jvm/3.1.2": { - "jar": "sha256-arXMDS/KQpiuM/OihVwx8E/XAAkehPrMdjPCIfVpB8U=", - "module": "sha256-Rtby9qC+PS1ulBL/eK4/z8dCs+df+abOlFw5WYSAkxk=", - "pom": "sha256-ge0I5NBzb++ZafzA7K5yAHrDlGFD6oC8kTasxOsn7Yo=" - }, - "io/ktor#ktor-serialization-kotlinx/3.1.2": { - "module": "sha256-KuhAlFsmiuidgKgruvLtotcYUr40U1hdUB/w7le51U8=", - "pom": "sha256-mzvI/iorZQNBRNjmkmsSvJrvmp7a9MtZ4Jfu0zm6tkA=" - }, - "io/ktor#ktor-serialization/3.1.2": { - "module": "sha256-RtMIqVsr24f70PzKTbsKGfLQMbJvLDkem3IWu9mPjiI=", - "pom": "sha256-C125cC6iCfWIJrkiODy+md8O0ZAZwQiMWlh5dMhIDwA=" - }, - "io/ktor#ktor-server-cio-jvm/3.1.2": { - "jar": "sha256-TKpF4vdem/hQxjLX+fmSiXCu5coUroDZtPXE2LdKY5U=", - "module": "sha256-2iziegi6qJu/QpnyTvwzxPf9I1ovFXP7WFu3nWfyGLA=", - "pom": "sha256-27cB5f6ejhkY2Ht/umCybZXvT+RC29c+1WjPeWNwO/U=" - }, - "io/ktor#ktor-server-cio/3.1.2": { - "module": "sha256-JJrdlZDY+kTd0XdiPHrJ4reE7gS+GgGIivqq9QTWYVU=", - "pom": "sha256-gPd72sj2VjWbHf2Q0wwkamHJo9C+WFcoLoWNZheLS6o=" - }, - "io/ktor#ktor-server-content-negotiation-jvm/3.1.2": { - "jar": "sha256-j4gb+ZAS0bsCtNlrhFszxN5jew2UEIwcYqHuc4TC0lk=", - "module": "sha256-SVqdCMmSkZuqZXRXFbirqwl+gpVY1qQMrPJfCinWTpY=", - "pom": "sha256-FnXa8EFUkQLrGvQbq0pt3X3+h31HlSqz9Vy0yAqVmVU=" - }, - "io/ktor#ktor-server-content-negotiation/3.1.2": { - "module": "sha256-aaNg0ktDtrzNPFTj+2S2WuQuCYli3oUN1nUIWJPeD04=", - "pom": "sha256-i2B7qbVhKm68Eo7bqPJMTUJ/LpAE105cdNlR2MyrWqA=" - }, - "io/ktor#ktor-server-core-jvm/3.1.2": { - "jar": "sha256-iBEDVZq7aObB0c780MUwkwJl18ougjB24XYXX4rGxOY=", - "module": "sha256-m4p2pwPqhT+7XKnQYyN+svD4THb6zX/jQgYQgL/axeI=", - "pom": "sha256-dEmOLZuVzvt7DO3MIIrhcai3n74KOTzDg1b1WZeAMlA=" - }, - "io/ktor#ktor-server-core/3.1.2": { - "module": "sha256-4lSGk0IJguc3mKY0YpXVhtf4T3g3d8a6/DqUa+4E5qQ=", - "pom": "sha256-Acdzm7TWm55iHHkA89pprWb9nPmf2MpHESoBO8vdRps=" - }, - "io/ktor#ktor-server-cors-jvm/3.1.2": { - "jar": "sha256-aA1T4MtDEPWyCY5bf6jGda51UaFc9bOTTkM4iG3lSQc=", - "module": "sha256-IPEh4FQl9sIIa8yhRyq9TQmHCP+14zlqr9bjSrds8Hg=", - "pom": "sha256-tUXnPxwsI7kt3W/6k+naiLmN7RYqbNgAn9Q9UysPeIw=" - }, - "io/ktor#ktor-server-cors/3.1.2": { - "module": "sha256-CQL+X+OfHJBMCBoIa/XAd1Fr9B4BtqY1Rj9BRBh4e/Q=", - "pom": "sha256-D68yyiklQ3/7PQodaSAX2ijTzgOg2fkySC3cptp48oA=" - }, - "io/ktor#ktor-server-default-headers-jvm/3.1.2": { - "jar": "sha256-0HUrWvpE6gKf0xlQage3kRU0qNnYciLGTcrgxoULQws=", - "module": "sha256-N8ThreclhA9YVf7JFLEDPFl6kT6oYsqEm9VvqPWO3SQ=", - "pom": "sha256-e6QCsbSqIbScCR1OJVwsKQZRTS1qQIOJ1eTUw9yqXk0=" - }, - "io/ktor#ktor-server-default-headers/3.1.2": { - "module": "sha256-3rWVQX41bUpYpf/rJuixM9tIQCTNRIsaRqAxbbSTZtE=", - "pom": "sha256-ZQBPlyNl1Y8FIcTWWN517XOqyP9SouFDu8rzAfllRPE=" - }, - "io/ktor#ktor-server-sse-jvm/3.1.2": { - "jar": "sha256-vyWJDQBALdqHGPwGWwFNDJihlu1DABf1HvY6j7EfgtY=", - "module": "sha256-6DqywqgD1l8/BkQ++6xR1F5HUc2nqbmOSfDeKAAn8go=", - "pom": "sha256-7GagHnbrV5vCMmnepaubZbCPOzghxaW5JMKC+h1Ykno=" - }, - "io/ktor#ktor-server-sse/3.1.2": { - "module": "sha256-LBnmaVa3hu/VXhQSWdhL4qVPpHLp5FwNZupGzWZjYZg=", - "pom": "sha256-HvmB8A/hoax81XoPnPojso+suX+1Ds0LO5r7xeAHy+o=" - }, - "io/ktor#ktor-server-status-pages-jvm/3.1.2": { - "jar": "sha256-rCkmzXujXwu4iMOrFF3AVOL+9fqVPf//NN7PuJEowOc=", - "module": "sha256-SyDYTW7MDyG6BSJLGT7Xmfy3i1wrsODcWcrcuzvYCko=", - "pom": "sha256-Y5uavNao1LFxDhoX4TsNcjz3E5ZLDYrjxQTUcSVrQrA=" - }, - "io/ktor#ktor-server-status-pages/3.1.2": { - "module": "sha256-kdl2Y7vk2LgM/Ko0VkThTKhXtcIj8fnZXDi3Fgg4vmA=", - "pom": "sha256-zHctVfjcxXHOl8VSrSu3mDCxMPNKMKdPTv4P0RlsL3Y=" - }, - "io/ktor#ktor-sse-jvm/3.1.2": { - "jar": "sha256-VSqeqy0QpMmzCC5YnpT//zu7+S4Tq47LhyGVlAp+kMQ=", - "module": "sha256-a+Dj4yneNokQAUFDO9ZICzuWibtiVpWi+XryqP2Q53A=", - "pom": "sha256-NFgOcSUEJOrJXk9FsmQaRjPWJDlmdt1YysiutYjU+kE=" - }, - "io/ktor#ktor-sse/3.1.2": { - "module": "sha256-10Vyu1yjrb9bPYbsuN416ZG+EC7P36gvfmxhW+wMvH0=", - "pom": "sha256-ySrv+ZpYpjyjtcGsKurq1570eQONm2QjLAEYhCZ+k9Y=" - }, - "io/ktor#ktor-utils-jvm/3.1.2": { - "jar": "sha256-/0m9ennrHA4wzCRPjOsreZQNLAZl8EiHX0qUUfTsHEw=", - "module": "sha256-qZnf4JCbFcqHPzZNOQc+zB74ST0P0TGkLHuDQ2NYkhM=", - "pom": "sha256-mN/IgBAFUWNmFWPCfmQS1yWmMtC1yJxw37atxbh7ATs=" - }, - "io/ktor#ktor-utils/3.1.2": { - "module": "sha256-K/6VIuFZfCVpCrrJdXLyXoP16Z6sU7aK9no7KbTujWg=", - "pom": "sha256-UbDVCglWz5/na3ZN7zaDNIRTdU2oQ9Vm0v3zAWbkdi8=" - }, - "io/ktor#ktor-websocket-serialization-jvm/3.1.2": { - "jar": "sha256-D2MHbFz3aA9DkWzuT2XUQeuRKT/vW9Xw0WVhEC21PfA=", - "module": "sha256-ZcdTmCf721le0cNiDnlgwNesP0hGBBr3kF1ph9/M6qc=", - "pom": "sha256-OxpuXkGJ7HNzKtYQceBJXIsSasZs4tvdNgK1JuZy4nY=" - }, - "io/ktor#ktor-websocket-serialization/3.1.2": { - "module": "sha256-7rXJKLPxQ9ut0Hmzno0UZ/WZ2Pd3/1GR+j23wHdTkAM=", - "pom": "sha256-PhfeNeQIf3wRDiExmB2p0lj9oK1ofW/SrYylydvKSok=" - }, - "io/ktor#ktor-websockets-jvm/3.1.2": { - "jar": "sha256-U0I/bUueO3L6K9vh5DvdTQx2hV1V78o4ogsQNezj6Tc=", - "module": "sha256-bOp2XLFt1lC7jtiLQhQ9/9dh6SnBEFEjCyf8W45ju1Y=", - "pom": "sha256-JUj5WAi39GGG1FLKC/UnvxPsepcDwRxiTTGXebqgNlY=" - }, - "io/ktor#ktor-websockets/3.1.2": { - "module": "sha256-GgOOGCIN7tGhOKdN9fbz02YT6XYnzZCZUFGmgqVzJYY=", - "pom": "sha256-6WI1wK5Wl9B1yZHxKxEU1g+ByYRBuBEVkpM7LQxsiR0=" - }, - "io/netty#netty-bom/4.1.114.Final": { - "pom": "sha256-Df0Iq8EG9iW+HW60mPqZPeZci1WAcN+xGvqaM5S7ZhI=" - }, - "io/reactivex/rxjava3#rxjava/3.0.11": { - "jar": "sha256-4rkA7kY8twRS5/Wr1b6CQCSPStpn9T49+CibT4lqDr4=", - "module": "sha256-Run4VI3Y5sxpAxy/E3ekza03cmXbJZ6d0q07wKbWfqo=", - "pom": "sha256-b9Q88XYL0iHXucD93n2mkpl9/MyTmiYsdGSR1WXhxRo=" - }, - "it/krzeminski#snakeyaml-engine-kmp-jvm/3.1.1": { - "jar": "sha256-cz4TR+PskJ6KfuGZ5Ipk0BgFaUYbO8CMimuxM19c4b0=", - "module": "sha256-VinJEJbLsJhiOjW/33wTmjDp0jcHg8L+yQ/sAB7abqs=", - "pom": "sha256-5nLipyZo30Ll5p9XdSdabFxLRiTX6o1ZCvpqb6J7L34=" - }, - "it/krzeminski#snakeyaml-engine-kmp/3.1.1": { - "module": "sha256-INAYWfQEX1f4NFaGXqPHyo4FCvz0fLhPMfablGwSenM=", - "pom": "sha256-i0cZ960NZXrClDo1+CQ3PfO59K3cS14eEsV246rxzbE=" - }, - "net/thauvin/erik/urlencoder#urlencoder-lib-jvm/1.6.0": { - "jar": "sha256-jQ/SrrSNGdxJxWPrwA8nSUfkX3FsEHU1wS6tY97NaI0=", - "module": "sha256-xR2qXFshotEfU5wbBIr4Up9G1hAMoiSzJRH7WGPb6Co=", - "pom": "sha256-0km6NJnFKFee+uva43MWkv1EgdmvnLh3wh2bf6UHHr0=" - }, - "net/thauvin/erik/urlencoder#urlencoder-lib/1.6.0": { - "module": "sha256-FwoYaL+6OY1km+K/UNbNhgNQyUskNncrJMs0vN6kobU=", - "pom": "sha256-h64XwAQtoKQCt8aHbH7yBM1Zmied35GpwW30qJ3q57w=" - }, - "org/apache#apache/23": { - "pom": "sha256-vBBiTgYj82V3+sVjnKKTbTJA7RUvttjVM6tNJwVDSRw=" - }, - "org/apache#apache/31": { - "pom": "sha256-VV0MnqppwEKv+SSSe5OB6PgXQTbTVe6tRFIkRS5ikcw=" - }, - "org/apache#apache/32": { - "pom": "sha256-z9hywOwn9Trmj0PbwP7N7YrddzB5pTr705DkB7Qs5y8=" - }, - "org/apache#apache/33": { - "pom": "sha256-14vYUkxfg4ChkKZSVoZimpXf5RLfIRETg6bYwJI6RBU=" - }, - "org/apache/commons#commons-compress/1.27.1": { - "jar": "sha256-KT2A9UtTa3QJXc1+o88KKbv8NAJRkoEzJJX0Qg03DRY=", - "pom": "sha256-34zBqDh9TOhCNjtyCf3G0135djg5/T/KtVig+D+dhBw=" - }, - "org/apache/commons#commons-lang3/3.11": { - "jar": "sha256-TuOAJZwGjR2+noSrUhhvKs1l3gZ+wJvv9zH8oWl/2xY=", - "pom": "sha256-mA1mXYP+0EZlE08FeOUHRCoOdQaRBzeEORsKeYhySnU=" - }, - "org/apache/commons#commons-lang3/3.16.0": { - "jar": "sha256-CHCd101gK3Bc5AF9JlRCEAVqS6WD1bIMCTc0Bv56APg=", - "pom": "sha256-4oA4OVbC5ywd6zowezt18F7kNkm31D8CFfe2x7Fe6iw=" - }, - "org/apache/commons#commons-parent/51": { - "pom": "sha256-m3edGLItjeVZYFVY57sKCjGz8Awqu5yHgRfDmKrKvso=" - }, - "org/apache/commons#commons-parent/69": { - "pom": "sha256-1Q2pw5vcqCPWGNG0oDtz8ZZJf8uGFv0NpyfIYjWSqbs=" - }, - "org/apache/commons#commons-parent/71": { - "pom": "sha256-lbe+cPMWrkyiL2+90I3iGC6HzYdKZQ3nw9M4anR6gqM=" - }, - "org/apache/commons#commons-parent/72": { - "pom": "sha256-Q0Xev8dnsa6saKvdcvxn0YtSHUs5A3KhG2P/DFhrIyA=" - }, - "org/apache/commons#commons-parent/74": { - "pom": "sha256-gOthsMh/3YJqBpMTsotnLaPxiFgy2kR7Uebophl+fss=" - }, - "org/apache/commons#commons-text/1.12.0": { - "jar": "sha256-3gIyV/8WYESla9GqkSToQ80F2sWAbMcFqTEfNVbVoV8=", - "pom": "sha256-stQ0HJIZgcs11VcPT8lzKgijSxUo3uhMBQfH8nGaM08=" - }, - "org/apache/cxf#cxf-bom/4.0.5": { - "pom": "sha256-h+P9uKS40oFhcRLRIRASfbolKtBBd7DE1vEIZt8L+Ko=" - }, - "org/apache/cxf#cxf/4.0.5": { - "pom": "sha256-zQNe4m/ykpujPLGbObKQE8ayCurFgEcOgj+arv2YPXg=" - }, - "org/apache/logging#logging-parent/11.3.0": { - "pom": "sha256-pcmFtW/hxYQzOTtQkabznlufeFGN2PySE0aQWZtk19A=" - }, - "org/apache/logging/log4j#log4j-bom/2.24.1": { - "pom": "sha256-vGPPsrS5bbS9cwyWLoJPtpKMuEkCwUFuR3q1y3KwsNM=" - }, - "org/apache/tika#tika-core/3.0.0": { - "jar": "sha256-4tCws/g8y4BSUccnY0aSe2Iu02skpdVr/xO9mi5zAJ4=", - "pom": "sha256-BRUiPM4KanpfViRbkNbcGxUqWBs2qYo6lqy79rmNXx0=" - }, - "org/apache/tika#tika-parent/3.0.0": { - "pom": "sha256-0uLks0WRly2Q037sr0MLbYZ4KrkDnwXqk+aPTqW4VpM=" - }, - "org/apache/velocity#velocity-engine-core/2.3": { - "jar": "sha256-sIbO6P2Bg+JAtK/PVP447DPdjrDaQUY25b96pNmFZik=", - "pom": "sha256-1CQqYXQkPx5oBDRXG6TmoduuGZwLw1Cph9X7nDzh4NM=" - }, - "org/apache/velocity#velocity-engine-parent/2.3": { - "pom": "sha256-TA5KkvaHDzmblG1bt4nRd+SkeUEUfD/dwubwY+nLlts=" - }, - "org/apache/velocity#velocity-master/4": { - "pom": "sha256-eirHPJDdEEtaB+bizQPpXsKNKfO4ME891//87LBJcS4=" - }, - "org/bitbucket/b_c#jose4j/0.9.6": { - "jar": "sha256-cxSvUM3pyZ6Or0Pu5heiPtzGu0MDYiEGQ1UJSZnYN+8=", - "pom": "sha256-P7f6cT6J1CeEvfTRkuziF0AAQL2n6TOIap9FzoubVX4=" - }, - "org/eclipse/jetty#jetty-bom/11.0.24": { - "pom": "sha256-OzjVNA/7MaYiymePR8K2Bawg6lhVJZ84Xm0ujyfs1dk=" - }, - "org/fusesource#fusesource-pom/1.12": { - "pom": "sha256-xA2WDarc73sBwbHGZXr7rE//teUxaPj8sLKLhOb9zKE=" - }, - "org/fusesource/jansi#jansi/2.4.1": { - "jar": "sha256-Ll53Wp3Fj/prvWqm8JnWL4ti3N60w8O7vlzyMBvC3ME=", - "pom": "sha256-P5jZeaTTVZ+HefuwBLNK51Fq+t9RDhHffMPNBz6xuzs=" - }, - "org/jetbrains#annotations/13.0": { - "jar": "sha256-rOKhDcji1f00kl7KwD5JiLLA+FFlDJS4zvSbob0RFHg=", - "pom": "sha256-llrrK+3/NpgZvd4b96CzuJuCR91pyIuGN112Fju4w5c=" - }, - "org/jetbrains#annotations/23.0.0": { - "jar": "sha256-ew8ZckCCy/y8ZuWr6iubySzwih6hHhkZM+1DgB6zzQU=", - "pom": "sha256-yUkPZVEyMo3yz7z990P1P8ORbWwdEENxdabKbjpndxw=" - }, - "org/jetbrains/intellij/deps#trove4j/1.0.20200330": { - "jar": "sha256-xf1yW/+rUYRr88d9sTg8YKquv+G3/i8A0j/ht98KQ50=", - "pom": "sha256-h3IcuqZaPJfYsbqdIHhA8WTJ/jh1n8nqEP/iZWX40+k=" - }, - "org/jetbrains/kotlin#kotlin-build-tools-api/2.1.20": { - "jar": "sha256-Uzw2yzYubtLRX1hzLn9MbSvtXJ1RebiXvEsJ0W1gU3c=", - "pom": "sha256-kn9h95cmHFnktTEDFNaf1KOrjvT3A596UyYHXEKkFzo=" - }, - "org/jetbrains/kotlin#kotlin-build-tools-impl/2.1.20": { - "jar": "sha256-bpSJbjIWA+O/6J/vAkeORNHWSj0l1J0GlIkv/AHGCs8=", - "pom": "sha256-EPseNeDocGdH6Og+ro+LQ0BrpmTkIB7J38ua99prQro=" - }, - "org/jetbrains/kotlin#kotlin-compiler-embeddable/2.1.20": { - "jar": "sha256-xUoAcYyMDj7oWL9Cdxx/QBxePBc4hh4Y6VNjcQQvobM=", - "pom": "sha256-InQE6sbYCbwNlN74kzbf332afVOHkqI01Svbr8Kuha8=" - }, - "org/jetbrains/kotlin#kotlin-compiler-runner/2.1.20": { - "jar": "sha256-3jtUI9j7+G6ivRM01AG8SqhOKOxIlFlS0RwAsQsUArY=", - "pom": "sha256-xgNdI3KARTSALDfOVU6MjLqq6EUUp7rWzAlkJNjySUU=" - }, - "org/jetbrains/kotlin#kotlin-daemon-client/2.1.20": { - "jar": "sha256-NjCjAYLGNXDrUZrmWqqUGSF9utCBT+3kLI3ecERlpMY=", - "pom": "sha256-+qpgvkJw6RSbWUOSZjlhkr60f/XjpAmF3u3FTlkXItI=" - }, - "org/jetbrains/kotlin#kotlin-daemon-embeddable/2.1.20": { - "jar": "sha256-2eg98dhHogG6PAFqeGztCRvpUDmX0J9qnPF5buSJ83Q=", - "pom": "sha256-sdOMCv1uHRXEjBxdFWzmBXj0MxNr7FI/TrGZ968/gik=" - }, - "org/jetbrains/kotlin#kotlin-reflect/1.6.10": { - "jar": "sha256-MnesECrheq0QpVq+x1/1aWyNEJeQOWQ0tJbnUIeFQgM=", - "pom": "sha256-V5BVJCdKAK4CiqzMJyg/a8WSWpNKBGwcxdBsjuTW1ak=" - }, - "org/jetbrains/kotlin#kotlin-reflect/1.9.22": { - "jar": "sha256-d/MRyhOEgR1Rn9o4n8sSaL2qBY1gUEbg7edsA7DfPpc=", - "pom": "sha256-xxLjWN97kxi2j1RjlxsIhnODf8DKQoXRw4LIEC7da18=" - }, - "org/jetbrains/kotlin#kotlin-reflect/2.1.20": { - "jar": "sha256-QZd48reoJrrW7iyh5L3r5jmrMG0pBPo+8qMI7PqrOBE=", - "pom": "sha256-XgIIh67A2JqcFo79ka7WKGVVOHf5MD8UXby50jumDcc=" - }, - "org/jetbrains/kotlin#kotlin-script-runtime/2.1.20": { - "jar": "sha256-rkOX+7OqKhraCSkOdTu6maQRRUiXfDEVUmuZWPTLGgQ=", - "pom": "sha256-D4O1qQFWxhpv8QlVey2YjicQ7j++n0pCV6bqDYdIw9Y=" - }, - "org/jetbrains/kotlin#kotlin-scripting-common/2.1.20": { - "jar": "sha256-X9v2rnIjfOM11gPrEsSbCbycGjPAwB8dYud/8zZjzvs=", - "pom": "sha256-H3dwkEXdkF63UFqUKA037HV/CHCc/p86dKunO7+Z95s=" - }, - "org/jetbrains/kotlin#kotlin-scripting-compiler-embeddable/2.1.20": { - "jar": "sha256-PU93KyOEFGUAF+l0YiVrfE1e36EBPL9Ud1c+sawuKIQ=", - "pom": "sha256-D/9/8dO/qczj77tNs4mJwmilHrZ/ge/QMRuKZGGLhak=" - }, - "org/jetbrains/kotlin#kotlin-scripting-compiler-impl-embeddable/2.1.20": { - "jar": "sha256-9mXXCxoIN/86Dve+xPxdn+1n6nXkaX3hWOtR8epQHD8=", - "pom": "sha256-tjmuINh6gV4wTd0goOTEk34Ttfx6Qme14VwOWQIphmU=" - }, - "org/jetbrains/kotlin#kotlin-scripting-jvm/2.1.20": { - "jar": "sha256-afRXrKuYNkwOtXjEl+DDypMLjPuCvndASdoEzeOAh/c=", - "pom": "sha256-PERTORE37EVcdL5Jb3HZpJhpbSVJvmT1mmBkfO7iVT0=" - }, - "org/jetbrains/kotlin#kotlin-serialization-compiler-plugin-embeddable/2.1.20": { - "jar": "sha256-5pZQZxDSxI0BfMiczB6kkQF5lXcJK3Ah/q2pX/Yv1X8=", - "pom": "sha256-Al1rBx59fPPsennw0/5He9Ydveir9ZbYn41DL3wBmCU=" - }, - "org/jetbrains/kotlin#kotlin-stdlib-jdk7/1.8.21": { - "jar": "sha256-M9FI2w4R3r0NkGd9KCQrztkH+cd3MAAP1ZeGcIkDnYY=", - "pom": "sha256-m7EH1dXjkwvFl38AekPNILfSTZGxweUo6m7g8kjxTTY=" - }, - "org/jetbrains/kotlin#kotlin-stdlib-jdk8/1.8.21": { - "jar": "sha256-PbdSowB08G7mxXmEqm8n2kT00rvH9UQmUfaYjxyyt9c=", - "pom": "sha256-ODnXKNfDCaXDaLAnC0S08ceHj/XKXTKpogT6o0kUWdg=" - }, - "org/jetbrains/kotlin#kotlin-stdlib/1.9.23": { - "jar": "sha256-iRDMI4gH2G71UMsfCxDdXtQLNaTsGlJSX3YK7ehOrTc=", - "module": "sha256-UZUZOzfc2touHAqw1RLEIrKtdq81V4Q6G5w0gPTnHQ4=", - "pom": "sha256-wm0n8mcQrUDiPu2f/gpkuFkejBPSI8ypDFk+5j87KKs=" - }, - "org/jetbrains/kotlin#kotlin-stdlib/2.1.20": { - "jar": "sha256-G8x06M6E4sJeqv3hDxJINJzOMGK242l4y+7GENsekwo=", - "module": "sha256-VdKW5FRF9siGmbCJZwbqlVCvh62Uhz3BO2W+u9VmCm8=", - "pom": "sha256-Z1DheZ7lAgd9rlw9WZeW9mdgb2DTXpXLeQRI3HkStAs=" - }, - "org/jetbrains/kotlinx#atomicfu-jvm/0.27.0": { - "jar": "sha256-K2hGQXAHCosIXYpyJMfAAtvWXqFOH4uXqWBRFaJS9/s=", - "module": "sha256-zi6Gt1JxP/5nAUvdHhLvKQxwLom/rLh6sn+/3X4Tusk=", - "pom": "sha256-WyUzVczAbyUcuFKuBHKkLV+9TQKZWebXgj6dE56gPZk=" - }, - "org/jetbrains/kotlinx#atomicfu/0.27.0": { - "module": "sha256-umecB1fjmeaKmfl9c4QosvtwB3F93/Dx3uuoYrr0RpA=", - "pom": "sha256-e3Fbn9t9MTr8hRjV/Kv0LrSfzNbNf/RHNqEF6AmUBdg=" - }, - "org/jetbrains/kotlinx#kotlinx-coroutines-bom/1.10.1": { - "pom": "sha256-nL0EumPnOZhWdFcT4xLS8hYaHUTtpQbe1HyNVtr4Rh8=" - }, - "org/jetbrains/kotlinx#kotlinx-coroutines-bom/1.10.2": { - "pom": "sha256-+vDGU45T3cBJmmNmTY52PCFlgLLhjnIsy98bQxpq/iY=" - }, - "org/jetbrains/kotlinx#kotlinx-coroutines-bom/1.8.0": { - "pom": "sha256-Ejnp2+E5fNWXE0KVayURvDrOe2QYQuQ3KgiNz6i5rVU=" - }, - "org/jetbrains/kotlinx#kotlinx-coroutines-core-jvm/1.10.1": { - "jar": "sha256-BpxZiGMyMOB07A05Mh7DzapFR8SekLqTbGPY/JHIwA0=", - "module": "sha256-GN1lRl7IDQ5uXXGBi/EZLvSBfPXSASgrW5sbcTrHlpo=", - "pom": "sha256-f5AURlw6uheoNXqJZcqcnKjJ4aBEfHrqEXxkB4CKUtY=" - }, - "org/jetbrains/kotlinx#kotlinx-coroutines-core-jvm/1.10.2": { - "jar": "sha256-XKF1s43zMf1kFVs1zYyuElH6nuNpcJs21C4KKIzM4/0=", - "module": "sha256-6eSnS02/4PXr7tiNSfNUbD7DCJQZsg5SUEAxNcLGTFM=", - "pom": "sha256-ZY9Xa5bIMuc4JAatsZfWTY4ul94Q6W36NwDez6KmDe8=" - }, - "org/jetbrains/kotlinx#kotlinx-coroutines-core-jvm/1.8.0": { - "jar": "sha256-mGCQahk3SQv187BtLw4Q70UeZblbJp8i2vaKPR9QZcU=", - "module": "sha256-/2oi2kAECTh1HbCuIRd+dlF9vxJqdnlvVCZye/dsEig=", - "pom": "sha256-pWM6vVNGfOuRYi2B8umCCAh3FF4LduG3V4hxVDSIXQs=" - }, - "org/jetbrains/kotlinx#kotlinx-coroutines-core/1.10.1": { - "module": "sha256-y/1tFz4KXCmGr5U/ixzPKYAqrQnqympOkRQQj4rKyLE=", - "pom": "sha256-Ip7SIxgcPK8nt6wwHIFp3KLYYxkbcQ5hNVGlh5XANlU=" - }, - "org/jetbrains/kotlinx#kotlinx-coroutines-core/1.10.2": { - "module": "sha256-j+JUF35xGnzRijwG2CQvzpRfQcLMoT3BmzOuQqVDUBY=", - "pom": "sha256-UZ2lQACW80YqTa6AeDrQUEE9S8gex65T+udq7wzL7Uw=" - }, - "org/jetbrains/kotlinx#kotlinx-coroutines-slf4j/1.10.1": { - "module": "sha256-Z53VZCkanbzH7lbmZCzzqdB7BXGWj9lN5BachzJ/i8U=", - "pom": "sha256-UqJfb2ZMxFkJQmTVEDOeVYOqyQJ/DqqqPXA1XHVQkkY=" - }, - "org/jetbrains/kotlinx#kotlinx-coroutines-slf4j/1.10.2": { - "jar": "sha256-1l3uPK+m97+u/ttJP8aLXGOr51BzT7ivkvrHoNMQFFc=", - "module": "sha256-B7xJACLGWAQpQfUrFxwPXOBkvWxjUikEMDmS5BegRbs=", - "pom": "sha256-xHdj+siNuwlDhJ0W4RucBdReYDhMfNExBe5xD7TdX7M=" - }, - "org/jetbrains/kotlinx#kotlinx-datetime-jvm/0.6.2": { - "jar": "sha256-ECdkkhEp4eRKdPQIt6C42sbRiSxgQuDkj4vbu/eMbS4=", - "module": "sha256-NU2xXaMv4YfblMbCNe96hDNrLdx5PQw3JEOZ320Kx9M=", - "pom": "sha256-OnOPkC80uNtLRGTRs9kj0mVuLKzEY2woadrFIO/Rbik=" - }, - "org/jetbrains/kotlinx#kotlinx-datetime/0.6.2": { - "module": "sha256-F5UTkzbHp4fwwvvyHSFc/1mRxx+AIZyjyiYOA0eIzCg=", - "pom": "sha256-6LX1lHxGTDyHzUJEdZ1odW/Db3pvZGQAFHGmXEX0z6U=" - }, - "org/jetbrains/kotlinx#kotlinx-io-bytestring-jvm/0.6.0": { - "jar": "sha256-uqd6eD1wpmr4jWiYodSXHkqoTmKyZBgFc3m98J+1uto=", - "module": "sha256-Tw2oHhXO+zujubirjmHoaoLtZd2N3S46cF2Euybr/Oo=", - "pom": "sha256-dQpt9xYR1MMAN+mCfSOVSSkKRuDBQBBoi4FM2ZZyG8c=" - }, - "org/jetbrains/kotlinx#kotlinx-io-bytestring-jvm/0.7.0": { - "jar": "sha256-6jimaw/0btgt3tnoHS3OcOX74DvWzFK0/IhpOB3qe30=", - "module": "sha256-D852CxW6wLkL7xvZDJfi0V+sQ6ZtwSCbSq7Jadk0Nv8=", - "pom": "sha256-mhfWfOIxynIhqWkS1WVtjRZ1gJ5FI/LDmupvs+o6bV8=" - }, - "org/jetbrains/kotlinx#kotlinx-io-bytestring/0.6.0": { - "module": "sha256-aO+bxmrpVPRzxZ9R679Ywdewb9b/9zNd0/s9JPipOQA=", - "pom": "sha256-I1NofPyzbJCaW8T08LUj0wv2WuXI34CsxW6enFJb528=" - }, - "org/jetbrains/kotlinx#kotlinx-io-bytestring/0.7.0": { - "module": "sha256-3NfGKkJ9279ezgt5jcEqD41VcSN/UScFEKUHIotjM3k=", - "pom": "sha256-b+eWaxTo7fC/rO+FfIiUpr9EtmFsbwK/7UoJMU7+0Zw=" - }, - "org/jetbrains/kotlinx#kotlinx-io-core-jvm/0.6.0": { - "jar": "sha256-QlI8gII9Me9Z+uQsklLvHTsRicqdPMOt/UAqKdBj5v8=", - "module": "sha256-tZuXjCxEJJpnRkGmlONaKs7LqBLah9NlpRZzQqjKU0c=", - "pom": "sha256-3DNkYsj1BEkGHNRdXLHI9oC+VEGqgQ6UQR/4GQmdT2s=" - }, - "org/jetbrains/kotlinx#kotlinx-io-core-jvm/0.7.0": { - "jar": "sha256-bt7cm+TYeK6oDH3WCfkb/Ef809NsyR/Q8/Mo+9ZlbI8=", - "module": "sha256-dDDspoloWorXVm2MgIIUpylQsdbwNjQd+MTYKah3Bsg=", - "pom": "sha256-I4nhfLeFp854BZ7v7yv5fpGCbCe4PMzhkbTkLtlfiBo=" - }, - "org/jetbrains/kotlinx#kotlinx-io-core/0.6.0": { - "module": "sha256-FIX7aljyQWnRr3PEFDAiUKx4u0axpD4Csa4hILKhJPA=", - "pom": "sha256-QIZ+EY9KW7uz291WZ3DY8Yu07w02MtyE+WyZ+2vD6oE=" - }, - "org/jetbrains/kotlinx#kotlinx-io-core/0.7.0": { - "module": "sha256-gTKXY+sZquO3OGcb7DFrkESEkcO/Unj24Q6kxwKS4iQ=", - "pom": "sha256-fu4E9DS9OmrRjhQFT0SH9DvKyQwDabBFA7FltzG+3Mo=" - }, - "org/jetbrains/kotlinx#kotlinx-serialization-bom/1.8.0": { - "pom": "sha256-xD5IdSnM/RIJ66hlOrjolZggNGSq+/5fBEje2ZKHFQk=" - }, - "org/jetbrains/kotlinx#kotlinx-serialization-bom/1.8.1": { - "pom": "sha256-APNVWudiSFHGfbEsMIvJziauMnzw1yR2akAeW6AGCMc=" - }, - "org/jetbrains/kotlinx#kotlinx-serialization-core-jvm/1.8.1": { - "jar": "sha256-NWW21NeJv3BoPEVWaUQof8HY3HXCPZi9h9AQWcx28rM=", - "module": "sha256-++GdWIrX1fZGZmaCA0/0Tglo0iBx/mzPn5ngPHpe+lc=", - "pom": "sha256-RGZV6NQ4KL+7OHzp0VGpNxowkrSLkJ6AYGtT/FiXnig=" - }, - "org/jetbrains/kotlinx#kotlinx-serialization-core/1.8.1": { - "module": "sha256-eL3oMFSUrxs445ZrUleskINAFkk/i60hm4iGx/vbJdU=", - "pom": "sha256-Rz8Ko+Sheqt4YNykkNxC6rthJPHSlT5qmVoIcX5QxxQ=" - }, - "org/jetbrains/kotlinx#kotlinx-serialization-json-io-jvm/1.8.1": { - "jar": "sha256-q17I6kiBUZfEan359BimJ5H+kc2lAjuUHOTehy2BDME=", - "module": "sha256-vz47hoSxN/py0pZVZ1/c4xRGewh5JikYMm2vedE+Afo=", - "pom": "sha256-27ETuPvVUEVZjiTmATIGrrzKkSr+Vjnr2VJjC579kjw=" - }, - "org/jetbrains/kotlinx#kotlinx-serialization-json-io/1.8.0": { - "module": "sha256-+3LQaky980DBOnBPywfUsWJ66NnDCtZnEwb6x1UnB7Q=", - "pom": "sha256-xgC76woBPRA7cbGCa+t0Sbnv/5x4Knl0JKoOdV+Cw0Q=" - }, - "org/jetbrains/kotlinx#kotlinx-serialization-json-io/1.8.1": { - "module": "sha256-WTtZ8otvvbjsNRD4+ZQksTTlv8Qe2GS82LAiDv4APnM=", - "pom": "sha256-2e2KSEKd687/Z05u1OdgPR1K5Ao3lWT9BlPQ3V9gJb8=" - }, - "org/jetbrains/kotlinx#kotlinx-serialization-json-jvm/1.8.1": { - "jar": "sha256-h2nlZHVX43AJGcMtUI9cXa1TxdgjTNEIRjVPvP8UqiQ=", - "module": "sha256-uZHLSTQAwdlgut+oYhcVjGN+XsqIgbIM0BJbtOz8+DE=", - "pom": "sha256-1mXWtB/gWPZmpvOGrS5JzBAe+P0u7+/vy8ER6R7oJDY=" - }, - "org/jetbrains/kotlinx#kotlinx-serialization-json/1.8.1": { - "module": "sha256-f33wBUM932BPUqq9avsh65YJMZfLS90Hk8SEydPEtnU=", - "pom": "sha256-x3AMmcg94CtGVBo9fktps4h0m3wPV9zrRU0UPyzYens=" - }, - "org/junit#junit-bom/5.10.2": { - "module": "sha256-3iOxFLPkEZqP5usXvtWjhSgWaYus5nBxV51tkn67CAo=", - "pom": "sha256-Fp3ZBKSw9lIM/+ZYzGIpK/6fPBSpifqSEgckzeQ6mWg=" - }, - "org/junit#junit-bom/5.11.0": { - "module": "sha256-9+2+Z/IgQnCMQQq8VHQI5cR29An1ViNqEXkiEnSi7S0=", - "pom": "sha256-5nRZ1IgkJKxjdPQNscj0ouiJRrNAugcsgL6TKivkZE0=" - }, - "org/junit#junit-bom/5.11.0-M2": { - "module": "sha256-hkd6vPSQ1soFmqmXPLEI0ipQb0nRpVabsyzGy/Q8LM4=", - "pom": "sha256-Sj/8Sk7c/sLLXWGZInBqlAcWF5hXGTn4VN/ac+ThfMg=" - }, - "org/junit#junit-bom/5.11.2": { - "module": "sha256-iDoFuJLxGFnzg23nm3IH4kfhQSVYPMuKO+9Ni8D1jyw=", - "pom": "sha256-9I6IU4qsFF6zrgNFqevQVbKPMpo13OjR6SgTJcqbDqI=" - }, - "org/reactivestreams#reactive-streams/1.0.3": { - "jar": "sha256-He4EgQctGckptiPhVeFNL2CF3AEVKaCg2+/ITPVx2GU=", - "pom": "sha256-zO1GcXX0JXgz9ssHUQ/5ezx1oG4aWNiCo515hT1RxgI=" - }, - "org/slf4j#slf4j-api/1.7.30": { - "pom": "sha256-fgdHdR6bZ+Gdy1IG8E6iLMA9JQxCJCZALq3QNRPywxQ=" - }, - "org/slf4j#slf4j-api/1.7.36": { - "pom": "sha256-+wRqnCKUN5KLsRwtJ8i113PriiXmDL0lPZhSEN7cJoQ=" - }, - "org/slf4j#slf4j-api/2.0.16": { - "jar": "sha256-oSV43eG6AL2bgW04iguHmSjQC6s8g8JA9wE79BlsV5o=", - "pom": "sha256-saAPWxxNvmK4BdZdI5Eab3cGOInXyx6G/oOJ1hkEc/c=" - }, - "org/slf4j#slf4j-api/2.0.17": { - "jar": "sha256-e3UdlSBhlU1av+1xgcH2RdM2CRtnmJFZHWMynGIuuDI=", - "pom": "sha256-FQxAKH987NwhuTgMqsmOkoxPM8Aj22s0jfHFrJdwJr8=" - }, - "org/slf4j#slf4j-bom/2.0.16": { - "pom": "sha256-BWYEjsglzfKHWGIK9k2eFK44qc2HSN1vr6bfSkGUwnk=" - }, - "org/slf4j#slf4j-bom/2.0.17": { - "pom": "sha256-940ntkK0uIbrg5/BArXNn+fzDzdZn/5oGFvk4WCQMek=" - }, - "org/slf4j#slf4j-parent/1.7.30": { - "pom": "sha256-EWR5VuSKDFv7OsM/bafoPzQQAraFfv0zWlBbaHvjS3U=" - }, - "org/slf4j#slf4j-parent/1.7.36": { - "pom": "sha256-uziNN/vN083mTDzt4hg4aTIY3EUfBAQMXfNgp47X6BI=" - }, - "org/slf4j#slf4j-parent/2.0.16": { - "pom": "sha256-CaC0zIFNcnRhbJsW1MD9mq8ezIEzNN5RMeVHJxsZguU=" - }, - "org/slf4j#slf4j-parent/2.0.17": { - "pom": "sha256-lc1x6FLf2ykSbli3uTnVfsKy5gJDkYUuC1Rd7ggrvzs=" - }, - "org/sonatype/oss#oss-parent/7": { - "pom": "sha256-tR+IZ8kranIkmVV/w6H96ne9+e9XRyL+kM5DailVlFQ=" - }, - "org/testcontainers#testcontainers-bom/1.20.2": { - "pom": "sha256-e4pU2xu9Xq+FrSwirUuuM4VBi+FATgqM0jVVtZiknDY=" - }, - "org/xerial#sqlite-jdbc/3.45.2.0": { - "jar": "sha256-qBcWI4S32dmP1hbKiAvL8lKM8p4xOTZm0t+FswewN2Q=", - "pom": "sha256-mHyAHc+pUy4jjB0gA9D3T7LCrjeCY3zIUVSC5xY42hs=" - } - } -} 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/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 281b5b8f..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-MmWcZqbnO6Pqx9ElZ3Nwl5K/TLUV8EdRh2uNKua+i3A="; - - 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 9e5f3ae5..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.2.0" - } - }, - "node_modules/some-sass-language-server": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/some-sass-language-server/-/some-sass-language-server-2.2.0.tgz", - "integrity": "sha512-liUG9OMbmPBM48IvyitBCsJ6A+kMAnkwxZbPlhBWxL+N6QBi5J2AhW67N5v6BKjjLbfB/OERzazAJSCXevfqVQ==", - "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 ab0e8e82..00000000 --- a/packages/some-sass-language-server/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "some-sass-language-server": "2.2.0" - } -} 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 e30b7502..00000000 --- a/scopedPackages/README.md +++ /dev/null @@ -1,76 +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 | -| `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 e8d2895e..00000000 --- a/scopedPackages/firefox-addons/addons.json +++ /dev/null @@ -1,51 +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": "ublock-origin" - }, - { - "slug": "undoclosetabbutton" - } -] diff --git a/scopedPackages/firefox-addons/generated-firefox-addons.nix b/scopedPackages/firefox-addons/generated-firefox-addons.nix deleted file mode 100644 index 87b65d9a..00000000 --- a/scopedPackages/firefox-addons/generated-firefox-addons.nix +++ /dev/null @@ -1,330 +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.4.0"; - addonId = "{446900e4-71c2-419f-a6a7-df9c091e268b}"; - url = "https://addons.mozilla.org/firefox/downloads/file/4484791/bitwarden_password_manager-2025.4.0.xpi"; - sha256 = "643cb6fd7b9d1b209f82ca552342390a45c3edc94645cb049e49d016ee28b63c"; - 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.106"; - addonId = "addon@darkreader.org"; - url = "https://addons.mozilla.org/firefox/downloads/file/4488139/darkreader-4.9.106.xpi"; - sha256 = "23c94085063aa6b57fae40ca9111ab049fffca5476c29e9990db3aa1a3fe1f10"; - 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.3.1"; - addonId = "floccus@handmadeideas.org"; - url = "https://addons.mozilla.org/firefox/downloads/file/4492899/floccus-5.5.3.1.xpi"; - sha256 = "7147732fd0e63f611d7cbf967649d757a7bbf10d0d2dfac6d78bae4db8405996"; - 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.12.1"; - addonId = "sponsorBlocker@ajay.app"; - url = "https://addons.mozilla.org/firefox/downloads/file/4480833/sponsorblock-5.12.1.xpi"; - sha256 = "1ba2e6f90f64281397c131f8cd195faa01832600bee19ec3b93dce9366cfa96e"; - 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; - }; - }; - "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 9ab0ea8d..00000000 --- a/scopedPackages/hass-components/tuya-local/overrides.nix +++ /dev/null @@ -1,11 +0,0 @@ -{pkgs, ...}: python3Packages: final: prev: { - tinytuya = prev.tinytuya.overridePythonAttrs (o: rec { - version = "1.16.3"; - src = pkgs.fetchFromGitHub { - owner = "jasonacox"; - repo = "tinytuya"; - rev = "v${version}"; - hash = "sha256-BnX12D758seiOPAEZOEOeKQbA/VDulKPiNh36D3nMo8="; - }; - }); -} 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 53136685..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-V0lu91aLMIjcFsDfqXJldQGfJVALErrl49qMnR2hplw="; - }; - - 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 1eab9a67..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.6"; -in - stdenv.mkDerivation { - inherit pname version; - - src = fetchFromGitHub { - owner = "Nerwyn"; - repo = pname; - rev = version; - hash = "sha256-KWr2luWOqBg3LXwB7F38DEPSu+FhBxkHPYRTMkU01gA="; - }; - - 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.. - ''; - }; -} diff --git a/updateSha.sh b/updateSha.sh new file mode 100755 index 00000000..0a3760ce --- /dev/null +++ b/updateSha.sh @@ -0,0 +1,97 @@ +#!/usr/bin/env bash + +# Deps: +# - jq +# - mozilla-addons-to-nix +# - alejandra +# - updateImages + +parseFetchurl() { + URL="$1" + FILE="$2" + HASH="$(nix store prefetch-file --refresh --json \ + --hash-type sha256 "$URL" --name "escaped" | jq -r .hash)" + + sed -i "s,url = .*,url = \"$URL\";," "$FILE" + sed -i "s,hash = .*,hash = \"$HASH\";," "$FILE" + + # For Firefox addons + sed -i "s,sha256 = .*,sha256 = \"$HASH\";," "$FILE" +} + +updateDocker() { + find "$FLAKE/devices/nos/modules/arion" \ + -name "*compose.nix" \ + -exec sh -c 'updateImages $(dirname "{}")' \; +} + +updateFFZ() { + FILE="$FLAKE/home/firefox/addons/default.nix" + URL="https://cdn.frankerfacez.com/script/frankerfacez-4.0-an+fx.xpi" + + parseFetchurl "$URL" "$FILE" +} + +updateFirefoxAddons() { + echo "Updating firefox addons using mozilla-addons-to-nix" + + ( + cd "$FLAKE/home/firefox/addons" || return; + + file=generated-firefox-addons.nix + if [[ -f $file ]]; then + printf "\nOld versions: \n" + + grep -A 1 --no-group-separator 'pname' "$file" | + awk '{ gsub(/"/, ""); gsub(/;/, ""); print $3 }' | + awk 'NR%2{printf $0" version ";next;}1' | paste -sd'\n' - + + printf "\nNew versions: \n" + fi + + mozilla-addons-to-nix addons.json generated-firefox-addons.nix + ) +} + +updateVuetorrent() { + FILE="$FLAKE/devices/nos/modules/qbittorrent/vuetorrent.nix" + + release=$(curl -s https://api.github.com/repos/VueTorrent/VueTorrent/releases/latest) + version=$(echo "$release" | jq -r .tag_name | tr -d v) + url="https://github.com/VueTorrent/VueTorrent/releases/download/v${version}/vuetorrent.zip" + hash="$(nix store prefetch-file --refresh --json \ + --hash-type sha256 "$url" --name "escaped" | jq -r .hash)" + + { + echo '# This file was autogenerated. DO NOT EDIT!' + echo '{' + echo " version = \"$version\";" + echo " url = \"$url\";" + echo " hash = \"$hash\";" + echo '}' + } >"$FILE" +} + + +doAll() { + updateDocker + updateFFZ + updateFirefoxAddons + updateVuetorrent +} + +doAllWithoutDocker() { + updateFFZ + updateFirefoxAddons + updateVuetorrent +} + + +[[ "$1" == "-a" || "$1" == "--all" ]] && doAll +[[ "$1" == "-ad" || "$1" == "--all-no-docker" ]] && doAllWithoutDocker +[[ "$1" == "-d" || "$1" == "--docker" ]] && updateDocker +[[ "$1" == "-f" || "$1" == "--firefox" ]] && updateFirefoxAddons +[[ "$1" == "-ffz" || "$1" == "--frankerfacez" ]] && updateFFZ +[[ "$1" == "-v" || "$1" == "--vuetorrent" ]] && updateVuetorrent + +alejandra "$FLAKE"