diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix index f549bc555e41f..6d4f5f3379913 100644 --- a/maintainers/maintainer-list.nix +++ b/maintainers/maintainer-list.nix @@ -6631,6 +6631,11 @@ githubId = 2096594; email = "Dietrich@Daroch.me"; }; + different-error = { + name = "Sanfer D'souza"; + github = "different-error"; + githubId = 9338001; + }; different-name = { name = "different-name"; email = "hello@different-name.dev"; diff --git a/nixos/doc/manual/redirects.json b/nixos/doc/manual/redirects.json index 4385b88e7cea1..26551b53b9586 100644 --- a/nixos/doc/manual/redirects.json +++ b/nixos/doc/manual/redirects.json @@ -1621,6 +1621,9 @@ "sec-kubernetes": [ "index.html#sec-kubernetes" ], + "module-services-nordvpn": [ + "index.html#module-services-nordvpn" + ], "ch-running": [ "index.html#ch-running" ], diff --git a/nixos/doc/manual/release-notes/rl-2605.section.md b/nixos/doc/manual/release-notes/rl-2605.section.md index 877e6af04345e..8cc22999a657d 100644 --- a/nixos/doc/manual/release-notes/rl-2605.section.md +++ b/nixos/doc/manual/release-notes/rl-2605.section.md @@ -14,6 +14,8 @@ designed to run on affordable, low-power devices. Available as [services.meshtasticd] (#opt-services.meshtasticd.enable). +- [NordVPN](https://github.com/NordSecurity/nordvpn-linux), a NordVPN client for linux. Available as [services.nordvpn](options.html#opt-services.nordvpn.enable). + - [knot-resolver](https://www.knot-resolver.cz/) in version 6. Available as `services.knot-resolver`. A module for knot-resolver 5 was already available as `services.kresd`. - [ImmichFrame](https://immichframe.dev/), display your photos from Immich as a digital photo frame. Available as `services.immichframe`. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 32696b47890ef..aacac4ecbe4e8 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1298,6 +1298,7 @@ ./services/networking/nncp.nix ./services/networking/nntp-proxy.nix ./services/networking/nomad.nix + ./services/networking/nordvpn.nix ./services/networking/nsd.nix ./services/networking/ntopng.nix ./services/networking/ntp/chrony.nix diff --git a/nixos/modules/services/networking/nordvpn.md b/nixos/modules/services/networking/nordvpn.md new file mode 100644 index 0000000000000..06016098894a1 --- /dev/null +++ b/nixos/modules/services/networking/nordvpn.md @@ -0,0 +1,65 @@ +# NordVPN {#module-services-nordvpn} + +*Source:* {file}`modules/services/networking/nordvpn.nix` + +*Upstream documentation:* + +NordVPN offers a paid virtual private network (VPN) service. +The service operates as closed-source, +but the Linux client uses open-source code licensed under GPLv3. +A minimal configuration in NixOS appears as follows: + +```nix +{ + services.nordvpn.enable = true; + networking.firewall.enable = true; + networking.firewall.checkReversePath = "loose"; +} +``` + +When using a firewall, set `networking.firewall.checkReversePath` to `"loose"` or `false`. +NordVPN includes a `kill-switch` feature that blocks all packets not associated with the VPN connection. + +Additionally, add your user to the `nordvpn` group. + +```nix +{ + users.users.yourUser = { + #.. + extraGroups = [ + #.. + "nordvpn" + ]; + }; +} +``` + +If you prefer to use your own user and group, you can do so using + +```nix +{ + services.nordvpn.user = "SOME-USER"; + services.nordvpn.group = "SOME-GROUP"; +} +``` + +NordVPN provides several useful CLI commands, including: + +```bash +nordvpn login # Log in using an OAuth URL +nordvpn login --token # Log in with a token obtained from your NordVPN account +nordvpn c # Connect to the VPN +nordvpn c ie # Connect to a NordVPN server in Ireland +nordvpn d # Disconnect from the VPN +nordvpn set technology openvpn # Switch to OpenVPN technology +nordvpn c # Reconnect after changing technology +``` + +Additionally, if you prefer to use the friendly GUI, + +```bash +nordvpn-gui +``` + +**Disclaimer:** NixOS currently does not support meshnet. +Contributions welcome! diff --git a/nixos/modules/services/networking/nordvpn.nix b/nixos/modules/services/networking/nordvpn.nix new file mode 100644 index 0000000000000..4460c7c1a75ab --- /dev/null +++ b/nixos/modules/services/networking/nordvpn.nix @@ -0,0 +1,171 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.services.nordvpn; + defaultUser = "nordvpn"; + defaultGroup = "nordvpn"; + + nordvpn = + let + cli = cfg.package.cli.overrideAttrs (old: { + preBuild = + let + extraPreBuild = lib.optionalString (cfg.group != defaultGroup) '' + substituteInPlace internal/permissions.go \ + --replace-fail \ + 'string{"nordvpn"}' \ + 'string{"${cfg.group}"}' + + substituteInPlace internal/constants.go \ + --replace-fail \ + 'NordvpnGroup = "nordvpn"' \ + 'NordvpnGroup = "${cfg.group}"' + ''; + in + extraPreBuild + (old.preBuild or ""); + + # postFixup wraps nordvpnd so that it can find binaries that it calls. + # here, instead, use systemd to update the path to those binaries. + postFixup = ""; + }); + in + pkgs.symlinkJoin { + inherit (cfg.package) pname version meta; + paths = [ + cli + cfg.package.gui + ]; + }; +in +{ + options.services.nordvpn = { + enable = lib.mkEnableOption "Enable NordVPN"; + package = lib.mkPackageOption pkgs "nordvpn" { }; + user = lib.mkOption { + type = lib.types.str; + default = defaultUser; + description = '' + The User that owns the `nordvpnd` systemd process. + If overriding the default, a user with the same name must exist. + ''; + }; + group = lib.mkOption { + type = lib.types.str; + default = defaultGroup; + description = '' + The Group that owns the `nordvpnd` systemd process. + If overriding the default, a group with the same name must exist. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + + # create the default user if that's the one used + users.users = lib.mkIf (cfg.user == defaultUser) { + ${defaultUser} = { + description = "User that runs `nordvpnd`."; + group = cfg.group; + isSystemUser = true; + }; + }; + + # create the default group if that's the one used + users.groups = lib.mkIf (cfg.group == defaultGroup) { + ${defaultGroup} = { }; + }; + + # nordvpnd uses resolved to configure dns + services.resolved.enable = true; + + # policy that allows nordvpnd to configure dns + security.polkit = { + enable = true; + extraConfig = '' + polkit.addRule(function(action, subject) { + if (action.id == "org.freedesktop.resolve1.set-dns-servers" + && subject.isInGroup("${cfg.group}")) { + return polkit.Result.YES; + } + }); + ''; + }; + + environment.systemPackages = [ + nordvpn + ]; + + systemd.services.nordvpnd = { + after = [ "network-online.target" ]; + description = "NordVPN daemon."; + path = ( + with pkgs; + [ + e2fsprogs + iproute2 + iptables + libxslt + procps + wireguard-tools + ] + ++ [ nordvpn ] + ); + serviceConfig = { + # nordvpnd needs CAP_NET_ADMIN to configure network interfaces + AmbientCapabilities = "CAP_NET_ADMIN"; + CapabilityBoundingSet = "CAP_NET_ADMIN"; + ExecStart = lib.getExe' nordvpn "nordvpnd"; + Group = cfg.group; + KillMode = "process"; + NonBlocking = true; + Requires = "nordvpnd.socket"; + Restart = "on-failure"; + RestartSec = 5; + RuntimeDirectory = "nordvpn"; + RuntimeDirectoryMode = "0750"; + StateDirectory = "nordvpn"; + StateDirectoryMode = "0750"; + User = cfg.user; + }; + wantedBy = [ "default.target" ]; + wants = [ "network-online.target" ]; + }; + + systemd.sockets.nordvpnd = { + description = "NordVPN Daemon Socket"; + listenStreams = [ "/run/nordvpn/nordvpnd.sock" ]; + partOf = [ "nordvpnd.service" ]; + socketConfig = { + DirectoryMode = "0750"; + NoDelay = true; + SocketGroup = cfg.group; + SocketMode = "0770"; + SocketUser = cfg.user; + }; + wantedBy = [ "sockets.target" ]; + }; + + systemd.user.services.norduserd = { + after = [ "network-online.target" ]; + description = "NordUserD Service"; + serviceConfig = { + ExecStart = lib.getExe' nordvpn "norduserd"; + NonBlocking = true; + Restart = "on-failure"; + RestartSec = 5; + }; + wantedBy = [ "graphical-session.target" ]; + wants = [ "network-online.target" ]; + }; + + }; + + meta = { + doc = ./nordvpn.md; + maintainers = with lib.maintainers; [ different-error ]; + }; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 628e8fd95cdde..b59f447e1b746 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -1106,6 +1106,7 @@ in nominatim = runTest ./nominatim.nix; non-default-filesystems = handleTest ./non-default-filesystems.nix { }; non-switchable-system = runTest ./non-switchable-system.nix; + nordvpn = runTest ./nordvpn.nix; noto-fonts = runTest ./noto-fonts.nix; noto-fonts-cjk-qt-default-weight = runTest ./noto-fonts-cjk-qt-default-weight.nix; novacomd = handleTestOn [ "x86_64-linux" ] ./novacomd.nix { }; diff --git a/nixos/tests/nordvpn.nix b/nixos/tests/nordvpn.nix new file mode 100644 index 0000000000000..4f0b9aecc4799 --- /dev/null +++ b/nixos/tests/nordvpn.nix @@ -0,0 +1,129 @@ +{ lib, ... }: +{ + name = "nordvpn"; + meta.maintainers = with lib.maintainers; [ different-error ]; + nodes = + let + commonConfig = user: { + # norduserd reads DBUS_SESSION_BUS_ADDRESS which the + # desktopManager sets on user session creation (i.e. login) + services.xserver.enable = true; + services.desktopManager.plasma6.enable = true; + services.displayManager.gdm.enable = true; + services.displayManager.autoLogin = { + enable = true; + user = user; + }; + }; + in + { + nada = { ... }: { }; + basic = + { ... }: + lib.recursiveUpdate { + users.users.alice = { + extraGroups = [ "nordvpn" ]; + isNormalUser = true; + }; + # default: run nordvpnd as nordvpn:nordvpn + services.nordvpn.enable = true; + } (commonConfig "alice"); + userOnly = + { ... }: + lib.recursiveUpdate { + users.users.kanye = { + extraGroups = [ "nordvpn" ]; + isNormalUser = true; + }; + # run nordvpnd as kanye:nordvpn + services.nordvpn = { + enable = true; + user = "kanye"; + }; + } (commonConfig "kanye"); + groupOnly = + { ... }: + lib.recursiveUpdate { + users.users.alice = { + extraGroups = [ "kanye" ]; + isNormalUser = true; + }; + users.groups.kanye = { }; + # run nordvpnd as nordvpn:kanye + services.nordvpn = { + enable = true; + group = "kanye"; + }; + } (commonConfig "alice"); + userAndGroup = + { ... }: + lib.recursiveUpdate { + users.users.kanye = { + group = "kanye"; + isNormalUser = true; + }; + users.groups.kanye = { }; + # run nordvpnd as kanye:kanye + services.nordvpn = { + enable = true; + group = "kanye"; + user = "kanye"; + }; + } (commonConfig "kanye"); + }; + + testScript = '' + class UserGroupTestCase: + def __init__(self, machine, user, has_nordvpn_usr, has_nordvpn_gp): + self.machine = machine + self.user = user + self.has_nordvpn_usr = has_nordvpn_usr + self.has_nordvpn_gp = has_nordvpn_gp + + def run(self): + self.machine.start() + self.verify_nordvpn_user() + self.verify_nordvpn_group() + self.verify_services() + self.machine.shutdown() + + def verify_nordvpn_user(self): + if self.has_nordvpn_usr: + self.machine.succeed("id nordvpn") + else: + self.machine.fail("id nordvpn") + + def verify_nordvpn_group(self): + group_str = self.machine.succeed(f"sudo -u {self.user} groups") + groups = [x.strip() for x in group_str.split(" ")] + if self.has_nordvpn_gp: + assert "nordvpn" in groups, f"nordvpn is not in {groups} but should be" + else: + assert "nordvpn" not in groups, f"nordvpn is in {groups} but should not be" + + def verify_services(self): + self.machine.wait_for_unit("nordvpnd", timeout=60) + self.machine.wait_for_unit("norduserd", self.user, timeout=60) + # verify can talk to nordvpnd. give nordvpnd at most 5s to initialize. + self.machine.wait_until_succeeds("nordvpn status", timeout=5) + self.machine.succeed("nordvpn status") + + test_cases = [ + UserGroupTestCase(basic, "alice", has_nordvpn_usr=True, has_nordvpn_gp=True), + UserGroupTestCase(userOnly, "kanye", has_nordvpn_usr=False, has_nordvpn_gp=True), + UserGroupTestCase(groupOnly, "alice", has_nordvpn_usr=True, has_nordvpn_gp=False), + UserGroupTestCase(userAndGroup, "kanye", has_nordvpn_usr=False, has_nordvpn_gp=False), + ] + + # NADA + nada.start() + nada.wait_for_unit("multi-user.target", timeout=60) + nada.fail("nordvpnd") + nada.fail("nordvpn") + nada.fail("norduserd") + nada.shutdown() + + for test_case in test_cases: + test_case.run() + ''; +} diff --git a/pkgs/by-name/no/nordvpn/cli.nix b/pkgs/by-name/no/nordvpn/cli.nix new file mode 100644 index 0000000000000..7e14184291528 --- /dev/null +++ b/pkgs/by-name/no/nordvpn/cli.nix @@ -0,0 +1,154 @@ +{ + myDesktopItemArgs, + myMeta, + mySrc, + myVersion, + + buildGoModule, + copyDesktopItems, + e2fsprogs, + fetchFromGitHub, + iproute2, + iptables, + lib, + libxslt, + makeDesktopItem, + makeWrapper, + openvpn, + pkg-config, + procps, + systemdMinimal, + wireguard-tools, +}: +let + patchedOpenvpn = openvpn.overrideAttrs (old: { + patches = + let + tunnelblickSrc = fetchFromGitHub { + owner = "Tunnelblick"; + repo = "Tunnelblick"; + tag = "v8.0"; + hash = "sha256-Kj/F7hI6E+giT+4iGDUjXCLgy/6jcohtTWtLXOpZfo0="; + }; + + p = "third_party/sources/openvpn/openvpn-${old.version}/patches"; + name2urlFtn = fname: "${tunnelblickSrc}/${p}/${fname}"; + in + (old.patches or [ ]) + ++ (lib.map name2urlFtn [ + "02-tunnelblick-openvpn_xorpatch-a.diff" + "03-tunnelblick-openvpn_xorpatch-b.diff" + "04-tunnelblick-openvpn_xorpatch-c.diff" + "05-tunnelblick-openvpn_xorpatch-d.diff" + "06-tunnelblick-openvpn_xorpatch-e.diff" + ]); + }); + +in +buildGoModule (finalAttrs: { + pname = "nordvpn-cli"; + version = myVersion; + + src = mySrc; + + nativeBuildInputs = [ + copyDesktopItems + makeWrapper + pkg-config + ]; + + vendorHash = "sha256-outOvVAu76Pa9lQbiXQP2wA2cee3Ofq41SwfL6JEKs0="; + + preBuild = '' + # use path $out/bin instead of /usr/lib + substituteInPlace internal/constants.go \ + --replace-fail "/usr/lib/nordvpn" "$out/bin" + + # use path <>/bin/openvpn + old_ovpn_path='filepath.Join(internal.AppDataPathStatic, "openvpn")' + new_ovpn_path='"${patchedOpenvpn}/bin/openvpn"' + substituteInPlace daemon/vpn/openvpn/config.go \ + --replace-fail "$old_ovpn_path" "$new_ovpn_path" + ''; + + ldflags = [ + "-X main.Environment=prod" + "-X main.Version=${finalAttrs.version}" + ]; + + subPackages = [ + "cmd/cli" + "cmd/daemon" + "cmd/norduser" + ]; + + doCheck = true; + + checkPhase = '' + runHook preCheck + + go test ./cli + # skip tests that require network access + go test ./daemon -skip \ + 'TestTransports|TestH1Transport_RoundTrip|Test.*FileList_RealURL' + go test ./norduser + + runHook postCheck + ''; + + postInstall = '' + # rename to standard names + BIN_DIR=$out/bin + install $BIN_DIR/cli $BIN_DIR/nordvpn + install $BIN_DIR/daemon $BIN_DIR/nordvpnd + install $BIN_DIR/norduser $BIN_DIR/norduserd + rm $BIN_DIR/{cli,daemon,norduser} + + # nordvpn needs icons for the system tray and notifications + ICONS_PATH=$out/share/icons/hicolor/scalable/apps + install -d $ICONS_PATH + install --mode=0444 assets/icon.svg $ICONS_PATH/nordvpn.svg + for file in assets/*; do + install --mode=0444 "$file" "$ICONS_PATH/nordvpn-$(basename $file)" + done + ''; + + postFixup = '' + wrapProgram $out/bin/nordvpnd --set PATH ${ + lib.makeBinPath [ + e2fsprogs + iproute2 + iptables + libxslt + patchedOpenvpn + procps + systemdMinimal + wireguard-tools + ] + } + ''; + + desktopItems = [ + (makeDesktopItem ( + myDesktopItemArgs + // { + comment = "I get called after NordVPN oauth browser login."; + desktopName = "NordVPN CLI"; + exec = "nordvpn click %u"; + mimeTypes = [ "x-scheme-handler/nordvpn" ]; + name = "nordvpn"; + noDisplay = true; + terminal = true; + } + )) + ]; + + meta = myMeta // { + description = '' + NordVPN cli application. + Contains client and daemon. + Even if you intend to use the gui only, you'd need this package. + ''; + mainProgram = "nordvpn"; + }; +}) diff --git a/pkgs/by-name/no/nordvpn/gui.nix b/pkgs/by-name/no/nordvpn/gui.nix new file mode 100644 index 0000000000000..583a803aff6db --- /dev/null +++ b/pkgs/by-name/no/nordvpn/gui.nix @@ -0,0 +1,43 @@ +{ + myDesktopItemArgs, + myMeta, + mySrc, + myVersion, + + flutter, + lib, + makeDesktopItem, +}: +flutter.buildFlutterApplication { + pname = "nordvpn-gui"; + version = myVersion; + + src = mySrc; + sourceRoot = "${mySrc.name}/gui"; + + pubspecLock = lib.importJSON ./pubspec.lock.json; + + patches = [ ./linux-cmake.patch ]; + + desktopItems = [ + (makeDesktopItem ( + myDesktopItemArgs + // { + comment = "NordVPN's GUI to manage vpn connection, settings, etc."; + desktopName = "NordVPN GUI"; + exec = "nordvpn-gui"; + name = "nordvpn-gui"; + noDisplay = false; + terminal = false; + } + )) + ]; + + meta = myMeta // { + description = '' + NordVPN gui application. + Presumes the dependent NordVPN cli application. + ''; + mainProgram = "nordvpn-gui"; + }; +} diff --git a/pkgs/by-name/no/nordvpn/linux-cmake.patch b/pkgs/by-name/no/nordvpn/linux-cmake.patch new file mode 100644 index 0000000000000..be2d8fd538500 --- /dev/null +++ b/pkgs/by-name/no/nordvpn/linux-cmake.patch @@ -0,0 +1,23 @@ +--- a/linux/CMakeLists.txt ++++ b/linux/CMakeLists.txt +@@ -51,10 +51,10 @@ + # System-level dependencies. + find_package(PkgConfig REQUIRED) + pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) ++pkg_check_modules(X11 REQUIRED IMPORTED_TARGET x11) + + add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") + # Fix for: https://github.com/NordSecurity/nordvpn-linux/issues/1136 +-find_package(X11 REQUIRED) + + # Define the application target. To change its name, change BINARY_NAME above, + # not the value here, or `flutter run` will no longer work. +@@ -73,7 +73,7 @@ + # Add dependency libraries. Add any application-specific dependencies here. + target_link_libraries(${BINARY_NAME} PRIVATE flutter) + target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) +-target_link_libraries(${BINARY_NAME} PRIVATE X11::X11) ++target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::X11) + + # Run the Flutter tool portions of the build. This must not be removed. + add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/pkgs/by-name/no/nordvpn/package.nix b/pkgs/by-name/no/nordvpn/package.nix new file mode 100644 index 0000000000000..2f859cb682f17 --- /dev/null +++ b/pkgs/by-name/no/nordvpn/package.nix @@ -0,0 +1,59 @@ +{ + callPackage, + fetchFromGitHub, + lib, + symlinkJoin, +}: +let + version = "4.3.1"; + + commonArgs = { + myVersion = version; + + mySrc = fetchFromGitHub { + owner = "NordSecurity"; + repo = "nordvpn-linux"; + tag = version; + hash = "sha256-o9+9IiXV2CS/Zj3bDg8EJn/UidwA6Fwn4ySFbwyCp60="; + }; + + myMeta = rec { + homepage = "https://github.com/nordsecurity/nordvpn-linux"; + changelog = "${homepage}/blob/main/contrib/changelog/prod/${version}.md"; + license = lib.licenses.gpl3Only; + maintainers = with lib.maintainers; [ different-error ]; + platforms = lib.platforms.linux; + }; + + myDesktopItemArgs = { + categories = [ "Network" ]; + genericName = "a vpn provider"; + icon = "nordvpn"; + type = "Application"; + }; + }; +in +symlinkJoin rec { + pname = "nordvpn"; + version = commonArgs.myVersion; + + # define these here to override in corresponding nixos module definition. + cli = callPackage ./cli.nix commonArgs; + gui = callPackage ./gui.nix commonArgs; + + paths = [ + cli + gui + ]; + + meta = commonArgs.myMeta // { + description = "NordVPN cli and gui applications for Linux."; + longDescription = '' + NordVPN cli and gui applications for Linux. + This package currently does not support meshnet. + Additionally, if `networking.firewall.enable = true;`, + then also set `networking.firewall.checkReversePath = "loose";`. + Contributions welcome! + ''; + }; +} diff --git a/pkgs/by-name/no/nordvpn/pubspec.lock.json b/pkgs/by-name/no/nordvpn/pubspec.lock.json new file mode 100644 index 0000000000000..5ca2058d3f70b --- /dev/null +++ b/pkgs/by-name/no/nordvpn/pubspec.lock.json @@ -0,0 +1,1526 @@ +{ + "packages": { + "_fe_analyzer_shared": { + "dependency": "transitive", + "description": { + "name": "_fe_analyzer_shared", + "sha256": "da0d9209ca76bde579f2da330aeb9df62b6319c834fa7baae052021b0462401f", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "85.0.0" + }, + "analyzer": { + "dependency": "transitive", + "description": { + "name": "analyzer", + "sha256": "f4ad0fea5f102201015c9aae9d93bc02f75dd9491529a8c21f88d17a8523d44c", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "7.6.0" + }, + "analyzer_plugin": { + "dependency": "transitive", + "description": { + "name": "analyzer_plugin", + "sha256": "a5ab7590c27b779f3d4de67f31c4109dbe13dd7339f86461a6f2a8ab2594d8ce", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.13.4" + }, + "args": { + "dependency": "transitive", + "description": { + "name": "args", + "sha256": "d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.7.0" + }, + "async": { + "dependency": "transitive", + "description": { + "name": "async", + "sha256": "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.13.0" + }, + "boolean_selector": { + "dependency": "transitive", + "description": { + "name": "boolean_selector", + "sha256": "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.1.2" + }, + "build": { + "dependency": "transitive", + "description": { + "name": "build", + "sha256": "cef23f1eda9b57566c81e2133d196f8e3df48f244b317368d65c5943d91148f0", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.4.2" + }, + "build_config": { + "dependency": "transitive", + "description": { + "name": "build_config", + "sha256": "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.1.2" + }, + "build_daemon": { + "dependency": "transitive", + "description": { + "name": "build_daemon", + "sha256": "8e928697a82be082206edb0b9c99c5a4ad6bc31c9e9b8b2f291ae65cd4a25daa", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "4.0.4" + }, + "build_resolvers": { + "dependency": "transitive", + "description": { + "name": "build_resolvers", + "sha256": "b9e4fda21d846e192628e7a4f6deda6888c36b5b69ba02ff291a01fd529140f0", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.4.4" + }, + "build_runner": { + "dependency": "direct dev", + "description": { + "name": "build_runner", + "sha256": "058fe9dce1de7d69c4b84fada934df3e0153dd000758c4d65964d0166779aa99", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.4.15" + }, + "build_runner_core": { + "dependency": "transitive", + "description": { + "name": "build_runner_core", + "sha256": "22e3aa1c80e0ada3722fe5b63fd43d9c8990759d0a2cf489c8c5d7b2bdebc021", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "8.0.0" + }, + "built_collection": { + "dependency": "transitive", + "description": { + "name": "built_collection", + "sha256": "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "5.1.1" + }, + "built_value": { + "dependency": "transitive", + "description": { + "name": "built_value", + "sha256": "a30f0a0e38671e89a492c44d005b5545b830a961575bbd8336d42869ff71066d", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "8.12.0" + }, + "characters": { + "dependency": "transitive", + "description": { + "name": "characters", + "sha256": "f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.4.0" + }, + "checked_yaml": { + "dependency": "transitive", + "description": { + "name": "checked_yaml", + "sha256": "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.0.4" + }, + "ci": { + "dependency": "transitive", + "description": { + "name": "ci", + "sha256": "145d095ce05cddac4d797a158bc4cf3b6016d1fe63d8c3d2fbd7212590adca13", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.1.0" + }, + "cli_util": { + "dependency": "transitive", + "description": { + "name": "cli_util", + "sha256": "ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.4.2" + }, + "clock": { + "dependency": "direct main", + "description": { + "name": "clock", + "sha256": "fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.1.2" + }, + "code_builder": { + "dependency": "transitive", + "description": { + "name": "code_builder", + "sha256": "11654819532ba94c34de52ff5feb52bd81cba1de00ef2ed622fd50295f9d4243", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "4.11.0" + }, + "collection": { + "dependency": "direct main", + "description": { + "name": "collection", + "sha256": "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.19.1" + }, + "convert": { + "dependency": "transitive", + "description": { + "name": "convert", + "sha256": "b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.1.2" + }, + "crypto": { + "dependency": "transitive", + "description": { + "name": "crypto", + "sha256": "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.0.6" + }, + "csv": { + "dependency": "transitive", + "description": { + "name": "csv", + "sha256": "c6aa2679b2a18cb57652920f674488d89712efaf4d3fdf2e537215b35fc19d6c", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "6.0.0" + }, + "cupertino_icons": { + "dependency": "direct main", + "description": { + "name": "cupertino_icons", + "sha256": "caac504f942f41dfadcf45229ce8c47065b93919a12739f20d6173a883c5ec73", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.0.2" + }, + "custom_lint": { + "dependency": "direct dev", + "description": { + "name": "custom_lint", + "sha256": "9656925637516c5cf0f5da018b33df94025af2088fe09c8ae2ca54c53f2d9a84", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.7.6" + }, + "custom_lint_builder": { + "dependency": "transitive", + "description": { + "name": "custom_lint_builder", + "sha256": "6cdc8e87e51baaaba9c43e283ed8d28e59a0c4732279df62f66f7b5984655414", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.7.6" + }, + "custom_lint_core": { + "dependency": "transitive", + "description": { + "name": "custom_lint_core", + "sha256": "31110af3dde9d29fb10828ca33f1dce24d2798477b167675543ce3d208dee8be", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.7.5" + }, + "custom_lint_visitor": { + "dependency": "transitive", + "description": { + "name": "custom_lint_visitor", + "sha256": "4a86a0d8415a91fbb8298d6ef03e9034dc8e323a599ddc4120a0e36c433983a2", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.0.0+7.7.0" + }, + "dart_style": { + "dependency": "transitive", + "description": { + "name": "dart_style", + "sha256": "8a0e5fba27e8ee025d2ffb4ee820b4e6e2cf5e4246a6b1a477eb66866947e0bb", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.1.1" + }, + "fake_async": { + "dependency": "direct dev", + "description": { + "name": "fake_async", + "sha256": "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.3.3" + }, + "faker": { + "dependency": "direct main", + "description": { + "name": "faker", + "sha256": "544c34e9e1d322824156d5a8d451bc1bb778263b892aded24ec7ba77b0706624", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.2.0" + }, + "ffi": { + "dependency": "transitive", + "description": { + "name": "ffi", + "sha256": "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.1.4" + }, + "file": { + "dependency": "transitive", + "description": { + "name": "file", + "sha256": "a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "7.0.1" + }, + "fixnum": { + "dependency": "direct main", + "description": { + "name": "fixnum", + "sha256": "b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.1.1" + }, + "flutter": { + "dependency": "direct main", + "description": "flutter", + "source": "sdk", + "version": "0.0.0" + }, + "flutter_driver": { + "dependency": "transitive", + "description": "flutter", + "source": "sdk", + "version": "0.0.0" + }, + "flutter_lints": { + "dependency": "direct dev", + "description": { + "name": "flutter_lints", + "sha256": "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "6.0.0" + }, + "flutter_localizations": { + "dependency": "transitive", + "description": "flutter", + "source": "sdk", + "version": "0.0.0" + }, + "flutter_riverpod": { + "dependency": "direct main", + "description": { + "name": "flutter_riverpod", + "sha256": "9532ee6db4a943a1ed8383072a2e3eeda041db5657cdf6d2acecf3c21ecbe7e1", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.6.1" + }, + "flutter_svg": { + "dependency": "direct main", + "description": { + "name": "flutter_svg", + "sha256": "c200fd79c918a40c5cd50ea0877fa13f81bdaf6f0a5d3dbcc2a13e3285d6aa1b", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.0.17" + }, + "flutter_test": { + "dependency": "direct dev", + "description": "flutter", + "source": "sdk", + "version": "0.0.0" + }, + "flutter_web_plugins": { + "dependency": "direct main", + "description": "flutter", + "source": "sdk", + "version": "0.0.0" + }, + "freezed": { + "dependency": "direct dev", + "description": { + "name": "freezed", + "sha256": "d2581edbd572e6e7c50eac5a9b91022a26200e08a7f5a82dcf70f070c0e2cb67", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.0.0" + }, + "freezed_annotation": { + "dependency": "direct main", + "description": { + "name": "freezed_annotation", + "sha256": "c87ff004c8aa6af2d531668b46a4ea379f7191dc6dfa066acd53d506da6e044b", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.0.0" + }, + "frontend_server_client": { + "dependency": "transitive", + "description": { + "name": "frontend_server_client", + "sha256": "f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "4.0.0" + }, + "fuchsia_remote_debug_protocol": { + "dependency": "transitive", + "description": "flutter", + "source": "sdk", + "version": "0.0.0" + }, + "get_it": { + "dependency": "direct main", + "description": { + "name": "get_it", + "sha256": "e87cd1d108e472a0580348a543a0c49ed3d70c8a5c809c6d418583e595d0a389", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "8.1.0" + }, + "glob": { + "dependency": "transitive", + "description": { + "name": "glob", + "sha256": "c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.1.3" + }, + "go_router": { + "dependency": "direct main", + "description": { + "name": "go_router", + "sha256": "c489908a54ce2131f1d1b7cc631af9c1a06fac5ca7c449e959192089f9489431", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "16.0.0" + }, + "google_identity_services_web": { + "dependency": "transitive", + "description": { + "name": "google_identity_services_web", + "sha256": "5d187c46dc59e02646e10fe82665fc3884a9b71bc1c90c2b8b749316d33ee454", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.3.3+1" + }, + "googleapis_auth": { + "dependency": "transitive", + "description": { + "name": "googleapis_auth", + "sha256": "b81fe352cc4a330b3710d2b7ad258d9bcef6f909bb759b306bf42973a7d046db", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.0.0" + }, + "graphs": { + "dependency": "transitive", + "description": { + "name": "graphs", + "sha256": "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.3.2" + }, + "grpc": { + "dependency": "direct main", + "description": { + "name": "grpc", + "sha256": "05ee99647485380706daee6342bcd3b5bc78a9f39d8d3d77798546554886956e", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "4.3.0" + }, + "hotreloader": { + "dependency": "transitive", + "description": { + "name": "hotreloader", + "sha256": "bc167a1163807b03bada490bfe2df25b0d744df359227880220a5cbd04e5734b", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "4.3.0" + }, + "http": { + "dependency": "direct main", + "description": { + "name": "http", + "sha256": "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.4.0" + }, + "http2": { + "dependency": "transitive", + "description": { + "name": "http2", + "sha256": "382d3aefc5bd6dc68c6b892d7664f29b5beb3251611ae946a98d35158a82bbfa", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.3.1" + }, + "http_multi_server": { + "dependency": "transitive", + "description": { + "name": "http_multi_server", + "sha256": "aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.2.2" + }, + "http_parser": { + "dependency": "transitive", + "description": { + "name": "http_parser", + "sha256": "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "4.1.2" + }, + "integration_test": { + "dependency": "direct dev", + "description": "flutter", + "source": "sdk", + "version": "0.0.0" + }, + "intl": { + "dependency": "direct main", + "description": { + "name": "intl", + "sha256": "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.20.2" + }, + "io": { + "dependency": "transitive", + "description": { + "name": "io", + "sha256": "dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.0.5" + }, + "js": { + "dependency": "transitive", + "description": { + "name": "js", + "sha256": "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.7.2" + }, + "json_annotation": { + "dependency": "transitive", + "description": { + "name": "json_annotation", + "sha256": "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "4.9.0" + }, + "leak_tracker": { + "dependency": "transitive", + "description": { + "name": "leak_tracker", + "sha256": "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "11.0.2" + }, + "leak_tracker_flutter_testing": { + "dependency": "direct dev", + "description": { + "name": "leak_tracker_flutter_testing", + "sha256": "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.0.10" + }, + "leak_tracker_testing": { + "dependency": "transitive", + "description": { + "name": "leak_tracker_testing", + "sha256": "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.0.2" + }, + "lints": { + "dependency": "transitive", + "description": { + "name": "lints", + "sha256": "a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "6.0.0" + }, + "logger": { + "dependency": "direct main", + "description": { + "name": "logger", + "sha256": "697d067c60c20999686a0add96cf6aba723b3aa1f83ecf806a8097231529ec32", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.4.0" + }, + "logging": { + "dependency": "transitive", + "description": { + "name": "logging", + "sha256": "c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.3.0" + }, + "matcher": { + "dependency": "transitive", + "description": { + "name": "matcher", + "sha256": "dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.12.17" + }, + "material_color_utilities": { + "dependency": "transitive", + "description": { + "name": "material_color_utilities", + "sha256": "f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.11.1" + }, + "meta": { + "dependency": "transitive", + "description": { + "name": "meta", + "sha256": "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.17.0" + }, + "mime": { + "dependency": "transitive", + "description": { + "name": "mime", + "sha256": "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.0.0" + }, + "package_config": { + "dependency": "transitive", + "description": { + "name": "package_config", + "sha256": "f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.2.0" + }, + "package_info_plus": { + "dependency": "direct main", + "description": { + "name": "package_info_plus", + "sha256": "7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "8.3.0" + }, + "package_info_plus_platform_interface": { + "dependency": "transitive", + "description": { + "name": "package_info_plus_platform_interface", + "sha256": "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.2.1" + }, + "path": { + "dependency": "direct main", + "description": { + "name": "path", + "sha256": "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.9.1" + }, + "path_parsing": { + "dependency": "transitive", + "description": { + "name": "path_parsing", + "sha256": "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.1.0" + }, + "path_provider_linux": { + "dependency": "transitive", + "description": { + "name": "path_provider_linux", + "sha256": "f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.2.1" + }, + "path_provider_platform_interface": { + "dependency": "transitive", + "description": { + "name": "path_provider_platform_interface", + "sha256": "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.1.2" + }, + "path_provider_windows": { + "dependency": "transitive", + "description": { + "name": "path_provider_windows", + "sha256": "bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.3.0" + }, + "petitparser": { + "dependency": "transitive", + "description": { + "name": "petitparser", + "sha256": "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "7.0.1" + }, + "platform": { + "dependency": "transitive", + "description": { + "name": "platform", + "sha256": "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.1.6" + }, + "plugin_platform_interface": { + "dependency": "direct dev", + "description": { + "name": "plugin_platform_interface", + "sha256": "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.1.8" + }, + "pool": { + "dependency": "transitive", + "description": { + "name": "pool", + "sha256": "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.5.1" + }, + "posix": { + "dependency": "direct main", + "description": { + "name": "posix", + "sha256": "a0117dc2167805aa9125b82eee515cc891819bac2f538c83646d355b16f58b9a", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "6.0.1" + }, + "process": { + "dependency": "transitive", + "description": { + "name": "process", + "sha256": "107d8be718f120bbba9dcd1e95e3bd325b1b4a4f07db64154635ba03f2567a0d", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "5.0.3" + }, + "protobuf": { + "dependency": "direct main", + "description": { + "name": "protobuf", + "sha256": "2fcc8a202ca7ec17dab7c97d6b6d91cf03aa07fe6f65f8afbb6dfa52cc5bd902", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "5.1.0" + }, + "pub_semver": { + "dependency": "transitive", + "description": { + "name": "pub_semver", + "sha256": "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.2.0" + }, + "pubspec_parse": { + "dependency": "transitive", + "description": { + "name": "pubspec_parse", + "sha256": "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.5.0" + }, + "riverpod": { + "dependency": "direct main", + "description": { + "name": "riverpod", + "sha256": "59062512288d3056b2321804332a13ffdd1bf16df70dcc8e506e411280a72959", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.6.1" + }, + "riverpod_analyzer_utils": { + "dependency": "transitive", + "description": { + "name": "riverpod_analyzer_utils", + "sha256": "03a17170088c63aab6c54c44456f5ab78876a1ddb6032ffde1662ddab4959611", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.5.10" + }, + "riverpod_annotation": { + "dependency": "direct main", + "description": { + "name": "riverpod_annotation", + "sha256": "e14b0bf45b71326654e2705d462f21b958f987087be850afd60578fcd502d1b8", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.6.1" + }, + "riverpod_generator": { + "dependency": "direct dev", + "description": { + "name": "riverpod_generator", + "sha256": "44a0992d54473eb199ede00e2260bd3c262a86560e3c6f6374503d86d0580e36", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.6.5" + }, + "riverpod_lint": { + "dependency": "direct dev", + "description": { + "name": "riverpod_lint", + "sha256": "89a52b7334210dbff8605c3edf26cfe69b15062beed5cbfeff2c3812c33c9e35", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.6.5" + }, + "rxdart": { + "dependency": "transitive", + "description": { + "name": "rxdart", + "sha256": "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.28.0" + }, + "screen_retriever": { + "dependency": "transitive", + "description": { + "name": "screen_retriever", + "sha256": "570dbc8e4f70bac451e0efc9c9bb19fa2d6799a11e6ef04f946d7886d2e23d0c", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.2.0" + }, + "screen_retriever_linux": { + "dependency": "transitive", + "description": { + "name": "screen_retriever_linux", + "sha256": "f7f8120c92ef0784e58491ab664d01efda79a922b025ff286e29aa123ea3dd18", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.2.0" + }, + "screen_retriever_macos": { + "dependency": "transitive", + "description": { + "name": "screen_retriever_macos", + "sha256": "71f956e65c97315dd661d71f828708bd97b6d358e776f1a30d5aa7d22d78a149", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.2.0" + }, + "screen_retriever_platform_interface": { + "dependency": "transitive", + "description": { + "name": "screen_retriever_platform_interface", + "sha256": "ee197f4581ff0d5608587819af40490748e1e39e648d7680ecf95c05197240c0", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.2.0" + }, + "screen_retriever_windows": { + "dependency": "transitive", + "description": { + "name": "screen_retriever_windows", + "sha256": "449ee257f03ca98a57288ee526a301a430a344a161f9202b4fcc38576716fe13", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.2.0" + }, + "searchable_listview": { + "dependency": "direct main", + "description": { + "name": "searchable_listview", + "sha256": "4d6fc66d51254d306ecd01677649f62ad86f7a31fc64c17ab6f4977b6db5a605", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.19.3" + }, + "shared_preferences": { + "dependency": "direct main", + "description": { + "name": "shared_preferences", + "sha256": "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.5.3" + }, + "shared_preferences_android": { + "dependency": "transitive", + "description": { + "name": "shared_preferences_android", + "sha256": "a2608114b1ffdcbc9c120eb71a0e207c71da56202852d4aab8a5e30a82269e74", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.4.12" + }, + "shared_preferences_foundation": { + "dependency": "transitive", + "description": { + "name": "shared_preferences_foundation", + "sha256": "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.5.4" + }, + "shared_preferences_linux": { + "dependency": "transitive", + "description": { + "name": "shared_preferences_linux", + "sha256": "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.4.1" + }, + "shared_preferences_platform_interface": { + "dependency": "direct dev", + "description": { + "name": "shared_preferences_platform_interface", + "sha256": "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.4.1" + }, + "shared_preferences_web": { + "dependency": "transitive", + "description": { + "name": "shared_preferences_web", + "sha256": "c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.4.3" + }, + "shared_preferences_windows": { + "dependency": "transitive", + "description": { + "name": "shared_preferences_windows", + "sha256": "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.4.1" + }, + "shelf": { + "dependency": "transitive", + "description": { + "name": "shelf", + "sha256": "e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.4.2" + }, + "shelf_web_socket": { + "dependency": "transitive", + "description": { + "name": "shelf_web_socket", + "sha256": "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.0.0" + }, + "sky_engine": { + "dependency": "transitive", + "description": "flutter", + "source": "sdk", + "version": "0.0.0" + }, + "slang": { + "dependency": "direct main", + "description": { + "name": "slang", + "sha256": "bc9488b19acbc4756aa60a9de19720045f9d49a4a7524d56475e0a6965bcd8bd", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "4.7.3" + }, + "slang_flutter": { + "dependency": "direct main", + "description": { + "name": "slang_flutter", + "sha256": "fff13b6fc8b0378ee23856c4f9fd7f8e2777b430090681f4d19ab14c47de9bc6", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "4.7.0" + }, + "source_gen": { + "dependency": "transitive", + "description": { + "name": "source_gen", + "sha256": "35c8150ece9e8c8d263337a265153c3329667640850b9304861faea59fc98f6b", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.0.0" + }, + "source_helper": { + "dependency": "transitive", + "description": { + "name": "source_helper", + "sha256": "a447acb083d3a5ef17f983dd36201aeea33fedadb3228fa831f2f0c92f0f3aca", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.3.7" + }, + "source_span": { + "dependency": "transitive", + "description": { + "name": "source_span", + "sha256": "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.10.1" + }, + "sprintf": { + "dependency": "transitive", + "description": { + "name": "sprintf", + "sha256": "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "7.0.0" + }, + "stack_trace": { + "dependency": "transitive", + "description": { + "name": "stack_trace", + "sha256": "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.12.1" + }, + "state_notifier": { + "dependency": "transitive", + "description": { + "name": "state_notifier", + "sha256": "b8677376aa54f2d7c58280d5a007f9e8774f1968d1fb1c096adcb4792fba29bb", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.0.0" + }, + "stream_channel": { + "dependency": "transitive", + "description": { + "name": "stream_channel", + "sha256": "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.1.4" + }, + "stream_transform": { + "dependency": "transitive", + "description": { + "name": "stream_transform", + "sha256": "ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.1.1" + }, + "string_scanner": { + "dependency": "transitive", + "description": { + "name": "string_scanner", + "sha256": "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.4.1" + }, + "sync_http": { + "dependency": "transitive", + "description": { + "name": "sync_http", + "sha256": "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.3.1" + }, + "term_glyph": { + "dependency": "transitive", + "description": { + "name": "term_glyph", + "sha256": "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.2.2" + }, + "test_api": { + "dependency": "transitive", + "description": { + "name": "test_api", + "sha256": "ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.7.7" + }, + "theme_tailor": { + "dependency": "direct dev", + "description": { + "name": "theme_tailor", + "sha256": "ba98be1d04856deef932757a3ca8fa7a5e2a6f96c30466a59c48924eeb608b97", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.0.3" + }, + "theme_tailor_annotation": { + "dependency": "direct main", + "description": { + "name": "theme_tailor_annotation", + "sha256": "0d5ecd13a6a52add2082aa60497179f6093acf482eb69e7fa3a9f37eb990ac34", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.0.2" + }, + "timing": { + "dependency": "transitive", + "description": { + "name": "timing", + "sha256": "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.0.2" + }, + "typed_data": { + "dependency": "transitive", + "description": { + "name": "typed_data", + "sha256": "f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.4.0" + }, + "url_launcher": { + "dependency": "direct main", + "description": { + "name": "url_launcher", + "sha256": "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "6.3.0" + }, + "url_launcher_android": { + "dependency": "transitive", + "description": { + "name": "url_launcher_android", + "sha256": "81777b08c498a292d93ff2feead633174c386291e35612f8da438d6e92c4447e", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "6.3.20" + }, + "url_launcher_ios": { + "dependency": "transitive", + "description": { + "name": "url_launcher_ios", + "sha256": "d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "6.3.4" + }, + "url_launcher_linux": { + "dependency": "transitive", + "description": { + "name": "url_launcher_linux", + "sha256": "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.2.1" + }, + "url_launcher_macos": { + "dependency": "transitive", + "description": { + "name": "url_launcher_macos", + "sha256": "c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.2.3" + }, + "url_launcher_platform_interface": { + "dependency": "direct dev", + "description": { + "name": "url_launcher_platform_interface", + "sha256": "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.3.2" + }, + "url_launcher_web": { + "dependency": "transitive", + "description": { + "name": "url_launcher_web", + "sha256": "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.4.1" + }, + "url_launcher_windows": { + "dependency": "transitive", + "description": { + "name": "url_launcher_windows", + "sha256": "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.1.4" + }, + "uuid": { + "dependency": "transitive", + "description": { + "name": "uuid", + "sha256": "a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "4.5.1" + }, + "vector_graphics": { + "dependency": "transitive", + "description": { + "name": "vector_graphics", + "sha256": "a4f059dc26fc8295b5921376600a194c4ec7d55e72f2fe4c7d2831e103d461e6", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.1.19" + }, + "vector_graphics_codec": { + "dependency": "transitive", + "description": { + "name": "vector_graphics_codec", + "sha256": "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.1.13" + }, + "vector_graphics_compiler": { + "dependency": "transitive", + "description": { + "name": "vector_graphics_compiler", + "sha256": "d354a7ec6931e6047785f4db12a1f61ec3d43b207fc0790f863818543f8ff0dc", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.1.19" + }, + "vector_math": { + "dependency": "transitive", + "description": { + "name": "vector_math", + "sha256": "d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "2.2.0" + }, + "vm_service": { + "dependency": "transitive", + "description": { + "name": "vm_service", + "sha256": "ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "15.0.0" + }, + "watcher": { + "dependency": "transitive", + "description": { + "name": "watcher", + "sha256": "5bf046f41320ac97a469d506261797f35254fa61c641741ef32dacda98b7d39c", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.1.3" + }, + "web": { + "dependency": "transitive", + "description": { + "name": "web", + "sha256": "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.1.1" + }, + "web_socket": { + "dependency": "transitive", + "description": { + "name": "web_socket", + "sha256": "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.0.1" + }, + "web_socket_channel": { + "dependency": "transitive", + "description": { + "name": "web_socket_channel", + "sha256": "d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.0.3" + }, + "webdriver": { + "dependency": "transitive", + "description": { + "name": "webdriver", + "sha256": "2f3a14ca026957870cfd9c635b83507e0e51d8091568e90129fbf805aba7cade", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.1.0" + }, + "win32": { + "dependency": "transitive", + "description": { + "name": "win32", + "sha256": "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "5.14.0" + }, + "window_manager": { + "dependency": "direct main", + "description": { + "name": "window_manager", + "sha256": "7eb6d6c4164ec08e1bf978d6e733f3cebe792e2a23fb07cbca25c2872bfdbdcd", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "0.5.1" + }, + "xdg_directories": { + "dependency": "transitive", + "description": { + "name": "xdg_directories", + "sha256": "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "1.1.0" + }, + "xml": { + "dependency": "transitive", + "description": { + "name": "xml", + "sha256": "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "6.6.1" + }, + "yaml": { + "dependency": "transitive", + "description": { + "name": "yaml", + "sha256": "b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce", + "url": "https://pub.dev" + }, + "source": "hosted", + "version": "3.1.3" + } + }, + "sdks": { + "dart": ">=3.10.0 <3.10.1", + "flutter": ">=3.29.0" + } +}