From 2fa9d9eccedd4ca78526dd8f5b299954e39cb5fd Mon Sep 17 00:00:00 2001 From: Maxwell Becker <49575486+mbecker20@users.noreply.github.com> Date: Sun, 17 Aug 2025 17:25:45 -0700 Subject: [PATCH] 1.19.0 (#722) * start 1.18.5 * prevent empty additional permission check (ie for new resources) * dev-2 * bump rust to 1.88 * tweaks * repo based stack commit happens from core repo cache rather than on server to simplify * clippy auto fix * clippy lints periphery * clippy fix komodo_client * dev-3 * emphasize ferret version pinning * bump svi with PR fix * dev-4 * webhook disabled early return * Fix missing alert types for whitelist * add "ScheduleRun" * fix status cache not cleaning on resource delete * dev-5 * forgot to pipe through poll in previous refactor * refetch given in ms * fix configure build extra args * reorder resource sync config * Implement ability to run actions at startup (#664) * Implement ability to run actions at startup * run post-startup actions after server is listening * startup use action query * fmt * Fix Google Login enabled message (#668) - it was showing "Github Login" instead of "Google Login" * Allow CIDR ranges in Allowed IPs (#666) * Allow CIDR ranges in Allowed IPs * Catch mixed IPv4/IPv6 mappings that are probably intended to match * forgiving vec * dev-6 * forgiving vec log. allowed ips docs * server stats UI: move current disk breakdown above charts * searchable container stats, toggle collaple container / disk sections * Add Clear repo cache method * fix execute usage docs * Komodo managed env-file should take precedence in all cases (ie come last in env file list) * tag include unused flag for future use * combine users page search * util backup / restore * refactor backup/restore duplication * cleanup restore * core image include util binary * dev-7 * back to LinesCodec * dev-8 * clean up * clean up logs * rename to komodo-util * dev-9 * enable_fance_toml * dev-10 enable fancy toml * add user agent to oidc requests (#701) Co-authored-by: eleith * fmt * use database library * clippy lint * consolidate and standardize cli * dev-11 * dev-12 implement backup using cli * dev-13 logs * command variant fields need to be #[arg] * tweak cli * gen client * fix terminal reconnect issue * rename cli to `km` * tweaks for the cli logs * wait for enter on --yes empty println * fix --yes * dev-15 * bump deps * update croner to latest, use static parser * dev-16 * cli execute polls updates until complete before logging * remove repo cache mount * cli nice * /backup -> /backups * dev-17 config loading preserves CONFIG_PATHS precedence * update dockerfile default docker cli config keywords * dev-18 * support .kmignore * add ignores log * Implement automatic backup pruning, default 14 backups before prune * db copy / restore uses idempotent upsert * cli update variable - "km set var VAR value" * improve cli initial logs * time the executions * implement update for most resources * dev 20 * add update page * dev 21 support cli update link * dev-22 test the deploy * dev-23 use indexmap * install-cli.py * Frontend mobile fixes (#714) * Allow ResourcePageHeader items to wrap * Allow CardHeader items to wrap * Increase z-index of sticky TableHeader, fixes #690 * Remove fixed widths from ActionButton, let them flex more to fit more layouts * Make Section scroll overflow * Remove grid class from Tabs, seems to prevent them from overflowing at small sizes * deploy 1.18.5-dev-24 * auto version increment and deploy * cli: profiles support aliases and merge on top of Default (root) config * fix page set titles * rust 1.89 and improve config logs * skip serializing for proper merge * fix clippy lints re 1.89 * remove layouts overflow-x-scroll * deploy 1.18.5-dev-25 * 1.89 docker images not ready yet * km cfg -a (print all profiles) * include commit variables * skip serializing profiles when empty * skip serialize default db / log configs * km cfg --debug print mode * correct defaults for CLI and only can pass restore folder from cli arg * some more skip serialization * db restore / copy index optional * add runfile command aliases * remove second schedule updating loop, can causes some schedules to be missed * deploy 1.18.5-dev-26 * add log when target db indexing disabled * cli: user password reset, update user super admin * Add manual network interface configuration for multi-NIC Docker environments (#719) * Add iproute2 to debian-debs * feat: Add manual network interface configuration for multi-NIC support Complete implementation of manual interface configuration: - Add internet_interface config option - Implement manual gateway routing - Add NET_ADMIN capability requirement - Clean up codebase changes * fix: Update internet interface handling for multi-NIC support * refactor: Enhance error messages and logging in networking module * refactor: Simplify interface argument handling and improve logging in network configuration and cleanup * refactor(network): simplify startup integration and improve error handling - Move config access and error handling into network::configure_internet_gateway() - Simplify startup.rs to single function call without parameters - Remove redundant check_network_privileges() function - Improve error handling by checking actual command output instead of pre-validation - Better separation of concerns between startup and network modules Addresses feedback from PR discussion: https://github.com/moghtech/komodo/pull/719#discussion_r2261542921 * fix(config): update default internet interface setting Addresses feedback from PR discussion: https://github.com/moghtech/komodo/pull/719#discussion_r2261552279 * fix(config): remove custom default for internet interface in CoreConfig * move mod.rs -> network.rs Addresses feedback from PR discussion: https://github.com/moghtech/komodo/pull/719#discussion_r2261558332 * add internet interface example * docs(build-images): document multi-platform builds with Docker Buildx (#721) * docs(build-images): add multi-platform buildx guide to builders.md * docs(build-images): add multi-platform buildx guide and clarify platform selection in Komodo UI Extra Args field * move to 1.19.0 * core support reading from multiple config files * config support yaml * deploy 1.19.0-dev-1 * deploy 1.19.0-dev-2 * add default komodo cli config * better config merge with base * no need to panic if empty config paths * improve km --help * prog on cli docs * tweak cli docs * tweak doc * split the runfile commands * update docsite deps * km ps initial * km ls * list resource apis * km con inspect * deploy 1.19.0-dev-3 * fix: need serde default * dev-4 fix container parsing issue * tweak * use include-based file finding for much faster discovery * just move to standard config dir .config/komodo/komodo.cli.* * update fe w/ new contianer info minimal serialization * add links to table names * deploy 1.19.0-dev-5 * links in tables * backend for Action arguments * deploy 1.19.0-dev-6 * deploy 1.19.0-dev-7 * deploy 1.19.0-dev-8 * no space at front of KeyValue default args * webhook branch / body optional * The incoming arguments * deploy 1.19.0-dev-9 * con -> cn * add config -> cf alias * .kmignore * .peripheryinclude * outdated * optional links, configurable table format * table_format -> table_borders * get types * include docsite in yarn install * update runnables command in docs * tweak * improve km ls only show important stuff * Add BackupCoreDatabase * deploy 1.19.0-dev-10 * backup command needs "--yes" * deploy 1.19.0-dev-11 * update rustc 1.89.0 * cli tweak * try chef * Fix chef (after dependencies) * try other compile command * fix * fix comment * cleanup stats page * ensure database backup procedure * UI allow configure Backup Core Database in Procedures * procedure description * deploy 1.19.0-dev-12 * deploy 1.19.0-dev-13 * GlobalAutoUpdate * deploy 1.19.0-dev-14 * default tags and global auto update procedure * deploy 1.19.0-dev-15 * trim the default procedure descriptions * deploy 1.19.0-dev-16 * in "system" theme, also poll for updates to the theme based on time. * Add next run to Action / Procedure column * km ls support filter by templates * fix procedure toml serialization when params = {} * deploy 1.19.0-dev-17 * KOMODO_INIT_ADMIN_USERNAME * KOMODO_FIRST_SERVER_NAME * add server.config.external_address for use with links * deploy 1.19.0-dev-18 * improve auto prune * fix system theme auto update * deploy 1.19.0-dev-19 * rename auth/CreateLocalUser -> SignUpLocalUser. Add write/CreateLocalUser for in-ui initialization. * deploy 1.19.0-dev-20 * UI can handle multiple active logins * deploy 1.19.0-dev-21 * fix * add logout function * fix oauth redirect * fix multi user exchange token function * default external address * just Add * style account switcher * backup and restore docs * rework docsite file / sidebar structure, start auto update docs * auto update docs * tweak * fix doc links * only pull / update running stacks / deployments images * deploy 1.19.0-dev-22 * deploy 1.19.0-dev-23 * fix #737 * community docs * add BackupCoreDatabase link to docs * update ferret v2 update guide using komodo-cli * fix data table headers overlapping topbar * don't alert when deploying * CommitSync returns Update * deploy 1.19.0-dev-24 * trim the decoded branch * action uses file contents deserializer * deploy 1.19.0-dev-25 * remove Toml from action args format * clarify External Address purpose * Fix podman compatibility in `get_container_stats` (#739) * Add podman compability for querying stats Podman and docker stats differ in results in significant ways but this filter change they will output the same stats * syntax fix * feat(dashboard): display CPU, memory, and disk usage on server cards (#729) * feat: mini-stats-card: Expose Server CPU , Memory, Disk Usage to Dashboard View * comment: resolved * Feat: fix overflow card , DRY stats-mini, add unreachable mini stats * lint: fix * deploy 1.19.0-dev-26 * 1.19.0 * linux, macos container install * cli main config --------- Co-authored-by: Brian Bradley Co-authored-by: Daniel Co-authored-by: eleith Co-authored-by: eleith Co-authored-by: Sam Edwards Co-authored-by: Marcel Pfennig <82059270+MP-Tool@users.noreply.github.com> Co-authored-by: itsmesid <693151+arevindh@users.noreply.github.com> Co-authored-by: mbecker20 Co-authored-by: Rhyn Co-authored-by: Anh Nguyen --- .gitignore | 2 +- .kminclude | 1 + Cargo.lock | 1441 +- Cargo.toml | 58 +- bin/binaries.Dockerfile | 8 +- bin/chef.binaries.Dockerfile | 34 + bin/cli/Cargo.toml | 24 +- bin/{util => cli}/aio.Dockerfile | 14 +- bin/{util => cli}/docs/copy-database.md | 24 +- bin/{util => cli}/multi-arch.Dockerfile | 16 +- bin/cli/runfile.toml | 4 + bin/{util => cli}/single-arch.Dockerfile | 10 +- bin/cli/src/args.rs | 55 - bin/cli/src/command/container.rs | 312 + bin/cli/src/command/database.rs | 320 + bin/cli/src/{exec.rs => command/execute.rs} | 290 +- bin/cli/src/command/list.rs | 1171 ++ bin/cli/src/command/mod.rs | 181 + bin/cli/src/command/update/mod.rs | 43 + bin/cli/src/command/update/resource.rs | 152 + bin/cli/src/command/update/user.rs | 122 + bin/cli/src/command/update/variable.rs | 70 + bin/cli/src/config.rs | 274 + bin/cli/src/helpers.rs | 17 - bin/cli/src/main.rs | 86 +- bin/cli/src/state.rs | 48 - bin/core/Cargo.toml | 8 +- bin/core/aio.Dockerfile | 19 +- bin/core/debian-deps.sh | 4 +- bin/core/multi-arch.Dockerfile | 26 +- bin/core/single-arch.Dockerfile | 13 +- bin/core/src/alert/discord.rs | 3 +- bin/core/src/alert/mod.rs | 41 +- bin/core/src/alert/ntfy.rs | 54 +- bin/core/src/alert/pushover.rs | 51 +- bin/core/src/alert/slack.rs | 3 +- bin/core/src/api/auth.rs | 11 +- bin/core/src/api/execute/action.rs | 65 +- bin/core/src/api/execute/build.rs | 20 +- bin/core/src/api/execute/maintenance.rs | 319 + bin/core/src/api/execute/mod.rs | 12 +- bin/core/src/api/execute/procedure.rs | 6 +- bin/core/src/api/execute/repo.rs | 20 +- bin/core/src/api/execute/stack.rs | 38 +- bin/core/src/api/execute/sync.rs | 6 +- bin/core/src/api/read/alert.rs | 10 +- bin/core/src/api/read/alerter.rs | 4 +- bin/core/src/api/read/build.rs | 8 +- bin/core/src/api/read/builder.rs | 4 +- bin/core/src/api/read/mod.rs | 1 + bin/core/src/api/read/permission.rs | 2 +- bin/core/src/api/read/provider.rs | 6 +- bin/core/src/api/read/server.rs | 8 +- bin/core/src/api/read/tag.rs | 6 +- bin/core/src/api/read/toml.rs | 2 +- bin/core/src/api/read/update.rs | 10 +- bin/core/src/api/read/user.rs | 10 +- bin/core/src/api/read/user_group.rs | 4 +- bin/core/src/api/read/variable.rs | 6 +- bin/core/src/api/user.rs | 10 +- bin/core/src/api/write/build.rs | 4 +- bin/core/src/api/write/deployment.rs | 4 +- bin/core/src/api/write/mod.rs | 1 + bin/core/src/api/write/permissions.rs | 16 +- bin/core/src/api/write/provider.rs | 72 +- bin/core/src/api/write/repo.rs | 8 +- bin/core/src/api/write/service_user.rs | 8 +- bin/core/src/api/write/stack.rs | 316 +- bin/core/src/api/write/sync.rs | 62 +- bin/core/src/api/write/tag.rs | 24 +- bin/core/src/api/write/user.rs | 133 +- bin/core/src/api/write/user_group.rs | 10 +- bin/core/src/api/write/variable.rs | 2 +- bin/core/src/auth/github/mod.rs | 6 +- bin/core/src/auth/google/mod.rs | 6 +- bin/core/src/auth/jwt.rs | 27 +- bin/core/src/auth/local.rs | 50 +- bin/core/src/auth/mod.rs | 2 +- bin/core/src/auth/oidc/mod.rs | 8 +- bin/core/src/config.rs | 84 +- bin/core/src/helpers/action_state.rs | 2 +- bin/core/src/helpers/builder.rs | 3 +- bin/core/src/helpers/cache.rs | 59 +- bin/core/src/helpers/mod.rs | 13 +- bin/core/src/helpers/procedure.rs | 58 +- bin/core/src/helpers/prune.rs | 40 +- bin/core/src/helpers/query.rs | 14 +- bin/core/src/helpers/update.rs | 21 +- bin/core/src/listener/integrations/github.rs | 15 +- bin/core/src/listener/integrations/gitlab.rs | 15 +- bin/core/src/listener/mod.rs | 18 +- bin/core/src/listener/resources.rs | 91 +- bin/core/src/listener/router.rs | 4 +- bin/core/src/main.rs | 20 +- bin/core/src/monitor/alert/deployment.rs | 21 +- bin/core/src/monitor/alert/server.rs | 12 +- bin/core/src/monitor/alert/stack.rs | 17 +- bin/core/src/monitor/mod.rs | 2 +- bin/core/src/network.rs | 312 + bin/core/src/permission.rs | 22 +- bin/core/src/resource/action.rs | 14 +- bin/core/src/resource/alerter.rs | 2 +- bin/core/src/resource/build.rs | 57 +- bin/core/src/resource/builder.rs | 19 +- bin/core/src/resource/deployment.rs | 54 +- bin/core/src/resource/mod.rs | 69 +- bin/core/src/resource/procedure.rs | 30 +- bin/core/src/resource/refresh.rs | 46 +- bin/core/src/resource/repo.rs | 74 +- bin/core/src/resource/server.rs | 3 +- bin/core/src/resource/stack.rs | 54 +- bin/core/src/resource/sync.rs | 28 +- bin/core/src/schedule.rs | 45 +- bin/core/src/stack/mod.rs | 6 +- bin/core/src/stack/remote.rs | 8 +- bin/core/src/stack/services.rs | 7 +- bin/core/src/startup.rs | 262 +- bin/core/src/state.rs | 10 +- bin/core/src/sync/deploy.rs | 2 +- bin/core/src/sync/execute.rs | 2 +- bin/core/src/sync/file.rs | 32 +- bin/core/src/sync/mod.rs | 2 +- bin/core/src/sync/resources.rs | 28 +- bin/core/src/sync/toml.rs | 17 +- bin/core/src/sync/user_groups.rs | 2 +- bin/core/src/sync/variables.rs | 2 +- bin/core/src/sync/view.rs | 2 +- bin/periphery/Cargo.toml | 7 +- bin/periphery/aio.Dockerfile | 8 +- bin/periphery/debian-deps.sh | 2 +- bin/periphery/multi-arch.Dockerfile | 6 +- bin/periphery/single-arch.Dockerfile | 6 +- bin/periphery/src/api/build.rs | 12 +- bin/periphery/src/api/compose.rs | 24 +- bin/periphery/src/api/container.rs | 14 +- bin/periphery/src/api/mod.rs | 4 +- bin/periphery/src/api/router.rs | 16 +- bin/periphery/src/api/terminal.rs | 11 +- bin/periphery/src/build.rs | 10 +- bin/periphery/src/compose/up.rs | 14 +- bin/periphery/src/config.rs | 42 +- bin/periphery/src/docker/stats.rs | 48 +- bin/periphery/src/git.rs | 80 +- bin/periphery/src/helpers.rs | 2 +- bin/periphery/src/stats.rs | 4 +- bin/periphery/src/terminal.rs | 20 +- bin/util/Cargo.toml | 23 - bin/util/src/copy_database.rs | 131 - bin/util/src/main.rs | 42 - client/core/rs/Cargo.toml | 4 +- client/core/rs/src/api/auth.rs | 17 +- client/core/rs/src/api/execute/action.rs | 14 +- client/core/rs/src/api/execute/build.rs | 9 +- client/core/rs/src/api/execute/maintenance.rs | 73 + client/core/rs/src/api/execute/mod.rs | 24 + client/core/rs/src/api/read/mod.rs | 2 + client/core/rs/src/api/write/tags.rs | 2 + client/core/rs/src/api/write/user.rs | 25 + .../rs/src/deserializers/forgiving_vec.rs | 95 + client/core/rs/src/deserializers/mod.rs | 2 + client/core/rs/src/entities/action.rs | 42 +- client/core/rs/src/entities/alerter.rs | 10 +- client/core/rs/src/entities/build.rs | 16 +- .../src/entities/config/cli/args/container.rs | 72 + .../src/entities/config/cli/args/database.rs | 73 + .../rs/src/entities/config/cli/args/list.rs | 161 + .../rs/src/entities/config/cli/args/mod.rs | 138 + .../rs/src/entities/config/cli/args/update.rs | 86 + client/core/rs/src/entities/config/cli/mod.rs | 334 + client/core/rs/src/entities/config/core.rs | 271 +- client/core/rs/src/entities/config/mod.rs | 98 +- .../core/rs/src/entities/config/periphery.rs | 64 +- client/core/rs/src/entities/deployment.rs | 12 +- .../core/rs/src/entities/docker/container.rs | 45 +- client/core/rs/src/entities/docker/stats.rs | 2 +- client/core/rs/src/entities/logger.rs | 26 +- client/core/rs/src/entities/mod.rs | 99 +- client/core/rs/src/entities/procedure.rs | 16 +- client/core/rs/src/entities/resource.rs | 15 +- client/core/rs/src/entities/server.rs | 34 +- client/core/rs/src/entities/stack.rs | 10 +- client/core/rs/src/entities/sync.rs | 20 +- client/core/rs/src/entities/tag.rs | 24 +- client/core/rs/src/lib.rs | 3 +- client/core/ts/package.json | 2 +- client/core/ts/runfile.toml | 3 + client/core/ts/src/lib.ts | 8 +- client/core/ts/src/responses.ts | 16 +- client/core/ts/src/types.ts | 202 +- compose/compose.env | 8 + compose/ferretdb.compose.yaml | 18 +- compose/mongo.compose.yaml | 14 +- config/core.config.toml | 41 +- config/komodo.cli.toml | 79 + config/periphery.config.toml | 10 +- deploy/deno.json | 1 + deploy/komodo.ts | 50 + docsite/docs/{ => ecosystem}/api.md | 0 docsite/docs/ecosystem/cli.mdx | 121 + .../community.md} | 5 +- docsite/docs/{ => ecosystem}/development.md | 16 +- docsite/docs/ecosystem/index.mdx | 11 + docsite/docs/file-paths.md | 30 - docsite/docs/resources/auto-update.md | 47 + .../{ => resources}/build-images/builders.md | 45 + .../build-images/configuration.md | 4 +- .../{ => resources}/build-images/index.mdx | 0 .../{ => resources}/build-images/pre-build.md | 0 .../build-images/versioning.md | 0 .../deploy-containers/configuration.md | 0 .../deploy-containers/index.mdx | 0 .../deploy-containers/lifetime-management.md | 0 .../docs/{ => resources}/docker-compose.md | 0 .../docs/{resources.md => resources/index.md} | 16 +- docsite/docs/{ => resources}/permissioning.md | 0 docsite/docs/{ => resources}/procedures.md | 3 +- .../docs/{ => resources}/sync-resources.md | 0 docsite/docs/{ => resources}/variables.md | 4 +- docsite/docs/{ => resources}/webhooks.md | 0 docsite/docs/setup/advanced.mdx | 5 + docsite/docs/setup/backup.md | 127 + docsite/docs/{ => setup}/connect-servers.mdx | 25 +- docsite/docs/setup/ferretdb.mdx | 2 +- docsite/docs/setup/index.mdx | 2 +- docsite/docs/setup/mongo.mdx | 4 +- docsite/docs/{ => setup}/version-upgrades.md | 0 docsite/package-lock.json | 14649 ---------------- docsite/package.json | 22 +- docsite/runfile.toml | 8 + docsite/sidebars.ts | 88 +- docsite/yarn.lock | 3556 ++-- example/alerter/Dockerfile | 2 +- example/update_logger/Dockerfile | 2 +- frontend/public/client/lib.d.ts | 8 +- frontend/public/client/lib.js | 8 +- frontend/public/client/responses.d.ts | 12 +- frontend/public/client/types.d.ts | 225 +- frontend/public/client/types.js | 36 +- frontend/public/index.d.ts | 5 + frontend/runfile.toml | 10 + frontend/src/components/alert/topbar.tsx | 89 - frontend/src/components/export.tsx | 2 +- frontend/src/components/layouts.tsx | 6 +- frontend/src/components/log.tsx | 10 +- frontend/src/components/monaco.tsx | 18 +- .../components/resources/action/config.tsx | 78 + .../src/components/resources/action/index.tsx | 2 +- .../src/components/resources/action/table.tsx | 22 + .../resources/alerter/config/alert_types.tsx | 7 +- .../src/components/resources/build/config.tsx | 2 +- .../src/components/resources/build/index.tsx | 1 - frontend/src/components/resources/common.tsx | 2 +- .../components/resources/deployment/index.tsx | 109 +- .../components/resources/deployment/log.tsx | 46 +- .../components/resources/procedure/config.tsx | 13 + .../components/resources/procedure/index.tsx | 2 +- .../components/resources/procedure/table.tsx | 28 +- .../resources/resource-sync/config.tsx | 502 +- .../resources/resource-sync/index.tsx | 2 +- .../resources/resource-sync/info.tsx | 4 +- .../resources/resource-sync/pending.tsx | 24 +- .../components/resources/server/config.tsx | 28 +- .../src/components/resources/server/index.tsx | 4 +- .../resources/server/stats-mini.tsx | 115 + .../src/components/resources/server/stats.tsx | 344 +- .../src/components/resources/stack/index.tsx | 2 +- .../src/components/resources/stack/log.tsx | 52 +- .../components/resources/stack/services.tsx | 6 +- frontend/src/components/topbar.tsx | 308 - frontend/src/components/topbar/components.tsx | 614 + frontend/src/components/topbar/index.tsx | 57 + frontend/src/components/updates/details.tsx | 21 +- frontend/src/components/updates/topbar.tsx | 115 - frontend/src/components/users/new.tsx | 66 + frontend/src/components/util.tsx | 58 +- frontend/src/lib/dashboard-preferences.ts | 31 + frontend/src/lib/hooks.ts | 188 +- frontend/src/lib/socket.tsx | 2 +- frontend/src/main.tsx | 4 - frontend/src/monaco/fancy_toml.ts | 240 + frontend/src/monaco/index.ts | 1 + frontend/src/monaco/toml.ts | 609 +- frontend/src/pages/containers.tsx | 8 +- frontend/src/pages/home/dashboard.tsx | 61 +- frontend/src/pages/login.tsx | 81 +- .../src/pages/server-info/container/index.tsx | 91 +- .../src/pages/server-info/container/log.tsx | 50 +- frontend/src/pages/settings/users.tsx | 62 +- frontend/src/pages/stack-service/index.tsx | 99 +- frontend/src/pages/stack-service/log.tsx | 50 +- frontend/src/pages/update.tsx | 16 + frontend/src/pages/updates.tsx | 109 +- frontend/src/pages/user_disabled.tsx | 5 +- frontend/src/router.tsx | 60 +- frontend/src/ui/card.tsx | 2 +- frontend/src/ui/data-table.tsx | 2 +- frontend/src/ui/theme.tsx | 17 + lib/config/Cargo.toml | 19 + lib/config/src/error.rs | 62 + lib/config/src/includes.rs | 57 + lib/config/src/lib.rs | 118 + lib/config/src/load.rs | 197 + lib/config/src/merge.rs | 93 + lib/database/Cargo.toml | 25 + bin/core/src/db.rs => lib/database/src/lib.rs | 155 +- lib/database/src/utils/backup.rs | 143 + lib/database/src/utils/copy.rs | 90 + lib/database/src/utils/mod.rs | 7 + lib/database/src/utils/restore.rs | 206 + lib/environment/src/lib.rs | 17 +- lib/environment_file/src/lib.rs | 2 +- lib/formatting/src/lib.rs | 18 +- lib/git/src/clone.rs | 17 +- lib/logger/src/lib.rs | 12 +- runfile.toml | 39 +- scripts/install-cli.py | 67 + scripts/setup-periphery.py | 4 +- 317 files changed, 14544 insertions(+), 21431 deletions(-) create mode 100644 .kminclude create mode 100644 bin/chef.binaries.Dockerfile rename bin/{util => cli}/aio.Dockerfile (55%) rename bin/{util => cli}/docs/copy-database.md (82%) rename bin/{util => cli}/multi-arch.Dockerfile (67%) create mode 100644 bin/cli/runfile.toml rename bin/{util => cli}/single-arch.Dockerfile (71%) delete mode 100644 bin/cli/src/args.rs create mode 100644 bin/cli/src/command/container.rs create mode 100644 bin/cli/src/command/database.rs rename bin/cli/src/{exec.rs => command/execute.rs} (63%) create mode 100644 bin/cli/src/command/list.rs create mode 100644 bin/cli/src/command/mod.rs create mode 100644 bin/cli/src/command/update/mod.rs create mode 100644 bin/cli/src/command/update/resource.rs create mode 100644 bin/cli/src/command/update/user.rs create mode 100644 bin/cli/src/command/update/variable.rs create mode 100644 bin/cli/src/config.rs delete mode 100644 bin/cli/src/helpers.rs delete mode 100644 bin/cli/src/state.rs create mode 100644 bin/core/src/api/execute/maintenance.rs create mode 100644 bin/core/src/network.rs delete mode 100644 bin/util/Cargo.toml delete mode 100644 bin/util/src/copy_database.rs delete mode 100644 bin/util/src/main.rs create mode 100644 client/core/rs/src/api/execute/maintenance.rs create mode 100644 client/core/rs/src/deserializers/forgiving_vec.rs create mode 100644 client/core/rs/src/entities/config/cli/args/container.rs create mode 100644 client/core/rs/src/entities/config/cli/args/database.rs create mode 100644 client/core/rs/src/entities/config/cli/args/list.rs create mode 100644 client/core/rs/src/entities/config/cli/args/mod.rs create mode 100644 client/core/rs/src/entities/config/cli/args/update.rs create mode 100644 client/core/rs/src/entities/config/cli/mod.rs create mode 100644 client/core/ts/runfile.toml create mode 100644 config/komodo.cli.toml create mode 100644 deploy/deno.json create mode 100755 deploy/komodo.ts rename docsite/docs/{ => ecosystem}/api.md (100%) create mode 100644 docsite/docs/ecosystem/cli.mdx rename docsite/docs/{other-resources.md => ecosystem/community.md} (84%) rename docsite/docs/{ => ecosystem}/development.md (72%) create mode 100644 docsite/docs/ecosystem/index.mdx delete mode 100644 docsite/docs/file-paths.md create mode 100644 docsite/docs/resources/auto-update.md rename docsite/docs/{ => resources}/build-images/builders.md (61%) rename docsite/docs/{ => resources}/build-images/configuration.md (95%) rename docsite/docs/{ => resources}/build-images/index.mdx (100%) rename docsite/docs/{ => resources}/build-images/pre-build.md (100%) rename docsite/docs/{ => resources}/build-images/versioning.md (100%) rename docsite/docs/{ => resources}/deploy-containers/configuration.md (100%) rename docsite/docs/{ => resources}/deploy-containers/index.mdx (100%) rename docsite/docs/{ => resources}/deploy-containers/lifetime-management.md (100%) rename docsite/docs/{ => resources}/docker-compose.md (100%) rename docsite/docs/{resources.md => resources/index.md} (88%) rename docsite/docs/{ => resources}/permissioning.md (100%) rename docsite/docs/{ => resources}/procedures.md (95%) rename docsite/docs/{ => resources}/sync-resources.md (100%) rename docsite/docs/{ => resources}/variables.md (92%) rename docsite/docs/{ => resources}/webhooks.md (100%) create mode 100644 docsite/docs/setup/backup.md rename docsite/docs/{ => setup}/connect-servers.mdx (77%) rename docsite/docs/{ => setup}/version-upgrades.md (100%) delete mode 100644 docsite/package-lock.json create mode 100644 docsite/runfile.toml create mode 100644 frontend/runfile.toml delete mode 100644 frontend/src/components/alert/topbar.tsx create mode 100644 frontend/src/components/resources/server/stats-mini.tsx delete mode 100644 frontend/src/components/topbar.tsx create mode 100644 frontend/src/components/topbar/components.tsx create mode 100644 frontend/src/components/topbar/index.tsx delete mode 100644 frontend/src/components/updates/topbar.tsx create mode 100644 frontend/src/lib/dashboard-preferences.ts create mode 100644 frontend/src/monaco/fancy_toml.ts create mode 100644 frontend/src/pages/update.tsx create mode 100644 lib/config/Cargo.toml create mode 100644 lib/config/src/error.rs create mode 100644 lib/config/src/includes.rs create mode 100644 lib/config/src/lib.rs create mode 100644 lib/config/src/load.rs create mode 100644 lib/config/src/merge.rs create mode 100644 lib/database/Cargo.toml rename bin/core/src/db.rs => lib/database/src/lib.rs (54%) create mode 100644 lib/database/src/utils/backup.rs create mode 100644 lib/database/src/utils/copy.rs create mode 100644 lib/database/src/utils/mod.rs create mode 100644 lib/database/src/utils/restore.rs create mode 100644 scripts/install-cli.py diff --git a/.gitignore b/.gitignore index d49f1f2d9..cbab6a9c3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ target node_modules dist +deno.lock .env .env.development .DS_Store @@ -9,5 +10,4 @@ dist /frontend/build /lib/ts_client/build -creds.toml .dev diff --git a/.kminclude b/.kminclude new file mode 100644 index 000000000..6def9c2bd --- /dev/null +++ b/.kminclude @@ -0,0 +1 @@ +.dev \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index fd6c188ad..35bc7aabf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,21 +13,21 @@ dependencies = [ [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.2.16", + "getrandom 0.3.3", "once_cell", "version_check 0.9.5", - "zerocopy 0.7.35", + "zerocopy", ] [[package]] @@ -56,9 +56,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.18" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" dependencies = [ "anstyle", "anstyle-parse", @@ -71,44 +71,44 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" dependencies = [ "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.7" +version = "3.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" dependencies = [ "anstyle", - "once_cell", + "once_cell_polyfill", "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.98" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" [[package]] name = "arc-swap" @@ -116,6 +116,19 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" +[[package]] +name = "async-compression" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddb939d66e4ae03cee6091612804ba446b12878410cfa17f785f4dd67d4014e8" +dependencies = [ + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + [[package]] name = "async-recursion" version = "1.1.1" @@ -124,7 +137,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -135,7 +148,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -159,15 +172,15 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-config" -version = "1.8.0" +version = "1.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455e9fb7743c6f6267eb2830ccc08686fbb3d13c9a689369562fd4d4ef9ea462" +checksum = "c478f5b10ce55c9a33f87ca3404ca92768b144fc1bfdede7c0121214a8283a25" dependencies = [ "aws-credential-types", "aws-runtime", @@ -195,9 +208,9 @@ dependencies = [ [[package]] name = "aws-credential-types" -version = "1.2.3" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "687bc16bc431a8533fe0097c7f0182874767f920989d7260950172ae8e3c4465" +checksum = "1541072f81945fa1251f8795ef6c92c4282d74d59f88498ae7d4bf00f0ebdad9" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -207,9 +220,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.13.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b756939cb2f8dc900aa6dcd505e6e2428e9cae7ff7b028c49e3946efa70878" +checksum = "08b5d4e069cbc868041a64bd68dc8cb39a0d79585cd6c5a24caa8c2d622121be" dependencies = [ "aws-lc-sys", "zeroize", @@ -217,9 +230,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.28.2" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa9b6986f250236c27e5a204062434a773a13243d2ffc2955f37bdba4c5c6a1" +checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff" dependencies = [ "bindgen", "cc", @@ -230,9 +243,9 @@ dependencies = [ [[package]] name = "aws-runtime" -version = "1.5.8" +version = "1.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f6c68419d8ba16d9a7463671593c54f81ba58cab466e9b759418da606dcc2e2" +checksum = "c034a1bc1d70e16e7f4e4caf7e9f7693e4c9c24cd91cf17c2a0b21abaebc7c8b" dependencies = [ "aws-credential-types", "aws-sigv4", @@ -254,9 +267,9 @@ dependencies = [ [[package]] name = "aws-sdk-ec2" -version = "1.139.0" +version = "1.159.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b92e3d00f89108bc36102fcb4f23fb0b59ee12a6dc62156c27ce40e42337127" +checksum = "ed753fc534bbb68760d5b2e3e46f81e5ccb9a96d8359b9ce793e123cb3073e8e" dependencies = [ "aws-credential-types", "aws-runtime", @@ -277,9 +290,9 @@ dependencies = [ [[package]] name = "aws-sdk-sso" -version = "1.73.0" +version = "1.81.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ac1674cba7872061a29baaf02209fefe499ff034dfd91bd4cc59e4d7741489" +checksum = "79ede098271e3471036c46957cba2ba30888f53bda2515bf04b560614a30a36e" dependencies = [ "aws-credential-types", "aws-runtime", @@ -299,9 +312,9 @@ dependencies = [ [[package]] name = "aws-sdk-ssooidc" -version = "1.74.0" +version = "1.82.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a6a22f077f5fd3e3c0270d4e1a110346cddf6769e9433eb9e6daceb4ca3b149" +checksum = "43326f724ba2cc957e6f3deac0ca1621a3e5d4146f5970c24c8a108dac33070f" dependencies = [ "aws-credential-types", "aws-runtime", @@ -321,9 +334,9 @@ dependencies = [ [[package]] name = "aws-sdk-sts" -version = "1.74.0" +version = "1.83.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d440e1d368759bd10df0dbdddbfff6473d7cd73e9d9ef2363dc9995ac2d711" +checksum = "a5468593c47efc31fdbe6c902d1a5fde8d9c82f78a3f8ccfe907b1e9434748cb" dependencies = [ "aws-credential-types", "aws-runtime", @@ -344,9 +357,9 @@ dependencies = [ [[package]] name = "aws-sigv4" -version = "1.3.3" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfb9021f581b71870a17eac25b52335b82211cdc092e02b6876b2bcefa61666" +checksum = "084c34162187d39e3740cb635acd73c4e3a551a36146ad6fe8883c929c9f876c" dependencies = [ "aws-credential-types", "aws-smithy-http", @@ -377,9 +390,9 @@ dependencies = [ [[package]] name = "aws-smithy-http" -version = "0.62.1" +version = "0.62.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99335bec6cdc50a346fda1437f9fefe33abf8c99060739a546a16457f2862ca9" +checksum = "7c4dacf2d38996cf729f55e7a762b30918229917eca115de45dfa8dfb97796c9" dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", @@ -397,25 +410,26 @@ dependencies = [ [[package]] name = "aws-smithy-http-client" -version = "1.0.1" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8aff1159006441d02e57204bf57a1b890ba68bedb6904ffd2873c1c4c11c546b" +checksum = "f108f1ca850f3feef3009bdcc977be201bca9a91058864d9de0684e64514bee0" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", "aws-smithy-types", - "h2 0.4.9", + "h2 0.3.27", + "h2 0.4.11", "http 0.2.12", "http 1.3.1", "http-body 0.4.6", "hyper 0.14.32", "hyper 1.6.0", "hyper-rustls 0.24.2", - "hyper-rustls 0.27.5", + "hyper-rustls 0.27.7", "hyper-util", "pin-project-lite", "rustls 0.21.12", - "rustls 0.23.27", + "rustls 0.23.31", "rustls-native-certs 0.8.1", "rustls-pki-types", "tokio", @@ -453,9 +467,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.8.3" +version = "1.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14302f06d1d5b7d333fd819943075b13d27c7700b414f574c3c35859bfb55d5e" +checksum = "9e107ce0783019dbff59b3a244aa0c114e4a8c9d93498af9162608cd5474e796" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -477,9 +491,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api" -version = "1.8.1" +version = "1.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd8531b6d8882fd8f48f82a9754e682e29dd44cff27154af51fa3eb730f59efb" +checksum = "75d52251ed4b9776a3e8487b2a01ac915f73b2da3af8fc1e77e0fce697a550d4" dependencies = [ "aws-smithy-async", "aws-smithy-types", @@ -529,9 +543,9 @@ dependencies = [ [[package]] name = "aws-types" -version = "1.3.7" +version = "1.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a322fec39e4df22777ed3ad8ea868ac2f94cd15e1a55f6ee8d8d6305057689a" +checksum = "b069d19bf01e46298eaedd7c6f283fe565a59263e53eebec945f3e6398f42390" dependencies = [ "aws-credential-types", "aws-smithy-async", @@ -630,7 +644,7 @@ checksum = "604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -647,7 +661,7 @@ dependencies = [ "hyper 1.6.0", "hyper-util", "pin-project-lite", - "rustls 0.23.27", + "rustls 0.23.31", "rustls-pemfile 2.2.0", "rustls-pki-types", "tokio", @@ -657,9 +671,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.74" +version = "0.3.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" dependencies = [ "addr2line", "cfg-if", @@ -706,9 +720,9 @@ dependencies = [ [[package]] name = "base64ct" -version = "1.7.3" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "bcrypt" @@ -718,7 +732,7 @@ checksum = "92758ad6077e4c76a6cadbce5005f666df70d4f13b19976b1a8062eef880040f" dependencies = [ "base64 0.22.1", "blowfish", - "getrandom 0.3.2", + "getrandom 0.3.3", "subtle", "zeroize", ] @@ -729,7 +743,7 @@ version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "cexpr", "clang-sys", "itertools 0.12.1", @@ -742,7 +756,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.100", + "syn 2.0.104", "which", ] @@ -754,9 +768,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "bitvec" @@ -791,9 +805,9 @@ dependencies = [ [[package]] name = "bollard" -version = "0.19.1" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899ca34eb6924d6ec2a77c6f7f5c7339e60fd68235eaf91edd5a15f12958bb06" +checksum = "8796b390a5b4c86f9f2e8173a68c2791f4fa6b038b84e96dbc01c016d1e6722c" dependencies = [ "base64 0.22.1", "bollard-stubs", @@ -814,7 +828,7 @@ dependencies = [ "serde_json", "serde_repr", "serde_urlencoded", - "thiserror 2.0.12", + "thiserror 2.0.14", "tokio", "tokio-util", "tower-service", @@ -824,9 +838,9 @@ dependencies = [ [[package]] name = "bollard-stubs" -version = "1.48.3-rc.28.0.4" +version = "1.49.0-rc.28.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ea257e555d16a2c01e5593f40b73865cdf12efbceda33c6d14a2d8d1490368" +checksum = "2e7814991259013d5a5bee4ae28657dae0747d843cf06c40f7fc0c2894d6fa38" dependencies = [ "serde", "serde_json", @@ -844,12 +858,12 @@ dependencies = [ "base64 0.22.1", "bitvec", "getrandom 0.2.16", - "getrandom 0.3.2", + "getrandom 0.3.3", "hex", - "indexmap 2.9.0", + "indexmap 2.10.0", "js-sys", "once_cell", - "rand 0.9.1", + "rand 0.9.2", "serde", "serde_bytes", "serde_json", @@ -859,9 +873,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.17.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "byteorder" @@ -890,7 +904,7 @@ dependencies = [ [[package]] name = "cache" -version = "1.18.4" +version = "1.19.0" dependencies = [ "anyhow", "tokio", @@ -898,9 +912,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.19" +version = "1.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362" +checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362" dependencies = [ "jobserver", "libc", @@ -918,9 +932,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "cfg_aliases" @@ -951,25 +965,14 @@ dependencies = [ [[package]] name = "chrono-tz" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efdce149c370f133a071ca8ef6ea340b7b88748ab0810097a9e2976eaa34b4f3" +checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3" dependencies = [ "chrono", - "chrono-tz-build", "phf", ] -[[package]] -name = "chrono-tz-build" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f10f8c9340e31fc120ff885fcdb54a0b48e474bbd77cab557f0c30a3e569402" -dependencies = [ - "parse-zoneinfo", - "phf_codegen", -] - [[package]] name = "cipher" version = "0.4.4" @@ -993,9 +996,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.40" +version = "4.5.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" +checksum = "50fd97c9dc2399518aa331917ac6f274280ec5eb34e555dd291899745c48ec6f" dependencies = [ "clap_builder", "clap_derive", @@ -1003,9 +1006,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.40" +version = "4.5.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" +checksum = "c35b5830294e1fa0462034af85cc95225a4cb07092c088c55bda3147cfcd8f65" dependencies = [ "anstream", "anstyle", @@ -1015,21 +1018,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.40" +version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" +checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] name = "clap_lex" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "cmake" @@ -1042,9 +1045,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "colored" @@ -1055,15 +1058,41 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "comfy-table" +version = "7.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a65ebfec4fb190b6f90e944a817d60499ee0744e582530e2c9900a22e591d9a" +dependencies = [ + "crossterm", + "unicode-segmentation", + "unicode-width", +] + [[package]] name = "command" -version = "1.18.4" +version = "1.19.0" dependencies = [ "komodo_client", "run_command", "svi", ] +[[package]] +name = "config" +version = "1.19.0" +dependencies = [ + "colored", + "indexmap 2.10.0", + "regex", + "serde", + "serde_json", + "serde_yaml_ng", + "thiserror 2.0.14", + "toml", + "wildcard", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -1108,9 +1137,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" dependencies = [ "core-foundation-sys", "libc", @@ -1132,12 +1161,23 @@ dependencies = [ ] [[package]] -name = "croner" -version = "2.1.0" +name = "crc32fast" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38fd53511eaf0b00a185613875fee58b208dfce016577d0ad4bb548e1c4fb3ee" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "croner" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c007081651a19b42931f86f7d4f74ee1c2a7d0cd2c6636a81695b5ffd4e9990" dependencies = [ "chrono", + "derive_builder", + "strum 0.27.2", ] [[package]] @@ -1147,10 +1187,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] -name = "crunchy" -version = "0.2.3" +name = "crossterm" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +dependencies = [ + "bitflags 2.9.1", + "crossterm_winapi", + "parking_lot 0.12.4", + "rustix", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" @@ -1176,9 +1238,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.3" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +checksum = "373b7c5dbd637569a2cca66e8d66b8c446a1e7bf064ea321d265d7b3dfe7c97e" dependencies = [ "cfg-if", "cpufeatures", @@ -1198,7 +1260,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1222,7 +1284,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1233,7 +1295,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1247,7 +1309,7 @@ dependencies = [ "hashbrown 0.14.5", "lock_api", "once_cell", - "parking_lot_core 0.9.10", + "parking_lot_core 0.9.11", ] [[package]] @@ -1256,6 +1318,24 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" +[[package]] +name = "database" +version = "1.19.0" +dependencies = [ + "anyhow", + "async-compression", + "bcrypt", + "chrono", + "futures-util", + "komodo_client", + "mongo_indexed", + "mungos", + "serde_json", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "der" version = "0.7.10" @@ -1285,18 +1365,18 @@ checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] name = "derive-where" -version = "1.3.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2364b9aa47e460ce9bca6ac1777d14c98eef7e274eb077beed49f3adc94183ed" +checksum = "510c292c8cf384b1a340b816a9a6cf2599eb8f566a44949024af88418000c50b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1317,7 +1397,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1327,7 +1407,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1347,7 +1427,7 @@ checksum = "9e520b61247a9470ec86a98baf2aebae5c6dd0f25f02b1c87cafe45b06c160e7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1358,7 +1438,7 @@ checksum = "12c90da6aa09bad94e4411461560183be70bb33bc30efb2ce941492f22ed6850" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1371,7 +1451,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1392,7 +1472,7 @@ checksum = "1bceb8b4ad480f8cf02ae4efb42c95add230544b4239d543cbd9f9141d838581" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1415,7 +1495,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1468,9 +1548,9 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" dependencies = [ "curve25519-dalek", "ed25519", @@ -1534,12 +1614,12 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] name = "environment" -version = "1.18.4" +version = "1.19.0" dependencies = [ "anyhow", "formatting", @@ -1549,9 +1629,9 @@ dependencies = [ [[package]] name = "environment_file" -version = "1.18.4" +version = "1.19.0" dependencies = [ - "thiserror 2.0.12", + "thiserror 2.0.14", ] [[package]] @@ -1571,12 +1651,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.11" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -1597,9 +1677,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.9" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" [[package]] name = "filedescriptor" @@ -1612,6 +1692,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "flate2" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1629,16 +1719,16 @@ dependencies = [ [[package]] name = "formatting" -version = "1.18.4" +version = "1.19.0" dependencies = [ "serror", ] [[package]] name = "fs-err" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f89bda4c2a21204059a977ed3bfe746677dfd137b83c339e702b0ac91d482aa" +checksum = "88d7be93788013f265201256d58f04936a8079ad5dc898743aa20525f503b683" dependencies = [ "autocfg", "tokio", @@ -1712,7 +1802,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1765,15 +1855,15 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "js-sys", @@ -1791,7 +1881,7 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "git" -version = "1.18.4" +version = "1.19.0" dependencies = [ "anyhow", "cache", @@ -1822,9 +1912,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" dependencies = [ "bytes", "fnv", @@ -1832,7 +1922,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.9.0", + "indexmap 2.10.0", "slab", "tokio", "tokio-util", @@ -1841,9 +1931,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75249d144030531f8dee69fe9cea04d3edf809a017ae445e2abdff6629e86633" +checksum = "17da50a276f1e01e0ba6c029e47b7100754904ee8a278f886546e98575380785" dependencies = [ "atomic-waker", "bytes", @@ -1851,7 +1941,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.3.1", - "indexmap 2.9.0", + "indexmap 2.10.0", "slab", "tokio", "tokio-util", @@ -1881,17 +1971,17 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" [[package]] name = "headers" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9" +checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "bytes", "headers-core", "http 1.3.1", @@ -1957,7 +2047,7 @@ dependencies = [ "ipconfig", "lru-cache", "once_cell", - "parking_lot 0.12.3", + "parking_lot 0.12.4", "rand 0.8.5", "resolv-conf", "smallvec", @@ -1993,17 +2083,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "hostname" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56f203cd1c76362b69e3863fd987520ac36cf70a8c92627449b2f64a8cf7d65" -dependencies = [ - "cfg-if", - "libc", - "windows-link", -] - [[package]] name = "http" version = "0.2.12" @@ -2088,14 +2167,14 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.3.26", + "h2 0.3.27", "http 0.2.12", "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.5.10", "tokio", "tower-service", "tracing", @@ -2111,7 +2190,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.9", + "h2 0.4.11", "http 1.3.1", "http-body 1.0.1", "httparse", @@ -2156,21 +2235,20 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.5" +version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "futures-util", "http 1.3.1", "hyper 1.6.0", "hyper-util", - "rustls 0.23.27", + "rustls 0.23.31", "rustls-native-certs 0.8.1", "rustls-pki-types", "tokio", "tokio-rustls 0.26.2", "tower-service", - "webpki-roots 0.26.8", + "webpki-roots 1.0.1", ] [[package]] @@ -2188,9 +2266,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb" +checksum = "7f66d5bd4c6f02bf0542fad85d626775bab9258cf795a4256dcaf3161114d1df" dependencies = [ "base64 0.22.1", "bytes", @@ -2204,7 +2282,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2", + "socket2 0.5.10", "system-configuration", "tokio", "tower-service", @@ -2253,21 +2331,22 @@ dependencies = [ [[package]] name = "icu_collections" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" dependencies = [ "displaydoc", + "potential_utf", "yoke", "zerofrom", "zerovec", ] [[package]] -name = "icu_locid" -version = "1.5.0" +name = "icu_locale_core" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" dependencies = [ "displaydoc", "litemap", @@ -2276,31 +2355,11 @@ dependencies = [ "zerovec", ] -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" - [[package]] name = "icu_normalizer" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" dependencies = [ "displaydoc", "icu_collections", @@ -2308,67 +2367,54 @@ dependencies = [ "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "utf8_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "1.5.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" [[package]] name = "icu_properties" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" dependencies = [ "displaydoc", "icu_collections", - "icu_locid_transform", + "icu_locale_core", "icu_properties_data", "icu_provider", - "tinystr", + "potential_utf", + "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" [[package]] name = "icu_provider" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" dependencies = [ "displaydoc", - "icu_locid", - "icu_provider_macros", + "icu_locale_core", "stable_deref_trait", "tinystr", "writeable", "yoke", "zerofrom", + "zerotrie", "zerovec", ] -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] - [[package]] name = "ident_case" version = "1.0.1" @@ -2388,9 +2434,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -2409,12 +2455,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", - "hashbrown 0.15.2", + "hashbrown 0.15.4", "serde", ] @@ -2441,20 +2487,31 @@ dependencies = [ [[package]] name = "interpolate" -version = "1.18.4" +version = "1.19.0" dependencies = [ "anyhow", "komodo_client", "svi", ] +[[package]] +name = "io-uring" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013" +dependencies = [ + "bitflags 2.9.1", + "cfg-if", + "libc", +] + [[package]] name = "ipconfig" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2", + "socket2 0.5.10", "widestring", "windows-sys 0.48.0", "winreg 0.50.0", @@ -2466,6 +2523,15 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +[[package]] +name = "ipnetwork" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf370abdafd54d13e54a620e8c3e1145f28e46cc9d704bc6d94414559df41763" +dependencies = [ + "serde", +] + [[package]] name = "iri-string" version = "0.7.8" @@ -2521,7 +2587,7 @@ version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" dependencies = [ - "getrandom 0.3.2", + "getrandom 0.3.3", "libc", ] @@ -2552,23 +2618,32 @@ dependencies = [ [[package]] name = "komodo_cli" -version = "1.18.4" +version = "1.19.0" dependencies = [ "anyhow", + "chrono", "clap", "colored", - "futures", + "comfy-table", + "config", + "database", + "dotenvy", + "environment_file", + "envy", + "futures-util", "komodo_client", - "merge_config_files", + "logger", "serde", + "serde_json", + "serde_qs", "tokio", "tracing", - "tracing-subscriber", + "wildcard", ] [[package]] name = "komodo_client" -version = "1.18.4" +version = "1.19.0" dependencies = [ "anyhow", "async_timing_util", @@ -2580,16 +2655,18 @@ dependencies = [ "derive_variants", "envy", "futures", - "indexmap 2.9.0", + "indexmap 2.10.0", + "ipnetwork", "mongo_indexed", "partial_derive2", "reqwest", "resolver_api", "serde", "serde_json", + "serde_qs", "serror", - "strum 0.27.1", - "thiserror 2.0.12", + "strum 0.27.2", + "thiserror 2.0.14", "tokio", "tokio-tungstenite 0.27.0", "tokio-util", @@ -2600,7 +2677,7 @@ dependencies = [ [[package]] name = "komodo_core" -version = "1.18.4" +version = "1.19.0" dependencies = [ "anyhow", "arc-swap", @@ -2616,9 +2693,12 @@ dependencies = [ "cache", "chrono", "chrono-tz", + "colored", "command", + "config", "croner", "dashmap", + "database", "derive_variants", "dotenvy", "english-to-cron", @@ -2629,28 +2709,25 @@ dependencies = [ "git", "hex", "hmac", - "indexmap 2.9.0", + "indexmap 2.10.0", "interpolate", "jsonwebtoken", "komodo_client", "logger", - "merge_config_files", - "mongo_indexed", - "mungos", "nom_pem", "octorust", "openidconnect", "partial_derive2", "periphery_client", - "rand 0.9.1", + "rand 0.9.2", "regex", "reqwest", "resolver_api", "response", - "rustls 0.23.27", + "rustls 0.23.31", "serde", "serde_json", - "serde_yaml", + "serde_yaml_ng", "serror", "sha2", "slack_client_rs", @@ -2670,7 +2747,7 @@ dependencies = [ [[package]] name = "komodo_periphery" -version = "1.18.4" +version = "1.19.0" dependencies = [ "anyhow", "arc-swap", @@ -2681,7 +2758,9 @@ dependencies = [ "bytes", "cache", "clap", + "colored", "command", + "config", "derive_variants", "dotenvy", "environment", @@ -2693,18 +2772,17 @@ dependencies = [ "interpolate", "komodo_client", "logger", - "merge_config_files", "periphery_client", "pin-project-lite", "portable-pty", - "rand 0.9.1", + "rand 0.9.2", "resolver_api", "response", "run_command", - "rustls 0.23.27", + "rustls 0.23.31", "serde", "serde_json", - "serde_yaml", + "serde_yaml_ng", "serror", "sysinfo", "tokio", @@ -2714,21 +2792,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "komodo_util" -version = "1.18.4" -dependencies = [ - "anyhow", - "dotenvy", - "envy", - "futures-util", - "mungos", - "serde", - "tokio", - "tracing", - "tracing-subscriber", -] - [[package]] name = "lazy_static" version = "1.5.0" @@ -2746,25 +2809,25 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.172" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libloading" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.53.2", ] [[package]] name = "libm" -version = "0.2.13" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9627da5196e5d8ed0b0495e61e518847578da83483c37288316d9b2e03a7f72" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "linked-hash-map" @@ -2780,15 +2843,15 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "litemap" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ "autocfg", "scopeguard", @@ -2805,7 +2868,7 @@ dependencies = [ [[package]] name = "logger" -version = "1.18.4" +version = "1.19.0" dependencies = [ "anyhow", "komodo_client", @@ -2827,6 +2890,12 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "macro_magic" version = "0.5.1" @@ -2836,7 +2905,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -2850,7 +2919,7 @@ dependencies = [ "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -2861,7 +2930,7 @@ checksum = "b02abfe41815b5bd98dbd4260173db2c116dda171dc0fe7838cb206333b83308" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -2872,7 +2941,7 @@ checksum = "73ea28ee64b88876bf45277ed9a5817c1817df061a74f2b988971a12570e5869" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -2893,21 +2962,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "merge_config_files" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "268a14a3b7df38fd426624ed6398cc3358ceb0717761c308a095545afd9dda80" -dependencies = [ - "serde", - "serde_json", - "thiserror 1.0.69", - "toml", -] +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "mime" @@ -2933,52 +2990,52 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", ] [[package]] name = "mio" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.52.0", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", ] [[package]] name = "mongo_indexed" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556e2883109599e3cc28c7ad0d700c0b5c297e4d17ae810c669d18f79a02df26" +checksum = "180b469d21b4cdb686c1e98050ec8e1168232f4b54022086668c93dc9839f9ab" dependencies = [ "mongo_indexed_derive", "mongodb", "serde", - "thiserror 1.0.69", + "thiserror 2.0.14", ] [[package]] name = "mongo_indexed_derive" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4f3a4215a0cb95aea5fe33a77d38f0e0f7e7b9bf315bede04e0ea0c46fb704a" +checksum = "cf8405357bf431a2e73d83057f2960e9349ab946389dd78af655832921434949" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] name = "mongodb" -version = "3.2.3" +version = "3.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdf4261933e5113914caec01c4bb16a7502bdaa9cf80fd87191765e7d9ff16b2" +checksum = "d0f8c69f13acf07eae386a2974f48ffd9187ea2aba8defbea9aa34e7e272c5f3" dependencies = [ "async-trait", "base64 0.13.1", @@ -3008,9 +3065,9 @@ dependencies = [ "serde", "serde_bytes", "serde_with", - "sha-1", + "sha1", "sha2", - "socket2", + "socket2 0.5.10", "stringprep", "strsim", "take_mut", @@ -3025,21 +3082,21 @@ dependencies = [ [[package]] name = "mongodb-internal-macros" -version = "3.2.3" +version = "3.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "619176c99deef0d50be51ce3193e9efd6a56ab0f4e6a38d5fd614880d148c7ae" +checksum = "b9202de265a3a8bbb43f9fe56db27c93137d4f9fb04c093f47e9c7de0c61ac7d" dependencies = [ "macro_magic", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] name = "mungos" -version = "3.2.0" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef5f7c37daa675e08ac7db72bd9aea2dfe0762845250a650d8676efa2ad92eee" +checksum = "d2cc7db433516e852091e2ede8cd755a717223a359b519b22710e56225a5d6a9" dependencies = [ "anyhow", "envy", @@ -3055,7 +3112,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "cfg-if", "cfg_aliases 0.1.1", "libc", @@ -3198,7 +3255,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", ] [[package]] @@ -3243,7 +3300,7 @@ dependencies = [ "reqwest-retry", "reqwest-tracing", "ring", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "serde_urlencoded", @@ -3260,10 +3317,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] -name = "openidconnect" -version = "4.0.0" +name = "once_cell_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd50d4a5e7730e754f94d977efe61f611aadd3131f6a2b464f6e3a4167e8ef7" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + +[[package]] +name = "openidconnect" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c6709ba2ea764bbed26bce1adf3c10517113ddea6f2d4196e4851757ef2b2" dependencies = [ "base64 0.21.7", "chrono", @@ -3306,7 +3369,7 @@ dependencies = [ "futures-sink", "js-sys", "pin-project-lite", - "thiserror 2.0.12", + "thiserror 2.0.14", "tracing", ] @@ -3336,7 +3399,7 @@ dependencies = [ "opentelemetry_sdk", "prost", "reqwest", - "thiserror 2.0.12", + "thiserror 2.0.14", "tonic", "tracing", ] @@ -3370,9 +3433,9 @@ dependencies = [ "futures-util", "opentelemetry", "percent-encoding", - "rand 0.9.1", + "rand 0.9.2", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.14", "tokio", "tokio-stream", ] @@ -3445,12 +3508,12 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" dependencies = [ "lock_api", - "parking_lot_core 0.9.10", + "parking_lot_core 0.9.11", ] [[package]] @@ -3469,26 +3532,17 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.11", + "redox_syscall 0.5.13", "smallvec", "windows-targets 0.52.6", ] -[[package]] -name = "parse-zoneinfo" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24" -dependencies = [ - "regex", -] - [[package]] name = "parse_link_header" version = "0.3.3" @@ -3517,7 +3571,7 @@ checksum = "3a506f66d52e40b2385d7b9f776fd5243d6cff16ba79147f859aa4e27d2d27cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -3556,13 +3610,13 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "periphery_client" -version = "1.18.4" +version = "1.19.0" dependencies = [ "anyhow", "komodo_client", "reqwest", "resolver_api", - "rustls 0.23.27", + "rustls 0.23.31", "serde", "serde_json", "serde_qs", @@ -3574,38 +3628,18 @@ dependencies = [ [[package]] name = "phf" -version = "0.11.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" dependencies = [ "phf_shared", ] -[[package]] -name = "phf_codegen" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" -dependencies = [ - "phf_generator", - "phf_shared", -] - -[[package]] -name = "phf_generator" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" -dependencies = [ - "phf_shared", - "rand 0.8.5", -] - [[package]] name = "phf_shared" -version = "0.11.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" dependencies = [ "siphasher", ] @@ -3627,7 +3661,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -3684,6 +3718,15 @@ dependencies = [ "winreg 0.10.1", ] +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -3696,17 +3739,17 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.8.24", + "zerocopy", ] [[package]] name = "prettyplease" -version = "0.2.32" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6" +checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a" dependencies = [ "proc-macro2", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -3747,14 +3790,14 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] name = "quinn" -version = "0.11.7" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012" +checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8" dependencies = [ "bytes", "cfg_aliases 0.2.1", @@ -3762,9 +3805,9 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash 2.1.1", - "rustls 0.23.27", - "socket2", - "thiserror 2.0.12", + "rustls 0.23.31", + "socket2 0.5.10", + "thiserror 2.0.14", "tokio", "tracing", "web-time", @@ -3772,19 +3815,20 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.11" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcbafbbdbb0f638fe3f35f3c56739f77a8a1d070cb25603226c83339b391472b" +checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" dependencies = [ "bytes", - "getrandom 0.3.2", - "rand 0.9.1", + "getrandom 0.3.3", + "lru-slab", + "rand 0.9.2", "ring", "rustc-hash 2.1.1", - "rustls 0.23.27", + "rustls 0.23.31", "rustls-pki-types", "slab", - "thiserror 2.0.12", + "thiserror 2.0.14", "tinyvec", "tracing", "web-time", @@ -3792,14 +3836,14 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.11" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "541d0f57c6ec747a90738a52741d3221f7960e8ac2f0ff4b1a63680e033b4ab5" +checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970" dependencies = [ "cfg_aliases 0.2.1", "libc", "once_cell", - "socket2", + "socket2 0.5.10", "tracing", "windows-sys 0.59.0", ] @@ -3815,9 +3859,9 @@ dependencies = [ [[package]] name = "r-efi" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "radium" @@ -3838,9 +3882,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", @@ -3881,7 +3925,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.2", + "getrandom 0.3.3", ] [[package]] @@ -3895,11 +3939,31 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.11" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", +] + +[[package]] +name = "ref-cast" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", ] [[package]] @@ -3939,9 +4003,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.20" +version = "0.12.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabf4c97d9130e2bf606614eb937e86edac8292eaa6f422f995d7e8de1eb1813" +checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531" dependencies = [ "base64 0.22.1", "bytes", @@ -3949,12 +4013,12 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.4.9", + "h2 0.4.11", "http 1.3.1", "http-body 1.0.1", "http-body-util", "hyper 1.6.0", - "hyper-rustls 0.27.5", + "hyper-rustls 0.27.7", "hyper-util", "js-sys", "log", @@ -3963,7 +4027,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.27", + "rustls 0.23.31", "rustls-native-certs 0.8.1", "rustls-pki-types", "serde", @@ -3981,7 +4045,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 1.0.0", + "webpki-roots 1.0.1", ] [[package]] @@ -4035,9 +4099,9 @@ dependencies = [ [[package]] name = "reqwest-tracing" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75b0eee96990cfb4c09545847385e89b2d2d2e571143d55264a05d77c713780" +checksum = "d70ea85f131b2ee9874f0b160ac5976f8af75f3c9badfe0d955880257d10bd83" dependencies = [ "anyhow", "async-trait", @@ -4051,12 +4115,9 @@ dependencies = [ [[package]] name = "resolv-conf" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48375394603e3dd4b2d64371f7148fd8c7baa2680e28741f2cb8d23b59e3d4c4" -dependencies = [ - "hostname", -] +checksum = "95325155c684b1c89f7765e30bc1c42e4a6da51ca513615660cb8a62ef9a88e3" [[package]] name = "resolver_api" @@ -4075,12 +4136,12 @@ checksum = "e45ff368040e7f3787e97e6f3a97718ca08e0553587747bd4d0bf3ca2b899963" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] name = "response" -version = "1.18.4" +version = "1.19.0" dependencies = [ "anyhow", "axum", @@ -4153,9 +4214,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" [[package]] name = "rustc-hash" @@ -4194,7 +4255,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "errno", "libc", "linux-raw-sys", @@ -4215,16 +4276,16 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.27" +version = "0.23.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321" +checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" dependencies = [ "aws-lc-rs", "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.3", + "rustls-webpki 0.103.4", "subtle", "zeroize", ] @@ -4273,11 +4334,12 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" dependencies = [ "web-time", + "zeroize", ] [[package]] @@ -4292,9 +4354,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.3" +version = "0.103.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" +checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" dependencies = [ "aws-lc-rs", "ring", @@ -4304,9 +4366,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" [[package]] name = "ryu" @@ -4339,6 +4401,30 @@ dependencies = [ "uuid", ] +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + [[package]] name = "schemars_derive" version = "0.8.22" @@ -4348,7 +4434,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -4387,7 +4473,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -4400,8 +4486,8 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" dependencies = [ - "bitflags 2.9.0", - "core-foundation 0.10.0", + "bitflags 2.9.1", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -4459,7 +4545,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -4470,16 +4556,16 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] name = "serde_json" -version = "1.0.140" +version = "1.0.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" dependencies = [ - "indexmap 2.9.0", + "indexmap 2.10.0", "itoa", "memchr", "ryu", @@ -4513,7 +4599,7 @@ checksum = "f3faaf9e727533a19351a43cc5a8de957372163c7d35cc48c90b75cdda13c352" dependencies = [ "percent-encoding", "serde", - "thiserror 2.0.12", + "thiserror 2.0.14", ] [[package]] @@ -4524,14 +4610,14 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] name = "serde_spanned" -version = "0.6.9" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83" dependencies = [ "serde", ] @@ -4550,15 +4636,17 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.12.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" +checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.9.0", + "indexmap 2.10.0", + "schemars 0.9.0", + "schemars 1.0.4", "serde", "serde_derive", "serde_json", @@ -4568,23 +4656,23 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.12.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" +checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" +name = "serde_yaml_ng" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +checksum = "7b4db627b98b36d4203a7b458cf3573730f2bb591b28871d916dfa9efabfd41f" dependencies = [ - "indexmap 2.9.0", + "indexmap 2.10.0", "itoa", "ryu", "serde", @@ -4614,17 +4702,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "sha-1" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - [[package]] name = "sha1" version = "0.10.6" @@ -4705,7 +4782,7 @@ checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" dependencies = [ "num-bigint", "num-traits", - "thiserror 2.0.12", + "thiserror 2.0.14", "time", ] @@ -4717,12 +4794,9 @@ checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "slab" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" [[package]] name = "slack_client_rs" @@ -4735,26 +4809,36 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "strum 0.27.1", + "strum 0.27.2", "strum_macros 0.27.1", ] [[package]] name = "smallvec" -version = "1.15.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", "windows-sys 0.52.0", ] +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "spin" version = "0.9.8" @@ -4802,9 +4886,9 @@ checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" [[package]] name = "strum" -version = "0.27.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" dependencies = [ "strum_macros 0.27.1", ] @@ -4819,7 +4903,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -4832,7 +4916,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -4843,11 +4927,11 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "svi" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d4d1d576ce8f4b01ac90fd0d9f4c95bf5cebbc9c08e89499b152bef770cd98" +checksum = "91bb902c47385644774ba89f7e7982d3a32cf1da4e8870bf633cdece450eced1" dependencies = [ - "thiserror 2.0.12", + "thiserror 2.0.14", ] [[package]] @@ -4863,9 +4947,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.100" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -4883,20 +4967,20 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] name = "sysinfo" -version = "0.35.2" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3ffa3e4ff2b324a57f7aeb3c349656c7b127c3c189520251a648102a92496e" +checksum = "07cec4dc2d2e357ca1e610cfb07de2fa7a10fc3e9fe89f72545f3d244ea87753" dependencies = [ "libc", "memchr", @@ -4912,7 +4996,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -4950,11 +5034,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "0b0949c3a6c842cbde3f1686d6eea5a010516deb7085f79db747562d4102f41e" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.14", ] [[package]] @@ -4965,28 +5049,27 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "cc5b44b4ab9c2fdd0e0512e6bece8388e214c0749f5862b114cc5b7a25daf227" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] name = "thread_local" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ "cfg-if", - "once_cell", ] [[package]] @@ -5031,9 +5114,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.6" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" dependencies = [ "displaydoc", "zerovec", @@ -5056,20 +5139,22 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.45.1" +version = "1.47.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" dependencies = [ "backtrace", "bytes", + "io-uring", "libc", "mio", - "parking_lot 0.12.3", + "parking_lot 0.12.4", "pin-project-lite", "signal-hook-registry", - "socket2", + "slab", + "socket2 0.6.0", "tokio-macros", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -5080,7 +5165,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -5099,7 +5184,7 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ - "rustls 0.23.27", + "rustls 0.23.31", "tokio", ] @@ -5135,7 +5220,7 @@ checksum = "489a59b6730eda1b0171fcfda8b121f4bee2b35cba8645ca35c5f7ba3eb736c1" dependencies = [ "futures-util", "log", - "rustls 0.23.27", + "rustls 0.23.31", "rustls-native-certs 0.8.1", "rustls-pki-types", "tokio", @@ -5145,9 +5230,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.15" +version = "0.7.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" dependencies = [ "bytes", "futures-core", @@ -5159,56 +5244,54 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.23" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8" dependencies = [ + "indexmap 2.10.0", "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_parser", + "toml_writer", + "winnow", ] [[package]] name = "toml_datetime" -version = "0.6.11" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3" dependencies = [ "serde", ] [[package]] -name = "toml_edit" -version = "0.22.27" +name = "toml_parser" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10" dependencies = [ - "indexmap 2.9.0", - "serde", - "serde_spanned", - "toml_datetime", - "toml_write", "winnow", ] [[package]] name = "toml_pretty" -version = "1.1.2" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd412f79539d72f97ac0ec9905b0178be1be4f255ddc2ae6f1ff3f7b234bb870" +checksum = "8dd195be7600b4b26e951a25b382b67a976d2d44bb967a1a5b573a3e63d18c29" dependencies = [ "ordered_hash_map", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.14", ] [[package]] -name = "toml_write" -version = "0.1.2" +name = "toml_writer" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64" [[package]] name = "tonic" @@ -5246,7 +5329,7 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", - "indexmap 2.9.0", + "indexmap 2.10.0", "pin-project-lite", "slab", "sync_wrapper", @@ -5263,7 +5346,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "bytes", "futures-core", "futures-util", @@ -5311,20 +5394,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.28" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", "valuable", @@ -5403,9 +5486,9 @@ dependencies = [ "http 1.3.1", "httparse", "log", - "rand 0.9.1", + "rand 0.9.2", "sha1", - "thiserror 2.0.12", + "thiserror 2.0.14", "utf-8", ] @@ -5420,11 +5503,11 @@ dependencies = [ "http 1.3.1", "httparse", "log", - "rand 0.9.1", - "rustls 0.23.27", + "rand 0.9.2", + "rustls 0.23.31", "rustls-pki-types", "sha1", - "thiserror 2.0.12", + "thiserror 2.0.14", "utf-8", ] @@ -5464,7 +5547,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a615d6c2764852a2e88a4f16e9ce1ea49bb776b5872956309e170d63a042a34f" dependencies = [ "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -5500,6 +5583,18 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-width" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" + [[package]] name = "unsafe-libyaml" version = "0.2.11" @@ -5536,12 +5631,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -5560,9 +5649,9 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" dependencies = [ - "getrandom 0.3.2", + "getrandom 0.3.3", "js-sys", - "rand 0.9.1", + "rand 0.9.2", "serde", "wasm-bindgen", ] @@ -5602,9 +5691,9 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" @@ -5637,7 +5726,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", "wasm-bindgen-shared", ] @@ -5672,7 +5761,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5742,18 +5831,9 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "webpki-roots" -version = "0.26.8" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "webpki-roots" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2853738d1cc4f2da3a225c18ec6c3721abb31961096e9dbf5ab35fa88b19cfdb" +checksum = "8782dd5a41a24eed3a4f40b606249b3e236ca61adf1f25ea4d45c73de122b502" dependencies = [ "rustls-pki-types", ] @@ -5782,7 +5862,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9b0540e91e49de3817c314da0dd3bc518093ceacc6ea5327cb0e1eb073e5189" dependencies = [ - "thiserror 2.0.12", + "thiserror 2.0.14", ] [[package]] @@ -5809,9 +5889,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.61.1" +version = "0.61.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ "windows-collections", "windows-core", @@ -5831,9 +5911,9 @@ dependencies = [ [[package]] name = "windows-core" -version = "0.61.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement", "windows-interface", @@ -5844,12 +5924,13 @@ dependencies = [ [[package]] name = "windows-future" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a1d6bbefcb7b60acd19828e1bc965da6fcf18a7e39490c5f8be71e54a19ba32" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ "windows-core", "windows-link", + "windows-threading", ] [[package]] @@ -5860,7 +5941,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -5871,14 +5952,14 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] name = "windows-link" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" [[package]] name = "windows-numerics" @@ -5892,9 +5973,9 @@ dependencies = [ [[package]] name = "windows-registry" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1da3e436dc7653dfdf3da67332e22bff09bb0e28b0239e1624499c7830842e" +checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" dependencies = [ "windows-link", "windows-result", @@ -5903,18 +5984,18 @@ dependencies = [ [[package]] name = "windows-result" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ "windows-link", ] @@ -5946,6 +6027,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.2", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -5970,13 +6060,38 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -5989,6 +6104,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -6001,6 +6122,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -6013,12 +6140,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -6031,6 +6170,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -6043,6 +6188,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -6055,6 +6206,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -6068,13 +6225,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "winnow" -version = "0.7.11" +name = "windows_x86_64_msvc" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" -dependencies = [ - "memchr", -] +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "winnow" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" [[package]] name = "winreg" @@ -6101,20 +6261,14 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", ] -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - [[package]] name = "writeable" -version = "0.5.5" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "wyz" @@ -6133,9 +6287,9 @@ checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" [[package]] name = "yoke" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" dependencies = [ "serde", "stable_deref_trait", @@ -6145,54 +6299,34 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", "synstructure", ] [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" dependencies = [ - "zerocopy-derive 0.7.35", -] - -[[package]] -name = "zerocopy" -version = "0.8.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" -dependencies = [ - "zerocopy-derive 0.8.24", + "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -6212,7 +6346,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", "synstructure", ] @@ -6223,10 +6357,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] -name = "zerovec" -version = "0.10.4" +name = "zerotrie" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" dependencies = [ "yoke", "zerofrom", @@ -6235,11 +6380,11 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] diff --git a/Cargo.toml b/Cargo.toml index 6b76950ba..829d2ada2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ members = [ ] [workspace.package] -version = "1.18.4" +version = "1.19.0" edition = "2024" authors = ["mbecker20 "] license = "GPL-3.0-or-later" @@ -23,8 +23,10 @@ environment_file = { path = "lib/environment_file" } environment = { path = "lib/environment" } interpolate = { path = "lib/interpolate" } formatting = { path = "lib/formatting" } +database = { path = "lib/database" } response = { path = "lib/response" } command = { path = "lib/command" } +config = { path = "lib/config" } logger = { path = "lib/logger" } cache = { path = "lib/cache" } git = { path = "lib/git" } @@ -35,20 +37,19 @@ serror = { version = "0.5.0", default-features = false } slack = { version = "0.4.0", package = "slack_client_rs", default-features = false, features = ["rustls"] } derive_default_builder = "0.1.8" derive_empty_traits = "0.1.0" -merge_config_files = "0.1.5" async_timing_util = "1.0.0" partial_derive2 = "0.4.3" derive_variants = "1.0.0" -mongo_indexed = "2.0.1" +mongo_indexed = "2.0.2" resolver_api = "3.0.0" -toml_pretty = "1.1.2" -mungos = "3.2.0" -svi = "1.1.0" +toml_pretty = "1.2.0" +mungos = "3.2.1" +svi = "1.2.0" # ASYNC -reqwest = { version = "0.12.20", default-features = false, features = ["json", "stream", "rustls-tls-native-roots"] } -tokio = { version = "1.45.1", features = ["full"] } -tokio-util = { version = "0.7.15", features = ["io", "codec"] } +reqwest = { version = "0.12.22", default-features = false, features = ["json", "stream", "rustls-tls-native-roots"] } +tokio = { version = "1.47.1", features = ["full"] } +tokio-util = { version = "0.7.16", features = ["io", "codec"] } tokio-stream = { version = "0.1.17", features = ["sync"] } pin-project-lite = "0.2.16" futures = "0.3.31" @@ -63,17 +64,18 @@ axum-server = { version = "0.7.2", features = ["tls-rustls"] } axum = { version = "0.8.4", features = ["ws", "json", "macros"] } # SER/DE -indexmap = { version = "2.9.0", features = ["serde"] } +ipnetwork = { version = "0.21.1", features = ["serde"] } +indexmap = { version = "2.10.0", features = ["serde"] } serde = { version = "1.0.219", features = ["derive"] } -strum = { version = "0.27.1", features = ["derive"] } -serde_json = "1.0.140" -serde_yaml = "0.9.34" +strum = { version = "0.27.2", features = ["derive"] } +serde_yaml_ng = "0.10.0" +serde_json = "1.0.142" serde_qs = "0.15.0" -toml = "0.8.23" +toml = "0.9.5" # ERROR -anyhow = "1.0.98" -thiserror = "2.0.12" +anyhow = "1.0.99" +thiserror = "2.0.14" # LOGGING opentelemetry-otlp = { version = "0.30.0", features = ["tls-roots", "reqwest-rustls"] } @@ -85,42 +87,44 @@ opentelemetry = "0.30.0" tracing = "0.1.41" # CONFIG -clap = { version = "4.5.40", features = ["derive"] } +clap = { version = "4.5.43", features = ["derive"] } dotenvy = "0.15.7" envy = "0.4.2" # CRYPTO / AUTH uuid = { version = "1.17.0", features = ["v4", "fast-rng", "serde"] } jsonwebtoken = { version = "9.3.1", default-features = false } -openidconnect = "4.0.0" +openidconnect = "4.0.1" urlencoding = "2.1.3" nom_pem = "4.0.0" bcrypt = "0.17.0" base64 = "0.22.1" -rustls = "0.23.27" +rustls = "0.23.31" hmac = "0.12.1" sha2 = "0.10.9" -rand = "0.9.1" +rand = "0.9.2" hex = "0.4.3" # SYSTEM portable-pty = "0.9.0" -bollard = "0.19.1" -sysinfo = "0.35.2" +bollard = "0.19.2" +sysinfo = "0.37.0" # CLOUD -aws-config = "1.8.0" -aws-sdk-ec2 = "1.139.0" -aws-credential-types = "1.2.3" +aws-config = "1.8.5" +aws-sdk-ec2 = "1.159.0" +aws-credential-types = "1.2.5" ## CRON english-to-cron = "0.1.6" -chrono-tz = "0.10.3" +chrono-tz = "0.10.4" chrono = "0.4.41" -croner = "2.1.0" +croner = "3.0.0" # MISC +async-compression = { version = "0.4.27", features = ["tokio", "gzip"] } derive_builder = "0.20.2" +comfy-table = "7.1.4" typeshare = "1.0.4" octorust = "0.10.0" dashmap = "6.1.0" diff --git a/bin/binaries.Dockerfile b/bin/binaries.Dockerfile index 81693856c..06980db07 100644 --- a/bin/binaries.Dockerfile +++ b/bin/binaries.Dockerfile @@ -1,7 +1,7 @@ ## Builds the Komodo Core, Periphery, and Util binaries ## for a specific architecture. -FROM rust:1.87.0-bullseye AS builder +FROM rust:1.89.0-bullseye AS builder WORKDIR /builder COPY Cargo.toml Cargo.lock ./ @@ -10,20 +10,20 @@ COPY ./client/core/rs ./client/core/rs COPY ./client/periphery ./client/periphery COPY ./bin/core ./bin/core COPY ./bin/periphery ./bin/periphery -COPY ./bin/util ./bin/util +COPY ./bin/cli ./bin/cli # Compile bin RUN \ cargo build -p komodo_core --release && \ cargo build -p komodo_periphery --release && \ - cargo build -p komodo_util --release + cargo build -p komodo_cli --release # Copy just the binaries to scratch image FROM scratch COPY --from=builder /builder/target/release/core /core COPY --from=builder /builder/target/release/periphery /periphery -COPY --from=builder /builder/target/release/util /util +COPY --from=builder /builder/target/release/km /km LABEL org.opencontainers.image.source=https://github.com/moghtech/komodo LABEL org.opencontainers.image.description="Komodo Binaries" diff --git a/bin/chef.binaries.Dockerfile b/bin/chef.binaries.Dockerfile new file mode 100644 index 000000000..d4c74903a --- /dev/null +++ b/bin/chef.binaries.Dockerfile @@ -0,0 +1,34 @@ +## Builds the Komodo Core, Periphery, and Util binaries +## for a specific architecture. + +## Uses chef for dependency caching to help speed up back-to-back builds. + +FROM lukemathwalker/cargo-chef:latest-rust-1.89.0-bullseye AS chef +WORKDIR /builder + +# Plan just the RECIPE to see if things have changed +FROM chef AS planner +COPY . . +RUN cargo chef prepare --recipe-path recipe.json + +FROM chef AS builder +COPY --from=planner /builder/recipe.json recipe.json +# Build JUST dependencies - cached layer +RUN cargo chef cook --release --recipe-path recipe.json +# NOW copy again (this time into builder) and build app +COPY . . +RUN \ + cargo build --release --bin core && \ + cargo build --release --bin periphery && \ + cargo build --release --bin km + +# Copy just the binaries to scratch image +FROM scratch + +COPY --from=builder /builder/target/release/core /core +COPY --from=builder /builder/target/release/periphery /periphery +COPY --from=builder /builder/target/release/km /km + +LABEL org.opencontainers.image.source=https://github.com/moghtech/komodo +LABEL org.opencontainers.image.description="Komodo Binaries" +LABEL org.opencontainers.image.licenses=GPL-3.0 \ No newline at end of file diff --git a/bin/cli/Cargo.toml b/bin/cli/Cargo.toml index 7ab8f3c06..bd8ff378c 100644 --- a/bin/cli/Cargo.toml +++ b/bin/cli/Cargo.toml @@ -1,30 +1,36 @@ [package] name = "komodo_cli" -description = "Command line tool to execute Komodo actions" +description = "Command line tool for Komodo" version.workspace = true edition.workspace = true authors.workspace = true license.workspace = true -homepage.workspace = true repository.workspace = true +homepage.workspace = true [[bin]] -name = "komodo" +name = "km" path = "src/main.rs" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] # local -# komodo_client = "1.16.12" +environment_file.workspace = true komodo_client.workspace = true +database.workspace = true +config.workspace = true +logger.workspace = true # external -tracing-subscriber.workspace = true -merge_config_files.workspace = true -futures.workspace = true +futures-util.workspace = true +comfy-table.workspace = true +serde_json.workspace = true +serde_qs.workspace = true +wildcard.workspace = true tracing.workspace = true colored.workspace = true +dotenvy.workspace = true anyhow.workspace = true +chrono.workspace = true tokio.workspace = true serde.workspace = true clap.workspace = true +envy.workspace = true \ No newline at end of file diff --git a/bin/util/aio.Dockerfile b/bin/cli/aio.Dockerfile similarity index 55% rename from bin/util/aio.Dockerfile rename to bin/cli/aio.Dockerfile index 542d34e52..882034344 100644 --- a/bin/util/aio.Dockerfile +++ b/bin/cli/aio.Dockerfile @@ -1,22 +1,24 @@ -FROM rust:1.87.0-bullseye AS builder +FROM rust:1.89.0-bullseye AS builder WORKDIR /builder COPY Cargo.toml Cargo.lock ./ COPY ./lib ./lib COPY ./client/core/rs ./client/core/rs COPY ./client/periphery ./client/periphery -COPY ./bin/util ./bin/util +COPY ./bin/cli ./bin/cli # Compile bin -RUN cargo build -p komodo_util --release +RUN cargo build -p komodo_cli --release # Copy binaries to distroless base FROM gcr.io/distroless/cc -COPY --from=builder /builder/target/release/util /usr/local/bin/util +COPY --from=builder /builder/target/release/km /usr/local/bin/km -CMD [ "util" ] +ENV KOMODO_CLI_CONFIG_PATHS="/config" + +CMD [ "km" ] LABEL org.opencontainers.image.source=https://github.com/moghtech/komodo -LABEL org.opencontainers.image.description="Komodo Util" +LABEL org.opencontainers.image.description="Komodo CLI" LABEL org.opencontainers.image.licenses=GPL-3.0 \ No newline at end of file diff --git a/bin/util/docs/copy-database.md b/bin/cli/docs/copy-database.md similarity index 82% rename from bin/util/docs/copy-database.md rename to bin/cli/docs/copy-database.md index 5ebcfaafb..a37026296 100644 --- a/bin/util/docs/copy-database.md +++ b/bin/cli/docs/copy-database.md @@ -7,13 +7,13 @@ Can be used to move between MongoDB / FerretDB, or upgrade from FerretDB v1 to v services: copy_database: - image: ghcr.io/moghtech/komodo-util + image: ghcr.io/moghtech/komodo-cli + command: km database copy -y environment: - MODE: CopyDatabase - SOURCE_URI: mongodb://${KOMODO_DB_USERNAME}:${KOMODO_DB_PASSWORD}@source:27017 - SOURCE_DB_NAME: ${KOMODO_DATABASE_DB_NAME:-komodo} - TARGET_URI: mongodb://${KOMODO_DB_USERNAME}:${KOMODO_DB_PASSWORD}@target:27017 - TARGET_DB_NAME: ${KOMODO_DATABASE_DB_NAME:-komodo} + KOMODO_DATABASE_URI: mongodb://${KOMODO_DB_USERNAME}:${KOMODO_DB_PASSWORD}@source:27017 + KOMODO_DATABASE_DB_NAME: ${KOMODO_DATABASE_DB_NAME:-komodo} + KOMODO_CLI_DATABASE_TARGET_URI: mongodb://${KOMODO_DB_USERNAME}:${KOMODO_DB_PASSWORD}@target:27017 + KOMODO_CLI_DATABASE_TARGET_DB_NAME: ${KOMODO_DATABASE_DB_NAME:-komodo} ``` @@ -90,13 +90,13 @@ services: ...(new database) copy_database: - image: ghcr.io/moghtech/komodo-util + image: ghcr.io/moghtech/komodo-cli + command: km database copy -y environment: - MODE: CopyDatabase - SOURCE_URI: mongodb://${KOMODO_DB_USERNAME}:${KOMODO_DB_PASSWORD}@ferretdb:27017/${KOMODO_DATABASE_DB_NAME:-komodo}?authMechanism=PLAIN - SOURCE_DB_NAME: ${KOMODO_DATABASE_DB_NAME:-komodo} - TARGET_URI: mongodb://${KOMODO_DB_USERNAME}:${KOMODO_DB_PASSWORD}@ferretdb2:27017 - TARGET_DB_NAME: ${KOMODO_DATABASE_DB_NAME:-komodo} + KOMODO_DATABASE_URI: mongodb://${KOMODO_DB_USERNAME}:${KOMODO_DB_PASSWORD}@ferretdb:27017/${KOMODO_DATABASE_DB_NAME:-komodo}?authMechanism=PLAIN + KOMODO_DATABASE_DB_NAME: ${KOMODO_DATABASE_DB_NAME:-komodo} + KOMODO_CLI_DATABASE_TARGET_URI: mongodb://${KOMODO_DB_USERNAME}:${KOMODO_DB_PASSWORD}@ferretdb2:27017 + KOMODO_CLI_DATABASE_TARGET_DB_NAME: ${KOMODO_DATABASE_DB_NAME:-komodo} ...(unchanged) ``` diff --git a/bin/util/multi-arch.Dockerfile b/bin/cli/multi-arch.Dockerfile similarity index 67% rename from bin/util/multi-arch.Dockerfile rename to bin/cli/multi-arch.Dockerfile index 129f4b7ba..682ff734b 100644 --- a/bin/util/multi-arch.Dockerfile +++ b/bin/cli/multi-arch.Dockerfile @@ -14,14 +14,16 @@ FROM debian:bullseye-slim WORKDIR /app ## Copy both binaries initially, but only keep appropriate one for the TARGETPLATFORM. -COPY --from=x86_64 /util /app/arch/linux/amd64 -COPY --from=aarch64 /util /app/arch/linux/arm64 +COPY --from=x86_64 /km /app/arch/linux/amd64 +COPY --from=aarch64 /km /app/arch/linux/arm64 ARG TARGETPLATFORM -RUN mv /app/arch/${TARGETPLATFORM} /usr/local/bin/util && rm -r /app/arch +RUN mv /app/arch/${TARGETPLATFORM} /usr/local/bin/km && rm -r /app/arch + +ENV KOMODO_CLI_CONFIG_PATHS="/config" + +CMD [ "km" ] LABEL org.opencontainers.image.source=https://github.com/moghtech/komodo -LABEL org.opencontainers.image.description="Komodo Util" -LABEL org.opencontainers.image.licenses=GPL-3.0 - -CMD [ "util" ] \ No newline at end of file +LABEL org.opencontainers.image.description="Komodo CLI" +LABEL org.opencontainers.image.licenses=GPL-3.0 \ No newline at end of file diff --git a/bin/cli/runfile.toml b/bin/cli/runfile.toml new file mode 100644 index 000000000..aa675d987 --- /dev/null +++ b/bin/cli/runfile.toml @@ -0,0 +1,4 @@ +[install-cli] +alias = "ic" +description = "installs the komodo-cli, available on the command line as 'km'" +cmd = "cargo install --path ." \ No newline at end of file diff --git a/bin/util/single-arch.Dockerfile b/bin/cli/single-arch.Dockerfile similarity index 71% rename from bin/util/single-arch.Dockerfile rename to bin/cli/single-arch.Dockerfile index 80a1cdf3d..ff0923f79 100644 --- a/bin/util/single-arch.Dockerfile +++ b/bin/cli/single-arch.Dockerfile @@ -7,10 +7,12 @@ FROM ${BINARIES_IMAGE} AS binaries FROM gcr.io/distroless/cc -COPY --from=binaries /util /usr/local/bin/util +COPY --from=binaries /km /usr/local/bin/km + +ENV KOMODO_CLI_CONFIG_PATHS="/config" + +CMD [ "km" ] LABEL org.opencontainers.image.source=https://github.com/moghtech/komodo -LABEL org.opencontainers.image.description="Komodo Util" +LABEL org.opencontainers.image.description="Komodo CLI" LABEL org.opencontainers.image.licenses=GPL-3.0 - -CMD [ "util" ] \ No newline at end of file diff --git a/bin/cli/src/args.rs b/bin/cli/src/args.rs deleted file mode 100644 index 01532df29..000000000 --- a/bin/cli/src/args.rs +++ /dev/null @@ -1,55 +0,0 @@ -use clap::{Parser, Subcommand}; -use komodo_client::api::execute::Execution; -use serde::Deserialize; - -#[derive(Parser, Debug)] -#[command(version, about, long_about = None)] -pub struct CliArgs { - /// Sync or Exec - #[command(subcommand)] - pub command: Command, - - /// The path to a creds file. - /// - /// Note: If each of `url`, `key` and `secret` are passed, - /// no file is required at this path. - #[arg(long, default_value_t = default_creds())] - pub creds: String, - - /// Pass url in args instead of creds file - #[arg(long)] - pub url: Option, - /// Pass api key in args instead of creds file - #[arg(long)] - pub key: Option, - /// Pass api secret in args instead of creds file - #[arg(long)] - pub secret: Option, - - /// Always continue on user confirmation prompts. - #[arg(long, short, default_value_t = false)] - pub yes: bool, -} - -fn default_creds() -> String { - let home = - std::env::var("HOME").unwrap_or_else(|_| String::from("/root")); - format!("{home}/.config/komodo/creds.toml") -} - -#[derive(Debug, Clone, Subcommand)] -pub enum Command { - /// Runs an execution - Execute { - #[command(subcommand)] - execution: Execution, - }, - // Room for more -} - -#[derive(Debug, Deserialize)] -pub struct CredsFile { - pub url: String, - pub key: String, - pub secret: String, -} diff --git a/bin/cli/src/command/container.rs b/bin/cli/src/command/container.rs new file mode 100644 index 000000000..af57dc2e6 --- /dev/null +++ b/bin/cli/src/command/container.rs @@ -0,0 +1,312 @@ +use std::collections::{HashMap, HashSet}; + +use anyhow::Context; +use colored::Colorize; +use comfy_table::{Attribute, Cell, Color}; +use futures_util::{ + FutureExt, TryStreamExt, stream::FuturesUnordered, +}; +use komodo_client::{ + api::read::{ + InspectDockerContainer, ListAllDockerContainers, ListServers, + }, + entities::{ + config::cli::args::container::{ + Container, ContainerCommand, InspectContainer, + }, + docker::{ + self, + container::{ContainerListItem, ContainerStateStatusEnum}, + }, + }, +}; + +use crate::{ + command::{ + PrintTable, clamp_sha, matches_wildcards, parse_wildcards, + print_items, + }, + config::cli_config, +}; + +pub async fn handle(container: &Container) -> anyhow::Result<()> { + match &container.command { + None => list_containers(container).await, + Some(ContainerCommand::Inspect(inspect)) => { + inspect_container(inspect).await + } + } +} + +async fn list_containers( + Container { + all, + down, + links, + reverse, + containers: names, + images, + networks, + servers, + format, + command: _, + }: &Container, +) -> anyhow::Result<()> { + let client = super::komodo_client().await?; + let (server_map, containers) = tokio::try_join!( + client + .read(ListServers::default()) + .map(|res| res.map(|res| res + .into_iter() + .map(|s| (s.id.clone(), s)) + .collect::>())), + client.read(ListAllDockerContainers { + servers: Default::default() + }), + )?; + + // (Option, Container) + let containers = containers.into_iter().map(|c| { + let server = if let Some(server_id) = c.server_id.as_ref() + && let Some(server) = server_map.get(server_id) + { + server + } else { + return (None, c); + }; + (Some(server.name.as_str()), c) + }); + + let names = parse_wildcards(names); + let servers = parse_wildcards(servers); + let images = parse_wildcards(images); + let networks = parse_wildcards(networks); + + let mut containers = containers + .into_iter() + .filter(|(server_name, c)| { + let state_check = if *all { + true + } else if *down { + !matches!(c.state, ContainerStateStatusEnum::Running) + } else { + matches!(c.state, ContainerStateStatusEnum::Running) + }; + let network_check = matches_wildcards( + &networks, + &c.network_mode + .as_deref() + .map(|n| vec![n]) + .unwrap_or_default(), + ) || matches_wildcards( + &networks, + &c.networks.iter().map(String::as_str).collect::>(), + ); + state_check + && network_check + && matches_wildcards(&names, &[c.name.as_str()]) + && matches_wildcards( + &servers, + &server_name + .as_deref() + .map(|i| vec![i]) + .unwrap_or_default(), + ) + && matches_wildcards( + &images, + &c.image.as_deref().map(|i| vec![i]).unwrap_or_default(), + ) + }) + .collect::>(); + containers.sort_by(|(a_s, a), (b_s, b)| { + a.state + .cmp(&b.state) + .then(a.name.cmp(&b.name)) + .then(a_s.cmp(b_s)) + .then(a.network_mode.cmp(&b.network_mode)) + .then(a.image.cmp(&b.image)) + }); + if *reverse { + containers.reverse(); + } + print_items(containers, *format, *links)?; + Ok(()) +} + +pub async fn inspect_container( + inspect: &InspectContainer, +) -> anyhow::Result<()> { + let client = super::komodo_client().await?; + let (server_map, mut containers) = tokio::try_join!( + client + .read(ListServers::default()) + .map(|res| res.map(|res| res + .into_iter() + .map(|s| (s.id.clone(), s)) + .collect::>())), + client.read(ListAllDockerContainers { + servers: Default::default() + }), + )?; + + containers.iter_mut().for_each(|c| { + let Some(server_id) = c.server_id.as_ref() else { + return; + }; + let Some(server) = server_map.get(server_id) else { + c.server_id = Some(String::from("Unknown")); + return; + }; + c.server_id = Some(server.name.clone()); + }); + + let names = [inspect.container.to_string()]; + let names = parse_wildcards(&names); + let servers = parse_wildcards(&inspect.servers); + + let mut containers = containers + .into_iter() + .filter(|c| { + matches_wildcards(&names, &[c.name.as_str()]) + && matches_wildcards( + &servers, + &c.server_id + .as_deref() + .map(|i| vec![i]) + .unwrap_or_default(), + ) + }) + .map(|c| async move { + client + .read(InspectDockerContainer { + container: c.name, + server: c.server_id.context("No server...")?, + }) + .await + }) + .collect::>() + .try_collect::>() + .await?; + + containers.sort_by(|a, b| a.name.cmp(&b.name)); + + match containers.len() { + 0 => { + println!( + "{}: Did not find any containers matching '{}'", + "INFO".green(), + inspect.container.bold() + ); + } + 1 => { + println!("{}", serialize_container(inspect, &containers[0])?); + } + _ => { + let containers = containers + .iter() + .map(|c| serialize_container(inspect, c)) + .collect::>>()? + .join("\n"); + println!("{containers}"); + } + } + + Ok(()) +} + +fn serialize_container( + inspect: &InspectContainer, + container: &docker::container::Container, +) -> anyhow::Result { + let res = if inspect.state { + serde_json::to_string_pretty(&container.state) + } else if inspect.mounts { + serde_json::to_string_pretty(&container.mounts) + } else if inspect.host_config { + serde_json::to_string_pretty(&container.host_config) + } else if inspect.config { + serde_json::to_string_pretty(&container.config) + } else if inspect.network_settings { + serde_json::to_string_pretty(&container.network_settings) + } else { + serde_json::to_string_pretty(container) + } + .context("Failed to serialize items to JSON")?; + Ok(res) +} + +// (Option, Container) +impl PrintTable for (Option<&'_ str>, ContainerListItem) { + fn header(links: bool) -> &'static [&'static str] { + if links { + &[ + "Container", + "State", + "Server", + "Ports", + "Networks", + "Image", + "Link", + ] + } else { + &["Container", "State", "Server", "Ports", "Networks", "Image"] + } + } + fn row(self, links: bool) -> Vec { + let color = match self.1.state { + ContainerStateStatusEnum::Running => Color::Green, + ContainerStateStatusEnum::Paused => Color::DarkYellow, + ContainerStateStatusEnum::Empty => Color::Grey, + _ => Color::Red, + }; + let mut networks = HashSet::new(); + if let Some(network) = self.1.network_mode { + networks.insert(network); + } + for network in self.1.networks { + networks.insert(network); + } + let mut networks = networks.into_iter().collect::>(); + networks.sort(); + let mut ports = self + .1 + .ports + .into_iter() + .flat_map(|p| p.public_port.map(|p| p.to_string())) + .collect::>() + .into_iter() + .collect::>(); + ports.sort(); + let ports = if ports.is_empty() { + Cell::new("") + } else { + Cell::new(format!(":{}", ports.join(", :"))) + }; + + let image = self.1.image.as_deref().unwrap_or("Unknown"); + let mut res = vec![ + Cell::new(self.1.name.clone()).add_attribute(Attribute::Bold), + Cell::new(self.1.state.to_string()) + .fg(color) + .add_attribute(Attribute::Bold), + Cell::new(self.0.unwrap_or("Unknown")), + ports, + Cell::new(networks.join(", ")), + Cell::new(clamp_sha(&image)), + ]; + if !links { + return res; + } + let link = if let Some(server_id) = self.1.server_id { + format!( + "{}/servers/{server_id}/container/{}", + cli_config().host, + self.1.name + ) + } else { + String::new() + }; + res.push(Cell::new(link)); + res + } +} diff --git a/bin/cli/src/command/database.rs b/bin/cli/src/command/database.rs new file mode 100644 index 000000000..2e5696793 --- /dev/null +++ b/bin/cli/src/command/database.rs @@ -0,0 +1,320 @@ +use std::path::Path; + +use anyhow::Context; +use colored::Colorize; +use komodo_client::entities::{ + config::cli::args::database::DatabaseCommand, optional_string, +}; + +use crate::{command::sanitize_uri, config::cli_config}; + +pub async fn handle(command: &DatabaseCommand) -> anyhow::Result<()> { + match command { + DatabaseCommand::Backup { yes, .. } => backup(*yes).await, + DatabaseCommand::Restore { + restore_folder, + index, + yes, + .. + } => restore(restore_folder.as_deref(), *index, *yes).await, + DatabaseCommand::Prune { yes, .. } => prune(*yes).await, + DatabaseCommand::Copy { yes, index, .. } => { + copy(*index, *yes).await + } + } +} + +async fn backup(yes: bool) -> anyhow::Result<()> { + let config = cli_config(); + + println!( + "\n🦎 {} Database {} Utility 🦎", + "Komodo".bold(), + "Backup".green().bold() + ); + println!( + "\n{}\n", + " - Backup all database contents to gzip compressed files." + .dimmed() + ); + if let Some(uri) = optional_string(&config.database.uri) { + println!("{}: {}", " - Source URI".dimmed(), sanitize_uri(&uri)); + } + if let Some(address) = optional_string(&config.database.address) { + println!("{}: {address}", " - Source Address".dimmed()); + } + if let Some(username) = optional_string(&config.database.username) { + println!("{}: {username}", " - Source Username".dimmed()); + } + println!( + "{}: {}\n", + " - Source Db Name".dimmed(), + config.database.db_name, + ); + println!( + "{}: {:?}", + " - Backups Folder".dimmed(), + config.backups_folder + ); + if config.max_backups == 0 { + println!( + "{}{}", + " - Backup pruning".dimmed(), + "disabled".red().dimmed() + ); + } else { + println!("{}: {}", " - Max Backups".dimmed(), config.max_backups); + } + + crate::command::wait_for_enter("start backup", yes)?; + + let db = database::init(&config.database).await?; + + database::utils::backup(&db, &config.backups_folder).await?; + + // Early return if backup pruning disabled + if config.max_backups == 0 { + return Ok(()); + } + + // Know that new backup was taken successfully at this point, + // safe to prune old backup folders + + prune_inner().await +} + +async fn restore( + restore_folder: Option<&Path>, + index: bool, + yes: bool, +) -> anyhow::Result<()> { + let config = cli_config(); + + println!( + "\n🦎 {} Database {} Utility 🦎", + "Komodo".bold(), + "Restore".purple().bold() + ); + println!( + "\n{}\n", + " - Restores database contents from gzip compressed files." + .dimmed() + ); + if let Some(uri) = optional_string(&config.database_target.uri) { + println!("{}: {}", " - Target URI".dimmed(), sanitize_uri(&uri)); + } + if let Some(address) = + optional_string(&config.database_target.address) + { + println!("{}: {address}", " - Target Address".dimmed()); + } + if let Some(username) = + optional_string(&config.database_target.username) + { + println!("{}: {username}", " - Target Username".dimmed()); + } + println!( + "{}: {}", + " - Target Db Name".dimmed(), + config.database_target.db_name, + ); + if !index { + println!( + "{}: {}", + " - Target Db Indexing".dimmed(), + "DISABLED".red(), + ); + } + println!( + "\n{}: {:?}", + " - Backups Folder".dimmed(), + config.backups_folder + ); + if let Some(restore_folder) = restore_folder { + println!("{}: {restore_folder:?}", " - Restore Folder".dimmed()); + } + + crate::command::wait_for_enter("start restore", yes)?; + + let db = if index { + database::Client::new(&config.database_target).await?.db + } else { + database::init(&config.database_target).await? + }; + + database::utils::restore( + &db, + &config.backups_folder, + restore_folder, + ) + .await +} + +async fn prune(yes: bool) -> anyhow::Result<()> { + let config = cli_config(); + + println!( + "\n🦎 {} Database {} Utility 🦎", + "Komodo".bold(), + "Backup Prune".cyan().bold() + ); + println!( + "\n{}\n", + " - Prunes database backup folders when greater than the configured amount." + .dimmed() + ); + println!( + "{}: {:?}", + " - Backups Folder".dimmed(), + config.backups_folder + ); + if config.max_backups == 0 { + println!( + "{}{}", + " - Backup pruning".dimmed(), + "disabled".red().dimmed() + ); + } else { + println!("{}: {}", " - Max Backups".dimmed(), config.max_backups); + } + + // Early return if backup pruning disabled + if config.max_backups == 0 { + info!( + "Backup pruning is disabled, enabled using 'max_backups' (KOMODO_CLI_MAX_BACKUPS)" + ); + return Ok(()); + } + + crate::command::wait_for_enter("start backup prune", yes)?; + + prune_inner().await +} + +async fn prune_inner() -> anyhow::Result<()> { + let config = cli_config(); + + let mut backups_dir = + match tokio::fs::read_dir(&config.backups_folder) + .await + .context("Failed to read backups folder for prune") + { + Ok(backups_dir) => backups_dir, + Err(e) => { + warn!("{e:#}"); + return Ok(()); + } + }; + + let mut backup_folders = Vec::new(); + loop { + match backups_dir.next_entry().await { + Ok(Some(entry)) => { + let Ok(metadata) = entry.metadata().await else { + continue; + }; + if metadata.is_dir() { + backup_folders.push(entry.path()); + } + } + Ok(None) => break, + Err(_) => { + continue; + } + } + } + // Ordered from oldest -> newest + backup_folders.sort(); + + let max_backups = config.max_backups as usize; + let backup_folders_len = backup_folders.len(); + + // Early return if under the backup count threshold + if backup_folders_len <= max_backups { + info!("No backups to prune"); + return Ok(()); + } + + let to_delete = + &backup_folders[..(backup_folders_len - max_backups)]; + + info!("Pruning old backups: {to_delete:?}"); + + for path in to_delete { + if let Err(e) = + tokio::fs::remove_dir_all(path).await.with_context(|| { + format!("Failed to delete backup folder at {path:?}") + }) + { + warn!("{e:#}"); + } + } + + Ok(()) +} + +async fn copy(index: bool, yes: bool) -> anyhow::Result<()> { + let config = cli_config(); + + println!( + "\n🦎 {} Database {} Utility 🦎", + "Komodo".bold(), + "Copy".blue().bold() + ); + println!( + "\n{}\n", + " - Copies database contents to another database.".dimmed() + ); + + if let Some(uri) = optional_string(&config.database.uri) { + println!("{}: {}", " - Source URI".dimmed(), sanitize_uri(&uri)); + } + if let Some(address) = optional_string(&config.database.address) { + println!("{}: {address}", " - Source Address".dimmed()); + } + if let Some(username) = optional_string(&config.database.username) { + println!("{}: {username}", " - Source Username".dimmed()); + } + println!( + "{}: {}\n", + " - Source Db Name".dimmed(), + config.database.db_name, + ); + + if let Some(uri) = optional_string(&config.database_target.uri) { + println!("{}: {}", " - Target URI".dimmed(), sanitize_uri(&uri)); + } + if let Some(address) = + optional_string(&config.database_target.address) + { + println!("{}: {address}", " - Target Address".dimmed()); + } + if let Some(username) = + optional_string(&config.database_target.username) + { + println!("{}: {username}", " - Target Username".dimmed()); + } + println!( + "{}: {}", + " - Target Db Name".dimmed(), + config.database_target.db_name, + ); + if !index { + println!( + "{}: {}", + " - Target Db Indexing".dimmed(), + "DISABLED".red(), + ); + } + + crate::command::wait_for_enter("start copy", yes)?; + + let source_db = database::init(&config.database).await?; + let target_db = if index { + database::Client::new(&config.database_target).await?.db + } else { + database::init(&config.database_target).await? + }; + + database::utils::copy(&source_db, &target_db).await +} diff --git a/bin/cli/src/exec.rs b/bin/cli/src/command/execute.rs similarity index 63% rename from bin/cli/src/exec.rs rename to bin/cli/src/command/execute.rs index 407f37833..7dab58ccb 100644 --- a/bin/cli/src/exec.rs +++ b/bin/cli/src/command/execute.rs @@ -1,22 +1,25 @@ use std::time::Duration; use colored::Colorize; +use futures_util::{StreamExt, stream::FuturesUnordered}; use komodo_client::{ - api::execute::{BatchExecutionResponse, Execution}, - entities::update::Update, + api::execute::{ + BatchExecutionResponse, BatchExecutionResponseItem, Execution, + }, + entities::{resource_link, update::Update}, }; -use crate::{ - helpers::wait_for_enter, - state::{cli_args, komodo_client}, -}; +use crate::config::cli_config; -pub enum ExecutionResult { +enum ExecutionResult { Single(Box), Batch(BatchExecutionResponse), } -pub async fn run(execution: Execution) -> anyhow::Result<()> { +pub async fn handle( + execution: &Execution, + yes: bool, +) -> anyhow::Result<()> { if matches!(execution, Execution::None(_)) { println!("Got 'none' execution. Doing nothing..."); tokio::time::sleep(Duration::from_secs(3)).await; @@ -25,7 +28,7 @@ pub async fn run(execution: Execution) -> anyhow::Result<()> { } println!("\n{}: Execution", "Mode".dimmed()); - match &execution { + match execution { Execution::None(data) => { println!("{}: {data:?}", "Data".dimmed()) } @@ -212,259 +215,268 @@ pub async fn run(execution: Execution) -> anyhow::Result<()> { Execution::TestAlerter(data) => { println!("{}: {data:?}", "Data".dimmed()) } + Execution::ClearRepoCache(data) => { + println!("{}: {data:?}", "Data".dimmed()) + } + Execution::BackupCoreDatabase(data) => { + println!("{}: {data:?}", "Data".dimmed()) + } + Execution::GlobalAutoUpdate(data) => { + println!("{}: {data:?}", "Data".dimmed()) + } Execution::Sleep(data) => { println!("{}: {data:?}", "Data".dimmed()) } } - if !cli_args().yes { - wait_for_enter("run execution")?; - } + super::wait_for_enter("run execution", yes)?; info!("Running Execution..."); - let res = match execution { - Execution::RunAction(request) => komodo_client() + let client = super::komodo_client().await?; + + let res = match execution.clone() { + Execution::RunAction(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::BatchRunAction(request) => komodo_client() - .execute(request) - .await - .map(ExecutionResult::Batch), - Execution::RunProcedure(request) => komodo_client() + Execution::BatchRunAction(request) => { + client.execute(request).await.map(ExecutionResult::Batch) + } + Execution::RunProcedure(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::BatchRunProcedure(request) => komodo_client() - .execute(request) - .await - .map(ExecutionResult::Batch), - Execution::RunBuild(request) => komodo_client() + Execution::BatchRunProcedure(request) => { + client.execute(request).await.map(ExecutionResult::Batch) + } + Execution::RunBuild(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::BatchRunBuild(request) => komodo_client() - .execute(request) - .await - .map(ExecutionResult::Batch), - Execution::CancelBuild(request) => komodo_client() + Execution::BatchRunBuild(request) => { + client.execute(request).await.map(ExecutionResult::Batch) + } + Execution::CancelBuild(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::Deploy(request) => komodo_client() + Execution::Deploy(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::BatchDeploy(request) => komodo_client() - .execute(request) - .await - .map(ExecutionResult::Batch), - Execution::PullDeployment(request) => komodo_client() + Execution::BatchDeploy(request) => { + client.execute(request).await.map(ExecutionResult::Batch) + } + Execution::PullDeployment(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::StartDeployment(request) => komodo_client() + Execution::StartDeployment(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::RestartDeployment(request) => komodo_client() + Execution::RestartDeployment(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::PauseDeployment(request) => komodo_client() + Execution::PauseDeployment(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::UnpauseDeployment(request) => komodo_client() + Execution::UnpauseDeployment(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::StopDeployment(request) => komodo_client() + Execution::StopDeployment(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::DestroyDeployment(request) => komodo_client() + Execution::DestroyDeployment(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::BatchDestroyDeployment(request) => komodo_client() - .execute(request) - .await - .map(ExecutionResult::Batch), - Execution::CloneRepo(request) => komodo_client() + Execution::BatchDestroyDeployment(request) => { + client.execute(request).await.map(ExecutionResult::Batch) + } + Execution::CloneRepo(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::BatchCloneRepo(request) => komodo_client() - .execute(request) - .await - .map(ExecutionResult::Batch), - Execution::PullRepo(request) => komodo_client() + Execution::BatchCloneRepo(request) => { + client.execute(request).await.map(ExecutionResult::Batch) + } + Execution::PullRepo(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::BatchPullRepo(request) => komodo_client() - .execute(request) - .await - .map(ExecutionResult::Batch), - Execution::BuildRepo(request) => komodo_client() + Execution::BatchPullRepo(request) => { + client.execute(request).await.map(ExecutionResult::Batch) + } + Execution::BuildRepo(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::BatchBuildRepo(request) => komodo_client() - .execute(request) - .await - .map(ExecutionResult::Batch), - Execution::CancelRepoBuild(request) => komodo_client() + Execution::BatchBuildRepo(request) => { + client.execute(request).await.map(ExecutionResult::Batch) + } + Execution::CancelRepoBuild(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::StartContainer(request) => komodo_client() + Execution::StartContainer(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::RestartContainer(request) => komodo_client() + Execution::RestartContainer(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::PauseContainer(request) => komodo_client() + Execution::PauseContainer(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::UnpauseContainer(request) => komodo_client() + Execution::UnpauseContainer(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::StopContainer(request) => komodo_client() + Execution::StopContainer(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::DestroyContainer(request) => komodo_client() + Execution::DestroyContainer(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::StartAllContainers(request) => komodo_client() + Execution::StartAllContainers(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::RestartAllContainers(request) => komodo_client() + Execution::RestartAllContainers(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::PauseAllContainers(request) => komodo_client() + Execution::PauseAllContainers(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::UnpauseAllContainers(request) => komodo_client() + Execution::UnpauseAllContainers(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::StopAllContainers(request) => komodo_client() + Execution::StopAllContainers(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::PruneContainers(request) => komodo_client() + Execution::PruneContainers(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::DeleteNetwork(request) => komodo_client() + Execution::DeleteNetwork(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::PruneNetworks(request) => komodo_client() + Execution::PruneNetworks(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::DeleteImage(request) => komodo_client() + Execution::DeleteImage(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::PruneImages(request) => komodo_client() + Execution::PruneImages(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::DeleteVolume(request) => komodo_client() + Execution::DeleteVolume(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::PruneVolumes(request) => komodo_client() + Execution::PruneVolumes(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::PruneDockerBuilders(request) => komodo_client() + Execution::PruneDockerBuilders(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::PruneBuildx(request) => komodo_client() + Execution::PruneBuildx(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::PruneSystem(request) => komodo_client() + Execution::PruneSystem(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::RunSync(request) => komodo_client() + Execution::RunSync(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::CommitSync(request) => komodo_client() + Execution::CommitSync(request) => client .write(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::DeployStack(request) => komodo_client() + Execution::DeployStack(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::BatchDeployStack(request) => komodo_client() - .execute(request) - .await - .map(ExecutionResult::Batch), - Execution::DeployStackIfChanged(request) => komodo_client() + Execution::BatchDeployStack(request) => { + client.execute(request).await.map(ExecutionResult::Batch) + } + Execution::DeployStackIfChanged(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::BatchDeployStackIfChanged(request) => komodo_client() - .execute(request) - .await - .map(ExecutionResult::Batch), - Execution::PullStack(request) => komodo_client() + Execution::BatchDeployStackIfChanged(request) => { + client.execute(request).await.map(ExecutionResult::Batch) + } + Execution::PullStack(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::BatchPullStack(request) => komodo_client() - .execute(request) - .await - .map(ExecutionResult::Batch), - Execution::StartStack(request) => komodo_client() + Execution::BatchPullStack(request) => { + client.execute(request).await.map(ExecutionResult::Batch) + } + Execution::StartStack(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::RestartStack(request) => komodo_client() + Execution::RestartStack(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::PauseStack(request) => komodo_client() + Execution::PauseStack(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::UnpauseStack(request) => komodo_client() + Execution::UnpauseStack(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::StopStack(request) => komodo_client() + Execution::StopStack(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::DestroyStack(request) => komodo_client() + Execution::DestroyStack(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), - Execution::BatchDestroyStack(request) => komodo_client() + Execution::BatchDestroyStack(request) => { + client.execute(request).await.map(ExecutionResult::Batch) + } + Execution::TestAlerter(request) => client .execute(request) .await - .map(ExecutionResult::Batch), - Execution::TestAlerter(request) => komodo_client() + .map(|u| ExecutionResult::Single(u.into())), + Execution::ClearRepoCache(request) => client + .execute(request) + .await + .map(|u| ExecutionResult::Single(u.into())), + Execution::BackupCoreDatabase(request) => client + .execute(request) + .await + .map(|u| ExecutionResult::Single(u.into())), + Execution::GlobalAutoUpdate(request) => client .execute(request) .await .map(|u| ExecutionResult::Single(u.into())), @@ -480,13 +492,67 @@ pub async fn run(execution: Execution) -> anyhow::Result<()> { match res { Ok(ExecutionResult::Single(update)) => { - println!("\n{}: {update:#?}", "SUCCESS".green()) + poll_update_until_complete(&update).await } - Ok(ExecutionResult::Batch(update)) => { - println!("\n{}: {update:#?}", "SUCCESS".green()) + Ok(ExecutionResult::Batch(updates)) => { + let mut handles = updates + .iter() + .map(|update| async move { + match update { + BatchExecutionResponseItem::Ok(update) => { + poll_update_until_complete(update).await + } + BatchExecutionResponseItem::Err(e) => { + error!("{e:#?}"); + Ok(()) + } + } + }) + .collect::>(); + while let Some(res) = handles.next().await { + match res { + Ok(()) => {} + Err(e) => { + error!("{e:#?}"); + } + } + } + Ok(()) + } + Err(e) => { + error!("{e:#?}"); + Ok(()) } - Err(e) => println!("{}\n\n{e:#?}", "ERROR".red()), } +} +async fn poll_update_until_complete( + update: &Update, +) -> anyhow::Result<()> { + let link = if update.id.is_empty() { + let (resource_type, id) = update.target.extract_variant_id(); + resource_link(&cli_config().host, resource_type, id) + } else { + format!("{}/updates/{}", cli_config().host, update.id) + }; + info!("Link: '{}'", link.bold()); + + let client = super::komodo_client().await?; + + let timer = tokio::time::Instant::now(); + let update = client.poll_update_until_complete(&update.id).await?; + if update.success { + info!( + "FINISHED in {}: {}", + format!("{:.1?}", timer.elapsed()).bold(), + "EXECUTION SUCCESSFUL".green(), + ); + } else { + warn!( + "FINISHED in {}: {}", + format!("{:.1?}", timer.elapsed()).bold(), + "EXECUTION FAILED".red(), + ); + } Ok(()) } diff --git a/bin/cli/src/command/list.rs b/bin/cli/src/command/list.rs new file mode 100644 index 000000000..d097f61fb --- /dev/null +++ b/bin/cli/src/command/list.rs @@ -0,0 +1,1171 @@ +use std::{cmp::Ordering, collections::HashMap}; + +use comfy_table::{Attribute, Cell, Color}; +use futures_util::{FutureExt, try_join}; +use komodo_client::{ + KomodoClient, + api::read::{ + ListActions, ListAlerters, ListBuilders, ListBuilds, + ListDeployments, ListProcedures, ListRepos, ListResourceSyncs, + ListSchedules, ListServers, ListStacks, ListTags, + }, + entities::{ + ResourceTargetVariant, + action::{ActionListItem, ActionListItemInfo, ActionState}, + alerter::{AlerterListItem, AlerterListItemInfo}, + build::{BuildListItem, BuildListItemInfo, BuildState}, + builder::{BuilderListItem, BuilderListItemInfo}, + config::cli::args::{ + self, + list::{ListCommand, ResourceFilters}, + }, + deployment::{ + DeploymentListItem, DeploymentListItemInfo, DeploymentState, + }, + procedure::{ + ProcedureListItem, ProcedureListItemInfo, ProcedureState, + }, + repo::{RepoListItem, RepoListItemInfo, RepoState}, + resource::{ResourceListItem, ResourceQuery}, + resource_link, + schedule::Schedule, + server::{ServerListItem, ServerListItemInfo, ServerState}, + stack::{StackListItem, StackListItemInfo, StackState}, + sync::{ + ResourceSyncListItem, ResourceSyncListItemInfo, + ResourceSyncState, + }, + }, +}; +use serde::Serialize; + +use crate::{ + command::{ + PrintTable, format_timetamp, matches_wildcards, parse_wildcards, + print_items, + }, + config::cli_config, +}; + +pub async fn handle(list: &args::list::List) -> anyhow::Result<()> { + match &list.command { + None => list_all(list).await, + Some(ListCommand::Servers(filters)) => { + list_resources::(filters, false).await + } + Some(ListCommand::Stacks(filters)) => { + list_resources::(filters, false).await + } + Some(ListCommand::Deployments(filters)) => { + list_resources::(filters, false).await + } + Some(ListCommand::Builds(filters)) => { + list_resources::(filters, false).await + } + Some(ListCommand::Repos(filters)) => { + list_resources::(filters, false).await + } + Some(ListCommand::Procedures(filters)) => { + list_resources::(filters, false).await + } + Some(ListCommand::Actions(filters)) => { + list_resources::(filters, false).await + } + Some(ListCommand::Syncs(filters)) => { + list_resources::(filters, false).await + } + Some(ListCommand::Builders(filters)) => { + list_resources::(filters, false).await + } + Some(ListCommand::Alerters(filters)) => { + list_resources::(filters, false).await + } + Some(ListCommand::Schedules(filters)) => { + list_schedules(filters).await + } + } +} + +/// Includes all resources besides builds and alerters. +async fn list_all(list: &args::list::List) -> anyhow::Result<()> { + let filters: ResourceFilters = list.clone().into(); + let client = super::komodo_client().await?; + let ( + tags, + mut servers, + mut stacks, + mut deployments, + mut builds, + mut repos, + mut procedures, + mut actions, + mut syncs, + ) = try_join!( + client.read(ListTags::default()).map(|res| res.map(|res| res + .into_iter() + .map(|t| (t.id, t.name)) + .collect::>())), + ServerListItem::list(client, &filters, true), + StackListItem::list(client, &filters, true), + DeploymentListItem::list(client, &filters, true), + BuildListItem::list(client, &filters, true), + RepoListItem::list(client, &filters, true), + ProcedureListItem::list(client, &filters, true), + ActionListItem::list(client, &filters, true), + ResourceSyncListItem::list(client, &filters, true), + )?; + + if !servers.is_empty() { + fix_tags(&mut servers, &tags); + print_items(servers, filters.format, list.links)?; + println!(); + } + + if !stacks.is_empty() { + fix_tags(&mut stacks, &tags); + print_items(stacks, filters.format, list.links)?; + println!(); + } + + if !deployments.is_empty() { + fix_tags(&mut deployments, &tags); + print_items(deployments, filters.format, list.links)?; + println!(); + } + + if !builds.is_empty() { + fix_tags(&mut builds, &tags); + print_items(builds, filters.format, list.links)?; + println!(); + } + + if !repos.is_empty() { + fix_tags(&mut repos, &tags); + print_items(repos, filters.format, list.links)?; + println!(); + } + + if !procedures.is_empty() { + fix_tags(&mut procedures, &tags); + print_items(procedures, filters.format, list.links)?; + println!(); + } + + if !actions.is_empty() { + fix_tags(&mut actions, &tags); + print_items(actions, filters.format, list.links)?; + println!(); + } + + if !syncs.is_empty() { + fix_tags(&mut syncs, &tags); + print_items(syncs, filters.format, list.links)?; + println!(); + } + + Ok(()) +} + +async fn list_resources( + filters: &ResourceFilters, + minimal: bool, +) -> anyhow::Result<()> +where + T: ListResources, + ResourceListItem: PrintTable + Serialize, +{ + let client = crate::command::komodo_client().await?; + let (mut resources, tags) = tokio::try_join!( + T::list(client, filters, minimal), + client.read(ListTags::default()).map(|res| res.map(|res| res + .into_iter() + .map(|t| (t.id, t.name)) + .collect::>())) + )?; + fix_tags(&mut resources, &tags); + if !resources.is_empty() { + print_items(resources, filters.format, filters.links)?; + } + Ok(()) +} + +async fn list_schedules( + filters: &ResourceFilters, +) -> anyhow::Result<()> { + let client = crate::command::komodo_client().await?; + let (mut schedules, tags) = tokio::try_join!( + client + .read(ListSchedules { + tags: filters.tags.clone(), + tag_behavior: Default::default(), + }) + .map(|res| res.map(|res| res + .into_iter() + .filter(|s| s.next_scheduled_run.is_some()) + .collect::>())), + client.read(ListTags::default()).map(|res| res.map(|res| res + .into_iter() + .map(|t| (t.id, t.name)) + .collect::>())) + )?; + schedules.iter_mut().for_each(|resource| { + resource.tags.iter_mut().for_each(|id| { + let Some(name) = tags.get(id) else { + *id = String::new(); + return; + }; + id.clone_from(name); + }); + }); + schedules.sort_by(|a, b| { + match (a.next_scheduled_run, b.next_scheduled_run) { + (Some(_), None) => return Ordering::Less, + (None, Some(_)) => return Ordering::Greater, + (Some(a), Some(b)) => return a.cmp(&b), + (None, None) => {} + } + a.name.cmp(&b.name).then(a.enabled.cmp(&b.enabled)) + }); + if !schedules.is_empty() { + print_items(schedules, filters.format, filters.links)?; + } + Ok(()) +} + +fn fix_tags( + resources: &mut Vec>, + tags: &HashMap, +) { + resources.iter_mut().for_each(|resource| { + resource.tags.iter_mut().for_each(|id| { + let Some(name) = tags.get(id) else { + *id = String::new(); + return; + }; + id.clone_from(name); + }); + }); +} + +trait ListResources: Sized +where + ResourceListItem: PrintTable, +{ + type Info; + async fn list( + client: &KomodoClient, + filters: &ResourceFilters, + // For use with root `km ls` + minimal: bool, + ) -> anyhow::Result>>; +} + +// LIST + +impl ListResources for ServerListItem { + type Info = ServerListItemInfo; + async fn list( + client: &KomodoClient, + filters: &ResourceFilters, + _minimal: bool, + ) -> anyhow::Result> { + let servers = client + .read(ListServers { + query: ResourceQuery::builder() + .tags(filters.tags.clone()) + // .tag_behavior(TagQueryBehavior::Any) + .templates(filters.templates) + .build(), + }) + .await?; + let names = parse_wildcards(&filters.names); + let server_wildcards = parse_wildcards(&filters.servers); + let mut servers = servers + .into_iter() + .filter(|server| { + let state_check = if filters.all { + true + } else if filters.down { + !matches!(server.info.state, ServerState::Ok) + } else if filters.in_progress { + false + } else { + matches!(server.info.state, ServerState::Ok) + }; + let name_items = &[server.name.as_str()]; + state_check + && matches_wildcards(&names, name_items) + && matches_wildcards(&server_wildcards, name_items) + }) + .collect::>(); + servers.sort_by(|a, b| { + a.info.state.cmp(&b.info.state).then(a.name.cmp(&b.name)) + }); + Ok(servers) + } +} + +impl ListResources for StackListItem { + type Info = StackListItemInfo; + async fn list( + client: &KomodoClient, + filters: &ResourceFilters, + _minimal: bool, + ) -> anyhow::Result> { + let (servers, mut stacks) = tokio::try_join!( + client + .read(ListServers { + query: ResourceQuery::builder().build(), + }) + .map(|res| res.map(|res| res + .into_iter() + .map(|s| (s.id.clone(), s)) + .collect::>())), + client.read(ListStacks { + query: ResourceQuery::builder() + .tags(filters.tags.clone()) + // .tag_behavior(TagQueryBehavior::Any) + .templates(filters.templates) + .build(), + }) + )?; + stacks.iter_mut().for_each(|stack| { + if stack.info.server_id.is_empty() { + return; + } + let Some(server) = servers.get(&stack.info.server_id) else { + return; + }; + stack.info.server_id.clone_from(&server.name); + }); + let names = parse_wildcards(&filters.names); + let servers = parse_wildcards(&filters.servers); + let mut stacks = stacks + .into_iter() + .filter(|stack| { + let state_check = if filters.all { + true + } else if filters.down { + !matches!( + stack.info.state, + StackState::Running | StackState::Deploying + ) + } else if filters.in_progress { + matches!(stack.info.state, StackState::Deploying) + } else { + matches!( + stack.info.state, + StackState::Running | StackState::Deploying + ) + }; + state_check + && matches_wildcards(&names, &[stack.name.as_str()]) + && matches_wildcards( + &servers, + &[stack.info.server_id.as_str()], + ) + }) + .collect::>(); + stacks.sort_by(|a, b| { + a.info + .state + .cmp(&b.info.state) + .then(a.name.cmp(&b.name)) + .then(a.info.server_id.cmp(&b.info.server_id)) + }); + Ok(stacks) + } +} + +impl ListResources for DeploymentListItem { + type Info = DeploymentListItemInfo; + async fn list( + client: &KomodoClient, + filters: &ResourceFilters, + _minimal: bool, + ) -> anyhow::Result> { + let (servers, mut deployments) = tokio::try_join!( + client + .read(ListServers { + query: ResourceQuery::builder().build(), + }) + .map(|res| res.map(|res| res + .into_iter() + .map(|s| (s.id.clone(), s)) + .collect::>())), + client.read(ListDeployments { + query: ResourceQuery::builder() + .tags(filters.tags.clone()) + // .tag_behavior(TagQueryBehavior::Any) + .templates(filters.templates) + .build(), + }) + )?; + deployments.iter_mut().for_each(|deployment| { + if deployment.info.server_id.is_empty() { + return; + } + let Some(server) = servers.get(&deployment.info.server_id) + else { + return; + }; + deployment.info.server_id.clone_from(&server.name); + }); + let names = parse_wildcards(&filters.names); + let servers = parse_wildcards(&filters.servers); + let mut deployments = deployments + .into_iter() + .filter(|deployment| { + let state_check = if filters.all { + true + } else if filters.down { + !matches!( + deployment.info.state, + DeploymentState::Running | DeploymentState::Deploying + ) + } else if filters.in_progress { + matches!(deployment.info.state, DeploymentState::Deploying) + } else { + matches!( + deployment.info.state, + DeploymentState::Running | DeploymentState::Deploying + ) + }; + state_check + && matches_wildcards(&names, &[deployment.name.as_str()]) + && matches_wildcards( + &servers, + &[deployment.info.server_id.as_str()], + ) + }) + .collect::>(); + deployments.sort_by(|a, b| { + a.info + .state + .cmp(&b.info.state) + .then(a.name.cmp(&b.name)) + .then(a.info.server_id.cmp(&b.info.server_id)) + }); + Ok(deployments) + } +} + +impl ListResources for BuildListItem { + type Info = BuildListItemInfo; + async fn list( + client: &KomodoClient, + filters: &ResourceFilters, + minimal: bool, + ) -> anyhow::Result> { + let (builders, mut builds) = tokio::try_join!( + client + .read(ListBuilders { + query: ResourceQuery::builder().build(), + }) + .map(|res| res.map(|res| res + .into_iter() + .map(|s| (s.id.clone(), s)) + .collect::>())), + client.read(ListBuilds { + query: ResourceQuery::builder() + .tags(filters.tags.clone()) + // .tag_behavior(TagQueryBehavior::Any) + .templates(filters.templates) + .build(), + }) + )?; + builds.iter_mut().for_each(|build| { + if build.info.builder_id.is_empty() { + return; + } + let Some(builder) = builders.get(&build.info.builder_id) else { + return; + }; + build.info.builder_id.clone_from(&builder.name); + }); + let names = parse_wildcards(&filters.names); + let builders = parse_wildcards(&filters.builders); + let mut builds = builds + .into_iter() + .filter(|build| { + let state_check = if filters.all { + true + } else if filters.down { + matches!( + build.info.state, + BuildState::Failed | BuildState::Unknown + ) + } else if minimal || filters.in_progress { + matches!(build.info.state, BuildState::Building) + } else { + true + }; + state_check + && matches_wildcards(&names, &[build.name.as_str()]) + && matches_wildcards( + &builders, + &[build.info.builder_id.as_str()], + ) + }) + .collect::>(); + builds.sort_by(|a, b| { + a.name + .cmp(&b.name) + .then(a.info.builder_id.cmp(&b.info.builder_id)) + .then(a.info.state.cmp(&b.info.state)) + }); + Ok(builds) + } +} + +impl ListResources for RepoListItem { + type Info = RepoListItemInfo; + async fn list( + client: &KomodoClient, + filters: &ResourceFilters, + minimal: bool, + ) -> anyhow::Result> { + let names = parse_wildcards(&filters.names); + let mut repos = client + .read(ListRepos { + query: ResourceQuery::builder() + .tags(filters.tags.clone()) + // .tag_behavior(TagQueryBehavior::Any) + .templates(filters.templates) + .build(), + }) + .await? + .into_iter() + .filter(|repo| { + let state_check = if filters.all { + true + } else if filters.down { + matches!( + repo.info.state, + RepoState::Failed | RepoState::Unknown + ) + } else if minimal || filters.in_progress { + matches!( + repo.info.state, + RepoState::Building | RepoState::Cloning + ) + } else { + true + }; + state_check + && matches_wildcards(&names, &[repo.name.as_str()]) + }) + .collect::>(); + repos.sort_by(|a, b| { + a.name + .cmp(&b.name) + .then(a.info.server_id.cmp(&b.info.server_id)) + .then(a.info.builder_id.cmp(&b.info.builder_id)) + }); + Ok(repos) + } +} + +impl ListResources for ProcedureListItem { + type Info = ProcedureListItemInfo; + async fn list( + client: &KomodoClient, + filters: &ResourceFilters, + minimal: bool, + ) -> anyhow::Result> { + let names = parse_wildcards(&filters.names); + let mut procedures = client + .read(ListProcedures { + query: ResourceQuery::builder() + .tags(filters.tags.clone()) + // .tag_behavior(TagQueryBehavior::Any) + .templates(filters.templates) + .build(), + }) + .await? + .into_iter() + .filter(|procedure| { + let state_check = if filters.all { + true + } else if filters.down { + matches!( + procedure.info.state, + ProcedureState::Failed | ProcedureState::Unknown + ) + } else if minimal || filters.in_progress { + matches!(procedure.info.state, ProcedureState::Running) + } else { + true + }; + state_check + && matches_wildcards(&names, &[procedure.name.as_str()]) + }) + .collect::>(); + procedures.sort_by(|a, b| { + match (a.info.next_scheduled_run, b.info.next_scheduled_run) { + (Some(_), None) => return Ordering::Less, + (None, Some(_)) => return Ordering::Greater, + (Some(a), Some(b)) => return a.cmp(&b), + (None, None) => {} + } + a.name.cmp(&b.name).then(a.info.state.cmp(&b.info.state)) + }); + Ok(procedures) + } +} + +impl ListResources for ActionListItem { + type Info = ActionListItemInfo; + async fn list( + client: &KomodoClient, + filters: &ResourceFilters, + minimal: bool, + ) -> anyhow::Result> { + let names = parse_wildcards(&filters.names); + let mut actions = client + .read(ListActions { + query: ResourceQuery::builder() + .tags(filters.tags.clone()) + // .tag_behavior(TagQueryBehavior::Any) + .templates(filters.templates) + .build(), + }) + .await? + .into_iter() + .filter(|action| { + let state_check = if filters.all { + true + } else if filters.down { + matches!( + action.info.state, + ActionState::Failed | ActionState::Unknown + ) + } else if minimal || filters.in_progress { + matches!(action.info.state, ActionState::Running) + } else { + true + }; + state_check + && matches_wildcards(&names, &[action.name.as_str()]) + }) + .collect::>(); + actions.sort_by(|a, b| { + match (a.info.next_scheduled_run, b.info.next_scheduled_run) { + (Some(_), None) => return Ordering::Less, + (None, Some(_)) => return Ordering::Greater, + (Some(a), Some(b)) => return a.cmp(&b), + (None, None) => {} + } + a.name.cmp(&b.name).then(a.info.state.cmp(&b.info.state)) + }); + Ok(actions) + } +} + +impl ListResources for ResourceSyncListItem { + type Info = ResourceSyncListItemInfo; + async fn list( + client: &KomodoClient, + filters: &ResourceFilters, + minimal: bool, + ) -> anyhow::Result> { + let names = parse_wildcards(&filters.names); + let mut syncs = client + .read(ListResourceSyncs { + query: ResourceQuery::builder() + .tags(filters.tags.clone()) + // .tag_behavior(TagQueryBehavior::Any) + .templates(filters.templates) + .build(), + }) + .await? + .into_iter() + .filter(|sync| { + let state_check = if filters.all { + true + } else if filters.down { + matches!( + sync.info.state, + ResourceSyncState::Failed | ResourceSyncState::Unknown + ) + } else if minimal || filters.in_progress { + matches!( + sync.info.state, + ResourceSyncState::Syncing | ResourceSyncState::Pending + ) + } else { + true + }; + state_check + && matches_wildcards(&names, &[sync.name.as_str()]) + }) + .collect::>(); + syncs.sort_by(|a, b| { + a.name.cmp(&b.name).then(a.info.state.cmp(&b.info.state)) + }); + Ok(syncs) + } +} + +impl ListResources for BuilderListItem { + type Info = BuilderListItemInfo; + async fn list( + client: &KomodoClient, + filters: &ResourceFilters, + minimal: bool, + ) -> anyhow::Result> { + let names = parse_wildcards(&filters.names); + let mut builders = client + .read(ListBuilders { + query: ResourceQuery::builder() + .tags(filters.tags.clone()) + // .tag_behavior(TagQueryBehavior::Any) + .templates(filters.templates) + .build(), + }) + .await? + .into_iter() + .filter(|builder| { + (!minimal || filters.all) + && matches_wildcards(&names, &[builder.name.as_str()]) + }) + .collect::>(); + builders.sort_by(|a, b| { + a.name + .cmp(&b.name) + .then(a.info.builder_type.cmp(&b.info.builder_type)) + }); + Ok(builders) + } +} + +impl ListResources for AlerterListItem { + type Info = AlerterListItemInfo; + async fn list( + client: &KomodoClient, + filters: &ResourceFilters, + minimal: bool, + ) -> anyhow::Result> { + let names = parse_wildcards(&filters.names); + let mut syncs = client + .read(ListAlerters { + query: ResourceQuery::builder() + .tags(filters.tags.clone()) + // .tag_behavior(TagQueryBehavior::Any) + .templates(filters.templates) + .build(), + }) + .await? + .into_iter() + .filter(|sync| { + (!minimal || filters.all) + && matches_wildcards(&names, &[sync.name.as_str()]) + }) + .collect::>(); + syncs.sort_by(|a, b| { + a.info + .enabled + .cmp(&b.info.enabled) + .then(a.name.cmp(&b.name)) + .then(a.info.endpoint_type.cmp(&b.info.endpoint_type)) + }); + Ok(syncs) + } +} + +// TABLE + +impl PrintTable for ResourceListItem { + fn header(links: bool) -> &'static [&'static str] { + if links { + &["Server", "State", "Address", "Tags", "Link"] + } else { + &["Server", "State", "Address", "Tags"] + } + } + fn row(self, links: bool) -> Vec { + let color = match self.info.state { + ServerState::Ok => Color::Green, + ServerState::NotOk => Color::Red, + ServerState::Disabled => Color::Blue, + }; + let mut res = vec![ + Cell::new(self.name).add_attribute(Attribute::Bold), + Cell::new(self.info.state.to_string()) + .fg(color) + .add_attribute(Attribute::Bold), + Cell::new(self.info.address), + Cell::new(self.tags.join(", ")), + ]; + if links { + res.push(Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::Server, + &self.id, + ))) + } + res + } +} + +impl PrintTable for ResourceListItem { + fn header(links: bool) -> &'static [&'static str] { + if links { + &["Stack", "State", "Server", "Tags", "Link"] + } else { + &["Stack", "State", "Server", "Tags"] + } + } + fn row(self, links: bool) -> Vec { + let color = match self.info.state { + StackState::Down => Color::Blue, + StackState::Running => Color::Green, + StackState::Deploying => Color::DarkYellow, + StackState::Paused => Color::DarkYellow, + StackState::Unknown => Color::Magenta, + _ => Color::Red, + }; + // let source = if self.info.files_on_host { + // "On Host" + // } else if !self.info.repo.is_empty() { + // self.info.repo_link.as_str() + // } else { + // "UI Defined" + // }; + let mut res = vec![ + Cell::new(self.name).add_attribute(Attribute::Bold), + Cell::new(self.info.state.to_string()) + .fg(color) + .add_attribute(Attribute::Bold), + Cell::new(self.info.server_id), + // Cell::new(source), + Cell::new(self.tags.join(", ")), + ]; + if links { + res.push(Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::Stack, + &self.id, + ))) + } + res + } +} + +impl PrintTable for ResourceListItem { + fn header(links: bool) -> &'static [&'static str] { + if links { + &["Deployment", "State", "Server", "Tags", "Link"] + } else { + &["Deployment", "State", "Server", "Tags"] + } + } + fn row(self, links: bool) -> Vec { + let color = match self.info.state { + DeploymentState::NotDeployed => Color::Blue, + DeploymentState::Running => Color::Green, + DeploymentState::Deploying => Color::DarkYellow, + DeploymentState::Paused => Color::DarkYellow, + DeploymentState::Unknown => Color::Magenta, + _ => Color::Red, + }; + let mut res = vec![ + Cell::new(self.name).add_attribute(Attribute::Bold), + Cell::new(self.info.state.to_string()) + .fg(color) + .add_attribute(Attribute::Bold), + Cell::new(self.info.server_id), + Cell::new(self.tags.join(", ")), + ]; + if links { + res.push(Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::Deployment, + &self.id, + ))) + } + res + } +} + +impl PrintTable for ResourceListItem { + fn header(links: bool) -> &'static [&'static str] { + if links { + &["Build", "State", "Builder", "Tags", "Link"] + } else { + &["Build", "State", "Builder", "Tags"] + } + } + fn row(self, links: bool) -> Vec { + let color = match self.info.state { + BuildState::Ok => Color::Green, + BuildState::Building => Color::DarkYellow, + BuildState::Unknown => Color::Magenta, + BuildState::Failed => Color::Red, + }; + let mut res = vec![ + Cell::new(self.name).add_attribute(Attribute::Bold), + Cell::new(self.info.state.to_string()) + .fg(color) + .add_attribute(Attribute::Bold), + Cell::new(self.info.builder_id), + Cell::new(self.tags.join(", ")), + ]; + if links { + res.push(Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::Build, + &self.id, + ))); + } + res + } +} + +impl PrintTable for ResourceListItem { + fn header(links: bool) -> &'static [&'static str] { + if links { + &["Repo", "State", "Link", "Tags", "Link"] + } else { + &["Repo", "State", "Link", "Tags"] + } + } + fn row(self, links: bool) -> Vec { + let color = match self.info.state { + RepoState::Ok => Color::Green, + RepoState::Building + | RepoState::Cloning + | RepoState::Pulling => Color::DarkYellow, + RepoState::Unknown => Color::Magenta, + RepoState::Failed => Color::Red, + }; + let mut res = vec![ + Cell::new(self.name).add_attribute(Attribute::Bold), + Cell::new(self.info.state.to_string()) + .fg(color) + .add_attribute(Attribute::Bold), + Cell::new(self.info.repo_link), + Cell::new(self.tags.join(", ")), + ]; + if links { + res.push(Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::Repo, + &self.id, + ))) + } + res + } +} + +impl PrintTable for ResourceListItem { + fn header(links: bool) -> &'static [&'static str] { + if links { + &["Procedure", "State", "Next Run", "Tags", "Link"] + } else { + &["Procedure", "State", "Next Run", "Tags"] + } + } + fn row(self, links: bool) -> Vec { + let color = match self.info.state { + ProcedureState::Ok => Color::Green, + ProcedureState::Running => Color::DarkYellow, + ProcedureState::Unknown => Color::Magenta, + ProcedureState::Failed => Color::Red, + }; + let next_run = if let Some(ts) = self.info.next_scheduled_run { + Cell::new( + format_timetamp(ts) + .unwrap_or(String::from("Invalid next ts")), + ) + .add_attribute(Attribute::Bold) + } else { + Cell::new(String::from("None")) + }; + let mut res = vec![ + Cell::new(self.name).add_attribute(Attribute::Bold), + Cell::new(self.info.state.to_string()) + .fg(color) + .add_attribute(Attribute::Bold), + next_run, + Cell::new(self.tags.join(", ")), + ]; + if links { + res.push(Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::Procedure, + &self.id, + ))) + } + res + } +} + +impl PrintTable for ResourceListItem { + fn header(links: bool) -> &'static [&'static str] { + if links { + &["Action", "State", "Next Run", "Tags", "Link"] + } else { + &["Action", "State", "Next Run", "Tags"] + } + } + fn row(self, links: bool) -> Vec { + let color = match self.info.state { + ActionState::Ok => Color::Green, + ActionState::Running => Color::DarkYellow, + ActionState::Unknown => Color::Magenta, + ActionState::Failed => Color::Red, + }; + let next_run = if let Some(ts) = self.info.next_scheduled_run { + Cell::new( + format_timetamp(ts) + .unwrap_or(String::from("Invalid next ts")), + ) + .add_attribute(Attribute::Bold) + } else { + Cell::new(String::from("None")) + }; + let mut res = vec![ + Cell::new(self.name).add_attribute(Attribute::Bold), + Cell::new(self.info.state.to_string()) + .fg(color) + .add_attribute(Attribute::Bold), + next_run, + Cell::new(self.tags.join(", ")), + ]; + if links { + res.push(Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::Action, + &self.id, + ))); + } + res + } +} + +impl PrintTable for ResourceListItem { + fn header(links: bool) -> &'static [&'static str] { + if links { + &["Sync", "State", "Tags", "Link"] + } else { + &["Sync", "State", "Tags"] + } + } + fn row(self, links: bool) -> Vec { + let color = match self.info.state { + ResourceSyncState::Ok => Color::Green, + ResourceSyncState::Pending | ResourceSyncState::Syncing => { + Color::DarkYellow + } + ResourceSyncState::Unknown => Color::Magenta, + ResourceSyncState::Failed => Color::Red, + }; + let mut res = vec![ + Cell::new(self.name).add_attribute(Attribute::Bold), + Cell::new(self.info.state.to_string()) + .fg(color) + .add_attribute(Attribute::Bold), + Cell::new(self.tags.join(", ")), + ]; + if links { + res.push(Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::ResourceSync, + &self.id, + ))) + } + res + } +} + +impl PrintTable for ResourceListItem { + fn header(links: bool) -> &'static [&'static str] { + if links { + &["Builder", "Type", "Tags", "Link"] + } else { + &["Builder", "Type", "Tags"] + } + } + fn row(self, links: bool) -> Vec { + let mut res = vec![ + Cell::new(self.name).add_attribute(Attribute::Bold), + Cell::new(self.info.builder_type), + Cell::new(self.tags.join(", ")), + ]; + if links { + res.push(Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::Builder, + &self.id, + ))); + } + res + } +} + +impl PrintTable for ResourceListItem { + fn header(links: bool) -> &'static [&'static str] { + if links { + &["Alerter", "Type", "Enabled", "Tags", "Link"] + } else { + &["Alerter", "Type", "Enabled", "Tags"] + } + } + fn row(self, links: bool) -> Vec { + let mut row = vec![ + Cell::new(self.name).add_attribute(Attribute::Bold), + Cell::new(self.info.endpoint_type), + if self.info.enabled { + Cell::new(self.info.enabled.to_string()).fg(Color::Green) + } else { + Cell::new(self.info.enabled.to_string()).fg(Color::Red) + }, + Cell::new(self.tags.join(", ")), + ]; + if links { + row.push(Cell::new(resource_link( + &cli_config().host, + ResourceTargetVariant::Alerter, + &self.id, + ))); + } + row + } +} + +impl PrintTable for Schedule { + fn header(links: bool) -> &'static [&'static str] { + if links { + &["Name", "Type", "Next Run", "Tags", "Link"] + } else { + &["Name", "Type", "Next Run", "Tags"] + } + } + fn row(self, links: bool) -> Vec { + let next_run = if let Some(ts) = self.next_scheduled_run { + Cell::new( + format_timetamp(ts) + .unwrap_or(String::from("Invalid next ts")), + ) + .add_attribute(Attribute::Bold) + } else { + Cell::new(String::from("None")) + }; + let (resource_type, id) = self.target.extract_variant_id(); + let mut res = vec![ + Cell::new(self.name).add_attribute(Attribute::Bold), + Cell::new(self.target.extract_variant_id().0), + next_run, + Cell::new(self.tags.join(", ")), + ]; + if links { + res.push(Cell::new(resource_link( + &cli_config().host, + resource_type, + id, + ))); + } + res + } +} diff --git a/bin/cli/src/command/mod.rs b/bin/cli/src/command/mod.rs new file mode 100644 index 000000000..282b0b65c --- /dev/null +++ b/bin/cli/src/command/mod.rs @@ -0,0 +1,181 @@ +use std::io::Read; + +use anyhow::{Context, anyhow}; +use chrono::TimeZone; +use colored::Colorize; +use comfy_table::{Attribute, Cell, Table}; +use komodo_client::{ + KomodoClient, + entities::config::cli::{CliTableBorders, args::CliFormat}, +}; +use serde::Serialize; +use tokio::sync::OnceCell; +use wildcard::Wildcard; + +use crate::config::cli_config; + +pub mod container; +pub mod database; +pub mod execute; +pub mod list; +pub mod update; + +async fn komodo_client() -> anyhow::Result<&'static KomodoClient> { + static KOMODO_CLIENT: OnceCell = + OnceCell::const_new(); + KOMODO_CLIENT + .get_or_try_init(|| async { + let config = cli_config(); + let (Some(key), Some(secret)) = + (&config.cli_key, &config.cli_secret) + else { + return Err(anyhow!( + "Must provide both cli_key and cli_secret" + )); + }; + KomodoClient::new(&config.host, key, secret) + .with_healthcheck() + .await + }) + .await +} + +fn wait_for_enter( + press_enter_to: &str, + skip: bool, +) -> anyhow::Result<()> { + if skip { + println!(); + return Ok(()); + } + println!( + "\nPress {} to {}\n", + "ENTER".green(), + press_enter_to.bold() + ); + let buffer = &mut [0u8]; + std::io::stdin() + .read_exact(buffer) + .context("failed to read ENTER")?; + Ok(()) +} + +/// Sanitizes uris of the form: +/// `protocol://username:password@address` +fn sanitize_uri(uri: &str) -> String { + // protocol: `mongodb` + // credentials_address: `username:password@address` + let Some((protocol, credentials_address)) = uri.split_once("://") + else { + // If no protocol, return as-is + return uri.to_string(); + }; + + // credentials: `username:password` + let Some((credentials, address)) = + credentials_address.split_once('@') + else { + // If no credentials, return as-is + return uri.to_string(); + }; + + match credentials.split_once(':') { + Some((username, _)) => { + format!("{protocol}://{username}:*****@{address}") + } + None => { + format!("{protocol}://*****@{address}") + } + } +} + +fn print_items( + items: Vec, + format: CliFormat, + links: bool, +) -> anyhow::Result<()> { + match format { + CliFormat::Table => { + let mut table = Table::new(); + let preset = { + use comfy_table::presets::*; + match cli_config().table_borders { + None | Some(CliTableBorders::Horizontal) => { + UTF8_HORIZONTAL_ONLY + } + Some(CliTableBorders::Vertical) => UTF8_FULL_CONDENSED, + Some(CliTableBorders::Inside) => UTF8_NO_BORDERS, + Some(CliTableBorders::Outside) => UTF8_BORDERS_ONLY, + Some(CliTableBorders::All) => UTF8_FULL, + } + }; + table.load_preset(preset).set_header( + T::header(links) + .into_iter() + .map(|h| Cell::new(h).add_attribute(Attribute::Bold)), + ); + for item in items { + table.add_row(item.row(links)); + } + println!("{table}"); + } + CliFormat::Json => { + println!( + "{}", + serde_json::to_string_pretty(&items) + .context("Failed to serialize items to JSON")? + ); + } + } + Ok(()) +} + +trait PrintTable { + fn header(links: bool) -> &'static [&'static str]; + fn row(self, links: bool) -> Vec; +} + +fn parse_wildcards(items: &[String]) -> Vec> { + items + .iter() + .flat_map(|i| { + Wildcard::new(i.as_bytes()).inspect_err(|e| { + warn!("Failed to parse wildcard: {i} | {e:?}") + }) + }) + .collect::>() +} + +fn matches_wildcards( + wildcards: &[Wildcard<'_>], + items: &[&str], +) -> bool { + if wildcards.is_empty() { + return true; + } + items.iter().any(|item| { + wildcards.iter().any(|wc| wc.is_match(item.as_bytes())) + }) +} + +fn format_timetamp(ts: i64) -> anyhow::Result { + let ts = chrono::Local + .timestamp_millis_opt(ts) + .single() + .context("Invalid ts")? + .format("%m/%d %H:%M:%S") + .to_string(); + Ok(ts) +} + +fn clamp_sha(maybe_sha: &str) -> String { + if maybe_sha.starts_with("sha256:") { + maybe_sha[0..20].to_string() + "..." + } else { + maybe_sha.to_string() + } +} + +// fn text_link(link: &str, text: &str) -> String { +// format!("\x1b]8;;{link}\x07{text}\x1b]8;;\x07") +// } diff --git a/bin/cli/src/command/update/mod.rs b/bin/cli/src/command/update/mod.rs new file mode 100644 index 000000000..328ba3951 --- /dev/null +++ b/bin/cli/src/command/update/mod.rs @@ -0,0 +1,43 @@ +use komodo_client::entities::{ + build::PartialBuildConfig, + config::cli::args::update::UpdateCommand, + deployment::PartialDeploymentConfig, repo::PartialRepoConfig, + server::PartialServerConfig, stack::PartialStackConfig, + sync::PartialResourceSyncConfig, +}; + +mod resource; +mod user; +mod variable; + +pub async fn handle(command: &UpdateCommand) -> anyhow::Result<()> { + match command { + UpdateCommand::Build(update) => { + resource::update::(update).await + } + UpdateCommand::Deployment(update) => { + resource::update::(update).await + } + UpdateCommand::Repo(update) => { + resource::update::(update).await + } + UpdateCommand::Server(update) => { + resource::update::(update).await + } + UpdateCommand::Stack(update) => { + resource::update::(update).await + } + UpdateCommand::Sync(update) => { + resource::update::(update).await + } + UpdateCommand::Variable { + name, + value, + secret, + yes, + } => variable::update(name, value, *secret, *yes).await, + UpdateCommand::User { username, command } => { + user::update(username, command).await + } + } +} diff --git a/bin/cli/src/command/update/resource.rs b/bin/cli/src/command/update/resource.rs new file mode 100644 index 000000000..37810531c --- /dev/null +++ b/bin/cli/src/command/update/resource.rs @@ -0,0 +1,152 @@ +use anyhow::Context; +use colored::Colorize; +use komodo_client::{ + api::write::{ + UpdateBuild, UpdateDeployment, UpdateRepo, UpdateResourceSync, + UpdateServer, UpdateStack, + }, + entities::{ + build::PartialBuildConfig, + config::cli::args::update::UpdateResource, + deployment::PartialDeploymentConfig, repo::PartialRepoConfig, + server::PartialServerConfig, stack::PartialStackConfig, + sync::PartialResourceSyncConfig, + }, +}; +use serde::{Serialize, de::DeserializeOwned}; + +pub async fn update< + T: std::fmt::Debug + Serialize + DeserializeOwned + ResourceUpdate, +>( + UpdateResource { + resource, + update, + yes, + }: &UpdateResource, +) -> anyhow::Result<()> { + println!("\n{}: Update {}\n", "Mode".dimmed(), T::resource_type()); + println!(" - {}: {resource}", "Name".dimmed()); + + let config = serde_qs::from_str::(update) + .context("Failed to deserialize config")?; + + match serde_json::to_string_pretty(&config) { + Ok(config) => { + println!(" - {}: {config}", "Update".dimmed()); + } + Err(_) => { + println!(" - {}: {config:#?}", "Update".dimmed()); + } + } + + crate::command::wait_for_enter("update resource", *yes)?; + + config.apply(resource).await +} + +pub trait ResourceUpdate { + fn resource_type() -> &'static str; + async fn apply(self, resource: &str) -> anyhow::Result<()>; +} + +impl ResourceUpdate for PartialBuildConfig { + fn resource_type() -> &'static str { + "Build" + } + async fn apply(self, resource: &str) -> anyhow::Result<()> { + let client = crate::command::komodo_client().await?; + client + .write(UpdateBuild { + id: resource.to_string(), + config: self, + }) + .await + .context("Failed to update build config")?; + Ok(()) + } +} + +impl ResourceUpdate for PartialDeploymentConfig { + fn resource_type() -> &'static str { + "Deployment" + } + async fn apply(self, resource: &str) -> anyhow::Result<()> { + let client = crate::command::komodo_client().await?; + client + .write(UpdateDeployment { + id: resource.to_string(), + config: self, + }) + .await + .context("Failed to update deployment config")?; + Ok(()) + } +} + +impl ResourceUpdate for PartialRepoConfig { + fn resource_type() -> &'static str { + "Repo" + } + async fn apply(self, resource: &str) -> anyhow::Result<()> { + let client = crate::command::komodo_client().await?; + client + .write(UpdateRepo { + id: resource.to_string(), + config: self, + }) + .await + .context("Failed to update repo config")?; + Ok(()) + } +} + +impl ResourceUpdate for PartialServerConfig { + fn resource_type() -> &'static str { + "Server" + } + async fn apply(self, resource: &str) -> anyhow::Result<()> { + let client = crate::command::komodo_client().await?; + client + .write(UpdateServer { + id: resource.to_string(), + config: self, + }) + .await + .context("Failed to update server config")?; + Ok(()) + } +} + +impl ResourceUpdate for PartialStackConfig { + fn resource_type() -> &'static str { + "Stack" + } + async fn apply(self, resource: &str) -> anyhow::Result<()> { + let client = crate::command::komodo_client().await?; + client + .write(UpdateStack { + id: resource.to_string(), + config: self, + }) + .await + .context("Failed to update stack config")?; + Ok(()) + } +} + +impl ResourceUpdate for PartialResourceSyncConfig { + fn resource_type() -> &'static str { + "Sync" + } + async fn apply(self, resource: &str) -> anyhow::Result<()> { + let client = crate::command::komodo_client().await?; + client + .write(UpdateResourceSync { + id: resource.to_string(), + config: self, + }) + .await + .context("Failed to update sync config")?; + Ok(()) + } +} diff --git a/bin/cli/src/command/update/user.rs b/bin/cli/src/command/update/user.rs new file mode 100644 index 000000000..6564190fa --- /dev/null +++ b/bin/cli/src/command/update/user.rs @@ -0,0 +1,122 @@ +use anyhow::Context; +use colored::Colorize; +use database::mungos::mongodb::bson::doc; +use komodo_client::entities::{ + config::{ + cli::args::{CliEnabled, update::UpdateUserCommand}, + empty_or_redacted, + }, + optional_string, +}; + +use crate::{command::sanitize_uri, config::cli_config}; + +pub async fn update( + username: &str, + command: &UpdateUserCommand, +) -> anyhow::Result<()> { + match command { + UpdateUserCommand::Password { + password, + unsanitized, + yes, + } => { + update_password(username, password, *unsanitized, *yes).await + } + UpdateUserCommand::SuperAdmin { enabled, yes } => { + update_super_admin(username, *enabled, *yes).await + } + } +} + +async fn update_password( + username: &str, + password: &str, + unsanitized: bool, + yes: bool, +) -> anyhow::Result<()> { + println!("\n{}: Update Password\n", "Mode".dimmed()); + println!(" - {}: {username}", "Username".dimmed()); + if unsanitized { + println!(" - {}: {password}", "Password".dimmed()); + } else { + println!( + " - {}: {}", + "Password".dimmed(), + empty_or_redacted(password) + ); + } + + crate::command::wait_for_enter("update password", yes)?; + + info!("Updating password..."); + + let db = database::Client::new(&cli_config().database).await?; + + let user = db + .users + .find_one(doc! { "username": username }) + .await + .context("Failed to query database for user")? + .context("No user found with given username")?; + + db.set_user_password(&user, password).await?; + + info!("Password updated ✅"); + + Ok(()) +} + +async fn update_super_admin( + username: &str, + super_admin: CliEnabled, + yes: bool, +) -> anyhow::Result<()> { + let config = cli_config(); + + println!("\n{}: Update Super Admin\n", "Mode".dimmed()); + println!(" - {}: {username}", "Username".dimmed()); + println!(" - {}: {super_admin}\n", "Super Admin".dimmed()); + + if let Some(uri) = optional_string(&config.database.uri) { + println!("{}: {}", " - Source URI".dimmed(), sanitize_uri(&uri)); + } + if let Some(address) = optional_string(&config.database.address) { + println!("{}: {address}", " - Source Address".dimmed()); + } + if let Some(username) = optional_string(&config.database.username) { + println!("{}: {username}", " - Source Username".dimmed()); + } + println!( + "{}: {}", + " - Source Db Name".dimmed(), + config.database.db_name, + ); + + crate::command::wait_for_enter("update super admin", yes)?; + + info!("Updating super admin..."); + + let db = database::Client::new(&config.database).await?; + + // Make sure the user exists first before saying it is successful. + let user = db + .users + .find_one(doc! { "username": username }) + .await + .context("Failed to query database for user")? + .context("No user found with given username")?; + + let super_admin: bool = super_admin.into(); + db.users + .update_one( + doc! { "username": user.username }, + doc! { "$set": { "super_admin": super_admin } }, + ) + .await + .context("Failed to update user super admin on db")?; + + info!("Super admin updated ✅"); + + Ok(()) +} diff --git a/bin/cli/src/command/update/variable.rs b/bin/cli/src/command/update/variable.rs new file mode 100644 index 000000000..888587d28 --- /dev/null +++ b/bin/cli/src/command/update/variable.rs @@ -0,0 +1,70 @@ +use anyhow::Context; +use colored::Colorize; +use komodo_client::api::{ + read::GetVariable, + write::{ + CreateVariable, UpdateVariableIsSecret, UpdateVariableValue, + }, +}; + +pub async fn update( + name: &str, + value: &str, + secret: Option, + yes: bool, +) -> anyhow::Result<()> { + println!("\n{}: Update Variable\n", "Mode".dimmed()); + println!(" - {}: {name}", "Name".dimmed()); + println!(" - {}: {value}", "Value".dimmed()); + if let Some(secret) = secret { + println!(" - {}: {secret}", "Is Secret".dimmed()); + } + + crate::command::wait_for_enter("update variable", yes)?; + + let client = crate::command::komodo_client().await?; + + let Ok(existing) = client + .read(GetVariable { + name: name.to_string(), + }) + .await + else { + // Create the variable + client + .write(CreateVariable { + name: name.to_string(), + value: value.to_string(), + is_secret: secret.unwrap_or_default(), + description: Default::default(), + }) + .await + .context("Failed to create variable")?; + info!("Variable created ✅"); + return Ok(()); + }; + + client + .write(UpdateVariableValue { + name: name.to_string(), + value: value.to_string(), + }) + .await + .context("Failed to update variable 'value'")?; + info!("Variable 'value' updated ✅"); + + let Some(secret) = secret else { return Ok(()) }; + + if secret != existing.is_secret { + client + .write(UpdateVariableIsSecret { + name: name.to_string(), + is_secret: secret, + }) + .await + .context("Failed to update variable 'is_secret'")?; + info!("Variable 'is_secret' updated to {secret} ✅"); + } + + Ok(()) +} diff --git a/bin/cli/src/config.rs b/bin/cli/src/config.rs new file mode 100644 index 000000000..cc5dc859c --- /dev/null +++ b/bin/cli/src/config.rs @@ -0,0 +1,274 @@ +use std::{path::PathBuf, sync::OnceLock}; + +use anyhow::Context; +use clap::Parser; +use colored::Colorize; +use environment_file::maybe_read_item_from_file; +use komodo_client::entities::{ + config::{ + DatabaseConfig, + cli::{ + CliConfig, Env, + args::{CliArgs, Command, Execute, database::DatabaseCommand}, + }, + }, + logger::LogConfig, +}; + +pub fn cli_args() -> &'static CliArgs { + static CLI_ARGS: OnceLock = OnceLock::new(); + CLI_ARGS.get_or_init(CliArgs::parse) +} + +pub fn cli_env() -> &'static Env { + static CLI_ARGS: OnceLock = OnceLock::new(); + CLI_ARGS.get_or_init(|| { + match envy::from_env() + .context("Failed to parse Komodo CLI environment") + { + Ok(env) => env, + Err(e) => { + panic!("{e:?}"); + } + } + }) +} + +pub fn cli_config() -> &'static CliConfig { + static CLI_CONFIG: OnceLock = OnceLock::new(); + CLI_CONFIG.get_or_init(|| { + let args = cli_args(); + let env = cli_env().clone(); + let config_paths = args + .config_path + .clone() + .unwrap_or(env.komodo_cli_config_paths); + let debug_startup = + args.debug_startup.unwrap_or(env.komodo_cli_debug_startup); + + if debug_startup { + println!( + "{}: Komodo CLI version: {}", + "DEBUG".cyan(), + env!("CARGO_PKG_VERSION").blue().bold() + ); + println!( + "{}: {}: {config_paths:?}", + "DEBUG".cyan(), + "Config Paths".dimmed(), + ); + } + + let config_keywords = args + .config_keyword + .clone() + .unwrap_or(env.komodo_cli_config_keywords); + let config_keywords = config_keywords + .iter() + .map(String::as_str) + .collect::>(); + if debug_startup { + println!( + "{}: {}: {config_keywords:?}", + "DEBUG".cyan(), + "Config File Keywords".dimmed(), + ); + } + let mut unparsed_config = (config::ConfigLoader { + paths: &config_paths + .iter() + .map(PathBuf::as_path) + .collect::>(), + match_wildcards: &config_keywords, + include_file_name: ".kminclude", + merge_nested: env.komodo_cli_merge_nested_config, + extend_array: env.komodo_cli_extend_config_arrays, + debug_print: debug_startup, + }) + .load::>() + .expect("failed at parsing config from paths"); + let init_parsed_config = serde_json::from_value::( + serde_json::Value::Object(unparsed_config.clone()), + ) + .context("Failed to parse config") + .unwrap(); + + let (host, key, secret) = match &args.command { + Command::Execute(Execute { + host, key, secret, .. + }) => (host.clone(), key.clone(), secret.clone()), + _ => (None, None, None), + }; + + let backups_folder = match &args.command { + Command::Database { + command: DatabaseCommand::Backup { backups_folder, .. }, + } => backups_folder.clone(), + Command::Database { + command: DatabaseCommand::Restore { backups_folder, .. }, + } => backups_folder.clone(), + _ => None, + }; + let (uri, address, username, password, db_name) = + match &args.command { + Command::Database { + command: + DatabaseCommand::Copy { + uri, + address, + username, + password, + db_name, + .. + }, + } => ( + uri.clone(), + address.clone(), + username.clone(), + password.clone(), + db_name.clone(), + ), + _ => (None, None, None, None, None), + }; + + let profile = args + .profile + .as_ref() + .or(init_parsed_config.default_profile.as_ref()); + + let unparsed_config = if let Some(profile) = profile + && !profile.is_empty() + { + // Find the profile config, + // then merge it with the Default config. + let serde_json::Value::Array(profiles) = unparsed_config + .remove("profile") + .context("Config has no profiles, but a profile is required") + .unwrap() + else { + panic!("`config.profile` is not array"); + }; + let Some(profile_config) = profiles.into_iter().find(|p| { + let Ok(parsed) = + serde_json::from_value::(p.clone()) + else { + return false; + }; + &parsed.config_profile == profile + || parsed + .config_aliases + .iter() + .any(|alias| alias == profile) + }) else { + panic!("No profile matching '{profile}' was found."); + }; + let serde_json::Value::Object(profile_config) = profile_config + else { + panic!("Profile config is not Object type."); + }; + config::merge_config( + unparsed_config, + profile_config.clone(), + env.komodo_cli_merge_nested_config, + env.komodo_cli_extend_config_arrays, + ) + .unwrap_or(profile_config) + } else { + unparsed_config + }; + let config = serde_json::from_value::( + serde_json::Value::Object(unparsed_config), + ) + .context("Failed to parse final config") + .unwrap(); + let config_profile = if config.config_profile.is_empty() { + String::from("None") + } else { + config.config_profile + }; + + CliConfig { + config_profile, + config_aliases: config.config_aliases, + default_profile: config.default_profile, + table_borders: env + .komodo_cli_table_borders + .or(config.table_borders), + host: host + .or(env.komodo_cli_host) + .or(env.komodo_host) + .unwrap_or(config.host), + cli_key: key.or(env.komodo_cli_key).or(config.cli_key), + cli_secret: secret + .or(env.komodo_cli_secret) + .or(config.cli_secret), + backups_folder: backups_folder + .or(env.komodo_cli_backups_folder) + .unwrap_or(config.backups_folder), + max_backups: env + .komodo_cli_max_backups + .unwrap_or(config.max_backups), + database_target: DatabaseConfig { + uri: uri + .or(env.komodo_cli_database_target_uri) + .unwrap_or(config.database_target.uri), + address: address + .or(env.komodo_cli_database_target_address) + .unwrap_or(config.database_target.address), + username: username + .or(env.komodo_cli_database_target_username) + .unwrap_or(config.database_target.username), + password: password + .or(env.komodo_cli_database_target_password) + .unwrap_or(config.database_target.password), + db_name: db_name + .or(env.komodo_cli_database_target_db_name) + .unwrap_or(config.database_target.db_name), + app_name: config.database_target.app_name, + }, + database: DatabaseConfig { + uri: maybe_read_item_from_file( + env.komodo_database_uri_file, + env.komodo_database_uri, + ) + .unwrap_or(config.database.uri), + address: env + .komodo_database_address + .unwrap_or(config.database.address), + username: maybe_read_item_from_file( + env.komodo_database_username_file, + env.komodo_database_username, + ) + .unwrap_or(config.database.username), + password: maybe_read_item_from_file( + env.komodo_database_password_file, + env.komodo_database_password, + ) + .unwrap_or(config.database.password), + db_name: env + .komodo_database_db_name + .unwrap_or(config.database.db_name), + app_name: config.database.app_name, + }, + cli_logging: LogConfig { + level: env + .komodo_cli_logging_level + .unwrap_or(config.cli_logging.level), + stdio: env + .komodo_cli_logging_stdio + .unwrap_or(config.cli_logging.stdio), + pretty: env + .komodo_cli_logging_pretty + .unwrap_or(config.cli_logging.pretty), + location: false, + otlp_endpoint: env + .komodo_cli_logging_otlp_endpoint + .unwrap_or(config.cli_logging.otlp_endpoint), + opentelemetry_service_name: env + .komodo_cli_logging_opentelemetry_service_name + .unwrap_or(config.cli_logging.opentelemetry_service_name), + }, + profile: config.profile, + } + }) +} diff --git a/bin/cli/src/helpers.rs b/bin/cli/src/helpers.rs deleted file mode 100644 index 13d6197c2..000000000 --- a/bin/cli/src/helpers.rs +++ /dev/null @@ -1,17 +0,0 @@ -use std::io::Read; - -use anyhow::Context; -use colored::Colorize; - -pub fn wait_for_enter(press_enter_to: &str) -> anyhow::Result<()> { - println!( - "\nPress {} to {}\n", - "ENTER".green(), - press_enter_to.bold() - ); - let buffer = &mut [0u8]; - std::io::stdin() - .read_exact(buffer) - .context("failed to read ENTER")?; - Ok(()) -} diff --git a/bin/cli/src/main.rs b/bin/cli/src/main.rs index 4ff563b8f..9f6897a0f 100644 --- a/bin/cli/src/main.rs +++ b/bin/cli/src/main.rs @@ -1,32 +1,72 @@ #[macro_use] extern crate tracing; -use colored::Colorize; -use komodo_client::api::read::GetVersion; +use anyhow::Context; +use komodo_client::entities::config::cli::args; -mod args; -mod exec; -mod helpers; -mod state; +use crate::config::cli_config; + +mod command; +mod config; + +async fn app() -> anyhow::Result<()> { + dotenvy::dotenv().ok(); + logger::init(&config::cli_config().cli_logging)?; + let args = config::cli_args(); + let env = config::cli_env(); + let debug_load = + args.debug_startup.unwrap_or(env.komodo_cli_debug_startup); + + match &args.command { + args::Command::Config { + all_profiles, + unsanitized, + } => { + let mut config = if *unsanitized { + cli_config().clone() + } else { + cli_config().sanitized() + }; + if !*all_profiles { + config.profile = Default::default(); + } + if debug_load { + println!("\n{config:#?}"); + } else { + println!( + "\nCLI Config {}", + serde_json::to_string_pretty(&config) + .context("Failed to serialize config for pretty print")? + ); + } + Ok(()) + } + args::Command::Container(container) => { + command::container::handle(container).await + } + args::Command::Inspect(inspect) => { + command::container::inspect_container(inspect).await + } + args::Command::List(list) => command::list::handle(list).await, + args::Command::Execute(args) => { + command::execute::handle(&args.execution, args.yes).await + } + args::Command::Update { command } => { + command::update::handle(command).await + } + args::Command::Database { command } => { + command::database::handle(command).await + } + } +} #[tokio::main] async fn main() -> anyhow::Result<()> { - tracing_subscriber::fmt().with_target(false).init(); - - info!( - "Komodo CLI version: {}", - env!("CARGO_PKG_VERSION").blue().bold() - ); - - let version = - state::komodo_client().read(GetVersion {}).await?.version; - info!("Komodo Core version: {}", version.blue().bold()); - - match &state::cli_args().command { - args::Command::Execute { execution } => { - exec::run(execution.to_owned()).await? - } + let mut term_signal = tokio::signal::unix::signal( + tokio::signal::unix::SignalKind::terminate(), + )?; + tokio::select! { + res = tokio::spawn(app()) => res?, + _ = term_signal.recv() => Ok(()), } - - Ok(()) } diff --git a/bin/cli/src/state.rs b/bin/cli/src/state.rs deleted file mode 100644 index 21c789ea0..000000000 --- a/bin/cli/src/state.rs +++ /dev/null @@ -1,48 +0,0 @@ -use std::sync::OnceLock; - -use clap::Parser; -use komodo_client::KomodoClient; -use merge_config_files::parse_config_file; - -pub fn cli_args() -> &'static crate::args::CliArgs { - static CLI_ARGS: OnceLock = OnceLock::new(); - CLI_ARGS.get_or_init(crate::args::CliArgs::parse) -} - -pub fn komodo_client() -> &'static KomodoClient { - static KOMODO_CLIENT: OnceLock = OnceLock::new(); - KOMODO_CLIENT.get_or_init(|| { - let args = cli_args(); - let crate::args::CredsFile { url, key, secret } = - match (&args.url, &args.key, &args.secret) { - (Some(url), Some(key), Some(secret)) => { - crate::args::CredsFile { - url: url.clone(), - key: key.clone(), - secret: secret.clone(), - } - } - (url, key, secret) => { - let mut creds: crate::args::CredsFile = - parse_config_file(cli_args().creds.as_str()) - .expect("failed to parse Komodo credentials"); - - if let Some(url) = url { - creds.url.clone_from(url); - } - if let Some(key) = key { - creds.key.clone_from(key); - } - if let Some(secret) = secret { - creds.secret.clone_from(secret); - } - - creds - } - }; - futures::executor::block_on( - KomodoClient::new(url, key, secret).with_healthcheck(), - ) - .expect("failed to initialize Komodo client") - }) -} diff --git a/bin/core/Cargo.toml b/bin/core/Cargo.toml index 64b275676..2f960ccf0 100644 --- a/bin/core/Cargo.toml +++ b/bin/core/Cargo.toml @@ -20,21 +20,20 @@ periphery_client.workspace = true environment_file.workspace = true interpolate.workspace = true formatting.workspace = true +database.workspace = true response.workspace = true command.workspace = true +config.workspace = true logger.workspace = true cache.workspace = true git.workspace = true # mogh serror = { workspace = true, features = ["axum"] } -merge_config_files.workspace = true async_timing_util.workspace = true partial_derive2.workspace = true derive_variants.workspace = true -mongo_indexed.workspace = true resolver_api.workspace = true toml_pretty.workspace = true -mungos.workspace = true slack.workspace = true svi.workspace = true # external @@ -51,13 +50,14 @@ tokio-util.workspace = true axum-extra.workspace = true tower-http.workspace = true serde_json.workspace = true -serde_yaml.workspace = true +serde_yaml_ng.workspace = true typeshare.workspace = true chrono-tz.workspace = true indexmap.workspace = true octorust.workspace = true wildcard.workspace = true arc-swap.workspace = true +colored.workspace = true dashmap.workspace = true tracing.workspace = true reqwest.workspace = true diff --git a/bin/core/aio.Dockerfile b/bin/core/aio.Dockerfile index 36a6bafd2..d94057da7 100644 --- a/bin/core/aio.Dockerfile +++ b/bin/core/aio.Dockerfile @@ -1,7 +1,7 @@ ## All in one, multi stage compile + runtime Docker build for your architecture. # Build Core -FROM rust:1.87.0-bullseye AS core-builder +FROM rust:1.89.0-bullseye AS core-builder WORKDIR /builder COPY Cargo.toml Cargo.lock ./ @@ -9,9 +9,11 @@ COPY ./lib ./lib COPY ./client/core/rs ./client/core/rs COPY ./client/periphery ./client/periphery COPY ./bin/core ./bin/core +COPY ./bin/cli ./bin/cli # Compile app -RUN cargo build -p komodo_core --release +RUN cargo build -p komodo_core --release && \ + cargo build -p komodo_cli --release # Build Frontend FROM node:20.12-alpine AS frontend-builder @@ -24,7 +26,7 @@ RUN cd frontend && yarn link komodo_client && yarn && yarn build # Final Image FROM debian:bullseye-slim -COPY ./bin/core/starship.toml /config/starship.toml +COPY ./bin/core/starship.toml /starship.toml COPY ./bin/core/debian-deps.sh . RUN sh ./debian-deps.sh && rm ./debian-deps.sh @@ -32,9 +34,10 @@ RUN sh ./debian-deps.sh && rm ./debian-deps.sh WORKDIR /app # Copy -COPY ./config/core.config.toml /config/config.toml +COPY ./config/core.config.toml /config/.default.config.toml COPY --from=frontend-builder /builder/frontend/dist /app/frontend COPY --from=core-builder /builder/target/release/core /usr/local/bin/core +COPY --from=core-builder /builder/target/release/km /usr/local/bin/km COPY --from=denoland/deno:bin /deno /usr/local/bin/deno # Set $DENO_DIR and preload external Deno deps @@ -46,9 +49,13 @@ RUN mkdir /action-cache && \ # Hint at the port EXPOSE 9120 +ENV KOMODO_CLI_CONFIG_PATHS="/config" +# This ensures any `komodo.cli.*` takes precedence over the Core `/config/*config.*` +ENV KOMODO_CLI_CONFIG_KEYWORDS="*config.*,*komodo.cli*.*" + +CMD [ "core" ] + # Label for Ghcr LABEL org.opencontainers.image.source=https://github.com/moghtech/komodo LABEL org.opencontainers.image.description="Komodo Core" LABEL org.opencontainers.image.licenses=GPL-3.0 - -ENTRYPOINT [ "core" ] diff --git a/bin/core/debian-deps.sh b/bin/core/debian-deps.sh index 0e4007777..8eb371e59 100644 --- a/bin/core/debian-deps.sh +++ b/bin/core/debian-deps.sh @@ -3,12 +3,12 @@ ## Core deps installer apt-get update -apt-get install -y git curl ca-certificates +apt-get install -y git curl ca-certificates iproute2 rm -rf /var/lib/apt/lists/* # Starship prompt curl -sS https://starship.rs/install.sh | sh -s -- --yes --bin-dir /usr/local/bin -echo 'export STARSHIP_CONFIG=/config/starship.toml' >> /root/.bashrc +echo 'export STARSHIP_CONFIG=/starship.toml' >> /root/.bashrc echo 'eval "$(starship init bash)"' >> /root/.bashrc diff --git a/bin/core/multi-arch.Dockerfile b/bin/core/multi-arch.Dockerfile index 8ac3900be..40be8e88e 100644 --- a/bin/core/multi-arch.Dockerfile +++ b/bin/core/multi-arch.Dockerfile @@ -15,20 +15,26 @@ FROM ${FRONTEND_IMAGE} AS frontend # Final Image FROM debian:bullseye-slim -COPY ./bin/core/starship.toml /config/starship.toml +COPY ./bin/core/starship.toml /starship.toml COPY ./bin/core/debian-deps.sh . RUN sh ./debian-deps.sh && rm ./debian-deps.sh WORKDIR /app -# Copy both binaries initially, but only keep appropriate one for the TARGETPLATFORM. -COPY --from=x86_64 /core /app/arch/linux/amd64 -COPY --from=aarch64 /core /app/arch/linux/arm64 ARG TARGETPLATFORM -RUN mv /app/arch/${TARGETPLATFORM} /usr/local/bin/core && rm -r /app/arch + +# Copy both binaries initially, but only keep appropriate one for the TARGETPLATFORM. +COPY --from=x86_64 /core /app/core/linux/amd64 +COPY --from=aarch64 /core /app/core/linux/arm64 +RUN mv /app/core/${TARGETPLATFORM} /usr/local/bin/core && rm -r /app/core + +# Same for util +COPY --from=x86_64 /km /app/km/linux/amd64 +COPY --from=aarch64 /km /app/km/linux/arm64 +RUN mv /app/km/${TARGETPLATFORM} /usr/local/bin/km && rm -r /app/km # Copy default config / static frontend / deno binary -COPY ./config/core.config.toml /config/config.toml +COPY ./config/core.config.toml /config/.default.config.toml COPY --from=frontend /frontend /app/frontend COPY --from=denoland/deno:bin /deno /usr/local/bin/deno @@ -41,9 +47,13 @@ RUN mkdir /action-cache && \ # Hint at the port EXPOSE 9120 +ENV KOMODO_CLI_CONFIG_PATHS="/config" +# This ensures any `komodo.cli.*` takes precedence over the Core `/config/*config.*` +ENV KOMODO_CLI_CONFIG_KEYWORDS="*config.*,*komodo.cli*.*" + +CMD [ "core" ] + # Label for Ghcr LABEL org.opencontainers.image.source=https://github.com/moghtech/komodo LABEL org.opencontainers.image.description="Komodo Core" LABEL org.opencontainers.image.licenses=GPL-3.0 - -CMD [ "core" ] \ No newline at end of file diff --git a/bin/core/single-arch.Dockerfile b/bin/core/single-arch.Dockerfile index 3e0c57c3a..712e0adfb 100644 --- a/bin/core/single-arch.Dockerfile +++ b/bin/core/single-arch.Dockerfile @@ -16,14 +16,15 @@ RUN cd frontend && yarn link komodo_client && yarn && yarn build FROM debian:bullseye-slim -COPY ./bin/core/starship.toml /config/starship.toml +COPY ./bin/core/starship.toml /starship.toml COPY ./bin/core/debian-deps.sh . RUN sh ./debian-deps.sh && rm ./debian-deps.sh # Copy -COPY ./config/core.config.toml /config/config.toml +COPY ./config/core.config.toml /config/.default.config.toml COPY --from=frontend-builder /builder/frontend/dist /app/frontend COPY --from=binaries /core /usr/local/bin/core +COPY --from=binaries /km /usr/local/bin/km COPY --from=denoland/deno:bin /deno /usr/local/bin/deno # Set $DENO_DIR and preload external Deno deps @@ -35,9 +36,13 @@ RUN mkdir /action-cache && \ # Hint at the port EXPOSE 9120 +ENV KOMODO_CLI_CONFIG_PATHS="/config" +# This ensures any `komodo.cli.*` takes precedence over the Core `/config/*config.*` +ENV KOMODO_CLI_CONFIG_KEYWORDS="*config.*,*komodo.cli*.*" + +CMD [ "core" ] + # Label for Ghcr LABEL org.opencontainers.image.source=https://github.com/moghtech/komodo LABEL org.opencontainers.image.description="Komodo Core" LABEL org.opencontainers.image.licenses=GPL-3.0 - -CMD [ "core" ] \ No newline at end of file diff --git a/bin/core/src/alert/discord.rs b/bin/core/src/alert/discord.rs index 4cd273eb6..d59504577 100644 --- a/bin/core/src/alert/discord.rs +++ b/bin/core/src/alert/discord.rs @@ -229,8 +229,7 @@ pub async fn send_alert( let sanitized_error = svi::replace_in_string(&format!("{e:?}"), &replacers); anyhow::Error::msg(format!( - "Error with slack request: {}", - sanitized_error + "Error with slack request: {sanitized_error}" )) })?; } diff --git a/bin/core/src/alert/mod.rs b/bin/core/src/alert/mod.rs index 2e57f464e..e0fe93a8e 100644 --- a/bin/core/src/alert/mod.rs +++ b/bin/core/src/alert/mod.rs @@ -1,5 +1,6 @@ use ::slack::types::Block; use anyhow::{Context, anyhow}; +use database::mungos::{find::find_collect, mongodb::bson::doc}; use derive_variants::ExtractVariant; use futures::future::join_all; use interpolate::Interpolator; @@ -11,7 +12,6 @@ use komodo_client::entities::{ komodo_timestamp, stack::StackState, }; -use mungos::{find::find_collect, mongodb::bson::doc}; use tracing::Instrument; use crate::helpers::query::get_variables_and_secrets; @@ -188,8 +188,7 @@ async fn send_custom_alert( let sanitized_error = svi::replace_in_string(&format!("{e:?}"), &replacers); anyhow::Error::msg(format!( - "Error with request: {}", - sanitized_error + "Error with request: {sanitized_error}" )) }) .context("failed at post request to alerter")?; @@ -245,35 +244,9 @@ fn resource_link( resource_type: ResourceTargetVariant, id: &str, ) -> String { - let path = match resource_type { - ResourceTargetVariant::System => unreachable!(), - ResourceTargetVariant::Build => format!("/builds/{id}"), - ResourceTargetVariant::Builder => { - format!("/builders/{id}") - } - ResourceTargetVariant::Deployment => { - format!("/deployments/{id}") - } - ResourceTargetVariant::Stack => { - format!("/stacks/{id}") - } - ResourceTargetVariant::Server => { - format!("/servers/{id}") - } - ResourceTargetVariant::Repo => format!("/repos/{id}"), - ResourceTargetVariant::Alerter => { - format!("/alerters/{id}") - } - ResourceTargetVariant::Procedure => { - format!("/procedures/{id}") - } - ResourceTargetVariant::Action => { - format!("/actions/{id}") - } - ResourceTargetVariant::ResourceSync => { - format!("/resource-syncs/{id}") - } - }; - - format!("{}{path}", core_config().host) + komodo_client::entities::resource_link( + &core_config().host, + resource_type, + id, + ) } diff --git a/bin/core/src/alert/ntfy.rs b/bin/core/src/alert/ntfy.rs index b82e8b7be..d09203ee5 100644 --- a/bin/core/src/alert/ntfy.rs +++ b/bin/core/src/alert/ntfy.rs @@ -13,8 +13,7 @@ pub async fn send_alert( AlertData::Test { id, name } => { let link = resource_link(ResourceTargetVariant::Alerter, id); format!( - "{level} | If you see this message, then Alerter {} is working\n{link}", - name, + "{level} | If you see this message, then Alerter {name} is working\n{link}", ) } AlertData::ServerUnreachable { @@ -27,19 +26,15 @@ pub async fn send_alert( let link = resource_link(ResourceTargetVariant::Server, id); match alert.level { SeverityLevel::Ok => { - format!( - "{level} | {}{} is now reachable\n{link}", - name, region - ) + format!("{level} | {name}{region} is now reachable\n{link}") } SeverityLevel::Critical => { let err = err .as_ref() - .map(|e| format!("\nerror: {:#?}", e)) + .map(|e| format!("\nerror: {e:#?}")) .unwrap_or_default(); format!( - "{level} | {}{} is unreachable ❌\n{link}{err}", - name, region + "{level} | {name}{region} is unreachable ❌\n{link}{err}" ) } _ => unreachable!(), @@ -54,8 +49,7 @@ pub async fn send_alert( let region = fmt_region(region); let link = resource_link(ResourceTargetVariant::Server, id); format!( - "{level} | {}{} cpu usage at {percentage:.1}%\n{link}", - name, region, + "{level} | {name}{region} cpu usage at {percentage:.1}%\n{link}", ) } AlertData::ServerMem { @@ -69,8 +63,7 @@ pub async fn send_alert( let link = resource_link(ResourceTargetVariant::Server, id); let percentage = 100.0 * used_gb / total_gb; format!( - "{level} | {}{} memory usage at {percentage:.1}%💾\n\nUsing {used_gb:.1} GiB / {total_gb:.1} GiB\n{link}", - name, region, + "{level} | {name}{region} memory usage at {percentage:.1}%💾\n\nUsing {used_gb:.1} GiB / {total_gb:.1} GiB\n{link}", ) } AlertData::ServerDisk { @@ -85,8 +78,7 @@ pub async fn send_alert( let link = resource_link(ResourceTargetVariant::Server, id); let percentage = 100.0 * used_gb / total_gb; format!( - "{level} | {}{} disk usage at {percentage:.1}%💿\nmount point: {:?}\nusing {used_gb:.1} GiB / {total_gb:.1} GiB\n{link}", - name, region, path, + "{level} | {name}{region} disk usage at {percentage:.1}%💿\nmount point: {path:?}\nusing {used_gb:.1} GiB / {total_gb:.1} GiB\n{link}", ) } AlertData::ContainerStateChange { @@ -100,8 +92,7 @@ pub async fn send_alert( let link = resource_link(ResourceTargetVariant::Deployment, id); let to_state = fmt_docker_container_state(to); format!( - "📦Deployment {} is now {}\nserver: {}\nprevious: {}\n{link}", - name, to_state, server_name, from, + "📦Deployment {name} is now {to_state}\nserver: {server_name}\nprevious: {from}\n{link}", ) } AlertData::DeploymentImageUpdateAvailable { @@ -113,8 +104,7 @@ pub async fn send_alert( } => { let link = resource_link(ResourceTargetVariant::Deployment, id); format!( - "⬆ Deployment {} has an update available\nserver: {}\nimage: {}\n{link}", - name, server_name, image, + "⬆ Deployment {name} has an update available\nserver: {server_name}\nimage: {image}\n{link}", ) } AlertData::DeploymentAutoUpdated { @@ -126,8 +116,7 @@ pub async fn send_alert( } => { let link = resource_link(ResourceTargetVariant::Deployment, id); format!( - "⬆ Deployment {} was updated automatically\nserver: {}\nimage: {}\n{link}", - name, server_name, image, + "⬆ Deployment {name} was updated automatically\nserver: {server_name}\nimage: {image}\n{link}", ) } AlertData::StackStateChange { @@ -141,8 +130,7 @@ pub async fn send_alert( let link = resource_link(ResourceTargetVariant::Stack, id); let to_state = fmt_stack_state(to); format!( - "🥞 Stack {} is now {}\nserver: {}\nprevious: {}\n{link}", - name, to_state, server_name, from, + "🥞 Stack {name} is now {to_state}\nserver: {server_name}\nprevious: {from}\n{link}", ) } AlertData::StackImageUpdateAvailable { @@ -155,8 +143,7 @@ pub async fn send_alert( } => { let link = resource_link(ResourceTargetVariant::Stack, id); format!( - "⬆ Stack {} has an update available\nserver: {}\nservice: {}\nimage: {}\n{link}", - name, server_name, service, image, + "⬆ Stack {name} has an update available\nserver: {server_name}\nservice: {service}\nimage: {image}\n{link}", ) } AlertData::StackAutoUpdated { @@ -171,8 +158,7 @@ pub async fn send_alert( if images.len() > 1 { "images" } else { "image" }; let images_str = images.join(", "); format!( - "⬆ Stack {} was updated automatically ⏫\nserver: {}\n{}: {}\n{link}", - name, server_name, images_label, images_str, + "⬆ Stack {name} was updated automatically ⏫\nserver: {server_name}\n{images_label}: {images_str}\n{link}", ) } AlertData::AwsBuilderTerminationFailed { @@ -180,28 +166,25 @@ pub async fn send_alert( message, } => { format!( - "{level} | Failed to terminate AWS builder instance\ninstance id: {}\n{}", - instance_id, message, + "{level} | Failed to terminate AWS builder instance\ninstance id: {instance_id}\n{message}", ) } AlertData::ResourceSyncPendingUpdates { id, name } => { let link = resource_link(ResourceTargetVariant::ResourceSync, id); format!( - "{level} | Pending resource sync updates on {}\n{link}", - name, + "{level} | Pending resource sync updates on {name}\n{link}", ) } AlertData::BuildFailed { id, name, version } => { let link = resource_link(ResourceTargetVariant::Build, id); format!( - "{level} | Build {} failed\nversion: v{}\n{link}", - name, version, + "{level} | Build {name} failed\nversion: v{version}\n{link}", ) } AlertData::RepoBuildFailed { id, name } => { let link = resource_link(ResourceTargetVariant::Repo, id); - format!("{level} | Repo build for {} failed\n{link}", name,) + format!("{level} | Repo build for {name} failed\n{link}",) } AlertData::ProcedureFailed { id, name } => { let link = resource_link(ResourceTargetVariant::Procedure, id); @@ -254,8 +237,7 @@ async fn send_message( } else { let text = response.text().await.with_context(|| { format!( - "Failed to send message to ntfy | {} | failed to get response text", - status + "Failed to send message to ntfy | {status} | failed to get response text" ) })?; Err(anyhow!( diff --git a/bin/core/src/alert/pushover.rs b/bin/core/src/alert/pushover.rs index 7e4fe3ca8..0ecec2d6c 100644 --- a/bin/core/src/alert/pushover.rs +++ b/bin/core/src/alert/pushover.rs @@ -12,8 +12,7 @@ pub async fn send_alert( AlertData::Test { id, name } => { let link = resource_link(ResourceTargetVariant::Alerter, id); format!( - "{level} | If you see this message, then Alerter {} is working\n{link}", - name, + "{level} | If you see this message, then Alerter {name} is working\n{link}", ) } AlertData::ServerUnreachable { @@ -26,19 +25,15 @@ pub async fn send_alert( let link = resource_link(ResourceTargetVariant::Server, id); match alert.level { SeverityLevel::Ok => { - format!( - "{level} | {}{} is now reachable\n{link}", - name, region - ) + format!("{level} | {name}{region} is now reachable\n{link}") } SeverityLevel::Critical => { let err = err .as_ref() - .map(|e| format!("\nerror: {:#?}", e)) + .map(|e| format!("\nerror: {e:#?}")) .unwrap_or_default(); format!( - "{level} | {}{} is unreachable ❌\n{link}{err}", - name, region + "{level} | {name}{region} is unreachable ❌\n{link}{err}" ) } _ => unreachable!(), @@ -53,8 +48,7 @@ pub async fn send_alert( let region = fmt_region(region); let link = resource_link(ResourceTargetVariant::Server, id); format!( - "{level} | {}{} cpu usage at {percentage:.1}%\n{link}", - name, region, + "{level} | {name}{region} cpu usage at {percentage:.1}%\n{link}", ) } AlertData::ServerMem { @@ -68,8 +62,7 @@ pub async fn send_alert( let link = resource_link(ResourceTargetVariant::Server, id); let percentage = 100.0 * used_gb / total_gb; format!( - "{level} | {}{} memory usage at {percentage:.1}%💾\n\nUsing {used_gb:.1} GiB / {total_gb:.1} GiB\n{link}", - name, region, + "{level} | {name}{region} memory usage at {percentage:.1}%💾\n\nUsing {used_gb:.1} GiB / {total_gb:.1} GiB\n{link}", ) } AlertData::ServerDisk { @@ -84,8 +77,7 @@ pub async fn send_alert( let link = resource_link(ResourceTargetVariant::Server, id); let percentage = 100.0 * used_gb / total_gb; format!( - "{level} | {}{} disk usage at {percentage:.1}%💿\nmount point: {:?}\nusing {used_gb:.1} GiB / {total_gb:.1} GiB\n{link}", - name, region, path, + "{level} | {name}{region} disk usage at {percentage:.1}%💿\nmount point: {path:?}\nusing {used_gb:.1} GiB / {total_gb:.1} GiB\n{link}", ) } AlertData::ContainerStateChange { @@ -99,8 +91,7 @@ pub async fn send_alert( let link = resource_link(ResourceTargetVariant::Deployment, id); let to_state = fmt_docker_container_state(to); format!( - "📦Deployment {} is now {}\nserver: {}\nprevious: {}\n{link}", - name, to_state, server_name, from, + "📦Deployment {name} is now {to_state}\nserver: {server_name}\nprevious: {from}\n{link}", ) } AlertData::DeploymentImageUpdateAvailable { @@ -112,8 +103,7 @@ pub async fn send_alert( } => { let link = resource_link(ResourceTargetVariant::Deployment, id); format!( - "⬆ Deployment {} has an update available\nserver: {}\nimage: {}\n{link}", - name, server_name, image, + "⬆ Deployment {name} has an update available\nserver: {server_name}\nimage: {image}\n{link}", ) } AlertData::DeploymentAutoUpdated { @@ -125,8 +115,7 @@ pub async fn send_alert( } => { let link = resource_link(ResourceTargetVariant::Deployment, id); format!( - "⬆ Deployment {} was updated automatically\nserver: {}\nimage: {}\n{link}", - name, server_name, image, + "⬆ Deployment {name} was updated automatically\nserver: {server_name}\nimage: {image}\n{link}", ) } AlertData::StackStateChange { @@ -140,8 +129,7 @@ pub async fn send_alert( let link = resource_link(ResourceTargetVariant::Stack, id); let to_state = fmt_stack_state(to); format!( - "🥞 Stack {} is now {}\nserver: {}\nprevious: {}\n{link}", - name, to_state, server_name, from, + "🥞 Stack {name} is now {to_state}\nserver: {server_name}\nprevious: {from}\n{link}", ) } AlertData::StackImageUpdateAvailable { @@ -154,8 +142,7 @@ pub async fn send_alert( } => { let link = resource_link(ResourceTargetVariant::Stack, id); format!( - "⬆ Stack {} has an update available\nserver: {}\nservice: {}\nimage: {}\n{link}", - name, server_name, service, image, + "⬆ Stack {name} has an update available\nserver: {server_name}\nservice: {service}\nimage: {image}\n{link}", ) } AlertData::StackAutoUpdated { @@ -170,8 +157,7 @@ pub async fn send_alert( if images.len() > 1 { "images" } else { "image" }; let images_str = images.join(", "); format!( - "⬆ Stack {} was updated automatically ⏫\nserver: {}\n{}: {}\n{link}", - name, server_name, images_label, images_str, + "⬆ Stack {name} was updated automatically ⏫\nserver: {server_name}\n{images_label}: {images_str}\n{link}", ) } AlertData::AwsBuilderTerminationFailed { @@ -179,16 +165,14 @@ pub async fn send_alert( message, } => { format!( - "{level} | Failed to terminate AWS builder instance\ninstance id: {}\n{}", - instance_id, message, + "{level} | Failed to terminate AWS builder instance\ninstance id: {instance_id}\n{message}", ) } AlertData::ResourceSyncPendingUpdates { id, name } => { let link = resource_link(ResourceTargetVariant::ResourceSync, id); format!( - "{level} | Pending resource sync updates on {}\n{link}", - name, + "{level} | Pending resource sync updates on {name}\n{link}", ) } AlertData::BuildFailed { id, name, version } => { @@ -199,7 +183,7 @@ pub async fn send_alert( } AlertData::RepoBuildFailed { id, name } => { let link = resource_link(ResourceTargetVariant::Repo, id); - format!("{level} | Repo build for {} failed\n{link}", name,) + format!("{level} | Repo build for {name} failed\n{link}",) } AlertData::ProcedureFailed { id, name } => { let link = resource_link(ResourceTargetVariant::Procedure, id); @@ -252,8 +236,7 @@ async fn send_message( } else { let text = response.text().await.with_context(|| { format!( - "Failed to send message to pushover | {} | failed to get response text", - status + "Failed to send message to pushover | {status} | failed to get response text" ) })?; Err(anyhow!( diff --git a/bin/core/src/alert/slack.rs b/bin/core/src/alert/slack.rs index b892c9c4c..97c530a79 100644 --- a/bin/core/src/alert/slack.rs +++ b/bin/core/src/alert/slack.rs @@ -450,8 +450,7 @@ pub async fn send_alert( let sanitized_error = svi::replace_in_string(&format!("{e:?}"), &replacers); anyhow::Error::msg(format!( - "Error with slack request: {}", - sanitized_error + "Error with slack request: {sanitized_error}" )) })?; } diff --git a/bin/core/src/api/auth.rs b/bin/core/src/api/auth.rs index ca2103d17..d8b8d6209 100644 --- a/bin/core/src/api/auth.rs +++ b/bin/core/src/api/auth.rs @@ -25,6 +25,7 @@ use crate::{ use super::Variant; +#[derive(Default)] pub struct AuthArgs { pub headers: HeaderMap, } @@ -41,7 +42,7 @@ pub struct AuthArgs { #[allow(clippy::enum_variant_names, clippy::large_enum_variant)] pub enum AuthRequest { GetLoginOptions(GetLoginOptions), - CreateLocalUser(CreateLocalUser), + SignUpLocalUser(SignUpLocalUser), LoginLocalUser(LoginLocalUser), ExchangeForJwt(ExchangeForJwt), GetUser(GetUser), @@ -62,7 +63,7 @@ pub fn router() -> Router { } if google_oauth_client().is_some() { - info!("🔑 Github Login Enabled"); + info!("🔑 Google Login Enabled"); router = router.nest("/google", google::router()) } @@ -138,8 +139,10 @@ impl Resolve for ExchangeForJwt { self, _: &AuthArgs, ) -> serror::Result { - let jwt = jwt_client().redeem_exchange_token(&self.token).await?; - Ok(ExchangeForJwtResponse { jwt }) + jwt_client() + .redeem_exchange_token(&self.token) + .await + .map_err(Into::into) } } diff --git a/bin/core/src/api/execute/action.rs b/bin/core/src/api/execute/action.rs index 70ae2eee2..3b34eca2b 100644 --- a/bin/core/src/api/execute/action.rs +++ b/bin/core/src/api/execute/action.rs @@ -7,6 +7,10 @@ use std::{ use anyhow::Context; use command::run_komodo_command; +use config::merge_objects; +use database::mungos::{ + by_id::update_one_by_id, mongodb::bson::to_document, +}; use interpolate::Interpolator; use komodo_client::{ api::{ @@ -14,6 +18,7 @@ use komodo_client::{ user::{CreateApiKey, CreateApiKeyResponse, DeleteApiKey}, }, entities::{ + FileFormat, JsonObject, action::Action, alert::{Alert, AlertData, SeverityLevel}, config::core::CoreConfig, @@ -22,8 +27,8 @@ use komodo_client::{ update::Update, user::action_user, }, + parsers::parse_key_value_list, }; -use mungos::{by_id::update_one_by_id, mongodb::bson::to_document}; use resolver_api::Resolve; use tokio::fs; @@ -46,7 +51,10 @@ use super::ExecuteArgs; impl super::BatchExecute for BatchRunAction { type Resource = Action; fn single_request(action: String) -> ExecuteRequest { - ExecuteRequest::RunAction(RunAction { action }) + ExecuteRequest::RunAction(RunAction { + action, + args: Default::default(), + }) } } @@ -91,6 +99,23 @@ impl Resolve for RunAction { update_update(update.clone()).await?; + let default_args = parse_action_arguments( + &action.config.arguments, + action.config.arguments_format, + ) + .context("Failed to parse default Action arguments")?; + + let args = merge_objects( + default_args, + self.args.unwrap_or_default(), + true, + true, + ) + .context("Failed to merge request args with default args")?; + + let args = serde_json::to_string(&args) + .context("Failed to serialize action run arguments")?; + let CreateApiKeyResponse { key, secret } = CreateApiKey { name: update.id.clone(), expires: 0, @@ -103,7 +128,7 @@ impl Resolve for RunAction { let contents = &mut action.config.file_contents; // Wrap the file contents in the execution context. - *contents = full_contents(contents, &key, &secret); + *contents = full_contents(contents, &args, &key, &secret); let replacers = interpolate(contents, &mut update, key.clone(), secret.clone()) @@ -179,7 +204,7 @@ impl Resolve for RunAction { let _ = update_one_by_id( &db_client().updates, &update.id, - mungos::update::Update::Set(update_doc), + database::mungos::update::Update::Set(update_doc), None, ) .await; @@ -236,7 +261,13 @@ async fn interpolate( Ok(interpolator.secret_replacers) } -fn full_contents(contents: &str, key: &str, secret: &str) -> String { +fn full_contents( + contents: &str, + // Pre-serialized to JSON string. + args: &str, + key: &str, + secret: &str, +) -> String { let CoreConfig { port, ssl_enabled, .. } = core_config(); @@ -261,6 +292,8 @@ const TOML = {{ parseCargoToml: __TOML__.parse, }} +const ARGS = {args}; + const komodo = KomodoClient('{base_url}', {{ type: 'api-key', params: {{ key: '{key}', secret: '{secret}' }} @@ -366,3 +399,25 @@ fn delete_file( } }) } + +fn parse_action_arguments( + args: &str, + format: FileFormat, +) -> anyhow::Result { + match format { + FileFormat::KeyValue => { + let args = parse_key_value_list(args) + .context("Failed to parse args as key value list")? + .into_iter() + .map(|(k, v)| (k, serde_json::Value::String(v))) + .collect(); + Ok(args) + } + FileFormat::Toml => toml::from_str(args) + .context("Failed to parse Toml to Action args"), + FileFormat::Yaml => serde_yaml_ng::from_str(args) + .context("Failed to parse Yaml to action args"), + FileFormat::Json => serde_json::from_str(args) + .context("Failed to parse Json to action args"), + } +} diff --git a/bin/core/src/api/execute/build.rs b/bin/core/src/api/execute/build.rs index 3e0b19625..febe50b2c 100644 --- a/bin/core/src/api/execute/build.rs +++ b/bin/core/src/api/execute/build.rs @@ -1,6 +1,14 @@ use std::{future::IntoFuture, time::Duration}; use anyhow::{Context, anyhow}; +use database::mungos::{ + by_id::update_one_by_id, + find::find_collect, + mongodb::{ + bson::{doc, to_bson, to_document}, + options::FindOneOptions, + }, +}; use formatting::format_serror; use futures::future::join_all; use interpolate::Interpolator; @@ -22,14 +30,6 @@ use komodo_client::{ user::auto_redeploy_user, }, }; -use mungos::{ - by_id::update_one_by_id, - find::find_collect, - mongodb::{ - bson::{doc, to_bson, to_document}, - options::FindOneOptions, - }, -}; use periphery_client::api; use resolver_api::Resolve; use tokio_util::sync::CancellationToken; @@ -352,7 +352,7 @@ impl Resolve for RunBuild { let _ = update_one_by_id( &db.updates, &update.id, - mungos::update::Update::Set(update_doc), + database::mungos::update::Update::Set(update_doc), None, ) .await; @@ -408,7 +408,7 @@ async fn handle_early_return( let _ = update_one_by_id( &db_client().updates, &update.id, - mungos::update::Update::Set(update_doc), + database::mungos::update::Update::Set(update_doc), None, ) .await; diff --git a/bin/core/src/api/execute/maintenance.rs b/bin/core/src/api/execute/maintenance.rs new file mode 100644 index 000000000..4ad70f74f --- /dev/null +++ b/bin/core/src/api/execute/maintenance.rs @@ -0,0 +1,319 @@ +use std::sync::OnceLock; + +use anyhow::{Context, anyhow}; +use command::run_komodo_command; +use database::mungos::{find::find_collect, mongodb::bson::doc}; +use formatting::{bold, format_serror}; +use komodo_client::{ + api::execute::{ + BackupCoreDatabase, ClearRepoCache, GlobalAutoUpdate, + }, + entities::{ + deployment::DeploymentState, server::ServerState, + stack::StackState, + }, +}; +use reqwest::StatusCode; +use resolver_api::Resolve; +use serror::AddStatusCodeError; +use tokio::sync::Mutex; + +use crate::{ + api::execute::{ + ExecuteArgs, pull_deployment_inner, pull_stack_inner, + }, + config::core_config, + helpers::update::update_update, + state::{ + db_client, deployment_status_cache, server_status_cache, + stack_status_cache, + }, +}; + +/// Makes sure the method can only be called once at a time +fn clear_repo_cache_lock() -> &'static Mutex<()> { + static LOCK: OnceLock> = OnceLock::new(); + LOCK.get_or_init(Default::default) +} + +impl Resolve for ClearRepoCache { + #[instrument( + name = "ClearRepoCache", + skip(user, update), + fields(user_id = user.id, update_id = update.id) + )] + async fn resolve( + self, + ExecuteArgs { user, update }: &ExecuteArgs, + ) -> Result { + if !user.admin { + return Err( + anyhow!("This method is admin only.") + .status_code(StatusCode::UNAUTHORIZED), + ); + } + + let _lock = clear_repo_cache_lock() + .try_lock() + .context("Clear already in progress...")?; + + let mut update = update.clone(); + + let mut contents = + tokio::fs::read_dir(&core_config().repo_directory) + .await + .context("Failed to read repo cache directory")?; + + loop { + let path = match contents + .next_entry() + .await + .context("Failed to read contents at path") + { + Ok(Some(contents)) => contents.path(), + Ok(None) => break, + Err(e) => { + update.push_error_log( + "Read Directory", + format_serror(&e.into()), + ); + continue; + } + }; + if path.is_dir() { + match tokio::fs::remove_dir_all(&path) + .await + .context("Failed to clear contents at path") + { + Ok(_) => {} + Err(e) => { + update.push_error_log( + "Clear Directory", + format_serror(&e.into()), + ); + } + }; + } + } + + update.finalize(); + update_update(update.clone()).await?; + + Ok(update) + } +} + +// + +/// Makes sure the method can only be called once at a time +fn backup_database_lock() -> &'static Mutex<()> { + static LOCK: OnceLock> = OnceLock::new(); + LOCK.get_or_init(Default::default) +} + +impl Resolve for BackupCoreDatabase { + #[instrument( + name = "BackupCoreDatabase", + skip(user, update), + fields(user_id = user.id, update_id = update.id) + )] + async fn resolve( + self, + ExecuteArgs { user, update }: &ExecuteArgs, + ) -> Result { + if !user.admin { + return Err( + anyhow!("This method is admin only.") + .status_code(StatusCode::UNAUTHORIZED), + ); + } + + let _lock = backup_database_lock() + .try_lock() + .context("Backup already in progress...")?; + + let mut update = update.clone(); + + update_update(update.clone()).await?; + + let res = run_komodo_command( + "Backup Core Database", + None, + "km database backup --yes", + ) + .await; + + update.logs.push(res); + update.finalize(); + + update_update(update.clone()).await?; + + Ok(update) + } +} + +// + +/// Makes sure the method can only be called once at a time +fn global_update_lock() -> &'static Mutex<()> { + static LOCK: OnceLock> = OnceLock::new(); + LOCK.get_or_init(Default::default) +} + +impl Resolve for GlobalAutoUpdate { + #[instrument( + name = "GlobalAutoUpdate", + skip(user, update), + fields(user_id = user.id, update_id = update.id) + )] + async fn resolve( + self, + ExecuteArgs { user, update }: &ExecuteArgs, + ) -> Result { + if !user.admin { + return Err( + anyhow!("This method is admin only.") + .status_code(StatusCode::UNAUTHORIZED), + ); + } + + let _lock = global_update_lock() + .try_lock() + .context("Global update already in progress...")?; + + let mut update = update.clone(); + + update_update(update.clone()).await?; + + // This is all done in sequence because there is no rush, + // the pulls / deploys happen spaced out to ease the load on system. + let servers = find_collect(&db_client().servers, None, None) + .await + .context("Failed to query for servers from database")?; + + let query = doc! { + "$or": [ + { "config.poll_for_updates": true }, + { "config.auto_update": true } + ] + }; + + let (stacks, repos) = tokio::try_join!( + find_collect(&db_client().stacks, query.clone(), None), + find_collect(&db_client().repos, None, None) + ) + .context("Failed to query for resources from database")?; + + let server_status_cache = server_status_cache(); + let stack_status_cache = stack_status_cache(); + + // Will be edited later at update.logs[0] + update.push_simple_log("Auto Pull", String::new()); + + for stack in stacks { + let Some(status) = stack_status_cache.get(&stack.id).await + else { + continue; + }; + // Only pull running stacks. + if !matches!(status.curr.state, StackState::Running) { + continue; + } + if let Some(server) = + servers.iter().find(|s| s.id == stack.config.server_id) + // This check is probably redundant along with running check + // but shouldn't hurt + && server_status_cache + .get(&server.id) + .await + .map(|s| matches!(s.state, ServerState::Ok)) + .unwrap_or_default() + { + let name = stack.name.clone(); + let repo = if stack.config.linked_repo.is_empty() { + None + } else { + let Some(repo) = + repos.iter().find(|r| r.id == stack.config.linked_repo) + else { + update.push_error_log( + &format!("Pull Stack {name}"), + format!( + "Did not find any Repo matching {}", + stack.config.linked_repo + ), + ); + continue; + }; + Some(repo.clone()) + }; + if let Err(e) = + pull_stack_inner(stack, Vec::new(), server, repo, None) + .await + { + update.push_error_log( + &format!("Pull Stack {name}"), + format_serror(&e.into()), + ); + } else { + if !update.logs[0].stdout.is_empty() { + update.logs[0].stdout.push('\n'); + } + update.logs[0] + .stdout + .push_str(&format!("Pulled Stack {} ✅", bold(name))); + } + } + } + + let deployment_status_cache = deployment_status_cache(); + let deployments = + find_collect(&db_client().deployments, query, None) + .await + .context("Failed to query for deployments from database")?; + for deployment in deployments { + let Some(status) = + deployment_status_cache.get(&deployment.id).await + else { + continue; + }; + // Only pull running deployments. + if !matches!(status.curr.state, DeploymentState::Running) { + continue; + } + if let Some(server) = + servers.iter().find(|s| s.id == deployment.config.server_id) + // This check is probably redundant along with running check + // but shouldn't hurt + && server_status_cache + .get(&server.id) + .await + .map(|s| matches!(s.state, ServerState::Ok)) + .unwrap_or_default() + { + let name = deployment.name.clone(); + if let Err(e) = + pull_deployment_inner(deployment, server).await + { + update.push_error_log( + &format!("Pull Deployment {name}"), + format_serror(&e.into()), + ); + } else { + if !update.logs[0].stdout.is_empty() { + update.logs[0].stdout.push('\n'); + } + update.logs[0].stdout.push_str(&format!( + "Pulled Deployment {} ✅", + bold(name) + )); + } + } + } + + update.finalize(); + update_update(update.clone()).await?; + + Ok(update) + } +} diff --git a/bin/core/src/api/execute/mod.rs b/bin/core/src/api/execute/mod.rs index 82642f032..af544b45b 100644 --- a/bin/core/src/api/execute/mod.rs +++ b/bin/core/src/api/execute/mod.rs @@ -5,6 +5,7 @@ use axum::{ Extension, Router, extract::Path, middleware, routing::post, }; use axum_extra::{TypedHeader, headers::ContentType}; +use database::mungos::by_id::find_one_by_id; use derive_variants::{EnumVariants, ExtractVariant}; use formatting::format_serror; use futures::future::join_all; @@ -17,7 +18,6 @@ use komodo_client::{ user::User, }, }; -use mungos::by_id::find_one_by_id; use resolver_api::Resolve; use response::JsonString; use serde::{Deserialize, Serialize}; @@ -37,6 +37,7 @@ mod action; mod alerter; mod build; mod deployment; +mod maintenance; mod procedure; mod repo; mod server; @@ -141,6 +142,11 @@ pub enum ExecuteRequest { // ==== SYNC ==== RunSync(RunSync), + + // ==== MAINTENANCE ==== + ClearRepoCache(ClearRepoCache), + BackupCoreDatabase(BackupCoreDatabase), + GlobalAutoUpdate(GlobalAutoUpdate), } pub fn router() -> Router { @@ -195,8 +201,10 @@ pub fn inner_handler( Box::pin(async move { let req_id = Uuid::new_v4(); - // need to validate no cancel is active before any update is created. + // Need to validate no cancel is active before any update is created. + // This ensures no double update created if Cancel is called more than once for the same request. build::validate_cancel_build(&request).await?; + repo::validate_cancel_repo_build(&request).await?; let update = init_execution_update(&request, &user).await?; diff --git a/bin/core/src/api/execute/procedure.rs b/bin/core/src/api/execute/procedure.rs index f4f539cf8..ec4ca2ee4 100644 --- a/bin/core/src/api/execute/procedure.rs +++ b/bin/core/src/api/execute/procedure.rs @@ -1,5 +1,8 @@ use std::pin::Pin; +use database::mungos::{ + by_id::update_one_by_id, mongodb::bson::to_document, +}; use formatting::{Color, bold, colored, format_serror, muted}; use komodo_client::{ api::execute::{ @@ -14,7 +17,6 @@ use komodo_client::{ user::User, }, }; -use mungos::{by_id::update_one_by_id, mongodb::bson::to_document}; use resolver_api::Resolve; use tokio::sync::Mutex; @@ -134,7 +136,7 @@ fn resolve_inner( let _ = update_one_by_id( &db_client().updates, &update.id, - mungos::update::Update::Set(update_doc), + database::mungos::update::Update::Set(update_doc), None, ) .await; diff --git a/bin/core/src/api/execute/repo.rs b/bin/core/src/api/execute/repo.rs index ca075e102..5adbdce2e 100644 --- a/bin/core/src/api/execute/repo.rs +++ b/bin/core/src/api/execute/repo.rs @@ -1,6 +1,13 @@ use std::{collections::HashSet, future::IntoFuture, time::Duration}; use anyhow::{Context, anyhow}; +use database::mungos::{ + by_id::update_one_by_id, + mongodb::{ + bson::{doc, to_document}, + options::FindOneOptions, + }, +}; use formatting::format_serror; use interpolate::Interpolator; use komodo_client::{ @@ -15,13 +22,6 @@ use komodo_client::{ update::{Log, Update}, }, }; -use mungos::{ - by_id::update_one_by_id, - mongodb::{ - bson::{doc, to_document}, - options::FindOneOptions, - }, -}; use periphery_client::api; use resolver_api::Resolve; use tokio_util::sync::CancellationToken; @@ -287,7 +287,7 @@ async fn handle_repo_update_return( let _ = update_one_by_id( &db_client().updates, &update.id, - mungos::update::Update::Set(update_doc), + database::mungos::update::Update::Set(update_doc), None, ) .await; @@ -520,7 +520,7 @@ impl Resolve for BuildRepo { let _ = update_one_by_id( &db.updates, &update.id, - mungos::update::Update::Set(update_doc), + database::mungos::update::Update::Set(update_doc), None, ) .await; @@ -569,7 +569,7 @@ async fn handle_builder_early_return( let _ = update_one_by_id( &db_client().updates, &update.id, - mungos::update::Update::Set(update_doc), + database::mungos::update::Update::Set(update_doc), None, ) .await; diff --git a/bin/core/src/api/execute/stack.rs b/bin/core/src/api/execute/stack.rs index 415e6a7f1..0e1829d16 100644 --- a/bin/core/src/api/execute/stack.rs +++ b/bin/core/src/api/execute/stack.rs @@ -1,4 +1,5 @@ use anyhow::Context; +use database::mungos::mongodb::bson::{doc, to_document}; use formatting::format_serror; use interpolate::Interpolator; use komodo_client::{ @@ -11,7 +12,6 @@ use komodo_client::{ update::{Log, Update}, }, }; -use mungos::mongodb::bson::{doc, to_document}; use periphery_client::api::compose::*; use resolver_api::Resolve; @@ -123,10 +123,10 @@ impl Resolve for DeployStack { Interpolator::new(Some(&variables), &secrets); interpolator.interpolate_stack(&mut stack)?; - if let Some(repo) = repo.as_mut() { - if !repo.config.skip_secret_interp { - interpolator.interpolate_repo(repo)?; - } + if let Some(repo) = repo.as_mut() + && !repo.config.skip_secret_interp + { + interpolator.interpolate_repo(repo)?; } interpolator.push_logs(&mut update.logs); @@ -378,16 +378,16 @@ pub async fn pull_stack_inner( mut repo: Option, mut update: Option<&mut Update>, ) -> anyhow::Result { - if let Some(update) = update.as_mut() { - if !services.is_empty() { - update.logs.push(Log::simple( - "Service/s", - format!( - "Execution requested for Stack service/s {}", - services.join(", ") - ), - )) - } + if let Some(update) = update.as_mut() + && !services.is_empty() + { + update.logs.push(Log::simple( + "Service/s", + format!( + "Execution requested for Stack service/s {}", + services.join(", ") + ), + )) } let git_token = stack_git_token(&mut stack, repo.as_mut()).await?; @@ -408,10 +408,10 @@ pub async fn pull_stack_inner( Interpolator::new(Some(&variables), &secrets); interpolator.interpolate_stack(&mut stack)?; - if let Some(repo) = repo.as_mut() { - if !repo.config.skip_secret_interp { - interpolator.interpolate_repo(repo)?; - } + if let Some(repo) = repo.as_mut() + && !repo.config.skip_secret_interp + { + interpolator.interpolate_repo(repo)?; } if let Some(update) = update { interpolator.push_logs(&mut update.logs); diff --git a/bin/core/src/api/execute/sync.rs b/bin/core/src/api/execute/sync.rs index 9f5ffc6d4..bc2579e91 100644 --- a/bin/core/src/api/execute/sync.rs +++ b/bin/core/src/api/execute/sync.rs @@ -1,6 +1,10 @@ use std::{collections::HashMap, str::FromStr}; use anyhow::{Context, anyhow}; +use database::mungos::{ + by_id::update_one_by_id, + mongodb::bson::{doc, oid::ObjectId}, +}; use formatting::{Color, colored, format_serror}; use komodo_client::{ api::{execute::RunSync, write::RefreshResourceSyncPending}, @@ -22,8 +26,6 @@ use komodo_client::{ user::sync_user, }, }; -use mongo_indexed::doc; -use mungos::{by_id::update_one_by_id, mongodb::bson::oid::ObjectId}; use resolver_api::Resolve; use crate::{ diff --git a/bin/core/src/api/read/alert.rs b/bin/core/src/api/read/alert.rs index 35f6cdb9d..e8f75163a 100644 --- a/bin/core/src/api/read/alert.rs +++ b/bin/core/src/api/read/alert.rs @@ -1,4 +1,9 @@ use anyhow::Context; +use database::mungos::{ + by_id::find_one_by_id, + find::find_collect, + mongodb::{bson::doc, options::FindOptions}, +}; use komodo_client::{ api::read::{ GetAlert, GetAlertResponse, ListAlerts, ListAlertsResponse, @@ -8,11 +13,6 @@ use komodo_client::{ sync::ResourceSync, }, }; -use mungos::{ - by_id::find_one_by_id, - find::find_collect, - mongodb::{bson::doc, options::FindOptions}, -}; use resolver_api::Resolve; use crate::{ diff --git a/bin/core/src/api/read/alerter.rs b/bin/core/src/api/read/alerter.rs index 253f78b98..f6a53ebaa 100644 --- a/bin/core/src/api/read/alerter.rs +++ b/bin/core/src/api/read/alerter.rs @@ -1,4 +1,6 @@ use anyhow::Context; +use database::mongo_indexed::Document; +use database::mungos::mongodb::bson::doc; use komodo_client::{ api::read::*, entities::{ @@ -6,8 +8,6 @@ use komodo_client::{ permission::PermissionLevel, }, }; -use mongo_indexed::Document; -use mungos::mongodb::bson::doc; use resolver_api::Resolve; use crate::{ diff --git a/bin/core/src/api/read/build.rs b/bin/core/src/api/read/build.rs index 3305e1031..1082847b7 100644 --- a/bin/core/src/api/read/build.rs +++ b/bin/core/src/api/read/build.rs @@ -2,6 +2,10 @@ use std::collections::{HashMap, HashSet}; use anyhow::Context; use async_timing_util::unix_timestamp_ms; +use database::mungos::{ + find::find_collect, + mongodb::{bson::doc, options::FindOptions}, +}; use futures::TryStreamExt; use komodo_client::{ api::read::*, @@ -13,10 +17,6 @@ use komodo_client::{ update::UpdateStatus, }, }; -use mungos::{ - find::find_collect, - mongodb::{bson::doc, options::FindOptions}, -}; use resolver_api::Resolve; use crate::{ diff --git a/bin/core/src/api/read/builder.rs b/bin/core/src/api/read/builder.rs index ba2e551b5..52cb18b94 100644 --- a/bin/core/src/api/read/builder.rs +++ b/bin/core/src/api/read/builder.rs @@ -1,4 +1,6 @@ use anyhow::Context; +use database::mongo_indexed::Document; +use database::mungos::mongodb::bson::doc; use komodo_client::{ api::read::*, entities::{ @@ -6,8 +8,6 @@ use komodo_client::{ permission::PermissionLevel, }, }; -use mongo_indexed::Document; -use mungos::mongodb::bson::doc; use resolver_api::Resolve; use crate::{ diff --git a/bin/core/src/api/read/mod.rs b/bin/core/src/api/read/mod.rs index 7bfbe0d30..611b6ce91 100644 --- a/bin/core/src/api/read/mod.rs +++ b/bin/core/src/api/read/mod.rs @@ -290,6 +290,7 @@ fn core_info() -> &'static GetCoreInfoResponse { disable_confirm_dialog: config.disable_confirm_dialog, disable_non_admin_create: config.disable_non_admin_create, disable_websocket_reconnect: config.disable_websocket_reconnect, + enable_fancy_toml: config.enable_fancy_toml, github_webhook_owners: config .github_webhook_app .installations diff --git a/bin/core/src/api/read/permission.rs b/bin/core/src/api/read/permission.rs index 3a2d36b0e..fb1a3526e 100644 --- a/bin/core/src/api/read/permission.rs +++ b/bin/core/src/api/read/permission.rs @@ -1,4 +1,5 @@ use anyhow::{Context, anyhow}; +use database::mungos::{find::find_collect, mongodb::bson::doc}; use komodo_client::{ api::read::{ GetPermission, GetPermissionResponse, ListPermissions, @@ -7,7 +8,6 @@ use komodo_client::{ }, entities::permission::PermissionLevel, }; -use mungos::{find::find_collect, mongodb::bson::doc}; use resolver_api::Resolve; use crate::{ diff --git a/bin/core/src/api/read/provider.rs b/bin/core/src/api/read/provider.rs index df416ae3b..023540031 100644 --- a/bin/core/src/api/read/provider.rs +++ b/bin/core/src/api/read/provider.rs @@ -1,10 +1,10 @@ use anyhow::{Context, anyhow}; -use komodo_client::api::read::*; -use mongo_indexed::{Document, doc}; -use mungos::{ +use database::mongo_indexed::{Document, doc}; +use database::mungos::{ by_id::find_one_by_id, find::find_collect, mongodb::options::FindOptions, }; +use komodo_client::api::read::*; use resolver_api::Resolve; use crate::state::db_client; diff --git a/bin/core/src/api/read/server.rs b/bin/core/src/api/read/server.rs index 610eeadf1..b7f756a3c 100644 --- a/bin/core/src/api/read/server.rs +++ b/bin/core/src/api/read/server.rs @@ -8,6 +8,10 @@ use anyhow::{Context, anyhow}; use async_timing_util::{ FIFTEEN_SECONDS_MS, get_timelength_in_ms, unix_timestamp_ms, }; +use database::mungos::{ + find::find_collect, + mongodb::{bson::doc, options::FindOptions}, +}; use komodo_client::{ api::read::*, entities::{ @@ -32,10 +36,6 @@ use komodo_client::{ update::Log, }, }; -use mungos::{ - find::find_collect, - mongodb::{bson::doc, options::FindOptions}, -}; use periphery_client::api::{ self as periphery, container::InspectContainer, diff --git a/bin/core/src/api/read/tag.rs b/bin/core/src/api/read/tag.rs index 6bb849181..60dcf64c6 100644 --- a/bin/core/src/api/read/tag.rs +++ b/bin/core/src/api/read/tag.rs @@ -1,10 +1,12 @@ use anyhow::Context; +use database::mongo_indexed::doc; +use database::mungos::{ + find::find_collect, mongodb::options::FindOptions, +}; use komodo_client::{ api::read::{GetTag, ListTags}, entities::tag::Tag, }; -use mongo_indexed::doc; -use mungos::{find::find_collect, mongodb::options::FindOptions}; use resolver_api::Resolve; use crate::{helpers::query::get_tag, state::db_client}; diff --git a/bin/core/src/api/read/toml.rs b/bin/core/src/api/read/toml.rs index bd71f7f6f..afc712aea 100644 --- a/bin/core/src/api/read/toml.rs +++ b/bin/core/src/api/read/toml.rs @@ -1,4 +1,5 @@ use anyhow::Context; +use database::mungos::find::find_collect; use komodo_client::{ api::read::{ ExportAllResourcesToToml, ExportAllResourcesToTomlResponse, @@ -13,7 +14,6 @@ use komodo_client::{ sync::ResourceSync, toml::ResourcesToml, user::User, }, }; -use mungos::find::find_collect; use resolver_api::Resolve; use crate::{ diff --git a/bin/core/src/api/read/update.rs b/bin/core/src/api/read/update.rs index f1176037b..a2b701557 100644 --- a/bin/core/src/api/read/update.rs +++ b/bin/core/src/api/read/update.rs @@ -1,6 +1,11 @@ use std::collections::HashMap; use anyhow::{Context, anyhow}; +use database::mungos::{ + by_id::find_one_by_id, + find::find_collect, + mongodb::{bson::doc, options::FindOptions}, +}; use komodo_client::{ api::read::{GetUpdate, ListUpdates, ListUpdatesResponse}, entities::{ @@ -20,11 +25,6 @@ use komodo_client::{ user::User, }, }; -use mungos::{ - by_id::find_one_by_id, - find::find_collect, - mongodb::{bson::doc, options::FindOptions}, -}; use resolver_api::Resolve; use crate::{ diff --git a/bin/core/src/api/read/user.rs b/bin/core/src/api/read/user.rs index 5a9395045..a4293728b 100644 --- a/bin/core/src/api/read/user.rs +++ b/bin/core/src/api/read/user.rs @@ -1,4 +1,9 @@ use anyhow::{Context, anyhow}; +use database::mungos::{ + by_id::find_one_by_id, + find::find_collect, + mongodb::{bson::doc, options::FindOptions}, +}; use komodo_client::{ api::read::{ FindUser, FindUserResponse, GetUsername, GetUsernameResponse, @@ -8,11 +13,6 @@ use komodo_client::{ }, entities::user::{UserConfig, admin_service_user}, }; -use mungos::{ - by_id::find_one_by_id, - find::find_collect, - mongodb::{bson::doc, options::FindOptions}, -}; use resolver_api::Resolve; use crate::{helpers::query::get_user, state::db_client}; diff --git a/bin/core/src/api/read/user_group.rs b/bin/core/src/api/read/user_group.rs index 611bd9de4..8b5a0f4dc 100644 --- a/bin/core/src/api/read/user_group.rs +++ b/bin/core/src/api/read/user_group.rs @@ -1,14 +1,14 @@ use std::str::FromStr; use anyhow::Context; -use komodo_client::api::read::*; -use mungos::{ +use database::mungos::{ find::find_collect, mongodb::{ bson::{Document, doc, oid::ObjectId}, options::FindOptions, }, }; +use komodo_client::api::read::*; use resolver_api::Resolve; use crate::state::db_client; diff --git a/bin/core/src/api/read/variable.rs b/bin/core/src/api/read/variable.rs index f196c1df2..a28b90b3e 100644 --- a/bin/core/src/api/read/variable.rs +++ b/bin/core/src/api/read/variable.rs @@ -1,7 +1,9 @@ use anyhow::Context; +use database::mongo_indexed::doc; +use database::mungos::{ + find::find_collect, mongodb::options::FindOptions, +}; use komodo_client::api::read::*; -use mongo_indexed::doc; -use mungos::{find::find_collect, mongodb::options::FindOptions}; use resolver_api::Resolve; use crate::{helpers::query::get_variable, state::db_client}; diff --git a/bin/core/src/api/user.rs b/bin/core/src/api/user.rs index e315b87c1..fcbfe0be3 100644 --- a/bin/core/src/api/user.rs +++ b/bin/core/src/api/user.rs @@ -4,13 +4,15 @@ use anyhow::{Context, anyhow}; use axum::{ Extension, Json, Router, extract::Path, middleware, routing::post, }; +use database::mongo_indexed::doc; +use database::mungos::{ + by_id::update_one_by_id, mongodb::bson::to_bson, +}; use derive_variants::EnumVariants; use komodo_client::{ api::user::*, entities::{api_key::ApiKey, komodo_timestamp, user::User}, }; -use mongo_indexed::doc; -use mungos::{by_id::update_one_by_id, mongodb::bson::to_bson}; use resolver_api::Resolve; use response::Response; use serde::{Deserialize, Serialize}; @@ -116,7 +118,7 @@ impl Resolve for PushRecentlyViewed { update_one_by_id( &db_client().users, &user.id, - mungos::update::Update::Set(update), + database::mungos::update::Update::Set(update), None, ) .await @@ -141,7 +143,7 @@ impl Resolve for SetLastSeenUpdate { update_one_by_id( &db_client().users, &user.id, - mungos::update::Update::Set(doc! { + database::mungos::update::Update::Set(doc! { "last_update_view": komodo_timestamp() }), None, diff --git a/bin/core/src/api/write/build.rs b/bin/core/src/api/write/build.rs index a4ed4f18e..075e7432e 100644 --- a/bin/core/src/api/write/build.rs +++ b/bin/core/src/api/write/build.rs @@ -1,6 +1,8 @@ use std::{path::PathBuf, str::FromStr, time::Duration}; use anyhow::{Context, anyhow}; +use database::mongo_indexed::doc; +use database::mungos::mongodb::bson::to_document; use formatting::format_serror; use komodo_client::{ api::write::*, @@ -16,8 +18,6 @@ use komodo_client::{ update::Update, }, }; -use mongo_indexed::doc; -use mungos::mongodb::bson::to_document; use octorust::types::{ ReposCreateWebhookRequest, ReposCreateWebhookRequestConfig, }; diff --git a/bin/core/src/api/write/deployment.rs b/bin/core/src/api/write/deployment.rs index f62c8fac9..2e7cb45c4 100644 --- a/bin/core/src/api/write/deployment.rs +++ b/bin/core/src/api/write/deployment.rs @@ -1,4 +1,5 @@ use anyhow::{Context, anyhow}; +use database::mungos::{by_id::update_one_by_id, mongodb::bson::doc}; use komodo_client::{ api::write::*, entities::{ @@ -15,7 +16,6 @@ use komodo_client::{ update::Update, }, }; -use mungos::{by_id::update_one_by_id, mongodb::bson::doc}; use periphery_client::api::{self, container::InspectContainer}; use resolver_api::Resolve; @@ -227,7 +227,7 @@ impl Resolve for RenameDeployment { update_one_by_id( &db_client().deployments, &deployment.id, - mungos::update::Update::Set( + database::mungos::update::Update::Set( doc! { "name": &name, "updated_at": komodo_timestamp() }, ), None, diff --git a/bin/core/src/api/write/mod.rs b/bin/core/src/api/write/mod.rs index 4d63d9cd0..c4acff70d 100644 --- a/bin/core/src/api/write/mod.rs +++ b/bin/core/src/api/write/mod.rs @@ -52,6 +52,7 @@ pub struct WriteArgs { #[serde(tag = "type", content = "params")] pub enum WriteRequest { // ==== USER ==== + CreateLocalUser(CreateLocalUser), UpdateUserUsername(UpdateUserUsername), UpdateUserPassword(UpdateUserPassword), DeleteUser(DeleteUser), diff --git a/bin/core/src/api/write/permissions.rs b/bin/core/src/api/write/permissions.rs index ed641ab63..3458658d2 100644 --- a/bin/core/src/api/write/permissions.rs +++ b/bin/core/src/api/write/permissions.rs @@ -1,6 +1,13 @@ use std::str::FromStr; use anyhow::{Context, anyhow}; +use database::mungos::{ + by_id::{find_one_by_id, update_one_by_id}, + mongodb::{ + bson::{Document, doc, oid::ObjectId, to_bson}, + options::UpdateOptions, + }, +}; use komodo_client::{ api::write::*, entities::{ @@ -8,13 +15,6 @@ use komodo_client::{ permission::{UserTarget, UserTargetVariant}, }, }; -use mungos::{ - by_id::{find_one_by_id, update_one_by_id}, - mongodb::{ - bson::{Document, doc, oid::ObjectId, to_bson}, - options::UpdateOptions, - }, -}; use resolver_api::Resolve; use crate::{helpers::query::get_user, state::db_client}; @@ -107,7 +107,7 @@ impl Resolve for UpdateUserBasePermissions { update_one_by_id( &db_client().users, &user_id, - mungos::update::Update::Set(update_doc), + database::mungos::update::Update::Set(update_doc), None, ) .await?; diff --git a/bin/core/src/api/write/provider.rs b/bin/core/src/api/write/provider.rs index 07d7bd0b7..312ccf445 100644 --- a/bin/core/src/api/write/provider.rs +++ b/bin/core/src/api/write/provider.rs @@ -1,4 +1,8 @@ use anyhow::{Context, anyhow}; +use database::mungos::{ + by_id::{delete_one_by_id, find_one_by_id, update_one_by_id}, + mongodb::bson::{doc, to_document}, +}; use komodo_client::{ api::write::*, entities::{ @@ -6,10 +10,6 @@ use komodo_client::{ provider::{DockerRegistryAccount, GitProviderAccount}, }, }; -use mungos::{ - by_id::{delete_one_by_id, find_one_by_id, update_one_by_id}, - mongodb::bson::{doc, to_document}, -}; use resolver_api::Resolve; use crate::{ @@ -90,22 +90,22 @@ impl Resolve for UpdateGitProviderAccount { ); } - if let Some(domain) = &self.account.domain { - if domain.is_empty() { - return Err( - anyhow!("cannot update git provider with empty domain") - .into(), - ); - } + if let Some(domain) = &self.account.domain + && domain.is_empty() + { + return Err( + anyhow!("cannot update git provider with empty domain") + .into(), + ); } - if let Some(username) = &self.account.username { - if username.is_empty() { - return Err( - anyhow!("cannot update git provider with empty username") - .into(), - ); - } + if let Some(username) = &self.account.username + && username.is_empty() + { + return Err( + anyhow!("cannot update git provider with empty username") + .into(), + ); } // Ensure update does not change id @@ -283,26 +283,26 @@ impl Resolve for UpdateDockerRegistryAccount { ); } - if let Some(domain) = &self.account.domain { - if domain.is_empty() { - return Err( - anyhow!( - "cannot update docker registry account with empty domain" - ) - .into(), - ); - } + if let Some(domain) = &self.account.domain + && domain.is_empty() + { + return Err( + anyhow!( + "cannot update docker registry account with empty domain" + ) + .into(), + ); } - if let Some(username) = &self.account.username { - if username.is_empty() { - return Err( - anyhow!( - "cannot update docker registry account with empty username" - ) - .into(), - ); - } + if let Some(username) = &self.account.username + && username.is_empty() + { + return Err( + anyhow!( + "cannot update docker registry account with empty username" + ) + .into(), + ); } self.account.id = None; diff --git a/bin/core/src/api/write/repo.rs b/bin/core/src/api/write/repo.rs index 6b35a4f2f..a68406ffc 100644 --- a/bin/core/src/api/write/repo.rs +++ b/bin/core/src/api/write/repo.rs @@ -1,4 +1,8 @@ use anyhow::{Context, anyhow}; +use database::mongo_indexed::doc; +use database::mungos::{ + by_id::update_one_by_id, mongodb::bson::to_document, +}; use formatting::format_serror; use komodo_client::{ api::write::*, @@ -13,8 +17,6 @@ use komodo_client::{ update::{Log, Update}, }, }; -use mongo_indexed::doc; -use mungos::{by_id::update_one_by_id, mongodb::bson::to_document}; use octorust::types::{ ReposCreateWebhookRequest, ReposCreateWebhookRequestConfig, }; @@ -117,7 +119,7 @@ impl Resolve for RenameRepo { update_one_by_id( &db_client().repos, &repo.id, - mungos::update::Update::Set( + database::mungos::update::Update::Set( doc! { "name": &name, "updated_at": komodo_timestamp() }, ), None, diff --git a/bin/core/src/api/write/service_user.rs b/bin/core/src/api/write/service_user.rs index a825254d6..093dbe48e 100644 --- a/bin/core/src/api/write/service_user.rs +++ b/bin/core/src/api/write/service_user.rs @@ -1,6 +1,10 @@ use std::str::FromStr; use anyhow::{Context, anyhow}; +use database::mungos::{ + by_id::find_one_by_id, + mongodb::bson::{doc, oid::ObjectId}, +}; use komodo_client::{ api::{user::CreateApiKey, write::*}, entities::{ @@ -8,10 +12,6 @@ use komodo_client::{ user::{User, UserConfig}, }, }; -use mungos::{ - by_id::find_one_by_id, - mongodb::bson::{doc, oid::ObjectId}, -}; use resolver_api::Resolve; use crate::{api::user::UserArgs, state::db_client}; diff --git a/bin/core/src/api/write/stack.rs b/bin/core/src/api/write/stack.rs index 46ae1a357..28e7b5e26 100644 --- a/bin/core/src/api/write/stack.rs +++ b/bin/core/src/api/write/stack.rs @@ -1,9 +1,13 @@ +use std::path::PathBuf; + use anyhow::{Context, anyhow}; +use database::mungos::mongodb::bson::{doc, to_document}; use formatting::format_serror; use komodo_client::{ api::write::*, entities::{ - FileContents, NoData, Operation, + FileContents, NoData, Operation, RepoExecutionArgs, + all_logs_success, config::core::CoreConfig, permission::PermissionLevel, repo::Repo, @@ -13,18 +17,16 @@ use komodo_client::{ user::stack_user, }, }; -use mungos::mongodb::bson::{doc, to_document}; use octorust::types::{ ReposCreateWebhookRequest, ReposCreateWebhookRequestConfig, }; use periphery_client::api::compose::{ GetComposeContentsOnHost, GetComposeContentsOnHostResponse, - WriteCommitComposeContents, WriteComposeContentsToHost, + WriteComposeContentsToHost, }; use resolver_api::Resolve; use crate::{ - api::execute::pull_stack_inner, config::core_config, helpers::{ periphery_client, @@ -35,7 +37,6 @@ use crate::{ permission::get_check_permissions, resource, stack::{ - get_stack_and_server, remote::{RemoteComposeContents, get_repo_compose_contents}, services::extract_services_into_res, }, @@ -114,24 +115,13 @@ impl Resolve for WriteStackFileContents { file_path, contents, } = self; - let (mut stack, server) = get_stack_and_server( + let stack = get_check_permissions::( &stack, user, PermissionLevel::Write.into(), - true, ) .await?; - let mut repo = if !stack.config.files_on_host - && !stack.config.linked_repo.is_empty() - { - crate::resource::get::(&stack.config.linked_repo) - .await? - .into() - } else { - None - }; - if !stack.config.files_on_host && stack.config.repo.is_empty() && stack.config.linked_repo.is_empty() @@ -146,77 +136,231 @@ impl Resolve for WriteStackFileContents { update.push_simple_log("File contents to write", &contents); - let stack_id = stack.id.clone(); - if stack.config.files_on_host { - match periphery_client(&server)? - .request(WriteComposeContentsToHost { - name: stack.name, - run_directory: stack.config.run_directory, - file_path, - contents, - }) - .await - .context("Failed to write contents to host") - { - Ok(log) => { - update.logs.push(log); - } - Err(e) => { - update.push_error_log( - "Write File Contents", - format_serror(&e.into()), - ); - } - }; - } else { - let git_token = - stack_git_token(&mut stack, repo.as_mut()).await?; - match periphery_client(&server)? - .request(WriteCommitComposeContents { - stack, - repo, - username: Some(user.username.clone()), - file_path, - contents, - git_token, - }) - .await - .context("Failed to write contents to host") - { - Ok(res) => { - update.logs.extend(res.logs); - } - Err(e) => { - update.push_error_log( - "Write File Contents", - format_serror(&e.into()), - ); - } - }; - } - - if let Err(e) = (RefreshStackCache { stack: stack_id }) - .resolve(&WriteArgs { - user: stack_user().to_owned(), - }) - .await - .map_err(|e| e.error) - .context( - "Failed to refresh stack cache after writing file contents", + write_stack_file_contents_on_host( + stack, file_path, contents, update, ) - { + .await + } else { + write_stack_file_contents_git( + stack, + &file_path, + &contents, + &user.username, + update, + ) + .await + } + } +} + +async fn write_stack_file_contents_on_host( + stack: Stack, + file_path: String, + contents: String, + mut update: Update, +) -> serror::Result { + if stack.config.server_id.is_empty() { + return Err(anyhow!( + "Cannot write file, Files on host Stack has not configured a Server" + ).into()); + } + let (server, state) = + get_server_with_state(&stack.config.server_id).await?; + if state != ServerState::Ok { + return Err( + anyhow!( + "Cannot write file when server is unreachable or disabled" + ) + .into(), + ); + } + match periphery_client(&server)? + .request(WriteComposeContentsToHost { + name: stack.name, + run_directory: stack.config.run_directory, + file_path, + contents, + }) + .await + .context("Failed to write contents to host") + { + Ok(log) => { + update.logs.push(log); + } + Err(e) => { update.push_error_log( - "Refresh stack cache", + "Write File Contents", format_serror(&e.into()), ); } + }; + if !all_logs_success(&update.logs) { + update.finalize(); + update.id = add_update(update.clone()).await?; + return Ok(update); + } + + // Finish with a cache refresh + if let Err(e) = (RefreshStackCache { stack: stack.id }) + .resolve(&WriteArgs { + user: stack_user().to_owned(), + }) + .await + .map_err(|e| e.error) + .context( + "Failed to refresh stack cache after writing file contents", + ) + { + update.push_error_log( + "Refresh stack cache", + format_serror(&e.into()), + ); + } + + update.finalize(); + update.id = add_update(update.clone()).await?; + + Ok(update) +} + +async fn write_stack_file_contents_git( + mut stack: Stack, + file_path: &str, + contents: &str, + username: &str, + mut update: Update, +) -> serror::Result { + let mut repo = if !stack.config.linked_repo.is_empty() { + crate::resource::get::(&stack.config.linked_repo) + .await? + .into() + } else { + None + }; + let git_token = stack_git_token(&mut stack, repo.as_mut()).await?; + + let mut repo_args: RepoExecutionArgs = if let Some(repo) = &repo { + repo.into() + } else { + (&stack).into() + }; + let root = repo_args.unique_path(&core_config().repo_directory)?; + repo_args.destination = Some(root.display().to_string()); + + let file_path = stack + .config + .run_directory + .parse::() + .context("Run directory is not a valid path")? + .join(file_path); + let full_path = + root.join(&file_path).components().collect::(); + + if let Some(parent) = full_path.parent() { + tokio::fs::create_dir_all(parent).await.with_context(|| { + format!( + "Failed to initialize stack file parent directory {parent:?}" + ) + })?; + } + + // Ensure the folder is initialized as git repo. + // This allows a new file to be committed on a branch that may not exist. + if !root.join(".git").exists() { + git::init_folder_as_repo( + &root, + &repo_args, + git_token.as_deref(), + &mut update.logs, + ) + .await; + + if !all_logs_success(&update.logs) { + update.finalize(); + update.id = add_update(update.clone()).await?; + return Ok(update); + } + } + + // Pull latest changes to repo to ensure linear commit history + match git::pull_or_clone( + repo_args, + &core_config().repo_directory, + git_token, + ) + .await + .context("Failed to pull latest changes before commit") + { + Ok((res, _)) => update.logs.extend(res.logs), + Err(e) => { + update.push_error_log("Pull Repo", format_serror(&e.into())); + update.finalize(); + return Ok(update); + } + }; + + if !all_logs_success(&update.logs) { + update.finalize(); + update.id = add_update(update.clone()).await?; + return Ok(update); + } + + if let Err(e) = tokio::fs::write(&full_path, &contents) + .await + .with_context(|| { + format!( + "Failed to write compose file contents to {full_path:?}" + ) + }) + { + update.push_error_log("Write File", format_serror(&e.into())); + } else { + update.push_simple_log( + "Write File", + format!("File written to {full_path:?}"), + ); + }; + + if !all_logs_success(&update.logs) { update.finalize(); update.id = add_update(update.clone()).await?; - Ok(update) + return Ok(update); } + + let commit_res = git::commit_file( + &format!("{username}: Write Stack File"), + &root, + &file_path, + &stack.config.branch, + ) + .await; + + update.logs.extend(commit_res.logs); + + // Finish with a cache refresh + if let Err(e) = (RefreshStackCache { stack: stack.id }) + .resolve(&WriteArgs { + user: stack_user().to_owned(), + }) + .await + .map_err(|e| e.error) + .context( + "Failed to refresh stack cache after writing file contents", + ) + { + update.push_error_log( + "Refresh stack cache", + format_serror(&e.into()), + ); + } + + update.finalize(); + update.id = add_update(update.clone()).await?; + + Ok(update) } impl Resolve for RefreshStackCache { @@ -411,24 +555,6 @@ impl Resolve for RefreshStackCache { .await .context("failed to update stack info on db")?; - if (stack.config.poll_for_updates || stack.config.auto_update) - && !stack.config.server_id.is_empty() - { - let (server, state) = - get_server_with_state(&stack.config.server_id).await?; - if state == ServerState::Ok { - let name = stack.name.clone(); - if let Err(e) = - pull_stack_inner(stack, Vec::new(), &server, repo, None) - .await - { - warn!( - "Failed to pull latest images for Stack {name} | {e:#}", - ); - } - } - } - Ok(NoData {}) } } diff --git a/bin/core/src/api/write/sync.rs b/bin/core/src/api/write/sync.rs index 0320789f3..1894e5314 100644 --- a/bin/core/src/api/write/sync.rs +++ b/bin/core/src/api/write/sync.rs @@ -4,6 +4,10 @@ use std::{ }; use anyhow::{Context, anyhow}; +use database::mungos::{ + by_id::update_one_by_id, + mongodb::bson::{doc, to_document}, +}; use formatting::format_serror; use komodo_client::{ api::{read::ExportAllResourcesToToml, write::*}, @@ -32,15 +36,10 @@ use komodo_client::{ user::sync_user, }, }; -use mungos::{ - by_id::update_one_by_id, - mongodb::bson::{doc, to_document}, -}; use octorust::types::{ ReposCreateWebhookRequest, ReposCreateWebhookRequestConfig, }; use resolver_api::Resolve; -use tokio::fs; use crate::{ alert::send_alerts, @@ -206,15 +205,16 @@ async fn write_sync_file_contents_on_host( let full_path = root.join(&resource_path).join(&file_path); if let Some(parent) = full_path.parent() { - fs::create_dir_all(parent).await.with_context(|| { + tokio::fs::create_dir_all(parent).await.with_context(|| { format!( "Failed to initialize resource file parent directory {parent:?}" ) })?; } - if let Err(e) = - fs::write(&full_path, &contents).await.with_context(|| { + if let Err(e) = tokio::fs::write(&full_path, &contents) + .await + .with_context(|| { format!( "Failed to write resource file contents to {full_path:?}" ) @@ -265,29 +265,32 @@ async fn write_sync_file_contents_git( contents, } = req; - let mut clone_args: RepoExecutionArgs = if let Some(repo) = &repo { + let mut repo_args: RepoExecutionArgs = if let Some(repo) = &repo { repo.into() } else { (&sync).into() }; - let root = clone_args.unique_path(&core_config().repo_directory)?; - clone_args.destination = Some(root.display().to_string()); + let root = repo_args.unique_path(&core_config().repo_directory)?; + repo_args.destination = Some(root.display().to_string()); - let access_token = if let Some(account) = &clone_args.account { - git_token(&clone_args.provider, account, |https| clone_args.https = https) + let git_token = if let Some(account) = &repo_args.account { + git_token(&repo_args.provider, account, |https| repo_args.https = https) .await .with_context( - || format!("Failed to get git token in call to db. Stopping run. | {} | {account}", clone_args.provider), + || format!("Failed to get git token in call to db. Stopping run. | {} | {account}", repo_args.provider), )? } else { None }; let file_path = - file_path.parse::().context("Invalid file path")?; - let resource_path = resource_path - .parse::() - .context("Invalid resource path")?; + file_path.parse::().with_context(|| { + format!("File path is not a valid path: {file_path}") + })?; + let resource_path = + resource_path.parse::().with_context(|| { + format!("Resource path is not a valid path: {resource_path}") + })?; let full_path = root .join(&resource_path) .join(&file_path) @@ -295,7 +298,7 @@ async fn write_sync_file_contents_git( .collect::(); if let Some(parent) = full_path.parent() { - fs::create_dir_all(parent).await.with_context(|| { + tokio::fs::create_dir_all(parent).await.with_context(|| { format!( "Failed to initialize resource file parent directory {parent:?}" ) @@ -307,8 +310,8 @@ async fn write_sync_file_contents_git( if !root.join(".git").exists() { git::init_folder_as_repo( &root, - &clone_args, - access_token.as_deref(), + &repo_args, + git_token.as_deref(), &mut update.logs, ) .await; @@ -322,9 +325,9 @@ async fn write_sync_file_contents_git( // Pull latest changes to repo to ensure linear commit history match git::pull_or_clone( - clone_args, + repo_args, &core_config().repo_directory, - access_token, + git_token, ) .await .context("Failed to pull latest changes before commit") @@ -343,8 +346,9 @@ async fn write_sync_file_contents_git( return Ok(update); } - if let Err(e) = - fs::write(&full_path, &contents).await.with_context(|| { + if let Err(e) = tokio::fs::write(&full_path, &contents) + .await + .with_context(|| { format!( "Failed to write resource file contents to {full_path:?}" ) @@ -378,10 +382,14 @@ async fn write_sync_file_contents_git( if let Err(e) = (RefreshResourceSyncPending { sync: sync.name }) .resolve(args) .await + .map_err(|e| e.error) + .context( + "Failed to refresh sync pending after writing file contents", + ) { update.push_error_log( "Refresh sync pending", - format_serror(&e.error.into()), + format_serror(&e.into()), ); } @@ -480,7 +488,7 @@ impl Resolve for CommitSync { .join(to_path_compatible_name(&sync.name)) .join(&resource_path); if let Some(parent) = file_path.parent() { - fs::create_dir_all(parent) + tokio::fs::create_dir_all(parent) .await .with_context(|| format!("Failed to initialize resource file parent directory {parent:?}"))?; }; diff --git a/bin/core/src/api/write/tag.rs b/bin/core/src/api/write/tag.rs index bd27a63c5..da8a68496 100644 --- a/bin/core/src/api/write/tag.rs +++ b/bin/core/src/api/write/tag.rs @@ -1,26 +1,18 @@ use std::str::FromStr; use anyhow::{Context, anyhow}; +use database::mungos::{ + by_id::{delete_one_by_id, update_one_by_id}, + mongodb::bson::{doc, oid::ObjectId}, +}; use komodo_client::{ api::write::{CreateTag, DeleteTag, RenameTag, UpdateTagColor}, entities::{ - action::Action, - alerter::Alerter, - build::Build, - builder::Builder, - deployment::Deployment, - procedure::Procedure, - repo::Repo, - server::Server, - stack::Stack, - sync::ResourceSync, - tag::{Tag, TagColor}, + action::Action, alerter::Alerter, build::Build, builder::Builder, + deployment::Deployment, procedure::Procedure, repo::Repo, + server::Server, stack::Stack, sync::ResourceSync, tag::Tag, }, }; -use mungos::{ - by_id::{delete_one_by_id, update_one_by_id}, - mongodb::bson::{doc, oid::ObjectId}, -}; use resolver_api::Resolve; use crate::{ @@ -44,7 +36,7 @@ impl Resolve for CreateTag { let mut tag = Tag { id: Default::default(), name: self.name, - color: TagColor::Slate, + color: self.color.unwrap_or_default(), owner: user.id.clone(), }; diff --git a/bin/core/src/api/write/user.rs b/bin/core/src/api/write/user.rs index 7afdf9744..add70a352 100644 --- a/bin/core/src/api/write/user.rs +++ b/bin/core/src/api/write/user.rs @@ -1,26 +1,107 @@ use std::str::FromStr; use anyhow::{Context, anyhow}; +use async_timing_util::unix_timestamp_ms; +use database::{ + hash_password, + mungos::mongodb::bson::{doc, oid::ObjectId}, +}; use komodo_client::{ - api::write::{ - DeleteUser, DeleteUserResponse, UpdateUserPassword, - UpdateUserPasswordResponse, UpdateUserUsername, - UpdateUserUsernameResponse, + api::write::*, + entities::{ + NoData, + user::{User, UserConfig}, }, - entities::{NoData, user::UserConfig}, }; -use mungos::mongodb::bson::{doc, oid::ObjectId}; +use reqwest::StatusCode; use resolver_api::Resolve; +use serror::AddStatusCodeError; -use crate::{ - config::core_config, helpers::hash_password, state::db_client, -}; +use crate::{config::core_config, state::db_client}; use super::WriteArgs; // +impl Resolve for CreateLocalUser { + #[instrument(name = "CreateLocalUser", skip(admin, self), fields(admin_id = admin.id, username = self.username))] + async fn resolve( + self, + WriteArgs { user: admin }: &WriteArgs, + ) -> serror::Result { + if !admin.admin { + return Err( + anyhow!("This method is admin-only.") + .status_code(StatusCode::UNAUTHORIZED), + ); + } + + if self.username.is_empty() { + return Err(anyhow!("Username cannot be empty.").into()); + } + + if ObjectId::from_str(&self.username).is_ok() { + return Err( + anyhow!("Username cannot be valid ObjectId").into(), + ); + } + + if self.password.is_empty() { + return Err(anyhow!("Password cannot be empty.").into()); + } + + let db = db_client(); + + if db + .users + .find_one(doc! { "username": &self.username }) + .await + .context("Failed to query for existing users")? + .is_some() + { + return Err(anyhow!("Username already taken.").into()); + } + + let ts = unix_timestamp_ms() as i64; + let hashed_password = hash_password(self.password)?; + + let mut user = User { + id: Default::default(), + username: self.username, + enabled: true, + admin: false, + super_admin: false, + create_server_permissions: false, + create_build_permissions: false, + updated_at: ts, + last_update_view: 0, + recents: Default::default(), + all: Default::default(), + config: UserConfig::Local { + password: hashed_password, + }, + }; + + user.id = db_client() + .users + .insert_one(&user) + .await + .context("failed to create user")? + .inserted_id + .as_object_id() + .context("inserted_id is not ObjectId")? + .to_string(); + + user.sanitize(); + + Ok(user) + } +} + +// + impl Resolve for UpdateUserUsername { + #[instrument(name = "UpdateUserUsername", skip(user), fields(user_id = user.id))] async fn resolve( self, WriteArgs { user }: &WriteArgs, @@ -38,6 +119,13 @@ impl Resolve for UpdateUserUsername { if self.username.is_empty() { return Err(anyhow!("Username cannot be empty.").into()); } + + if ObjectId::from_str(&self.username).is_ok() { + return Err( + anyhow!("Username cannot be valid ObjectId").into(), + ); + } + let db = db_client(); if db .users @@ -64,6 +152,7 @@ impl Resolve for UpdateUserUsername { // impl Resolve for UpdateUserPassword { + #[instrument(name = "UpdateUserPassword", skip(user, self), fields(user_id = user.id))] async fn resolve( self, WriteArgs { user }: &WriteArgs, @@ -78,25 +167,7 @@ impl Resolve for UpdateUserPassword { ); } } - let UserConfig::Local { .. } = user.config else { - return Err(anyhow!("User is not local user").into()); - }; - if self.password.is_empty() { - return Err(anyhow!("Password cannot be empty.").into()); - } - let id = ObjectId::from_str(&user.id) - .context("User id not valid ObjectId.")?; - let hashed_password = hash_password(self.password)?; - db_client() - .users - .update_one( - doc! { "_id": id }, - doc! { "$set": { - "config.data.password": hashed_password - } }, - ) - .await - .context("Failed to update user password on database.")?; + db_client().set_user_password(user, &self.password).await?; Ok(NoData {}) } } @@ -104,12 +175,16 @@ impl Resolve for UpdateUserPassword { // impl Resolve for DeleteUser { + #[instrument(name = "DeleteUser", skip(admin), fields(user = self.user))] async fn resolve( self, WriteArgs { user: admin }: &WriteArgs, ) -> serror::Result { if !admin.admin { - return Err(anyhow!("Calling user is not admin.").into()); + return Err( + anyhow!("This method is admin-only.") + .status_code(StatusCode::UNAUTHORIZED), + ); } if admin.username == self.user || admin.id == self.user { return Err(anyhow!("User cannot delete themselves.").into()); diff --git a/bin/core/src/api/write/user_group.rs b/bin/core/src/api/write/user_group.rs index 12e956a16..125adbf3e 100644 --- a/bin/core/src/api/write/user_group.rs +++ b/bin/core/src/api/write/user_group.rs @@ -1,15 +1,15 @@ use std::{collections::HashMap, str::FromStr}; use anyhow::{Context, anyhow}; -use komodo_client::{ - api::write::*, - entities::{komodo_timestamp, user_group::UserGroup}, -}; -use mungos::{ +use database::mungos::{ by_id::{delete_one_by_id, find_one_by_id, update_one_by_id}, find::find_collect, mongodb::bson::{doc, oid::ObjectId}, }; +use komodo_client::{ + api::write::*, + entities::{komodo_timestamp, user_group::UserGroup}, +}; use resolver_api::Resolve; use crate::state::db_client; diff --git a/bin/core/src/api/write/variable.rs b/bin/core/src/api/write/variable.rs index b3d1ef6b2..6df2dd4e8 100644 --- a/bin/core/src/api/write/variable.rs +++ b/bin/core/src/api/write/variable.rs @@ -1,9 +1,9 @@ use anyhow::{Context, anyhow}; +use database::mungos::mongodb::bson::doc; use komodo_client::{ api::write::*, entities::{Operation, ResourceTarget, variable::Variable}, }; -use mungos::mongodb::bson::doc; use resolver_api::Resolve; use crate::{ diff --git a/bin/core/src/auth/github/mod.rs b/bin/core/src/auth/github/mod.rs index 8b28461dd..7ddda339e 100644 --- a/bin/core/src/auth/github/mod.rs +++ b/bin/core/src/auth/github/mod.rs @@ -2,12 +2,12 @@ use anyhow::{Context, anyhow}; use axum::{ Router, extract::Query, response::Redirect, routing::get, }; +use database::mongo_indexed::Document; +use database::mungos::mongodb::bson::doc; use komodo_client::entities::{ komodo_timestamp, user::{User, UserConfig}, }; -use mongo_indexed::Document; -use mungos::mongodb::bson::doc; use reqwest::StatusCode; use serde::Deserialize; use serror::AddStatusCode; @@ -134,7 +134,7 @@ async fn callback( format!("{}?token={exchange_token}", core_config().host) } else { let splitter = if redirect.contains('?') { '&' } else { '?' }; - format!("{}{splitter}token={exchange_token}", redirect) + format!("{redirect}{splitter}token={exchange_token}") }; Ok(Redirect::to(&redirect_url)) } diff --git a/bin/core/src/auth/google/mod.rs b/bin/core/src/auth/google/mod.rs index 74d234e89..f7895b258 100644 --- a/bin/core/src/auth/google/mod.rs +++ b/bin/core/src/auth/google/mod.rs @@ -3,9 +3,9 @@ use async_timing_util::unix_timestamp_ms; use axum::{ Router, extract::Query, response::Redirect, routing::get, }; +use database::mongo_indexed::Document; +use database::mungos::mongodb::bson::doc; use komodo_client::entities::user::{User, UserConfig}; -use mongo_indexed::Document; -use mungos::mongodb::bson::doc; use reqwest::StatusCode; use serde::Deserialize; use serror::AddStatusCode; @@ -148,7 +148,7 @@ async fn callback( format!("{}?token={exchange_token}", core_config().host) } else { let splitter = if redirect.contains('?') { '&' } else { '?' }; - format!("{}{splitter}token={exchange_token}", redirect) + format!("{redirect}{splitter}token={exchange_token}") }; Ok(Redirect::to(&redirect_url)) } diff --git a/bin/core/src/auth/jwt.rs b/bin/core/src/auth/jwt.rs index 8cf7d9fb4..14532f926 100644 --- a/bin/core/src/auth/jwt.rs +++ b/bin/core/src/auth/jwt.rs @@ -4,17 +4,19 @@ use anyhow::{Context, anyhow}; use async_timing_util::{ Timelength, get_timelength_in_ms, unix_timestamp_ms, }; +use database::mungos::mongodb::bson::doc; use jsonwebtoken::{ DecodingKey, EncodingKey, Header, Validation, decode, encode, }; -use komodo_client::entities::config::core::CoreConfig; -use mungos::mongodb::bson::doc; +use komodo_client::{ + api::auth::JwtResponse, entities::config::core::CoreConfig, +}; use serde::{Deserialize, Serialize}; use tokio::sync::Mutex; use crate::helpers::random_string; -type ExchangeTokenMap = Mutex>; +type ExchangeTokenMap = Mutex>; #[derive(Serialize, Deserialize)] pub struct JwtClaims { @@ -51,16 +53,20 @@ impl JwtClient { }) } - pub fn encode(&self, user_id: String) -> anyhow::Result { + pub fn encode( + &self, + user_id: String, + ) -> anyhow::Result { let iat = unix_timestamp_ms(); let exp = iat + self.ttl_ms; let claims = JwtClaims { - id: user_id, + id: user_id.clone(), iat, exp, }; - encode(&self.header, &claims, &self.encoding_key) - .context("failed at signing claim") + let jwt = encode(&self.header, &claims, &self.encoding_key) + .context("failed at signing claim")?; + Ok(JwtResponse { user_id, jwt }) } pub fn decode(&self, jwt: &str) -> anyhow::Result { @@ -70,7 +76,10 @@ impl JwtClient { } #[instrument(level = "debug", skip_all)] - pub async fn create_exchange_token(&self, jwt: String) -> String { + pub async fn create_exchange_token( + &self, + jwt: JwtResponse, + ) -> String { let exchange_token = random_string(40); self.exchange_tokens.lock().await.insert( exchange_token.clone(), @@ -86,7 +95,7 @@ impl JwtClient { pub async fn redeem_exchange_token( &self, exchange_token: &str, - ) -> anyhow::Result { + ) -> anyhow::Result { let (jwt, valid_until) = self .exchange_tokens .lock() diff --git a/bin/core/src/auth/local.rs b/bin/core/src/auth/local.rs index ecc16456c..91306639a 100644 --- a/bin/core/src/auth/local.rs +++ b/bin/core/src/auth/local.rs @@ -2,30 +2,31 @@ use std::str::FromStr; use anyhow::{Context, anyhow}; use async_timing_util::unix_timestamp_ms; +use database::{ + hash_password, + mungos::mongodb::bson::{Document, doc, oid::ObjectId}, +}; use komodo_client::{ api::auth::{ - CreateLocalUser, CreateLocalUserResponse, LoginLocalUser, - LoginLocalUserResponse, + LoginLocalUser, LoginLocalUserResponse, SignUpLocalUser, + SignUpLocalUserResponse, }, entities::user::{User, UserConfig}, }; -use mongo_indexed::Document; -use mungos::mongodb::bson::{doc, oid::ObjectId}; use resolver_api::Resolve; use crate::{ api::auth::AuthArgs, config::core_config, - helpers::hash_password, state::{db_client, jwt_client}, }; -impl Resolve for CreateLocalUser { - #[instrument(name = "CreateLocalUser", skip(self))] +impl Resolve for SignUpLocalUser { + #[instrument(name = "SignUpLocalUser", skip(self))] async fn resolve( self, _: &AuthArgs, - ) -> serror::Result { + ) -> serror::Result { let core_config = core_config(); if !core_config.local_auth { @@ -46,16 +47,27 @@ impl Resolve for CreateLocalUser { return Err(anyhow!("Password cannot be empty string").into()); } - let hashed_password = hash_password(self.password)?; + let db = db_client(); let no_users_exist = - db_client().users.find_one(Document::new()).await?.is_none(); + db.users.find_one(Document::new()).await?.is_none(); if !no_users_exist && core_config.disable_user_registration { return Err(anyhow!("User registration is disabled").into()); } + if db + .users + .find_one(doc! { "username": &self.username }) + .await + .context("Failed to query for existing users")? + .is_some() + { + return Err(anyhow!("Username already taken.").into()); + } + let ts = unix_timestamp_ms() as i64; + let hashed_password = hash_password(self.password)?; let user = User { id: Default::default(), @@ -84,11 +96,10 @@ impl Resolve for CreateLocalUser { .context("inserted_id is not ObjectId")? .to_string(); - let jwt = jwt_client() - .encode(user_id) - .context("failed to generate jwt for user")?; - - Ok(CreateLocalUserResponse { jwt }) + jwt_client() + .encode(user_id.clone()) + .context("failed to generate jwt for user") + .map_err(Into::into) } } @@ -130,10 +141,9 @@ impl Resolve for LoginLocalUser { return Err(anyhow!("invalid credentials").into()); } - let jwt = jwt_client() - .encode(user.id) - .context("failed at generating jwt for user")?; - - Ok(LoginLocalUserResponse { jwt }) + jwt_client() + .encode(user.id.clone()) + .context("failed at generating jwt for user") + .map_err(Into::into) } } diff --git a/bin/core/src/auth/mod.rs b/bin/core/src/auth/mod.rs index a91f046b5..0add64615 100644 --- a/bin/core/src/auth/mod.rs +++ b/bin/core/src/auth/mod.rs @@ -4,8 +4,8 @@ use axum::{ extract::Request, http::HeaderMap, middleware::Next, response::Response, }; +use database::mungos::mongodb::bson::doc; use komodo_client::entities::{komodo_timestamp, user::User}; -use mungos::mongodb::bson::doc; use reqwest::StatusCode; use serde::Deserialize; use serror::AddStatusCode; diff --git a/bin/core/src/auth/oidc/mod.rs b/bin/core/src/auth/oidc/mod.rs index 598be01d2..bbf09377a 100644 --- a/bin/core/src/auth/oidc/mod.rs +++ b/bin/core/src/auth/oidc/mod.rs @@ -6,11 +6,11 @@ use axum::{ }; use client::oidc_client; use dashmap::DashMap; +use database::mungos::mongodb::bson::{Document, doc}; use komodo_client::entities::{ komodo_timestamp, user::{User, UserConfig}, }; -use mungos::mongodb::bson::{Document, doc}; use openidconnect::{ AccessTokenHash, AuthorizationCode, CsrfToken, EmptyAdditionalClaims, Nonce, OAuth2TokenResponse, @@ -31,11 +31,15 @@ use super::RedirectQuery; pub mod client; +static APP_USER_AGENT: &str = + concat!("Komodo/", env!("CARGO_PKG_VERSION"),); + fn reqwest_client() -> &'static reqwest::Client { static REQWEST: OnceLock = OnceLock::new(); REQWEST.get_or_init(|| { reqwest::Client::builder() .redirect(reqwest::redirect::Policy::none()) + .user_agent(APP_USER_AGENT) .build() .expect("Invalid OIDC reqwest client") }) @@ -312,7 +316,7 @@ async fn callback( let exchange_token = jwt_client().create_exchange_token(jwt).await; let redirect_url = if let Some(redirect) = redirect { let splitter = if redirect.contains('?') { '&' } else { '?' }; - format!("{}{splitter}token={exchange_token}", redirect) + format!("{redirect}{splitter}token={exchange_token}") } else { format!("{}?token={exchange_token}", core_config().host) }; diff --git a/bin/core/src/config.rs b/bin/core/src/config.rs index 322992b48..c09f1cda4 100644 --- a/bin/core/src/config.rs +++ b/bin/core/src/config.rs @@ -1,36 +1,69 @@ -use std::sync::OnceLock; +use std::{path::PathBuf, sync::OnceLock}; use anyhow::Context; +use colored::Colorize; +use config::ConfigLoader; use environment_file::{ maybe_read_item_from_file, maybe_read_list_from_file, }; use komodo_client::entities::{ - config::core::{ - AwsCredentials, CoreConfig, DatabaseConfig, Env, - GithubWebhookAppConfig, GithubWebhookAppInstallationConfig, - OauthCredentials, + config::{ + DatabaseConfig, + core::{ + AwsCredentials, CoreConfig, Env, GithubWebhookAppConfig, + GithubWebhookAppInstallationConfig, OauthCredentials, + }, }, logger::LogConfig, }; -use merge_config_files::parse_config_file; pub fn core_config() -> &'static CoreConfig { static CORE_CONFIG: OnceLock = OnceLock::new(); CORE_CONFIG.get_or_init(|| { let env: Env = match envy::from_env() - .context("failed to parse core Env") { + .context("Failed to parse Komodo Core environment") { Ok(env) => env, Err(e) => { - panic!("{e:#?}"); + panic!("{e:?}"); } }; - let config_path = &env.komodo_config_path; - let config = - parse_config_file::(config_path.as_str()) - .unwrap_or_else(|e| { - panic!("failed at parsing config at {config_path} | {e:#}") - }); - let installations = match (maybe_read_list_from_file(env.komodo_github_webhook_app_installations_ids_file,env.komodo_github_webhook_app_installations_ids), env.komodo_github_webhook_app_installations_namespaces) { + let config = if env.komodo_config_paths.is_empty() { + println!( + "{}: No config paths found, using default config", + "INFO".green(), + ); + CoreConfig::default() + } else { + let config_keywords = env.komodo_config_keywords + .iter() + .map(String::as_str) + .collect::>(); + println!( + "{}: {}: {config_keywords:?}", + "INFO".green(), + "Config File Keywords".dimmed(), + ); + (ConfigLoader { + paths: &env.komodo_config_paths + .iter() + .map(PathBuf::as_path) + .collect::>(), + match_wildcards: &config_keywords, + include_file_name: ".kcoreinclude", + merge_nested: env.komodo_merge_nested_config, + extend_array: env.komodo_extend_config_arrays, + debug_print: env.komodo_config_debug, + }).load::() + .expect("Failed at parsing config from paths") + }; + + let installations = match ( + maybe_read_list_from_file( + env.komodo_github_webhook_app_installations_ids_file, + env.komodo_github_webhook_app_installations_ids + ), + env.komodo_github_webhook_app_installations_namespaces + ) { (Some(ids), Some(namespaces)) => { if ids.len() != namespaces.len() { panic!("KOMODO_GITHUB_WEBHOOK_APP_INSTALLATIONS_IDS length and KOMODO_GITHUB_WEBHOOK_APP_INSTALLATIONS_NAMESPACES length mismatch. Got {ids:?} and {namespaces:?}") @@ -76,6 +109,14 @@ pub fn core_config() -> &'static CoreConfig { .komodo_database_db_name .unwrap_or(config.database.db_name), }, + init_admin_username: maybe_read_item_from_file( + env.komodo_init_admin_username_file, + env.komodo_init_admin_username + ).or(config.init_admin_username), + init_admin_password: maybe_read_item_from_file( + env.komodo_init_admin_password_file, + env.komodo_init_admin_password + ).unwrap_or(config.init_admin_password), oidc_enabled: env.komodo_oidc_enabled.unwrap_or(config.oidc_enabled), oidc_provider: env.komodo_oidc_provider.unwrap_or(config.oidc_provider), oidc_redirect_host: env.komodo_oidc_redirect_host.unwrap_or(config.oidc_redirect_host), @@ -136,7 +177,8 @@ pub fn core_config() -> &'static CoreConfig { port: env.komodo_port.unwrap_or(config.port), bind_ip: env.komodo_bind_ip.unwrap_or(config.bind_ip), timezone: env.komodo_timezone.unwrap_or(config.timezone), - first_server: env.komodo_first_server.unwrap_or(config.first_server), + first_server: env.komodo_first_server.or(config.first_server), + first_server_name: env.komodo_first_server_name.unwrap_or(config.first_server_name), frontend_path: env.komodo_frontend_path.unwrap_or(config.frontend_path), jwt_ttl: env .komodo_jwt_ttl @@ -181,6 +223,10 @@ pub fn core_config() -> &'static CoreConfig { .unwrap_or(config.disable_user_registration), disable_non_admin_create: env.komodo_disable_non_admin_create .unwrap_or(config.disable_non_admin_create), + disable_init_resources: env.komodo_disable_init_resources + .unwrap_or(config.disable_init_resources), + enable_fancy_toml: env.komodo_enable_fancy_toml + .unwrap_or(config.enable_fancy_toml), lock_login_credentials_for: env.komodo_lock_login_credentials_for .unwrap_or(config.lock_login_credentials_for), local_auth: env.komodo_local_auth @@ -192,7 +238,10 @@ pub fn core_config() -> &'static CoreConfig { stdio: env .komodo_logging_stdio .unwrap_or(config.logging.stdio), - pretty: env.komodo_logging_pretty.unwrap_or(config.logging.pretty), + pretty: env.komodo_logging_pretty + .unwrap_or(config.logging.pretty), + location: env.komodo_logging_location + .unwrap_or(config.logging.location), otlp_endpoint: env .komodo_logging_otlp_endpoint .unwrap_or(config.logging.otlp_endpoint), @@ -201,6 +250,7 @@ pub fn core_config() -> &'static CoreConfig { .unwrap_or(config.logging.opentelemetry_service_name), }, pretty_startup_config: env.komodo_pretty_startup_config.unwrap_or(config.pretty_startup_config), + internet_interface: env.komodo_internet_interface.unwrap_or(config.internet_interface), ssl_enabled: env.komodo_ssl_enabled.unwrap_or(config.ssl_enabled), ssl_key_file: env.komodo_ssl_key_file.unwrap_or(config.ssl_key_file), ssl_cert_file: env.komodo_ssl_cert_file.unwrap_or(config.ssl_cert_file), diff --git a/bin/core/src/helpers/action_state.rs b/bin/core/src/helpers/action_state.rs index e103f5dd2..608365db5 100644 --- a/bin/core/src/helpers/action_state.rs +++ b/bin/core/src/helpers/action_state.rs @@ -63,7 +63,7 @@ impl pub fn update( &self, handler: impl Fn(&mut States), - ) -> anyhow::Result> { + ) -> anyhow::Result> { let mut lock = self .0 .lock() diff --git a/bin/core/src/helpers/builder.rs b/bin/core/src/helpers/builder.rs index ee6761368..f50e6ac68 100644 --- a/bin/core/src/helpers/builder.rs +++ b/bin/core/src/helpers/builder.rs @@ -128,8 +128,7 @@ async fn get_aws_builder( stage: "build instance connected".to_string(), success: true, stdout: format!( - "established contact with periphery on builder\nperiphery version: v{}", - version + "established contact with periphery on builder\nperiphery version: v{version}" ), start_ts: start_connect_ts, end_ts: komodo_timestamp(), diff --git a/bin/core/src/helpers/cache.rs b/bin/core/src/helpers/cache.rs index a9ae902d1..d0b8ace9c 100644 --- a/bin/core/src/helpers/cache.rs +++ b/bin/core/src/helpers/cache.rs @@ -1,6 +1,5 @@ use std::{collections::HashMap, hash::Hash}; -use komodo_client::busy::Busy; use tokio::sync::RwLock; #[derive(Default)] @@ -34,7 +33,7 @@ impl< #[instrument(level = "debug", skip(self))] pub async fn get_list(&self) -> Vec { let cache = self.cache.read().await; - cache.iter().map(|(_, e)| e.clone()).collect() + cache.values().cloned().collect() } #[instrument(level = "debug", skip(self))] @@ -46,22 +45,22 @@ impl< self.cache.write().await.insert(key.into(), val); } - #[instrument(level = "debug", skip(self, handler))] - pub async fn update_entry( - &self, - key: Key, - handler: impl Fn(&mut T), - ) where - Key: Into + std::fmt::Debug, - { - let mut cache = self.cache.write().await; - handler(cache.entry(key.into()).or_default()); - } + // #[instrument(level = "debug", skip(self, handler))] + // pub async fn update_entry( + // &self, + // key: Key, + // handler: impl Fn(&mut T), + // ) where + // Key: Into + std::fmt::Debug, + // { + // let mut cache = self.cache.write().await; + // handler(cache.entry(key.into()).or_default()); + // } - #[instrument(level = "debug", skip(self))] - pub async fn clear(&self) { - self.cache.write().await.clear(); - } + // #[instrument(level = "debug", skip(self))] + // pub async fn clear(&self) { + // self.cache.write().await.clear(); + // } #[instrument(level = "debug", skip(self))] pub async fn remove(&self, key: &K) { @@ -69,16 +68,16 @@ impl< } } -impl< - K: PartialEq + Eq + Hash + std::fmt::Debug + Clone, - T: Clone + Default + Busy, -> Cache -{ - #[instrument(level = "debug", skip(self))] - pub async fn busy(&self, id: &K) -> bool { - match self.get(id).await { - Some(state) => state.busy(), - None => false, - } - } -} +// impl< +// K: PartialEq + Eq + Hash + std::fmt::Debug + Clone, +// T: Clone + Default + Busy, +// > Cache +// { +// #[instrument(level = "debug", skip(self))] +// pub async fn busy(&self, id: &K) -> bool { +// match self.get(id).await { +// Some(state) => state.busy(), +// None => false, +// } +// } +// } diff --git a/bin/core/src/helpers/mod.rs b/bin/core/src/helpers/mod.rs index 52bbc1cef..8105df84b 100644 --- a/bin/core/src/helpers/mod.rs +++ b/bin/core/src/helpers/mod.rs @@ -1,6 +1,8 @@ use std::{fmt::Write, time::Duration}; use anyhow::{Context, anyhow}; +use database::mongo_indexed::Document; +use database::mungos::mongodb::bson::{Bson, doc}; use indexmap::IndexSet; use komodo_client::entities::{ ResourceTarget, @@ -13,8 +15,6 @@ use komodo_client::entities::{ stack::Stack, user::User, }; -use mongo_indexed::Document; -use mungos::mongodb::bson::{Bson, doc}; use periphery_client::PeripheryClient; use rand::Rng; @@ -54,15 +54,6 @@ pub fn random_string(length: usize) -> String { .collect() } -const BCRYPT_COST: u32 = 10; -pub fn hash_password

(password: P) -> anyhow::Result -where - P: AsRef<[u8]>, -{ - bcrypt::hash(password, BCRYPT_COST) - .context("failed to hash password") -} - /// First checks db for token, then checks core config. /// Only errors if db call errors. /// Returns (token, use_https) diff --git a/bin/core/src/helpers/procedure.rs b/bin/core/src/helpers/procedure.rs index 01d785604..9eb8b5a35 100644 --- a/bin/core/src/helpers/procedure.rs +++ b/bin/core/src/helpers/procedure.rs @@ -1,6 +1,7 @@ use std::time::{Duration, Instant}; use anyhow::{Context, anyhow}; +use database::mungos::by_id::find_one_by_id; use formatting::{Color, bold, colored, format_serror, muted}; use futures::future::join_all; use komodo_client::{ @@ -17,7 +18,6 @@ use komodo_client::{ user::procedure_user, }, }; -use mungos::by_id::find_one_by_id; use resolver_api::Resolve; use tokio::sync::Mutex; @@ -1124,6 +1124,57 @@ async fn execute_execution( ) .await? } + Execution::ClearRepoCache(req) => { + let req = ExecuteRequest::ClearRepoCache(req); + let update = init_execution_update(&req, &user).await?; + let ExecuteRequest::ClearRepoCache(req) = req else { + unreachable!() + }; + let update_id = update.id.clone(); + handle_resolve_result( + req + .resolve(&ExecuteArgs { user, update }) + .await + .map_err(|e| e.error) + .context("Failed at ClearRepoCache"), + &update_id, + ) + .await? + } + Execution::BackupCoreDatabase(req) => { + let req = ExecuteRequest::BackupCoreDatabase(req); + let update = init_execution_update(&req, &user).await?; + let ExecuteRequest::BackupCoreDatabase(req) = req else { + unreachable!() + }; + let update_id = update.id.clone(); + handle_resolve_result( + req + .resolve(&ExecuteArgs { user, update }) + .await + .map_err(|e| e.error) + .context("Failed at BackupCoreDatabase"), + &update_id, + ) + .await? + } + Execution::GlobalAutoUpdate(req) => { + let req = ExecuteRequest::GlobalAutoUpdate(req); + let update = init_execution_update(&req, &user).await?; + let ExecuteRequest::GlobalAutoUpdate(req) = req else { + unreachable!() + }; + let update_id = update.id.clone(); + handle_resolve_result( + req + .resolve(&ExecuteArgs { user, update }) + .await + .map_err(|e| e.error) + .context("Failed at GlobalAutoUpdate"), + &update_id, + ) + .await? + } Execution::Sleep(req) => { let duration = Duration::from_millis(req.duration_ms as u64); tokio::time::sleep(duration).await; @@ -1215,7 +1266,10 @@ impl ExtendBatch for BatchRunProcedure { impl ExtendBatch for BatchRunAction { type Resource = Action; fn single_execution(action: String) -> Execution { - Execution::RunAction(RunAction { action }) + Execution::RunAction(RunAction { + action, + args: Default::default(), + }) } } diff --git a/bin/core/src/helpers/prune.rs b/bin/core/src/helpers/prune.rs index fce9a7d3a..1bf1fb5dd 100644 --- a/bin/core/src/helpers/prune.rs +++ b/bin/core/src/helpers/prune.rs @@ -2,8 +2,8 @@ use anyhow::Context; use async_timing_util::{ ONE_DAY_MS, Timelength, unix_timestamp_ms, wait_until_timelength, }; -use futures::future::join_all; -use mungos::{find::find_collect, mongodb::bson::doc}; +use database::mungos::{find::find_collect, mongodb::bson::doc}; +use futures::{StreamExt, stream::FuturesUnordered}; use periphery_client::api::image::PruneImages; use crate::{config::core_config, state::db_client}; @@ -30,24 +30,26 @@ pub fn spawn_prune_loop() { } async fn prune_images() -> anyhow::Result<()> { - let futures = find_collect(&db_client().servers, None, None) - .await - .context("failed to get servers from db")? - .into_iter() - .filter(|server| { - server.config.enabled && server.config.auto_prune - }) - .map(|server| async move { - ( - async { - periphery_client(&server)?.request(PruneImages {}).await - } - .await, - server, - ) - }); + let mut futures = find_collect( + &db_client().servers, + doc! { "config.enabled": true, "config.auto_prune": true }, + None, + ) + .await + .context("failed to get servers from db")? + .into_iter() + .map(|server| async move { + ( + async { + periphery_client(&server)?.request(PruneImages {}).await + } + .await, + server, + ) + }) + .collect::>(); - for (res, server) in join_all(futures).await { + while let Some((res, server)) = futures.next().await { if let Err(e) = res { error!( "failed to prune images on server {} ({}) | {e:#}", diff --git a/bin/core/src/helpers/query.rs b/bin/core/src/helpers/query.rs index 78263b556..a88ad4a08 100644 --- a/bin/core/src/helpers/query.rs +++ b/bin/core/src/helpers/query.rs @@ -6,6 +6,13 @@ use std::{ use anyhow::{Context, anyhow}; use async_timing_util::{ONE_MIN_MS, unix_timestamp_ms}; +use database::mungos::{ + find::find_collect, + mongodb::{ + bson::{Document, doc, oid::ObjectId}, + options::FindOneOptions, + }, +}; use komodo_client::entities::{ Operation, ResourceTarget, ResourceTargetVariant, action::{Action, ActionState}, @@ -27,13 +34,6 @@ use komodo_client::entities::{ user_group::UserGroup, variable::Variable, }; -use mungos::{ - find::find_collect, - mongodb::{ - bson::{Document, doc, oid::ObjectId}, - options::FindOneOptions, - }, -}; use periphery_client::api::stats; use tokio::sync::Mutex; diff --git a/bin/core/src/helpers/update.rs b/bin/core/src/helpers/update.rs index 7b1d01fcc..612391f68 100644 --- a/bin/core/src/helpers/update.rs +++ b/bin/core/src/helpers/update.rs @@ -1,4 +1,8 @@ use anyhow::Context; +use database::mungos::{ + by_id::{find_one_by_id, update_one_by_id}, + mongodb::bson::to_document, +}; use komodo_client::entities::{ Operation, ResourceTarget, action::Action, @@ -14,10 +18,6 @@ use komodo_client::entities::{ update::{Update, UpdateListItem}, user::User, }; -use mungos::{ - by_id::{find_one_by_id, update_one_by_id}, - mongodb::bson::to_document, -}; use crate::{ api::execute::ExecuteRequest, resource, state::db_client, @@ -77,7 +77,7 @@ pub async fn add_update_without_send( #[instrument(level = "debug")] pub async fn update_update(update: Update) -> anyhow::Result<()> { - update_one_by_id(&db_client().updates, &update.id, mungos::update::Update::Set(to_document(&update)?), None) + update_one_by_id(&db_client().updates, &update.id, database::mungos::update::Update::Set(to_document(&update)?), None) .await .context("failed to update the update on db. the update build process was deleted")?; let update = update_list_item(update).await?; @@ -499,6 +499,17 @@ pub async fn init_execution_update( resource::get::(&data.alerter).await?.id, ), ), + + // Maintenance + ExecuteRequest::ClearRepoCache(_data) => { + (Operation::ClearRepoCache, ResourceTarget::system()) + } + ExecuteRequest::BackupCoreDatabase(_data) => { + (Operation::BackupCoreDatabase, ResourceTarget::system()) + } + ExecuteRequest::GlobalAutoUpdate(_data) => { + (Operation::GlobalAutoUpdate, ResourceTarget::system()) + } }; let mut update = make_update(target, operation, user); diff --git a/bin/core/src/listener/integrations/github.rs b/bin/core/src/listener/integrations/github.rs index ce155f2d0..7e1f2b026 100644 --- a/bin/core/src/listener/integrations/github.rs +++ b/bin/core/src/listener/integrations/github.rs @@ -7,7 +7,7 @@ use sha2::Sha256; use crate::{ config::core_config, - listener::{VerifyBranch, VerifySecret}, + listener::{ExtractBranch, VerifySecret}, }; type HmacSha256 = Hmac; @@ -53,19 +53,12 @@ struct GithubWebhookBody { branch: String, } -impl VerifyBranch for Github { - fn verify_branch( - body: &str, - expected_branch: &str, - ) -> anyhow::Result<()> { +impl ExtractBranch for Github { + fn extract_branch(body: &str) -> anyhow::Result { let branch = serde_json::from_str::(body) .context("Failed to parse github request body")? .branch .replace("refs/heads/", ""); - if branch == expected_branch { - Ok(()) - } else { - Err(anyhow!("request branch does not match expected")) - } + Ok(branch) } } diff --git a/bin/core/src/listener/integrations/gitlab.rs b/bin/core/src/listener/integrations/gitlab.rs index b8b3520f5..6f57e3ad7 100644 --- a/bin/core/src/listener/integrations/gitlab.rs +++ b/bin/core/src/listener/integrations/gitlab.rs @@ -3,7 +3,7 @@ use serde::Deserialize; use crate::{ config::core_config, - listener::{VerifyBranch, VerifySecret}, + listener::{ExtractBranch, VerifySecret}, }; /// Listener implementation for Gitlab type API @@ -40,19 +40,12 @@ struct GitlabWebhookBody { branch: String, } -impl VerifyBranch for Gitlab { - fn verify_branch( - body: &str, - expected_branch: &str, - ) -> anyhow::Result<()> { +impl ExtractBranch for Gitlab { + fn extract_branch(body: &str) -> anyhow::Result { let branch = serde_json::from_str::(body) .context("Failed to parse gitlab request body")? .branch .replace("refs/heads/", ""); - if branch == expected_branch { - Ok(()) - } else { - Err(anyhow!("request branch does not match expected")) - } + Ok(branch) } } diff --git a/bin/core/src/listener/mod.rs b/bin/core/src/listener/mod.rs index 97f72d1ad..9caf6cfd7 100644 --- a/bin/core/src/listener/mod.rs +++ b/bin/core/src/listener/mod.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +use anyhow::anyhow; use axum::{Router, http::HeaderMap}; use komodo_client::entities::resource::Resource; use tokio::sync::Mutex; @@ -37,13 +38,16 @@ trait VerifySecret { } /// Implemented on the integration struct, eg [integrations::github::Github] -trait VerifyBranch { - /// Returns Err if the branch extracted from request - /// body does not match the expected branch. - fn verify_branch( - body: &str, - expected_branch: &str, - ) -> anyhow::Result<()>; +trait ExtractBranch { + fn extract_branch(body: &str) -> anyhow::Result; + fn verify_branch(body: &str, expected: &str) -> anyhow::Result<()> { + let branch = Self::extract_branch(body)?; + if branch == expected { + Ok(()) + } else { + Err(anyhow!("request branch does not match expected")) + } + } } /// For Procedures and Actions, incoming webhook diff --git a/bin/core/src/listener/resources.rs b/bin/core/src/listener/resources.rs index ea767b7ad..6d807c0a3 100644 --- a/bin/core/src/listener/resources.rs +++ b/bin/core/src/listener/resources.rs @@ -1,6 +1,6 @@ -use std::sync::OnceLock; +use std::{str::FromStr, sync::OnceLock}; -use anyhow::anyhow; +use anyhow::{Context, anyhow}; use komodo_client::{ api::{ execute::*, @@ -13,6 +13,7 @@ use komodo_client::{ }; use resolver_api::Resolve; use serde::Deserialize; +use serde_json::json; use crate::{ api::{ @@ -39,20 +40,20 @@ fn build_locks() -> &'static ListenerLockCache { BUILD_LOCKS.get_or_init(Default::default) } -pub async fn handle_build_webhook( +pub async fn handle_build_webhook( build: Build, body: String, ) -> anyhow::Result<()> { + if !build.config.webhook_enabled { + return Ok(()); + } + // Acquire and hold lock to make a task queue for // subsequent listener calls on same resource. // It would fail if we let it go through from action state busy. let lock = build_locks().get_or_insert_default(&build.id).await; let _lock = lock.lock().await; - if !build.config.webhook_enabled { - return Err(anyhow!("build does not have webhook enabled")); - } - B::verify_branch(&body, &build.config.branch)?; let user = git_webhook_user().to_owned(); @@ -155,7 +156,7 @@ pub enum RepoWebhookOption { Build, } -pub async fn handle_repo_webhook( +pub async fn handle_repo_webhook( option: RepoWebhookOption, repo: Repo, body: String, @@ -174,22 +175,22 @@ pub async fn handle_repo_webhook( } async fn handle_repo_webhook_inner< - B: super::VerifyBranch, + B: super::ExtractBranch, E: RepoExecution, >( repo: Repo, body: String, ) -> anyhow::Result<()> { + if !repo.config.webhook_enabled { + return Ok(()); + } + // Acquire and hold lock to make a task queue for // subsequent listener calls on same resource. // It would fail if we let it go through from action state busy. let lock = repo_locks().get_or_insert_default(&repo.id).await; let _lock = lock.lock().await; - if !repo.config.webhook_enabled { - return Err(anyhow!("repo does not have webhook enabled")); - } - B::verify_branch(&body, &repo.config.branch)?; E::resolve(repo).await @@ -269,7 +270,7 @@ pub enum StackWebhookOption { Deploy, } -pub async fn handle_stack_webhook( +pub async fn handle_stack_webhook( option: StackWebhookOption, stack: Stack, body: String, @@ -286,22 +287,22 @@ pub async fn handle_stack_webhook( } pub async fn handle_stack_webhook_inner< - B: super::VerifyBranch, + B: super::ExtractBranch, E: StackExecution, >( stack: Stack, body: String, ) -> anyhow::Result<()> { + if !stack.config.webhook_enabled { + return Ok(()); + } + // Acquire and hold lock to make a task queue for // subsequent listener calls on same resource. // It would fail if we let it go through, from "action state busy". let lock = stack_locks().get_or_insert_default(&stack.id).await; let _lock = lock.lock().await; - if !stack.config.webhook_enabled { - return Err(anyhow!("stack does not have webhook enabled")); - } - B::verify_branch(&body, &stack.config.branch)?; E::resolve(stack).await.map_err(|e| e.error) @@ -365,7 +366,7 @@ pub enum SyncWebhookOption { Sync, } -pub async fn handle_sync_webhook( +pub async fn handle_sync_webhook( option: SyncWebhookOption, sync: ResourceSync, body: String, @@ -384,22 +385,22 @@ pub async fn handle_sync_webhook( } async fn handle_sync_webhook_inner< - B: super::VerifyBranch, + B: super::ExtractBranch, E: SyncExecution, >( sync: ResourceSync, body: String, ) -> anyhow::Result<()> { + if !sync.config.webhook_enabled { + return Ok(()); + } + // Acquire and hold lock to make a task queue for // subsequent listener calls on same resource. // It would fail if we let it go through from action state busy. let lock = sync_locks().get_or_insert_default(&sync.id).await; let _lock = lock.lock().await; - if !sync.config.webhook_enabled { - return Err(anyhow!("sync does not have webhook enabled")); - } - B::verify_branch(&body, &sync.config.branch)?; E::resolve(sync).await @@ -421,11 +422,15 @@ fn procedure_locks() -> &'static ListenerLockCache { PROCEDURE_LOCKS.get_or_init(Default::default) } -pub async fn handle_procedure_webhook( +pub async fn handle_procedure_webhook( procedure: Procedure, target_branch: &str, body: String, ) -> anyhow::Result<()> { + if !procedure.config.webhook_enabled { + return Ok(()); + } + // Acquire and hold lock to make a task queue for // subsequent listener calls on same resource. // It would fail if we let it go through from action state busy. @@ -433,10 +438,6 @@ pub async fn handle_procedure_webhook( procedure_locks().get_or_insert_default(&procedure.id).await; let _lock = lock.lock().await; - if !procedure.config.webhook_enabled { - return Err(anyhow!("procedure does not have webhook enabled")); - } - if target_branch != ANY_BRANCH { B::verify_branch(&body, target_branch)?; } @@ -471,28 +472,42 @@ fn action_locks() -> &'static ListenerLockCache { ACTION_LOCKS.get_or_init(Default::default) } -pub async fn handle_action_webhook( +pub async fn handle_action_webhook( action: Action, target_branch: &str, body: String, ) -> anyhow::Result<()> { + if !action.config.webhook_enabled { + return Ok(()); + } + // Acquire and hold lock to make a task queue for // subsequent listener calls on same resource. // It would fail if we let it go through from action state busy. let lock = action_locks().get_or_insert_default(&action.id).await; let _lock = lock.lock().await; - if !action.config.webhook_enabled { - return Err(anyhow!("action does not have webhook enabled")); - } + let branch = B::extract_branch(&body)?; - if target_branch != ANY_BRANCH { - B::verify_branch(&body, target_branch)?; + if target_branch != ANY_BRANCH && branch != target_branch { + return Err(anyhow!("request branch does not match expected")); } let user = git_webhook_user().to_owned(); - let req = - ExecuteRequest::RunAction(RunAction { action: action.id }); + + let body = serde_json::Value::from_str(&body) + .context("Failed to deserialize webhook body")?; + let serde_json::Value::Object(args) = json!({ + "WEBHOOK_BRANCH": branch, + "WEBHOOK_BODY": body, + }) else { + return Err(anyhow!("Something is wrong with serde_json...")); + }; + + let req = ExecuteRequest::RunAction(RunAction { + action: action.id, + args: args.into(), + }); let update = init_execution_update(&req, &user).await?; let ExecuteRequest::RunAction(req) = req else { unreachable!() diff --git a/bin/core/src/listener/router.rs b/bin/core/src/listener/router.rs index a69124d32..f255ad471 100644 --- a/bin/core/src/listener/router.rs +++ b/bin/core/src/listener/router.rs @@ -11,7 +11,7 @@ use tracing::Instrument; use crate::resource::KomodoResource; use super::{ - CustomSecret, VerifyBranch, VerifySecret, + CustomSecret, ExtractBranch, VerifySecret, resources::{ RepoWebhookOption, StackWebhookOption, SyncWebhookOption, handle_action_webhook, handle_build_webhook, @@ -42,7 +42,7 @@ fn default_branch() -> String { String::from("main") } -pub fn router() -> Router { +pub fn router() -> Router { Router::new() .route( "/build/{id}", diff --git a/bin/core/src/main.rs b/bin/core/src/main.rs index 8910a6e7a..6597c85ab 100644 --- a/bin/core/src/main.rs +++ b/bin/core/src/main.rs @@ -5,7 +5,7 @@ use std::{net::SocketAddr, str::FromStr}; use anyhow::Context; use axum::Router; -use axum_server::tls_rustls::RustlsConfig; +use axum_server::{Handle, tls_rustls::RustlsConfig}; use tower_http::{ cors::{Any, CorsLayer}, services::{ServeDir, ServeFile}, @@ -18,10 +18,10 @@ mod api; mod auth; mod cloud; mod config; -mod db; mod helpers; mod listener; mod monitor; +mod network; mod permission; mod resource; mod schedule; @@ -65,7 +65,7 @@ async fn app() -> anyhow::Result<()> { // Spawn background tasks monitor::spawn_monitor_loop(); resource::spawn_resource_refresh_loop(); - resource::spawn_all_resources_refresh_loop(); + resource::spawn_all_resources_cache_refresh_loop(); resource::spawn_build_state_refresh_loop(); resource::spawn_repo_state_refresh_loop(); resource::spawn_procedure_state_refresh_loop(); @@ -104,6 +104,18 @@ async fn app() -> anyhow::Result<()> { let socket_addr = SocketAddr::from_str(&addr) .context("failed to parse listen address")?; + let handle = Handle::new(); + tokio::spawn({ + // Cannot run actions until the server is available. + // We can use a handle for the server, and wait until + // the handle is listening before running actions + let handle = handle.clone(); + async move { + handle.listening().await; + startup::run_startup_actions().await; + } + }); + if config.ssl_enabled { info!("🔒 Core SSL Enabled"); rustls::crypto::ring::default_provider() @@ -117,6 +129,7 @@ async fn app() -> anyhow::Result<()> { .await .context("Invalid ssl cert / key")?; axum_server::bind_rustls(socket_addr, ssl_config) + .handle(handle) .serve(app) .await .context("failed to start https server") @@ -124,6 +137,7 @@ async fn app() -> anyhow::Result<()> { info!("🔓 Core SSL Disabled"); info!("Komodo Core starting on http://{socket_addr}"); axum_server::bind(socket_addr) + .handle(handle) .serve(app) .await .context("failed to start http server") diff --git a/bin/core/src/monitor/alert/deployment.rs b/bin/core/src/monitor/alert/deployment.rs index 9b153628d..f53f126c4 100644 --- a/bin/core/src/monitor/alert/deployment.rs +++ b/bin/core/src/monitor/alert/deployment.rs @@ -7,8 +7,10 @@ use komodo_client::entities::{ }; use crate::{ - alert::send_alerts, monitor::deployment_status_cache, resource, - state::db_client, + alert::send_alerts, + monitor::deployment_status_cache, + resource, + state::{action_states, db_client}, }; #[instrument(level = "debug")] @@ -17,6 +19,7 @@ pub async fn alert_deployments( server_names: &HashMap, ) { let mut alerts = Vec::::new(); + let action_states = action_states(); for status in deployment_status_cache().get_list().await { // Don't alert if prev None let Some(prev) = status.prev else { @@ -31,6 +34,20 @@ pub async fn alert_deployments( continue; } + // Don't alert if deploying + if action_states + .deployment + .get(&status.curr.id) + .await + .map(|s| s.get().map(|s| s.deploying)) + .transpose() + .ok() + .flatten() + .unwrap_or_default() + { + continue; + } + if status.curr.state != prev { // send alert let Ok(deployment) = diff --git a/bin/core/src/monitor/alert/server.rs b/bin/core/src/monitor/alert/server.rs index 71b848d2c..892a300c0 100644 --- a/bin/core/src/monitor/alert/server.rs +++ b/bin/core/src/monitor/alert/server.rs @@ -6,6 +6,12 @@ use std::{ }; use anyhow::Context; +use database::mongo_indexed::Indexed; +use database::mungos::{ + bulk_update::{self, BulkUpdate}, + find::find_collect, + mongodb::bson::{doc, oid::ObjectId, to_bson}, +}; use derive_variants::ExtractVariant; use komodo_client::entities::{ ResourceTarget, @@ -13,12 +19,6 @@ use komodo_client::entities::{ komodo_timestamp, optional_string, server::{Server, ServerState}, }; -use mongo_indexed::Indexed; -use mungos::{ - bulk_update::{self, BulkUpdate}, - find::find_collect, - mongodb::bson::{doc, oid::ObjectId, to_bson}, -}; use crate::{ alert::send_alerts, diff --git a/bin/core/src/monitor/alert/stack.rs b/bin/core/src/monitor/alert/stack.rs index 98c73ee68..64bac8012 100644 --- a/bin/core/src/monitor/alert/stack.rs +++ b/bin/core/src/monitor/alert/stack.rs @@ -9,7 +9,7 @@ use komodo_client::entities::{ use crate::{ alert::send_alerts, resource, - state::{db_client, stack_status_cache}, + state::{action_states, db_client, stack_status_cache}, }; #[instrument(level = "debug")] @@ -17,6 +17,7 @@ pub async fn alert_stacks( ts: i64, server_names: &HashMap, ) { + let action_states = action_states(); let mut alerts = Vec::::new(); for status in stack_status_cache().get_list().await { // Don't alert if prev None @@ -32,6 +33,20 @@ pub async fn alert_stacks( continue; } + // Don't alert if deploying + if action_states + .stack + .get(&status.curr.id) + .await + .map(|s| s.get().map(|s| s.deploying)) + .transpose() + .ok() + .flatten() + .unwrap_or_default() + { + continue; + } + if status.curr.state != prev { // send alert let Ok(stack) = diff --git a/bin/core/src/monitor/mod.rs b/bin/core/src/monitor/mod.rs index d7615372c..e7824efe2 100644 --- a/bin/core/src/monitor/mod.rs +++ b/bin/core/src/monitor/mod.rs @@ -1,4 +1,5 @@ use async_timing_util::wait_until_timelength; +use database::mungos::{find::find_collect, mongodb::bson::doc}; use futures::future::join_all; use helpers::insert_stacks_status_unknown; use komodo_client::entities::{ @@ -12,7 +13,6 @@ use komodo_client::entities::{ stack::{ComposeProject, StackService, StackState}, stats::SystemStats, }; -use mungos::{find::find_collect, mongodb::bson::doc}; use periphery_client::api::{self, git::GetLatestCommit}; use serror::Serror; diff --git a/bin/core/src/network.rs b/bin/core/src/network.rs new file mode 100644 index 000000000..5d38e566a --- /dev/null +++ b/bin/core/src/network.rs @@ -0,0 +1,312 @@ +//! # Network Configuration Module +//! +//! This module provides manual network interface configuration for multi-NIC Docker environments. +//! It allows Komodo Core to specify which network interface should be used as the default route +//! for internet traffic, which is particularly useful in complex networking setups with multiple +//! network interfaces. +//! +//! ## Features +//! - Automatic container environment detection +//! - Interface validation (existence and UP state) +//! - Gateway discovery from routing tables or network configuration +//! - Safe default route modification with privilege checking +//! - Comprehensive error handling and logging + +use anyhow::{Context, anyhow}; +use tokio::process::Command; +use tracing::{debug, info, trace, warn}; + +/// Standard gateway addresses to test for Docker networks +const DOCKER_GATEWAY_CANDIDATES: &[&str] = &[".1", ".254"]; + +/// Container environment detection files +const DOCKERENV_FILE: &str = "/.dockerenv"; +const CGROUP_FILE: &str = "/proc/1/cgroup"; + +/// Check if running in container environment +fn is_container_environment() -> bool { + // Check for Docker-specific indicators + if std::path::Path::new(DOCKERENV_FILE).exists() { + return true; + } + + // Check container environment variable + if std::env::var("container").is_ok() { + return true; + } + + // Check cgroup for container runtime indicators + if let Ok(content) = std::fs::read_to_string(CGROUP_FILE) { + if content.contains("docker") || content.contains("containerd") { + return true; + } + } + + false +} + +/// Configure internet gateway for specified interface +pub async fn configure_internet_gateway() { + use crate::config::core_config; + + let config = core_config(); + + if !is_container_environment() { + debug!("Not in container, skipping network configuration"); + return; + } + + if !config.internet_interface.is_empty() { + debug!( + "Configuring internet interface: {}", + config.internet_interface + ); + if let Err(e) = + configure_manual_interface(&config.internet_interface).await + { + warn!("Failed to configure internet gateway: {e:#}"); + } + } else { + debug!("No interface specified, using default routing"); + } +} + +/// Configure interface as default route +async fn configure_manual_interface( + interface_name: &str, +) -> anyhow::Result<()> { + // Verify interface exists and is up + let interface_check = Command::new("ip") + .args(["addr", "show", interface_name]) + .output() + .await + .context("Failed to check interface status")?; + + if !interface_check.status.success() { + return Err(anyhow!( + "Interface '{}' does not exist or is not accessible. Available interfaces can be listed with 'ip addr show'", + interface_name + )); + } + + let interface_info = + String::from_utf8_lossy(&interface_check.stdout); + if !interface_info.contains("state UP") { + return Err(anyhow!( + "Interface '{}' is not UP. Please ensure the interface is enabled and connected", + interface_name + )); + } + + debug!("Interface {} is UP", interface_name); + + let gateway = find_gateway(interface_name).await?; + debug!("Found gateway {} for {}", gateway, interface_name); + + set_default_gateway(&gateway, interface_name).await?; + info!( + "🌐 Configured {} as default gateway via {}", + interface_name, gateway + ); + Ok(()) +} + +/// Find gateway for interface +async fn find_gateway( + interface_name: &str, +) -> anyhow::Result { + // Get interface IP address + let addr_output = Command::new("ip") + .args(["addr", "show", interface_name]) + .output() + .await + .context("Failed to get interface address")?; + + let addr_info = String::from_utf8_lossy(&addr_output.stdout); + let mut ip_cidr = None; + + // Extract IP/CIDR from interface info + for line in addr_info.lines() { + if line.trim().starts_with("inet ") && !line.contains("127.0.0.1") + { + let parts: Vec<&str> = line.split_whitespace().collect(); + if let Some(found_ip_cidr) = parts.get(1) { + debug!( + "Interface {} has IP {}", + interface_name, found_ip_cidr + ); + ip_cidr = Some(*found_ip_cidr); + break; + } + } + } + + let ip_cidr = ip_cidr.ok_or_else(|| anyhow!( + "Could not find IP address for interface '{}'. Ensure interface has a valid IPv4 address", + interface_name + ))?; + + trace!( + "Finding gateway for interface {} in network {}", + interface_name, ip_cidr + ); + + // Try to find gateway from routing table + let route_output = Command::new("ip") + .args(["route", "show", "dev", interface_name]) + .output() + .await + .context("Failed to get routes for interface")?; + + if route_output.status.success() { + let routes = String::from_utf8(route_output.stdout)?; + trace!("Routes for {}: {}", interface_name, routes.trim()); + + // Look for routes with gateway + for line in routes.lines() { + if line.contains("via") { + let parts: Vec<&str> = line.split_whitespace().collect(); + if let Some(via_idx) = parts.iter().position(|&x| x == "via") + { + if let Some(&gateway) = parts.get(via_idx + 1) { + trace!( + "Found gateway {} for {} from routing table", + gateway, interface_name + ); + return Ok(gateway.to_string()); + } + } + } + } + } + + // Derive gateway from network configuration (Docker standard: .1) + if let Some(network_base) = ip_cidr.split('/').next() { + let ip_parts: Vec<&str> = network_base.split('.').collect(); + if ip_parts.len() == 4 { + let potential_gateways: Vec = DOCKER_GATEWAY_CANDIDATES + .iter() + .map(|suffix| { + format!( + "{}.{}.{}{}", + ip_parts[0], ip_parts[1], ip_parts[2], suffix + ) + }) + .collect(); + + for gateway in potential_gateways { + trace!( + "Testing potential gateway {} for {}", + gateway, interface_name + ); + + // Check if gateway is reachable + let route_test = Command::new("ip") + .args(["route", "get", &gateway, "dev", interface_name]) + .output() + .await; + + if let Ok(output) = route_test { + if output.status.success() { + trace!( + "Gateway {} is reachable via {}", + gateway, interface_name + ); + return Ok(gateway.to_string()); + } + } + + // Fallback: assume .1 is gateway (Docker standard) + if gateway.ends_with(".1") { + trace!( + "Assuming Docker gateway {} for {}", + gateway, interface_name + ); + return Ok(gateway.to_string()); + } + } + } + } + + Err(anyhow!( + "Could not determine gateway for interface '{}' in network '{}'. \ + Ensure the interface is properly configured with a valid gateway", + interface_name, + ip_cidr + )) +} + +/// Set default gateway to use specified interface +async fn set_default_gateway( + gateway: &str, + interface_name: &str, +) -> anyhow::Result<()> { + trace!( + "Setting default gateway to {} via {}", + gateway, interface_name + ); + + // Check if we have network privileges + if !check_network_privileges().await { + warn!( + "⚠️ Container lacks network privileges (NET_ADMIN capability required)" + ); + warn!( + "Add 'cap_add: [\"NET_ADMIN\"]' to your docker-compose.yaml" + ); + return Err(anyhow!( + "Insufficient network privileges to modify routing table. \ + Container needs NET_ADMIN capability to configure network interfaces" + )); + } + + // Remove existing default routes + let remove_default = Command::new("sh") + .args(["-c", "ip route del default 2>/dev/null || true"]) + .output() + .await; + + if let Ok(output) = remove_default { + if output.status.success() { + trace!("Removed existing default routes"); + } + } + + // Add new default route + let add_default_cmd = format!( + "ip route add default via {gateway} dev {interface_name}" + ); + trace!("Adding default route: {}", add_default_cmd); + + let add_default = Command::new("sh") + .args(["-c", &add_default_cmd]) + .output() + .await + .context("Failed to add default route")?; + + if !add_default.status.success() { + let error = String::from_utf8_lossy(&add_default.stderr) + .trim() + .to_string(); + return Err(anyhow!( + "❌ Failed to set default gateway via '{}': {}. \ + Verify interface configuration and network permissions", + interface_name, + error + )); + } + + trace!("Default gateway set to {} via {}", gateway, interface_name); + Ok(()) +} + +/// Check if we have sufficient network privileges +async fn check_network_privileges() -> bool { + // Try to test NET_ADMIN capability with a harmless route operation + let capability_test = Command::new("sh") + .args(["-c", "ip route add 198.51.100.1/32 dev lo 2>/dev/null && ip route del 198.51.100.1/32 dev lo 2>/dev/null"]) + .output() + .await; + + matches!(capability_test, Ok(output) if output.status.success()) +} diff --git a/bin/core/src/permission.rs b/bin/core/src/permission.rs index 5d37954cf..b5173b377 100644 --- a/bin/core/src/permission.rs +++ b/bin/core/src/permission.rs @@ -1,6 +1,8 @@ use std::collections::HashSet; use anyhow::{Context, anyhow}; +use database::mongo_indexed::doc; +use database::mungos::find::find_collect; use futures::{FutureExt, future::BoxFuture}; use indexmap::IndexSet; use komodo_client::{ @@ -11,8 +13,6 @@ use komodo_client::{ user::User, }, }; -use mongo_indexed::doc; -use mungos::find::find_collect; use resolver_api::Resolve; use crate::{ @@ -83,6 +83,8 @@ pub fn get_user_permission_on_resource<'a, T: KomodoResource>( let resource = get::(resource_id).await?; let initial_specific = if let Some(additional_target) = T::inherit_specific_permissions_from(&resource) + // Ensure target is actually assigned + && !additional_target.is_empty() { GetPermission { target: additional_target, @@ -174,19 +176,19 @@ pub async fn get_resource_ids_for_user( let resource_type = T::resource_type(); // Check user 'all' on variant - if let Some(permission) = user.all.get(&resource_type).cloned() { - if permission.level > PermissionLevel::None { - return Ok(None); - } + if let Some(permission) = user.all.get(&resource_type).cloned() + && permission.level > PermissionLevel::None + { + return Ok(None); } // Check user groups 'all' on variant let groups = get_user_user_groups(&user.id).await?; for group in &groups { - if let Some(permission) = group.all.get(&resource_type).cloned() { - if permission.level > PermissionLevel::None { - return Ok(None); - } + if let Some(permission) = group.all.get(&resource_type).cloned() + && permission.level > PermissionLevel::None + { + return Ok(None); } } diff --git a/bin/core/src/resource/action.rs b/bin/core/src/resource/action.rs index 46679ba0e..e2a499ecd 100644 --- a/bin/core/src/resource/action.rs +++ b/bin/core/src/resource/action.rs @@ -1,6 +1,10 @@ use std::time::Duration; use anyhow::Context; +use database::mungos::{ + find::find_collect, + mongodb::{Collection, bson::doc, options::FindOneOptions}, +}; use komodo_client::entities::{ NoData, Operation, ResourceTarget, ResourceTargetVariant, action::{ @@ -12,10 +16,6 @@ use komodo_client::entities::{ update::Update, user::User, }; -use mungos::{ - find::find_collect, - mongodb::{Collection, bson::doc, options::FindOneOptions}, -}; use crate::{ helpers::query::{get_action_state, get_last_run_at}, @@ -155,6 +155,7 @@ impl super::KomodoResource for Action { _update: &mut Update, ) -> anyhow::Result<()> { cancel_schedule(&ResourceTarget::Action(resource.id.clone())); + action_state_cache().remove(&resource.id).await; Ok(()) } } @@ -221,4 +222,7 @@ async fn get_action_state_from_db(id: &str) -> ActionState { const DEFAULT_ACTION_FILE_CONTENTS: &str = "// Run actions using the pre initialized 'komodo' client. const version: Types.GetVersionResponse = await komodo.read('GetVersion', {}); -console.log('🦎 Komodo version:', version.version, '🦎\\n');"; +console.log('🦎 Komodo version:', version.version, '🦎\\n'); + +// Access arguments using the 'ARGS' object. +console.log(ARGS);"; diff --git a/bin/core/src/resource/alerter.rs b/bin/core/src/resource/alerter.rs index 37f3f411f..e7e0e0235 100644 --- a/bin/core/src/resource/alerter.rs +++ b/bin/core/src/resource/alerter.rs @@ -1,3 +1,4 @@ +use database::mungos::mongodb::Collection; use derive_variants::ExtractVariant; use komodo_client::entities::{ Operation, ResourceTarget, ResourceTargetVariant, @@ -9,7 +10,6 @@ use komodo_client::entities::{ update::Update, user::User, }; -use mungos::mongodb::Collection; use crate::state::db_client; diff --git a/bin/core/src/resource/build.rs b/bin/core/src/resource/build.rs index 0b42b76f4..86463b62f 100644 --- a/bin/core/src/resource/build.rs +++ b/bin/core/src/resource/build.rs @@ -1,6 +1,10 @@ use std::time::Duration; use anyhow::Context; +use database::mungos::{ + find::find_collect, + mongodb::{Collection, bson::doc, options::FindOptions}, +}; use formatting::format_serror; use komodo_client::{ api::write::RefreshBuildCache, @@ -21,10 +25,6 @@ use komodo_client::{ user::{User, build_user}, }, }; -use mungos::{ - find::find_collect, - mongodb::{Collection, bson::doc, options::FindOptions}, -}; use resolver_api::Resolve; use crate::{ @@ -216,9 +216,10 @@ impl super::KomodoResource for Build { } async fn post_delete( - _resource: &Resource, + resource: &Resource, _update: &mut Update, ) -> anyhow::Result<()> { + build_state_cache().remove(&resource.id).await; Ok(()) } } @@ -255,30 +256,30 @@ async fn validate_config( config: &mut PartialBuildConfig, user: &User, ) -> anyhow::Result<()> { - if let Some(builder_id) = &config.builder_id { - if !builder_id.is_empty() { - let builder = super::get_check_permissions::( - builder_id, - user, - PermissionLevel::Read.attach(), - ) - .await - .context("Cannot attach Build to this Builder")?; - config.builder_id = Some(builder.id) - } + if let Some(builder_id) = &config.builder_id + && !builder_id.is_empty() + { + let builder = super::get_check_permissions::( + builder_id, + user, + PermissionLevel::Read.attach(), + ) + .await + .context("Cannot attach Build to this Builder")?; + config.builder_id = Some(builder.id) } - if let Some(linked_repo) = &config.linked_repo { - if !linked_repo.is_empty() { - let repo = get_check_permissions::( - linked_repo, - user, - PermissionLevel::Read.attach(), - ) - .await - .context("Cannot attach Repo to this Build")?; - // in case it comes in as name - config.linked_repo = Some(repo.id); - } + if let Some(linked_repo) = &config.linked_repo + && !linked_repo.is_empty() + { + let repo = get_check_permissions::( + linked_repo, + user, + PermissionLevel::Read.attach(), + ) + .await + .context("Cannot attach Repo to this Build")?; + // in case it comes in as name + config.linked_repo = Some(repo.id); } if let Some(build_args) = &config.build_args { environment_vars_from_str(build_args) diff --git a/bin/core/src/resource/builder.rs b/bin/core/src/resource/builder.rs index a709e949a..6aac3e47b 100644 --- a/bin/core/src/resource/builder.rs +++ b/bin/core/src/resource/builder.rs @@ -1,4 +1,8 @@ use anyhow::Context; +use database::mungos::mongodb::{ + Collection, + bson::{Document, doc, to_document}, +}; use indexmap::IndexSet; use komodo_client::entities::{ MergePartial, Operation, ResourceTarget, ResourceTargetVariant, @@ -13,10 +17,6 @@ use komodo_client::entities::{ update::Update, user::User, }; -use mungos::mongodb::{ - Collection, - bson::{Document, doc, to_document}, -}; use crate::state::db_client; @@ -119,7 +119,8 @@ impl super::KomodoResource for Builder { fn update_document( original: Resource, config: Self::PartialConfig, - ) -> Result { + ) -> Result + { let config = original.config.merge_partial(config); to_document(&config) } @@ -151,7 +152,9 @@ impl super::KomodoResource for Builder { .builds .update_many( doc! { "config.builder_id": &resource.id }, - mungos::update::Update::Set(doc! { "config.builder_id": "" }), + database::mungos::update::Update::Set( + doc! { "config.builder_id": "" }, + ), ) .await .context("failed to update_many builds on database")?; @@ -159,7 +162,9 @@ impl super::KomodoResource for Builder { .repos .update_many( doc! { "config.builder_id": &resource.id }, - mungos::update::Update::Set(doc! { "config.builder_id": "" }), + database::mungos::update::Update::Set( + doc! { "config.builder_id": "" }, + ), ) .await .context("failed to update_many repos on database")?; diff --git a/bin/core/src/resource/deployment.rs b/bin/core/src/resource/deployment.rs index 303131624..dab5496c4 100644 --- a/bin/core/src/resource/deployment.rs +++ b/bin/core/src/resource/deployment.rs @@ -1,4 +1,5 @@ use anyhow::Context; +use database::mungos::mongodb::Collection; use formatting::format_serror; use indexmap::IndexSet; use komodo_client::entities::{ @@ -18,7 +19,6 @@ use komodo_client::entities::{ update::Update, user::User, }; -use mungos::mongodb::Collection; use periphery_client::api::container::RemoveContainer; use crate::{ @@ -301,9 +301,10 @@ impl super::KomodoResource for Deployment { } async fn post_delete( - _resource: &Resource, + resource: &Resource, _update: &mut Update, ) -> anyhow::Result<()> { + deployment_status_cache().remove(&resource.id).await; Ok(()) } } @@ -313,36 +314,33 @@ async fn validate_config( config: &mut PartialDeploymentConfig, user: &User, ) -> anyhow::Result<()> { - if let Some(server_id) = &config.server_id { - if !server_id.is_empty() { - let server = get_check_permissions::( - server_id, - user, - PermissionLevel::Read.attach(), - ) - .await - .context("Cannot attach Deployment to this Server")?; - config.server_id = Some(server.id); - } + if let Some(server_id) = &config.server_id + && !server_id.is_empty() + { + let server = get_check_permissions::( + server_id, + user, + PermissionLevel::Read.attach(), + ) + .await + .context("Cannot attach Deployment to this Server")?; + config.server_id = Some(server.id); } if let Some(DeploymentImage::Build { build_id, version }) = &config.image + && !build_id.is_empty() { - if !build_id.is_empty() { - let build = get_check_permissions::( - build_id, - user, - PermissionLevel::Read.attach(), - ) - .await - .context( - "Cannot update deployment with this build attached.", - )?; - config.image = Some(DeploymentImage::Build { - build_id: build.id, - version: *version, - }); - } + let build = get_check_permissions::( + build_id, + user, + PermissionLevel::Read.attach(), + ) + .await + .context("Cannot update deployment with this build attached.")?; + config.image = Some(DeploymentImage::Build { + build_id: build.id, + version: *version, + }); } if let Some(volumes) = &config.volumes { conversions_from_str(volumes).context("Invalid volumes")?; diff --git a/bin/core/src/resource/mod.rs b/bin/core/src/resource/mod.rs index 2e0cbd435..3fa90585c 100644 --- a/bin/core/src/resource/mod.rs +++ b/bin/core/src/resource/mod.rs @@ -4,6 +4,15 @@ use std::{ }; use anyhow::{Context, anyhow}; +use database::mungos::{ + by_id::{delete_one_by_id, update_one_by_id}, + find::find_collect, + mongodb::{ + Collection, + bson::{Document, doc, oid::ObjectId, to_document}, + options::FindOptions, + }, +}; use formatting::format_serror; use futures::future::join_all; use indexmap::IndexSet; @@ -24,15 +33,6 @@ use komodo_client::{ }, parsers::parse_string_list, }; -use mungos::{ - by_id::{delete_one_by_id, update_one_by_id}, - find::find_collect, - mongodb::{ - Collection, - bson::{Document, doc, oid::ObjectId, to_document}, - options::FindOptions, - }, -}; use partial_derive2::{Diff, MaybeNone, PartialDiff}; use resolver_api::Resolve; use serde::{Serialize, de::DeserializeOwned}; @@ -70,7 +70,8 @@ pub use procedure::{ refresh_procedure_state_cache, spawn_procedure_state_refresh_loop, }; pub use refresh::{ - refresh_all_resources_cache, spawn_all_resources_refresh_loop, + refresh_all_resources_cache, + spawn_all_resources_cache_refresh_loop, spawn_resource_refresh_loop, }; pub use repo::{ @@ -181,7 +182,8 @@ pub trait KomodoResource { fn update_document( _original: Resource, config: Self::PartialConfig, - ) -> Result { + ) -> Result + { to_document(&config) } @@ -271,26 +273,26 @@ pub async fn list_for_user( list_for_user_using_document::(filters, user, permissions).await } -#[instrument(level = "debug")] -pub async fn list_for_user_using_pattern( - pattern: &str, - query: ResourceQuery, - user: &User, - permissions: PermissionLevelAndSpecifics, - all_tags: &[Tag], -) -> anyhow::Result> { - let list = list_full_for_user_using_pattern::( - pattern, - query, - user, - permissions, - all_tags, - ) - .await? - .into_iter() - .map(|resource| T::to_list_item(resource)); - Ok(join_all(list).await) -} +// #[instrument(level = "debug")] +// pub async fn list_for_user_using_pattern( +// pattern: &str, +// query: ResourceQuery, +// user: &User, +// permissions: PermissionLevelAndSpecifics, +// all_tags: &[Tag], +// ) -> anyhow::Result> { +// let list = list_full_for_user_using_pattern::( +// pattern, +// query, +// user, +// permissions, +// all_tags, +// ) +// .await? +// .into_iter() +// .map(|resource| T::to_list_item(resource)); +// Ok(join_all(list).await) +// } #[instrument(level = "debug")] pub async fn list_for_user_using_document( @@ -705,6 +707,7 @@ pub async fn update_meta( Ok(tag) => Ok(tag.id), Err(_) => CreateTag { name: tag.to_string(), + color: None, } .resolve(args) .await @@ -762,7 +765,7 @@ pub async fn rename( update_one_by_id( T::coll(), &resource.id, - mungos::update::Update::Set( + database::mungos::update::Update::Set( doc! { "name": &name, "updated_at": komodo_timestamp() }, ), None, @@ -872,7 +875,7 @@ pub fn validate_resource_query_tags( .find(|t| t.name == *tag || t.id == *tag) .map(|tag| tag.id.clone()) .with_context(|| { - format!("No tag found matching name or id: {}", tag) + format!("No tag found matching name or id: {tag}") }) }) .collect::>>()?; diff --git a/bin/core/src/resource/procedure.rs b/bin/core/src/resource/procedure.rs index cc3c6ac94..eaa5eb551 100644 --- a/bin/core/src/resource/procedure.rs +++ b/bin/core/src/resource/procedure.rs @@ -1,6 +1,10 @@ use std::time::Duration; use anyhow::{Context, anyhow}; +use database::mungos::{ + find::find_collect, + mongodb::{Collection, bson::doc, options::FindOneOptions}, +}; use komodo_client::{ api::execute::Execution, entities::{ @@ -24,10 +28,6 @@ use komodo_client::{ user::User, }, }; -use mungos::{ - find::find_collect, - mongodb::{Collection, bson::doc, options::FindOneOptions}, -}; use crate::{ config::core_config, @@ -165,6 +165,7 @@ impl super::KomodoResource for Procedure { _update: &mut Update, ) -> anyhow::Result<()> { cancel_schedule(&ResourceTarget::Procedure(resource.id.clone())); + procedure_state_cache().remove(&resource.id).await; Ok(()) } } @@ -724,6 +725,27 @@ async fn validate_config( .await?; params.alerter = alerter.id; } + Execution::ClearRepoCache(_params) => { + if !user.admin { + return Err(anyhow!( + "Non admin user cannot clear repo cache" + )); + } + } + Execution::BackupCoreDatabase(_params) => { + if !user.admin { + return Err(anyhow!( + "Non admin user cannot trigger core database backup" + )); + } + } + Execution::GlobalAutoUpdate(_params) => { + if !user.admin { + return Err(anyhow!( + "Non admin user cannot trigger global auto update" + )); + } + } Execution::Sleep(_) => {} } } diff --git a/bin/core/src/resource/refresh.rs b/bin/core/src/resource/refresh.rs index 3e415bf73..216483290 100644 --- a/bin/core/src/resource/refresh.rs +++ b/bin/core/src/resource/refresh.rs @@ -1,6 +1,7 @@ use std::time::Duration; use async_timing_util::{Timelength, get_timelength_in_ms}; +use database::mungos::find::find_collect; use komodo_client::{ api::write::{ RefreshBuildCache, RefreshRepoCache, RefreshResourceSyncPending, @@ -8,17 +9,16 @@ use komodo_client::{ }, entities::user::{build_user, repo_user, stack_user, sync_user}, }; -use mungos::find::find_collect; use resolver_api::Resolve; use crate::{ - api::{execute::pull_deployment_inner, write::WriteArgs}, + api::write::WriteArgs, config::core_config, helpers::all_resources::AllResourcesById, state::{all_resources_cache, db_client}, }; -pub fn spawn_all_resources_refresh_loop() { +pub fn spawn_all_resources_cache_refresh_loop() { tokio::spawn(async move { let mut interval = tokio::time::interval(Duration::from_secs(15)); loop { @@ -57,7 +57,6 @@ pub fn spawn_resource_refresh_loop() { async fn refresh_all() { refresh_stacks().await; - refresh_deployments().await; refresh_builds().await; refresh_repos().await; refresh_syncs().await; @@ -87,45 +86,6 @@ async fn refresh_stacks() { } } -async fn refresh_deployments() { - let servers = find_collect(&db_client().servers, None, None) - .await - .inspect_err(|e| { - warn!( - "Failed to get Servers from database in refresh task | {e:#}" - ) - }) - .unwrap_or_default(); - let Ok(deployments) = find_collect(&db_client().deployments, None, None) - .await - .inspect_err(|e| { - warn!( - "Failed to get Deployments from database in refresh task | {e:#}" - ) - }) - else { - return; - }; - for deployment in deployments { - if deployment.config.poll_for_updates - || deployment.config.auto_update - { - if let Some(server) = - servers.iter().find(|s| s.id == deployment.config.server_id) - { - let name = deployment.name.clone(); - if let Err(e) = - pull_deployment_inner(deployment, server).await - { - warn!( - "Failed to pull latest image for Deployment {name} | {e:#}" - ); - } - } - } - } -} - async fn refresh_builds() { let Ok(builds) = find_collect(&db_client().builds, None, None) .await diff --git a/bin/core/src/resource/repo.rs b/bin/core/src/resource/repo.rs index 8880ec65c..9d44196ed 100644 --- a/bin/core/src/resource/repo.rs +++ b/bin/core/src/resource/repo.rs @@ -1,6 +1,10 @@ use std::time::Duration; use anyhow::Context; +use database::mungos::{ + find::find_collect, + mongodb::{Collection, bson::doc, options::FindOneOptions}, +}; use formatting::format_serror; use komodo_client::entities::{ Operation, ResourceTarget, ResourceTargetVariant, @@ -16,10 +20,6 @@ use komodo_client::entities::{ update::Update, user::User, }; -use mungos::{ - find::find_collect, - mongodb::{Collection, bson::doc, options::FindOneOptions}, -}; use periphery_client::api::git::DeleteRepo; use crate::{ @@ -161,13 +161,6 @@ impl super::KomodoResource for Repo { } async fn pre_delete( - _resource: &Resource, - _update: &mut Update, - ) -> anyhow::Result<()> { - Ok(()) - } - - async fn post_delete( repo: &Resource, update: &mut Update, ) -> anyhow::Result<()> { @@ -191,13 +184,24 @@ impl super::KomodoResource for Repo { { Ok(log) => update.logs.push(log), Err(e) => update.push_error_log( - "delete repo on periphery", - format_serror(&e.context("failed to delete repo").into()), + "Delete Repo on Periphery", + format_serror( + &e.context("Failed to delete repo files").into(), + ), ), } Ok(()) } + + async fn post_delete( + repo: &Resource, + _update: &mut Update, + ) -> anyhow::Result<()> { + repo_state_cache().remove(&repo.id).await; + + Ok(()) + } } pub fn spawn_repo_state_refresh_loop() { @@ -232,29 +236,29 @@ async fn validate_config( config: &mut PartialRepoConfig, user: &User, ) -> anyhow::Result<()> { - if let Some(server_id) = &config.server_id { - if !server_id.is_empty() { - let server = get_check_permissions::( - server_id, - user, - PermissionLevel::Read.attach(), - ) - .await - .context("Cannot attach Repo to this Server")?; - config.server_id = Some(server.id); - } + if let Some(server_id) = &config.server_id + && !server_id.is_empty() + { + let server = get_check_permissions::( + server_id, + user, + PermissionLevel::Read.attach(), + ) + .await + .context("Cannot attach Repo to this Server")?; + config.server_id = Some(server.id); } - if let Some(builder_id) = &config.builder_id { - if !builder_id.is_empty() { - let builder = super::get_check_permissions::( - builder_id, - user, - PermissionLevel::Read.attach(), - ) - .await - .context("Cannot attach Repo to this Builder")?; - config.builder_id = Some(builder.id); - } + if let Some(builder_id) = &config.builder_id + && !builder_id.is_empty() + { + let builder = super::get_check_permissions::( + builder_id, + user, + PermissionLevel::Read.attach(), + ) + .await + .context("Cannot attach Repo to this Builder")?; + config.builder_id = Some(builder.id); } Ok(()) } diff --git a/bin/core/src/resource/server.rs b/bin/core/src/resource/server.rs index db30e5d58..7f4dfae55 100644 --- a/bin/core/src/resource/server.rs +++ b/bin/core/src/resource/server.rs @@ -1,4 +1,5 @@ use anyhow::Context; +use database::mungos::mongodb::{Collection, bson::doc}; use indexmap::IndexSet; use komodo_client::entities::{ Operation, ResourceTarget, ResourceTargetVariant, komodo_timestamp, @@ -11,7 +12,6 @@ use komodo_client::entities::{ update::Update, user::User, }; -use mungos::mongodb::{Collection, bson::doc}; use crate::{ config::core_config, @@ -75,6 +75,7 @@ impl super::KomodoResource for Server { .unwrap_or(String::from("Unknown")), region: server.config.region, address: server.config.address, + external_address: server.config.external_address, send_unreachable_alerts: server .config .send_unreachable_alerts, diff --git a/bin/core/src/resource/stack.rs b/bin/core/src/resource/stack.rs index 09cf1a0ed..95fff164c 100644 --- a/bin/core/src/resource/stack.rs +++ b/bin/core/src/resource/stack.rs @@ -1,4 +1,5 @@ use anyhow::Context; +use database::mungos::mongodb::Collection; use formatting::format_serror; use indexmap::IndexSet; use komodo_client::{ @@ -19,7 +20,6 @@ use komodo_client::{ user::{User, stack_user}, }, }; -use mungos::mongodb::Collection; use periphery_client::api::compose::ComposeExecution; use resolver_api::Resolve; @@ -320,7 +320,6 @@ impl super::KomodoResource for Stack { }; if !server.config.enabled { - // Don't need to update.push_simple_log( "destroy stack", "skipping stack destroy, server is disabled.", @@ -366,9 +365,10 @@ impl super::KomodoResource for Stack { } async fn post_delete( - _resource: &Resource, + resource: &Resource, _update: &mut Update, ) -> anyhow::Result<()> { + stack_status_cache().remove(&resource.id).await; Ok(()) } } @@ -378,31 +378,31 @@ async fn validate_config( config: &mut PartialStackConfig, user: &User, ) -> anyhow::Result<()> { - if let Some(server_id) = &config.server_id { - if !server_id.is_empty() { - let server = get_check_permissions::( - server_id, - user, - PermissionLevel::Read.attach(), - ) - .await - .context("Cannot attach Stack to this Server")?; - // in case it comes in as name - config.server_id = Some(server.id); - } + if let Some(server_id) = &config.server_id + && !server_id.is_empty() + { + let server = get_check_permissions::( + server_id, + user, + PermissionLevel::Read.attach(), + ) + .await + .context("Cannot attach Stack to this Server")?; + // in case it comes in as name + config.server_id = Some(server.id); } - if let Some(linked_repo) = &config.linked_repo { - if !linked_repo.is_empty() { - let repo = get_check_permissions::( - linked_repo, - user, - PermissionLevel::Read.attach(), - ) - .await - .context("Cannot attach Repo to this Stack")?; - // in case it comes in as name - config.linked_repo = Some(repo.id); - } + if let Some(linked_repo) = &config.linked_repo + && !linked_repo.is_empty() + { + let repo = get_check_permissions::( + linked_repo, + user, + PermissionLevel::Read.attach(), + ) + .await + .context("Cannot attach Repo to this Stack")?; + // in case it comes in as name + config.linked_repo = Some(repo.id); } Ok(()) } diff --git a/bin/core/src/resource/sync.rs b/bin/core/src/resource/sync.rs index 77487d752..189c3e27c 100644 --- a/bin/core/src/resource/sync.rs +++ b/bin/core/src/resource/sync.rs @@ -1,4 +1,6 @@ use anyhow::Context; +use database::mongo_indexed::doc; +use database::mungos::mongodb::Collection; use formatting::format_serror; use komodo_client::{ api::write::RefreshResourceSyncPending, @@ -18,8 +20,6 @@ use komodo_client::{ user::{User, sync_user}, }, }; -use mongo_indexed::doc; -use mungos::mongodb::Collection; use resolver_api::Resolve; use crate::{ @@ -221,18 +221,18 @@ async fn validate_config( config: &mut PartialResourceSyncConfig, user: &User, ) -> anyhow::Result<()> { - if let Some(linked_repo) = &config.linked_repo { - if !linked_repo.is_empty() { - let repo = get_check_permissions::( - linked_repo, - user, - PermissionLevel::Read.attach(), - ) - .await - .context("Cannot attach Repo to this Resource Sync")?; - // in case it comes in as name - config.linked_repo = Some(repo.id); - } + if let Some(linked_repo) = &config.linked_repo + && !linked_repo.is_empty() + { + let repo = get_check_permissions::( + linked_repo, + user, + PermissionLevel::Read.attach(), + ) + .await + .context("Cannot attach Repo to this Resource Sync")?; + // in case it comes in as name + config.linked_repo = Some(repo.id); } Ok(()) } diff --git a/bin/core/src/schedule.rs b/bin/core/src/schedule.rs index 79507c0ca..9489ac83f 100644 --- a/bin/core/src/schedule.rs +++ b/bin/core/src/schedule.rs @@ -6,6 +6,8 @@ use std::{ use anyhow::{Context, anyhow}; use async_timing_util::Timelength; use chrono::Local; +use croner::parser::CronParser; +use database::mungos::find::find_collect; use formatting::format_serror; use komodo_client::{ api::execute::{RunAction, RunProcedure}, @@ -18,7 +20,6 @@ use komodo_client::{ user::{action_user, procedure_user}, }, }; -use mungos::find::find_collect; use resolver_api::Resolve; use crate::{ @@ -32,6 +33,7 @@ use crate::{ pub fn spawn_schedule_executor() { // Executor thread tokio::spawn(async move { + update_schedules().await; loop { let current_time = async_timing_util::wait_until_timelength( Timelength::OneSecond, @@ -62,6 +64,7 @@ pub fn spawn_schedule_executor() { let request = ExecuteRequest::RunAction(RunAction { action: id.clone(), + args: Default::default(), }); let update = match init_execution_update( &request, @@ -188,18 +191,6 @@ pub fn spawn_schedule_executor() { } } }); - // Updater thread - tokio::spawn(async move { - update_schedules().await; - loop { - async_timing_util::wait_until_timelength( - Timelength::FiveMinutes, - 500, - ) - .await; - update_schedules().await - } - }); } type UnixTimestampMs = i64; @@ -284,16 +275,24 @@ pub fn update_schedule(schedule: impl HasSchedule) { ); } +fn cron_parser() -> &'static CronParser { + static CRON_PARSER: OnceLock = OnceLock::new(); + CRON_PARSER.get_or_init(|| { + CronParser::builder() + .seconds(croner::parser::Seconds::Required) + .dom_and_dow(true) + .build() + }) +} + /// Finds the next run occurence in UTC ms. fn find_next_occurrence( schedule: impl HasSchedule, ) -> anyhow::Result { let cron = match schedule.format() { - ScheduleFormat::Cron => croner::Cron::new(schedule.schedule()) - .with_seconds_required() - .with_dom_and_dow() - .parse() - .context("Failed to parse schedule CRON")?, + ScheduleFormat::Cron => cron_parser() + .parse(schedule.schedule()) + .context("Invalid CRON schedule")?, ScheduleFormat::English => { let cron = english_to_cron::str_cron_syntax(schedule.schedule()) @@ -305,13 +304,9 @@ fn find_next_occurrence( .take(6) .collect::>() .join(" "); - croner::Cron::new(&cron) - .with_seconds_required() - .with_dom_and_dow() - .parse() - .with_context(|| { - format!("Failed to parse schedule CRON: {cron}") - })? + cron_parser() + .parse(&cron) + .with_context(|| format!("English expression produced invalid CRON schedule | produced: {cron}"))? } }; let next = diff --git a/bin/core/src/stack/mod.rs b/bin/core/src/stack/mod.rs index 04d264063..a467fbe55 100644 --- a/bin/core/src/stack/mod.rs +++ b/bin/core/src/stack/mod.rs @@ -29,11 +29,11 @@ pub async fn get_stack_and_server( return Err(anyhow!("Stack has no server configured")); } - let (server, status) = + let (server, state) = get_server_with_state(&stack.config.server_id).await?; - if block_if_server_unreachable && status != ServerState::Ok { + if block_if_server_unreachable && state != ServerState::Ok { return Err(anyhow!( - "cannot send action when server is unreachable or disabled" + "Cannot send command when server is unreachable or disabled" )); } diff --git a/bin/core/src/stack/remote.rs b/bin/core/src/stack/remote.rs index 0861eda0b..a4fce3b89 100644 --- a/bin/core/src/stack/remote.rs +++ b/bin/core/src/stack/remote.rs @@ -40,10 +40,10 @@ pub async fn get_repo_compose_contents( for path in stack.file_paths() { let file_path = run_directory.join(path); - if !file_path.exists() { - if let Some(missing_files) = &mut missing_files { - missing_files.push(path.to_string()); - } + if !file_path.exists() + && let Some(missing_files) = &mut missing_files + { + missing_files.push(path.to_string()); } // If file does not exist, will show up in err case so the log is handled match fs::read_to_string(&file_path).with_context(|| { diff --git a/bin/core/src/stack/services.rs b/bin/core/src/stack/services.rs index 4ebd93df4..c0ef39359 100644 --- a/bin/core/src/stack/services.rs +++ b/bin/core/src/stack/services.rs @@ -29,8 +29,11 @@ pub fn extract_services_into_res( compose_contents: &str, res: &mut Vec, ) -> anyhow::Result<()> { - let compose = serde_yaml::from_str::(compose_contents) - .context("failed to parse service names from compose contents")?; + let compose = + serde_yaml_ng::from_str::(compose_contents) + .context( + "failed to parse service names from compose contents", + )?; let mut services = Vec::with_capacity(compose.services.capacity()); diff --git a/bin/core/src/startup.rs b/bin/core/src/startup.rs index 2dbd6aacc..5f301f79d 100644 --- a/bin/core/src/startup.rs +++ b/bin/core/src/startup.rs @@ -1,37 +1,114 @@ use std::str::FromStr; +use colored::Colorize; +use database::mungos::{ + find::find_collect, + mongodb::bson::{Document, doc, oid::ObjectId, to_document}, +}; use futures::future::join_all; use komodo_client::{ - api::write::{CreateBuilder, CreateServer}, + api::{ + auth::SignUpLocalUser, + execute::{ + BackupCoreDatabase, Execution, GlobalAutoUpdate, RunAction, + }, + write::{ + CreateBuilder, CreateProcedure, CreateServer, CreateTag, + UpdateResourceMeta, + }, + }, entities::{ ResourceTarget, builder::{PartialBuilderConfig, PartialServerBuilderConfig}, komodo_timestamp, + procedure::{EnabledExecution, ProcedureConfig, ProcedureStage}, server::{PartialServerConfig, Server}, sync::ResourceSync, + tag::TagColor, update::Log, - user::system_user, + user::{action_user, system_user}, }, }; -use mungos::{ - find::find_collect, - mongodb::bson::{Document, doc, oid::ObjectId, to_document}, -}; use resolver_api::Resolve; use crate::{ - api::write::WriteArgs, config::core_config, helpers::random_string, - resource, state::db_client, + api::{ + auth::AuthArgs, + execute::{ExecuteArgs, ExecuteRequest}, + write::WriteArgs, + }, + config::core_config, + helpers::update::init_execution_update, + network, resource, + state::db_client, }; +/// Runs the Actions with `run_at_startup: true` +pub async fn run_startup_actions() { + let startup_actions = match find_collect( + &db_client().actions, + doc! { "config.run_at_startup": true }, + None, + ) + .await + { + Ok(actions) => actions, + Err(e) => { + error!("Failed to fetch actions for startup | {e:#?}"); + return; + } + }; + + for action in startup_actions { + let name = action.name; + let id = action.id; + let update = match init_execution_update( + &ExecuteRequest::RunAction(RunAction { + action: name.clone(), + args: Default::default(), + }), + action_user(), + ) + .await + { + Ok(update) => update, + Err(e) => { + error!( + "Failed to initialize update for action {name} ({id}) | {e:#?}" + ); + continue; + } + }; + + if let Err(e) = (RunAction { + action: name.clone(), + args: Default::default(), + }) + .resolve(&ExecuteArgs { + user: action_user().to_owned(), + update, + }) + .await + { + error!( + "Failed to execute startup action {name} ({id}) | {e:#?}" + ); + } + } +} + /// This function should be run on startup, /// after the db client has been initialized pub async fn on_startup() { + // Configure manual network interface if specified + network::configure_internet_gateway().await; + tokio::join!( in_progress_update_cleanup(), open_alert_cleanup(), - ensure_first_server_and_builder(), clean_up_server_templates(), + ensure_first_server_and_builder(), + ensure_init_user_and_resources(), ); } @@ -120,10 +197,10 @@ async fn open_alert_cleanup() { /// Ensures a default server / builder exists with the defined address async fn ensure_first_server_and_builder() { - let first_server = &core_config().first_server; - if first_server.is_empty() { + let config = core_config(); + let Some(address) = config.first_server.clone() else { return; - } + }; let db = db_client(); let Ok(server) = db .servers @@ -137,9 +214,9 @@ async fn ensure_first_server_and_builder() { server } else { match (CreateServer { - name: format!("server-{}", random_string(5)), + name: config.first_server_name.clone(), config: PartialServerConfig { - address: Some(first_server.to_string()), + address: Some(address), enabled: Some(true), ..Default::default() }, @@ -165,7 +242,7 @@ async fn ensure_first_server_and_builder() { return; }; if let Err(e) = (CreateBuilder { - name: String::from("local"), + name: String::from("Local"), config: PartialBuilderConfig::Server( PartialServerBuilderConfig { server_id: Some(server.id), @@ -184,6 +261,161 @@ async fn ensure_first_server_and_builder() { } } +async fn ensure_init_user_and_resources() { + let db = db_client(); + + // Assumes if there are any existing users, procedures, or tags, + // the default procedures do not need to be set up. + let Ok((None, None, None)) = tokio::try_join!( + db.users.find_one(Document::new()), + db.procedures.find_one(Document::new()), + db.tags.find_one(Document::new()), + ).inspect_err(|e| error!("Failed to initialize default procedures | Failed to query db | {e:?}")) else { + return + }; + + let config = core_config(); + + // Init admin user if set in config. + if let Some(username) = &config.init_admin_username { + info!("Creating init admin user..."); + SignUpLocalUser { + username: username.clone(), + password: config.init_admin_password.clone(), + } + .resolve(&AuthArgs::default()) + .await + .expect("Failed to initialize default admin user.") + .jwt; + db.users + .find_one(doc! { "username": username }) + .await + .expect("Failed to query database for initial user") + .expect("Failed to find initial user after creation"); + }; + + if config.disable_init_resources { + info!("System resources init {}", "DISABLED".red()); + return; + } + + info!("Creating init system resources..."); + + let write_args = WriteArgs { + user: system_user().to_owned(), + }; + + // Create default 'system' tag + let default_tags = match (CreateTag { + name: String::from("system"), + color: Some(TagColor::Red), + }) + .resolve(&write_args) + .await + { + Ok(tag) => vec![tag.id], + Err(e) => { + warn!("Failed to create default tag | {:#}", e.error); + Vec::new() + } + }; + + // Backup Core Database + async { + let Ok(config) = ProcedureConfig::builder() + .stages(vec![ProcedureStage { + name: String::from("Stage 1"), + enabled: true, + executions: vec![ + EnabledExecution { + execution: Execution::BackupCoreDatabase(BackupCoreDatabase {}), + enabled: true + } + ] + }]) + .schedule(String::from("Every day at 01:00")) + .build() + .inspect_err(|e| error!("Failed to initialize backup core database procedure | Failed to build Procedure | {e:?}")) else { + return; + }; + let procedure = match (CreateProcedure { + name: String::from("Backup Core Database"), + config: config.into() + }).resolve(&write_args).await { + Ok(procedure) => procedure, + Err(e) => { + error!( + "Failed to initialize default database backup Procedure | Failed to create Procedure | {:#}", + e.error + ); + return; + } + }; + if let Err(e) = (UpdateResourceMeta { + target: ResourceTarget::Procedure(procedure.id), + tags: Some(default_tags.clone()), + description: Some(String::from( + "Triggers the Core database backup at the scheduled time.", + )), + template: None, + }).resolve(&write_args).await { + warn!("Failed to update default database backup Procedure tags / description | {:#}", e.error); + } + }.await; + + // GlobalAutoUpdate + async { + let Ok(config) = ProcedureConfig::builder() + .stages(vec![ProcedureStage { + name: String::from("Stage 1"), + enabled: true, + executions: vec![ + EnabledExecution { + execution: Execution::GlobalAutoUpdate(GlobalAutoUpdate {}), + enabled: true + } + ] + }]) + .schedule(String::from("Every day at 03:00")) + .build() + .inspect_err(|e| error!("Failed to initialize global auto update procedure | Failed to build Procedure | {e:?}")) else { + return; + }; + let procedure = match (CreateProcedure { + name: String::from("Global Auto Update"), + config: config.into(), + }) + .resolve(&write_args) + .await + { + Ok(procedure) => procedure, + Err(e) => { + error!( + "Failed to initialize global auto update Procedure | Failed to create Procedure | {:#}", + e.error + ); + return; + } + }; + if let Err(e) = (UpdateResourceMeta { + target: ResourceTarget::Procedure(procedure.id), + tags: Some(default_tags.clone()), + description: Some(String::from( + "Pulls and auto updates Stacks and Deployments using 'poll_for_updates' or 'auto_update'.", + )), + template: None, + }) + .resolve(&write_args) + .await + { + warn!( + "Failed to update global auto update Procedure tags / description | {:#}", + e.error + ); + } + }.await; +} + /// v1.17.5 removes the ServerTemplate resource. /// References to this resource type need to be cleaned up /// to avoid type errors reading from the database. diff --git a/bin/core/src/state.rs b/bin/core/src/state.rs index 14df4e726..454b3b392 100644 --- a/bin/core/src/state.rs +++ b/bin/core/src/state.rs @@ -5,6 +5,7 @@ use std::{ use anyhow::Context; use arc_swap::ArcSwap; +use database::Client; use komodo_client::entities::{ action::ActionState, build::BuildState, @@ -21,7 +22,6 @@ use octorust::auth::{ use crate::{ auth::jwt::JwtClient, config::core_config, - db::DbClient, helpers::{ action_state::ActionStates, all_resources::AllResourcesById, cache::Cache, @@ -32,16 +32,16 @@ use crate::{ }, }; -static DB_CLIENT: OnceLock = OnceLock::new(); +static DB_CLIENT: OnceLock = OnceLock::new(); -pub fn db_client() -> &'static DbClient { +pub fn db_client() -> &'static Client { DB_CLIENT .get() .expect("db_client accessed before initialized") } pub async fn init_db_client() { - let client = DbClient::new(&core_config().database) + let client = Client::new(&core_config().database) .await .context("failed to initialize database client") .unwrap(); @@ -134,11 +134,13 @@ pub fn action_states() -> &'static ActionStates { ACTION_STATES.get_or_init(ActionStates::default) } +/// Cache of ids to status pub type DeploymentStatusCache = Cache< String, Arc>, >; +/// Cache of ids to status pub fn deployment_status_cache() -> &'static DeploymentStatusCache { static DEPLOYMENT_STATUS_CACHE: OnceLock = OnceLock::new(); diff --git a/bin/core/src/sync/deploy.rs b/bin/core/src/sync/deploy.rs index 633f0fb48..ac3829d7a 100644 --- a/bin/core/src/sync/deploy.rs +++ b/bin/core/src/sync/deploy.rs @@ -181,7 +181,7 @@ pub async fn deploy_from_cache( "\n{}: finished after {} round{}", muted("INFO"), bold(round), - (round > 1).then_some("s").unwrap_or_default() + if round > 1 { "s" } else { Default::default() } )); logs.push(Log::simple("Sync Deploy", log)); diff --git a/bin/core/src/sync/execute.rs b/bin/core/src/sync/execute.rs index facfb7834..2c413db1b 100644 --- a/bin/core/src/sync/execute.rs +++ b/bin/core/src/sync/execute.rs @@ -1,12 +1,12 @@ use std::collections::HashMap; use anyhow::Context; +use database::mungos::find::find_collect; use formatting::{Color, bold, colored, muted}; use komodo_client::entities::{ ResourceTargetVariant, tag::Tag, toml::ResourceToml, update::Log, user::sync_user, }; -use mungos::find::find_collect; use partial_derive2::MaybeNone; use crate::{api::write::WriteArgs, resource::ResourceMetaUpdate}; diff --git a/bin/core/src/sync/file.rs b/bin/core/src/sync/file.rs index 64c3157e7..9b6aaf53a 100644 --- a/bin/core/src/sync/file.rs +++ b/bin/core/src/sync/file.rs @@ -206,8 +206,8 @@ fn read_resources_directory( contents: format_serror(&e.into()), }); }; - } else if path.is_dir() { - if let Err(e) = read_resources_directory( + } else if path.is_dir() + && let Err(e) = read_resources_directory( root_path, resource_path, curr_path, @@ -219,20 +219,20 @@ fn read_resources_directory( ) .with_context(|| { format!("failed to read resources from {path:?}") - }) { - file_errors.push(SyncFileContents { - resource_path: resource_path.display().to_string(), - path: curr_path.display().to_string(), - contents: format_serror(&e.into()), - }); - log.push('\n'); - log.push_str(&format!( - "{}: {} from {}", - colored("ERROR", Color::Red), - colored("adding resources", Color::Green), - colored(path.display(), Color::Blue) - )); - } + }) + { + file_errors.push(SyncFileContents { + resource_path: resource_path.display().to_string(), + path: curr_path.display().to_string(), + contents: format_serror(&e.into()), + }); + log.push('\n'); + log.push_str(&format!( + "{}: {} from {}", + colored("ERROR", Color::Red), + colored("adding resources", Color::Green), + colored(path.display(), Color::Blue) + )); } } Ok(()) diff --git a/bin/core/src/sync/mod.rs b/bin/core/src/sync/mod.rs index 7025fcd1e..fb59471ff 100644 --- a/bin/core/src/sync/mod.rs +++ b/bin/core/src/sync/mod.rs @@ -1,12 +1,12 @@ use std::{collections::HashMap, str::FromStr}; use anyhow::anyhow; +use database::mungos::mongodb::bson::oid::ObjectId; use komodo_client::entities::{ ResourceTargetVariant, tag::Tag, toml::{ResourceToml, ResourcesToml}, }; -use mungos::mongodb::bson::oid::ObjectId; use toml::ToToml; use crate::resource::KomodoResource; diff --git a/bin/core/src/sync/resources.rs b/bin/core/src/sync/resources.rs index e9038855c..018d43413 100644 --- a/bin/core/src/sync/resources.rs +++ b/bin/core/src/sync/resources.rs @@ -669,6 +669,9 @@ impl ResourceSyncTrait for Procedure { .map(|a| a.name.clone()) .unwrap_or_default(); } + Execution::ClearRepoCache(_) => {} + Execution::BackupCoreDatabase(_) => {} + Execution::GlobalAutoUpdate(_) => {} Execution::Sleep(_) => {} } } @@ -761,25 +764,24 @@ impl ExecuteResourceSync for Procedure { ) .await; } - if !resource.config.is_none() { - if let Err(e) = crate::resource::update::( + if !resource.config.is_none() + && let Err(e) = crate::resource::update::( id, resource.config.clone(), sync_user(), ) .await - { - if i == 9 { - has_error = true; - log.push_str(&format!( - "\n{}: failed to update {} '{}' | {e:#}", - colored("ERROR", Color::Red), - Self::resource_type(), - bold(&name) - )); - } - continue; + { + if i == 9 { + has_error = true; + log.push_str(&format!( + "\n{}: failed to update {} '{}' | {e:#}", + colored("ERROR", Color::Red), + Self::resource_type(), + bold(&name) + )); } + continue; } log.push_str(&format!( diff --git a/bin/core/src/sync/toml.rs b/bin/core/src/sync/toml.rs index 89b6db6b3..c414a3e43 100644 --- a/bin/core/src/sync/toml.rs +++ b/bin/core/src/sync/toml.rs @@ -28,6 +28,8 @@ pub const TOML_PRETTY_OPTIONS: toml_pretty::Options = toml_pretty::Options { tab: " ", skip_empty_string: true, + // Usually we do this, but has to be changed for some cases. + skip_empty_object: true, max_inline_array_length: 30, inline_array: false, }; @@ -786,7 +788,11 @@ impl ToToml for Procedure { .map(|a| &a.name) .unwrap_or(&String::new()), ), - Execution::Sleep(_) | Execution::None(_) => {} + Execution::None(_) + | Execution::Sleep(_) + | Execution::ClearRepoCache(_) + | Execution::BackupCoreDatabase(_) + | Execution::GlobalAutoUpdate(_) => {} } } } @@ -821,8 +827,13 @@ impl ToToml for Procedure { for stage in stages { toml.push_str("\n\n[[procedure.config.stage]]\n"); toml.push_str( - &toml_pretty::to_string(stage, TOML_PRETTY_OPTIONS) - .context("failed to serialize procedures to toml")?, + &toml_pretty::to_string( + stage, + // If the execution.params are fully missing, + // deserialization will fail. + TOML_PRETTY_OPTIONS.skip_empty_object(false), + ) + .context("failed to serialize procedures to toml")?, ); } } diff --git a/bin/core/src/sync/user_groups.rs b/bin/core/src/sync/user_groups.rs index 1a8f653e2..63f7ec9ad 100644 --- a/bin/core/src/sync/user_groups.rs +++ b/bin/core/src/sync/user_groups.rs @@ -3,6 +3,7 @@ use std::{ }; use anyhow::Context; +use database::mungos::find::find_collect; use formatting::{Color, bold, colored, muted}; use indexmap::{IndexMap, IndexSet}; use komodo_client::{ @@ -27,7 +28,6 @@ use komodo_client::{ user_group::UserGroup, }, }; -use mungos::find::find_collect; use resolver_api::Resolve; use serde::Serialize; diff --git a/bin/core/src/sync/variables.rs b/bin/core/src/sync/variables.rs index 556c5774f..8da24a013 100644 --- a/bin/core/src/sync/variables.rs +++ b/bin/core/src/sync/variables.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use anyhow::Context; +use database::mungos::find::find_collect; use formatting::{Color, bold, colored, muted}; use komodo_client::{ api::write::*, @@ -8,7 +9,6 @@ use komodo_client::{ sync::DiffData, update::Log, user::sync_user, variable::Variable, }, }; -use mungos::find::find_collect; use resolver_api::Resolve; use crate::{api::write::WriteArgs, state::db_client}; diff --git a/bin/core/src/sync/view.rs b/bin/core/src/sync/view.rs index 218ee19db..be6f59c25 100644 --- a/bin/core/src/sync/view.rs +++ b/bin/core/src/sync/view.rs @@ -1,13 +1,13 @@ use std::collections::HashMap; use anyhow::Context; +use database::mungos::find::find_collect; use komodo_client::entities::{ ResourceTargetVariant, sync::{DiffData, ResourceDiff}, tag::Tag, toml::ResourceToml, }; -use mungos::find::find_collect; use partial_derive2::MaybeNone; use super::ResourceSyncTrait; diff --git a/bin/periphery/Cargo.toml b/bin/periphery/Cargo.toml index 324ffdc92..f62bdedaa 100644 --- a/bin/periphery/Cargo.toml +++ b/bin/periphery/Cargo.toml @@ -23,12 +23,12 @@ interpolate.workspace = true formatting.workspace = true response.workspace = true command.workspace = true +config.workspace = true logger.workspace = true cache.workspace = true git.workspace = true # mogh serror = { workspace = true, features = ["axum"] } -merge_config_files.workspace = true async_timing_util.workspace = true derive_variants.workspace = true resolver_api.workspace = true @@ -39,9 +39,10 @@ tokio-stream.workspace = true portable-pty.workspace = true axum-server.workspace = true serde_json.workspace = true -serde_yaml.workspace = true +serde_yaml_ng.workspace = true tokio-util.workspace = true arc-swap.workspace = true +colored.workspace = true futures.workspace = true tracing.workspace = true bollard.workspace = true @@ -56,4 +57,4 @@ axum.workspace = true clap.workspace = true envy.workspace = true uuid.workspace = true -rand.workspace = true +rand.workspace = true \ No newline at end of file diff --git a/bin/periphery/aio.Dockerfile b/bin/periphery/aio.Dockerfile index 5b5b43341..db0468655 100644 --- a/bin/periphery/aio.Dockerfile +++ b/bin/periphery/aio.Dockerfile @@ -1,6 +1,6 @@ ## All in one, multi stage compile + runtime Docker build for your architecture. -FROM rust:1.87.0-bullseye AS builder +FROM rust:1.89.0-bullseye AS builder WORKDIR /builder COPY Cargo.toml Cargo.lock ./ @@ -15,7 +15,7 @@ RUN cargo build -p komodo_periphery --release # Final Image FROM debian:bullseye-slim -COPY ./bin/periphery/starship.toml /config/starship.toml +COPY ./bin/periphery/starship.toml /starship.toml COPY ./bin/periphery/debian-deps.sh . RUN sh ./debian-deps.sh && rm ./debian-deps.sh @@ -23,8 +23,8 @@ COPY --from=builder /builder/target/release/periphery /usr/local/bin/periphery EXPOSE 8120 +CMD [ "periphery" ] + LABEL org.opencontainers.image.source=https://github.com/moghtech/komodo LABEL org.opencontainers.image.description="Komodo Periphery" LABEL org.opencontainers.image.licenses=GPL-3.0 - -CMD [ "periphery" ] diff --git a/bin/periphery/debian-deps.sh b/bin/periphery/debian-deps.sh index d8812cf60..363a5f53c 100644 --- a/bin/periphery/debian-deps.sh +++ b/bin/periphery/debian-deps.sh @@ -23,6 +23,6 @@ rm -rf /var/lib/apt/lists/* # Starship prompt curl -sS https://starship.rs/install.sh | sh -s -- --yes --bin-dir /usr/local/bin -echo 'export STARSHIP_CONFIG=/config/starship.toml' >> /root/.bashrc +echo 'export STARSHIP_CONFIG=/starship.toml' >> /root/.bashrc echo 'eval "$(starship init bash)"' >> /root/.bashrc diff --git a/bin/periphery/multi-arch.Dockerfile b/bin/periphery/multi-arch.Dockerfile index 19a64c1b4..3751fafe9 100644 --- a/bin/periphery/multi-arch.Dockerfile +++ b/bin/periphery/multi-arch.Dockerfile @@ -12,7 +12,7 @@ FROM ${AARCH64_BINARIES} AS aarch64 FROM debian:bullseye-slim -COPY ./bin/periphery/starship.toml /config/starship.toml +COPY ./bin/periphery/starship.toml /starship.toml COPY ./bin/periphery/debian-deps.sh . RUN sh ./debian-deps.sh && rm ./debian-deps.sh @@ -27,8 +27,8 @@ RUN mv /app/arch/${TARGETPLATFORM} /usr/local/bin/periphery && rm -r /app/arch EXPOSE 8120 +CMD [ "periphery" ] + LABEL org.opencontainers.image.source=https://github.com/moghtech/komodo LABEL org.opencontainers.image.description="Komodo Periphery" LABEL org.opencontainers.image.licenses=GPL-3.0 - -CMD [ "periphery" ] \ No newline at end of file diff --git a/bin/periphery/single-arch.Dockerfile b/bin/periphery/single-arch.Dockerfile index f9e9343ee..586939ca0 100644 --- a/bin/periphery/single-arch.Dockerfile +++ b/bin/periphery/single-arch.Dockerfile @@ -8,7 +8,7 @@ FROM ${BINARIES_IMAGE} AS binaries FROM debian:bullseye-slim -COPY ./bin/periphery/starship.toml /config/starship.toml +COPY ./bin/periphery/starship.toml /starship.toml COPY ./bin/periphery/debian-deps.sh . RUN sh ./debian-deps.sh && rm ./debian-deps.sh @@ -16,8 +16,8 @@ COPY --from=binaries /periphery /usr/local/bin/periphery EXPOSE 8120 +CMD [ "periphery" ] + LABEL org.opencontainers.image.source=https://github.com/moghtech/komodo LABEL org.opencontainers.image.description="Komodo Periphery" LABEL org.opencontainers.image.licenses=GPL-3.0 - -CMD [ "periphery" ] \ No newline at end of file diff --git a/bin/periphery/src/api/build.rs b/bin/periphery/src/api/build.rs index a17e91104..b918afa81 100644 --- a/bin/periphery/src/api/build.rs +++ b/bin/periphery/src/api/build.rs @@ -96,12 +96,12 @@ impl Resolve for WriteDockerfileContentsToHost { .components() .collect::(); // Ensure parent directory exists - if let Some(parent) = full_path.parent() { - if !parent.exists() { - tokio::fs::create_dir_all(parent) - .await - .with_context(|| format!("Failed to initialize dockerfile parent directory {parent:?}"))?; - } + if let Some(parent) = full_path.parent() + && !parent.exists() + { + tokio::fs::create_dir_all(parent) + .await + .with_context(|| format!("Failed to initialize dockerfile parent directory {parent:?}"))?; } fs::write(&full_path, contents).await.with_context(|| { format!("Failed to write dockerfile contents to {full_path:?}") diff --git a/bin/periphery/src/api/compose.rs b/bin/periphery/src/api/compose.rs index 10e5e625a..dba988e12 100644 --- a/bin/periphery/src/api/compose.rs +++ b/bin/periphery/src/api/compose.rs @@ -103,8 +103,11 @@ impl Resolve for GetComposeLog { timestamps, } = self; let docker_compose = docker_compose(); - let timestamps = - timestamps.then_some(" --timestamps").unwrap_or_default(); + let timestamps = if timestamps { + " --timestamps" + } else { + Default::default() + }; let command = format!( "{docker_compose} -p {project} logs --tail {tail}{timestamps} {}", services.join(" ") @@ -126,8 +129,11 @@ impl Resolve for GetComposeLogSearch { } = self; let docker_compose = docker_compose(); let grep = log_grep(&terms, combinator, invert); - let timestamps = - timestamps.then_some(" --timestamps").unwrap_or_default(); + let timestamps = if timestamps { + " --timestamps" + } else { + Default::default() + }; let command = format!( "{docker_compose} -p {project} logs --tail 5000{timestamps} {} 2>&1 | {grep}", services.join(" ") @@ -269,7 +275,7 @@ impl Resolve for WriteCommitComposeContents { .join(&file_path); let msg = if let Some(username) = username { - format!("{}: Write Compose File", username) + format!("{username}: Write Compose File") } else { "Write Compose File".to_string() }; @@ -556,7 +562,7 @@ impl Resolve for ComposeUp { return Ok(res); } let compose = - serde_yaml::from_str::(&config_log.stdout) + serde_yaml_ng::from_str::(&config_log.stdout) .context("Failed to parse compose contents")?; // Record sanitized compose config output res.compose_config = Some(config_log.stdout); @@ -601,7 +607,7 @@ impl Resolve for ComposeUp { let build_extra_args = parse_extra_args(&stack.config.build_extra_args); let command = format!( - "{docker_compose} -p {project_name} -f {file_args}{env_file}{additional_env_files} build{build_extra_args}{service_args}", + "{docker_compose} -p {project_name} -f {file_args}{additional_env_files}{env_file} build{build_extra_args}{service_args}", ); let Some(log) = run_komodo_command_with_sanitization( "Compose Build", @@ -625,7 +631,7 @@ impl Resolve for ComposeUp { // Pull images before destroying to minimize downtime. // If this fails, do not continue. let command = format!( - "{docker_compose} -p {project_name} -f {file_args}{env_file}{additional_env_files} pull{service_args}", + "{docker_compose} -p {project_name} -f {file_args}{additional_env_files}{env_file} pull{service_args}", ); let log = run_komodo_command( "Compose Pull", @@ -653,7 +659,7 @@ impl Resolve for ComposeUp { // Run compose up let extra_args = parse_extra_args(&stack.config.extra_args); let command = format!( - "{docker_compose} -p {project_name} -f {file_args}{env_file}{additional_env_files} up -d{extra_args}{service_args}", + "{docker_compose} -p {project_name} -f {file_args}{additional_env_files}{env_file} up -d{extra_args}{service_args}", ); let Some(log) = run_komodo_command_with_sanitization( diff --git a/bin/periphery/src/api/container.rs b/bin/periphery/src/api/container.rs index b986ce90d..9e37e6f83 100644 --- a/bin/periphery/src/api/container.rs +++ b/bin/periphery/src/api/container.rs @@ -44,8 +44,11 @@ impl Resolve for GetContainerLog { tail, timestamps, } = self; - let timestamps = - timestamps.then_some(" --timestamps").unwrap_or_default(); + let timestamps = if timestamps { + " --timestamps" + } else { + Default::default() + }; let command = format!("docker logs {name} --tail {tail}{timestamps}"); Ok(run_komodo_command("Get container log", None, command).await) @@ -65,8 +68,11 @@ impl Resolve for GetContainerLogSearch { timestamps, } = self; let grep = log_grep(&terms, combinator, invert); - let timestamps = - timestamps.then_some(" --timestamps").unwrap_or_default(); + let timestamps = if timestamps { + " --timestamps" + } else { + Default::default() + }; let command = format!( "docker logs {name} --tail 5000{timestamps} 2>&1 | {grep}" ); diff --git a/bin/periphery/src/api/mod.rs b/bin/periphery/src/api/mod.rs index 50d467dac..d6baade29 100644 --- a/bin/periphery/src/api/mod.rs +++ b/bin/periphery/src/api/mod.rs @@ -182,7 +182,7 @@ impl Resolve for ListGitProviders { self, _: &Args, ) -> serror::Result> { - Ok(periphery_config().git_providers.clone()) + Ok(periphery_config().git_providers.0.clone()) } } @@ -196,7 +196,7 @@ impl Resolve for ListDockerRegistries { self, _: &Args, ) -> serror::Result> { - Ok(periphery_config().docker_registries.clone()) + Ok(periphery_config().docker_registries.0.clone()) } } diff --git a/bin/periphery/src/api/router.rs b/bin/periphery/src/api/router.rs index e425c55b7..5b122bb9a 100644 --- a/bin/periphery/src/api/router.rs +++ b/bin/periphery/src/api/router.rs @@ -1,5 +1,3 @@ -use std::net::SocketAddr; - use anyhow::{Context, anyhow}; use axum::{ Router, @@ -13,6 +11,7 @@ use axum::{ use derive_variants::ExtractVariant; use resolver_api::Resolve; use serror::{AddStatusCode, AddStatusCodeError, Json}; +use std::net::{IpAddr, SocketAddr}; use uuid::Uuid; use crate::config::periphery_config; @@ -124,7 +123,18 @@ async fn guard_request_by_ip( .context("could not get ConnectionInfo of request") .status_code(StatusCode::UNAUTHORIZED)?; let ip = socket_addr.ip(); - if periphery_config().allowed_ips.contains(&ip) { + + let ip_match = periphery_config().allowed_ips.iter().any(|net| { + net.contains(ip) + || match ip { + IpAddr::V4(ipv4) => { + net.contains(IpAddr::V6(ipv4.to_ipv6_mapped())) + } + IpAddr::V6(_) => net.contains(ip.to_canonical()), + } + }); + + if ip_match { Ok(next.run(req).await) } else { Err( diff --git a/bin/periphery/src/api/terminal.rs b/bin/periphery/src/api/terminal.rs index f1f98f311..4d1aff11d 100644 --- a/bin/periphery/src/api/terminal.rs +++ b/bin/periphery/src/api/terminal.rs @@ -193,14 +193,11 @@ async fn handle_terminal_websocket( // println!("Got ws read bytes - for resize"); if let Ok(dimensions) = serde_json::from_slice::(&bytes[1..]) + && let Err(e) = terminal.stdin.send(StdinMsg::Resize(dimensions)).await { - if let Err(e) = - terminal.stdin.send(StdinMsg::Resize(dimensions)).await - { - debug!("WS -> PTY channel send error: {e:}"); - terminal.cancel(); - break; - }; + debug!("WS -> PTY channel send error: {e:}"); + terminal.cancel(); + break; } } Some(Ok(Message::Text(text))) => { diff --git a/bin/periphery/src/build.rs b/bin/periphery/src/build.rs index b2bceb5e8..2f3e95dd3 100644 --- a/bin/periphery/src/build.rs +++ b/bin/periphery/src/build.rs @@ -27,12 +27,10 @@ pub async fn write_dockerfile( .collect::(); // Ensure parent directory exists - if let Some(parent) = full_dockerfile_path.parent() { - if !parent.exists() { - tokio::fs::create_dir_all(parent) - .await - .with_context(|| format!("Failed to initialize dockerfile parent directory {parent:?}"))?; - } + if let Some(parent) = full_dockerfile_path.parent() && !parent.exists() { + tokio::fs::create_dir_all(parent) + .await + .with_context(|| format!("Failed to initialize dockerfile parent directory {parent:?}"))?; } tokio::fs::write(&full_dockerfile_path, dockerfile).await.with_context(|| { diff --git a/bin/periphery/src/compose/up.rs b/bin/periphery/src/compose/up.rs index 8d9384c60..1450ddd1c 100644 --- a/bin/periphery/src/compose/up.rs +++ b/bin/periphery/src/compose/up.rs @@ -81,8 +81,7 @@ pub async fn maybe_login_registry( ) { if !stack.config.registry_provider.is_empty() && !stack.config.registry_account.is_empty() - { - if let Err(e) = docker_login( + && let Err(e) = docker_login( &stack.config.registry_provider, &stack.config.registry_account, registry_token.as_deref(), @@ -95,11 +94,10 @@ pub async fn maybe_login_registry( ) }) .context("Failed to login to image registry") - { - logs.push(Log::error( - "Login to Registry", - format_serror(&e.into()), - )); - } + { + logs.push(Log::error( + "Login to Registry", + format_serror(&e.into()), + )); } } diff --git a/bin/periphery/src/config.rs b/bin/periphery/src/config.rs index 064ad68a7..d67508265 100644 --- a/bin/periphery/src/config.rs +++ b/bin/periphery/src/config.rs @@ -1,12 +1,13 @@ -use std::sync::OnceLock; +use std::{path::PathBuf, sync::OnceLock}; use clap::Parser; +use colored::Colorize; +use config::ConfigLoader; use environment_file::maybe_read_list_from_file; use komodo_client::entities::{ config::periphery::{CliArgs, Env, PeripheryConfig}, logger::{LogConfig, LogLevel}, }; -use merge_config_files::parse_config_paths; pub fn periphery_config() -> &'static PeripheryConfig { static PERIPHERY_CONFIG: OnceLock = @@ -17,19 +18,41 @@ pub fn periphery_config() -> &'static PeripheryConfig { let args = CliArgs::parse(); let config_paths = args.config_path.unwrap_or(env.periphery_config_paths); + let config = if config_paths.is_empty() { + println!( + "{}: No config paths found, using default config", + "INFO".green(), + ); PeripheryConfig::default() } else { - parse_config_paths::( - config_paths, - args.config_keyword.unwrap_or(env.periphery_config_keywords), - args + (ConfigLoader { + paths: &config_paths + .iter() + .map(PathBuf::as_path) + .collect::>(), + match_wildcards: &args + .config_keyword + .unwrap_or(env.periphery_config_keywords) + .iter() + .map(String::as_str) + .collect::>(), + include_file_name: ".peripheryinclude", + merge_nested: args .merge_nested_config .unwrap_or(env.periphery_merge_nested_config), - args + extend_array: args .extend_config_arrays .unwrap_or(env.periphery_extend_config_arrays), - ) + debug_print: args + .log_level + .map(|level| { + level == tracing::Level::DEBUG + || level == tracing::Level::TRACE + }) + .unwrap_or_default(), + }) + .load() .expect("failed at parsing config from paths") }; @@ -69,6 +92,9 @@ pub fn periphery_config() -> &'static PeripheryConfig { pretty: env .periphery_logging_pretty .unwrap_or(config.logging.pretty), + location: env + .periphery_logging_location + .unwrap_or(config.logging.location), otlp_endpoint: env .periphery_logging_otlp_endpoint .unwrap_or(config.logging.otlp_endpoint), diff --git a/bin/periphery/src/docker/stats.rs b/bin/periphery/src/docker/stats.rs index 1fbb437d0..203d76df2 100644 --- a/bin/periphery/src/docker/stats.rs +++ b/bin/periphery/src/docker/stats.rs @@ -60,7 +60,14 @@ async fn update_container_stats() { pub async fn get_container_stats( container_name: Option, ) -> anyhow::Result> { - let format = "--format \"{{ json . }}\""; + let format = "--format '{\"BlockIO\":\"{{ .BlockIO }}\", \ + \"CPUPerc\":\"{{ .CPUPerc }}\", \ + \"ID\":\"{{ .ID }}\", \ + \"MemPerc\":\"{{ .MemPerc }}\", \ + \"MemUsage\":\"{{ .MemUsage }}\", \ + \"Name\":\"{{ .Name }}\", \ + \"NetIO\":\"{{ .NetIO }}\",\ + \"PIDs\":\"{{ .PIDs }}\"}'"; let container_name = match container_name { Some(name) => format!(" {name}"), None => "".to_string(), @@ -231,18 +238,29 @@ fn convert_memory_stats( } fn convert_network_stats( - network_stats: models::ContainerNetworkStats, -) -> ContainerNetworkStats { - ContainerNetworkStats { - rx_bytes: network_stats.rx_bytes, - rx_packets: network_stats.rx_packets, - rx_errors: network_stats.rx_errors, - rx_dropped: network_stats.rx_dropped, - tx_bytes: network_stats.tx_bytes, - tx_packets: network_stats.tx_packets, - tx_errors: network_stats.tx_errors, - tx_dropped: network_stats.tx_dropped, - endpoint_id: network_stats.endpoint_id, - instance_id: network_stats.instance_id, - } + network_stats: HashMap< + std::string::String, + models::ContainerNetworkStats, + >, +) -> HashMap { + network_stats + .into_iter() + .map(|(name, network_stats)| { + ( + name, + ContainerNetworkStats { + rx_bytes: network_stats.rx_bytes, + rx_packets: network_stats.rx_packets, + rx_errors: network_stats.rx_errors, + rx_dropped: network_stats.rx_dropped, + tx_bytes: network_stats.tx_bytes, + tx_packets: network_stats.tx_packets, + tx_errors: network_stats.tx_errors, + tx_dropped: network_stats.tx_dropped, + endpoint_id: network_stats.endpoint_id, + instance_id: network_stats.instance_id, + }, + ) + }) + .collect() } diff --git a/bin/periphery/src/git.rs b/bin/periphery/src/git.rs index 9d91c960a..7709bbd8d 100644 --- a/bin/periphery/src/git.rs +++ b/bin/periphery/src/git.rs @@ -43,50 +43,50 @@ pub async fn handle_post_repo_execution( let mut res = PeripheryRepoExecutionResponse { res, env_file_path }; - if let Some(on_clone) = on_clone { - if !on_clone.is_none() { - let path = res - .res - .path - .join(on_clone.path) - .components() - .collect::(); - if let Some(log) = run_komodo_command_with_sanitization( - "On Clone", - path.as_path(), - on_clone.command, - true, - &replacers, - ) - .await - { - res.res.logs.push(log); - if !all_logs_success(&res.res.logs) { - return Ok(res); - } + if let Some(on_clone) = on_clone + && !on_clone.is_none() + { + let path = res + .res + .path + .join(on_clone.path) + .components() + .collect::(); + if let Some(log) = run_komodo_command_with_sanitization( + "On Clone", + path.as_path(), + on_clone.command, + true, + &replacers, + ) + .await + { + res.res.logs.push(log); + if !all_logs_success(&res.res.logs) { + return Ok(res); } } } - if let Some(on_pull) = on_pull { - if !on_pull.is_none() { - let path = res - .res - .path - .join(on_pull.path) - .components() - .collect::(); - if let Some(log) = run_komodo_command_with_sanitization( - "On Pull", - path.as_path(), - on_pull.command, - true, - &replacers, - ) - .await - { - res.res.logs.push(log); - } + if let Some(on_pull) = on_pull + && !on_pull.is_none() + { + let path = res + .res + .path + .join(on_pull.path) + .components() + .collect::(); + if let Some(log) = run_komodo_command_with_sanitization( + "On Pull", + path.as_path(), + on_pull.command, + true, + &replacers, + ) + .await + { + res.res.logs.push(log); } } diff --git a/bin/periphery/src/helpers.rs b/bin/periphery/src/helpers.rs index 5ba096fdc..529714178 100644 --- a/bin/periphery/src/helpers.rs +++ b/bin/periphery/src/helpers.rs @@ -79,7 +79,7 @@ pub fn log_grep( combinator: SearchCombinator, invert: bool, ) -> String { - let maybe_invert = invert.then_some(" -v").unwrap_or_default(); + let maybe_invert = if invert { " -v" } else { Default::default() }; match combinator { SearchCombinator::Or => { format!("grep{maybe_invert} -E '{}'", terms.join("|")) diff --git a/bin/periphery/src/stats.rs b/bin/periphery/src/stats.rs index c066d6048..f130ed2b4 100644 --- a/bin/periphery/src/stats.rs +++ b/bin/periphery/src/stats.rs @@ -120,7 +120,7 @@ impl StatsClient { return false; } let path = d.mount_point(); - for mount in &config.exclude_disk_mounts { + for mount in config.exclude_disk_mounts.iter() { if path == mount { return false; } @@ -128,7 +128,7 @@ impl StatsClient { if config.include_disk_mounts.is_empty() { return true; } - for mount in &config.include_disk_mounts { + for mount in config.include_disk_mounts.iter() { if path == mount { return true; } diff --git a/bin/periphery/src/terminal.rs b/bin/periphery/src/terminal.rs index 1a820e32f..ede42e5ec 100644 --- a/bin/periphery/src/terminal.rs +++ b/bin/periphery/src/terminal.rs @@ -36,16 +36,16 @@ pub async fn create_terminal( ); let mut terminals = terminals().write().await; use TerminalRecreateMode::*; - if matches!(recreate, Never | DifferentCommand) { - if let Some(terminal) = terminals.get(&name) { - if terminal.command == command { - return Ok(()); - } else if matches!(recreate, Never) { - return Err(anyhow!( - "Terminal {name} already exists, but has command {} instead of {command}", - terminal.command - )); - } + if matches!(recreate, Never | DifferentCommand) + && let Some(terminal) = terminals.get(&name) + { + if terminal.command == command { + return Ok(()); + } else if matches!(recreate, Never) { + return Err(anyhow!( + "Terminal {name} already exists, but has command {} instead of {command}", + terminal.command + )); } } if let Some(prev) = terminals.insert( diff --git a/bin/util/Cargo.toml b/bin/util/Cargo.toml deleted file mode 100644 index 25e798f3c..000000000 --- a/bin/util/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "komodo_util" -version.workspace = true -edition.workspace = true -authors.workspace = true -license.workspace = true -repository.workspace = true -homepage.workspace = true - -[[bin]] -name = "util" -path = "src/main.rs" - -[dependencies] -tracing-subscriber.workspace = true -futures-util.workspace = true -dotenvy.workspace = true -tracing.workspace = true -anyhow.workspace = true -mungos.workspace = true -tokio.workspace = true -serde.workspace = true -envy.workspace = true \ No newline at end of file diff --git a/bin/util/src/copy_database.rs b/bin/util/src/copy_database.rs deleted file mode 100644 index 200f8fcbc..000000000 --- a/bin/util/src/copy_database.rs +++ /dev/null @@ -1,131 +0,0 @@ -use std::time::Duration; - -use anyhow::Context; -use futures_util::{TryStreamExt, future::join_all}; -use mungos::{ - init::MongoBuilder, - mongodb::{ - bson::{Document, RawDocumentBuf}, - options::InsertManyOptions, - }, -}; -use serde::Deserialize; - -#[derive(Deserialize)] -struct Env { - /// Provide the source mongo uri to copy from - source_uri: String, - /// Provide the source db name to copy from. - /// Default: komodo - #[serde(default = "default_db_name")] - source_db_name: String, - /// Provide the source mongo uri to copy to - target_uri: String, - /// Provide the target db name to copy to. - /// Default: komodo - #[serde(default = "default_db_name")] - target_db_name: String, - /// Give the target database some time to initialize. - #[serde(default = "default_startup_sleep_seconds")] - startup_sleep_seconds: u64, -} - -fn default_db_name() -> String { - String::from("komodo") -} - -fn default_startup_sleep_seconds() -> u64 { - 5 -} - -pub async fn main() -> anyhow::Result<()> { - let env = envy::from_env::()?; - - info!("Sleeping for {} seconds...", env.startup_sleep_seconds); - tokio::time::sleep(Duration::from_secs(env.startup_sleep_seconds)) - .await; - - info!("Copying database..."); - - let source_db = MongoBuilder::default() - .uri(env.source_uri) - .build() - .await - .context("Invalid SOURCE_URI")? - .database(&env.source_db_name); - let target_db = MongoBuilder::default() - .uri(env.target_uri) - .build() - .await - .context("Invalid SOURCE_URI")? - .database(&env.target_db_name); - - let mut handles = Vec::new(); - - for collection in source_db - .list_collection_names() - .await - .context("Failed to list collections on source db")? - { - let source = source_db.collection::(&collection); - let target = target_db.collection::(&collection); - - handles.push(tokio::spawn(async move { - let res = async { - let mut buffer = Vec::::new(); - let mut count = 0; - let mut cursor = source - .find(Document::new()) - .await - .context("Failed to query source collection")?; - while let Some(doc) = cursor - .try_next() - .await - .context("Failed to get next document")? - { - count += 1; - buffer.push(doc); - if buffer.len() >= 20_000 { - if let Err(e) = target - .insert_many(&buffer) - .with_options( - InsertManyOptions::builder().ordered(false).build(), - ) - .await - { - error!("Failed to flush document batch in {collection} collection | {e:#}"); - }; - buffer.clear(); - } - } - if !buffer.is_empty() { - target - .insert_many(&buffer) - .with_options( - InsertManyOptions::builder().ordered(false).build(), - ) - .await - .context("Failed to flush documents")?; - } - anyhow::Ok(count) - } - .await; - match res { - Ok(count) => { - if count > 0 { - info!("Finished copying {collection} collection | Copied {count}"); - } - } - Err(e) => { - error!("Failed to copy {collection} collection | {e:#}") - } - } - })); - } - - join_all(handles).await; - - info!("Finished copying database ✅"); - - Ok(()) -} diff --git a/bin/util/src/main.rs b/bin/util/src/main.rs deleted file mode 100644 index af9c2c478..000000000 --- a/bin/util/src/main.rs +++ /dev/null @@ -1,42 +0,0 @@ -#[macro_use] -extern crate tracing; - -use serde::Deserialize; - -mod copy_database; - -#[derive(Deserialize, Debug, Default)] -enum Mode { - #[default] - CopyDatabase, -} - -#[derive(Deserialize)] -struct Env { - mode: Mode, -} - -async fn app() -> anyhow::Result<()> { - dotenvy::dotenv().ok(); - tracing_subscriber::fmt::init(); - - let env = envy::from_env::()?; - - info!("Komodo Util version: v{}", env!("CARGO_PKG_VERSION")); - info!("Mode: {:?}", env.mode); - - match env.mode { - Mode::CopyDatabase => copy_database::main().await, - } -} - -#[tokio::main] -async fn main() -> anyhow::Result<()> { - let mut term_signal = tokio::signal::unix::signal( - tokio::signal::unix::SignalKind::terminate(), - )?; - tokio::select! { - res = tokio::spawn(app()) => res?, - _ = term_signal.recv() => Ok(()), - } -} diff --git a/client/core/rs/Cargo.toml b/client/core/rs/Cargo.toml index 1b5411786..22ed658a6 100644 --- a/client/core/rs/Cargo.toml +++ b/client/core/rs/Cargo.toml @@ -33,6 +33,7 @@ tokio-util.workspace = true thiserror.workspace = true typeshare.workspace = true indexmap.workspace = true +serde_qs.workspace = true futures.workspace = true reqwest.workspace = true tracing.workspace = true @@ -43,4 +44,5 @@ strum.workspace = true envy.workspace = true uuid.workspace = true clap.workspace = true -bson.workspace = true \ No newline at end of file +bson.workspace = true +ipnetwork.workspace = true \ No newline at end of file diff --git a/client/core/rs/src/api/auth.rs b/client/core/rs/src/api/auth.rs index c6ca3b20f..9b6419403 100644 --- a/client/core/rs/src/api/auth.rs +++ b/client/core/rs/src/api/auth.rs @@ -11,6 +11,8 @@ pub trait KomodoAuthRequest: HasResponse {} #[typeshare] #[derive(Serialize, Deserialize, Debug, Clone)] pub struct JwtResponse { + /// User ID for signed in user. + pub user_id: String, /// A token the user can use to authenticate their requests. pub jwt: String, } @@ -47,19 +49,20 @@ pub struct GetLoginOptionsResponse { // -/// Create a new local user account. Will fail if a user with the +/// Sign up a new local user account. Will fail if a user with the /// given username already exists. -/// Response: [CreateLocalUserResponse]. +/// Response: [SignUpLocalUserResponse]. /// -/// Note. This method is only available if the core api has `local_auth` enabled. +/// Note. This method is only available if the core api has `local_auth` enabled, +/// and if user registration is not disabled (after the first user). #[typeshare] #[derive( Serialize, Deserialize, Debug, Clone, Resolve, EmptyTraits, )] #[empty_traits(KomodoAuthRequest)] -#[response(CreateLocalUserResponse)] +#[response(SignUpLocalUserResponse)] #[error(serror::Error)] -pub struct CreateLocalUser { +pub struct SignUpLocalUser { /// The username for the new user. pub username: String, /// The password for the new user. @@ -67,9 +70,9 @@ pub struct CreateLocalUser { pub password: String, } -/// Response for [CreateLocalUser]. +/// Response for [SignUpLocalUser]. #[typeshare] -pub type CreateLocalUserResponse = JwtResponse; +pub type SignUpLocalUserResponse = JwtResponse; // diff --git a/client/core/rs/src/api/execute/action.rs b/client/core/rs/src/api/execute/action.rs index b5f8a2fb6..cee479cc7 100644 --- a/client/core/rs/src/api/execute/action.rs +++ b/client/core/rs/src/api/execute/action.rs @@ -1,10 +1,11 @@ +use anyhow::Context; use clap::Parser; use derive_empty_traits::EmptyTraits; use resolver_api::Resolve; use serde::{Deserialize, Serialize}; use typeshare::typeshare; -use crate::entities::update::Update; +use crate::entities::{JsonObject, update::Update}; use super::{BatchExecutionResponse, KomodoExecuteRequest}; @@ -26,6 +27,17 @@ use super::{BatchExecutionResponse, KomodoExecuteRequest}; pub struct RunAction { /// Id or name pub action: String, + + /// Custom arguments which are merged on top of the default arguments. + /// CLI Format: `"VAR1=val1&VAR2=val2"` + /// + /// Webhook-triggered actions use this to pass WEBHOOK_BRANCH and WEBHOOK_BODY. + #[clap(value_parser = args_parser)] + pub args: Option, +} + +fn args_parser(args: &str) -> anyhow::Result { + serde_qs::from_str(args).context("Failed to parse args") } /// Runs multiple Actions in parallel that match pattern. Response: [BatchExecutionResponse] diff --git a/client/core/rs/src/api/execute/build.rs b/client/core/rs/src/api/execute/build.rs index dadff102f..0efc0efb1 100644 --- a/client/core/rs/src/api/execute/build.rs +++ b/client/core/rs/src/api/execute/build.rs @@ -13,9 +13,16 @@ use super::{BatchExecutionResponse, KomodoExecuteRequest}; /// Runs the target build. Response: [Update]. /// /// 1. Get a handle to the builder. If using AWS builder, this means starting a builder ec2 instance. +/// /// 2. Clone the repo on the builder. If an `on_clone` commmand is given, it will be executed. +/// /// 3. Execute `docker build {...params}`, where params are determined using the builds configuration. -/// 4. If a dockerhub account is attached, the build will be pushed to that account. +/// +/// 4. If a docker registry is configured, the build will be pushed to the registry. +/// +/// 5. If using AWS builder, destroy the builder ec2 instance. +/// +/// 6. Deploy any Deployments with *Redeploy on Build* enabled. #[typeshare] #[derive( Debug, diff --git a/client/core/rs/src/api/execute/maintenance.rs b/client/core/rs/src/api/execute/maintenance.rs new file mode 100644 index 000000000..b57dc936c --- /dev/null +++ b/client/core/rs/src/api/execute/maintenance.rs @@ -0,0 +1,73 @@ +use clap::Parser; +use derive_empty_traits::EmptyTraits; +use resolver_api::Resolve; +use serde::{Deserialize, Serialize}; +use typeshare::typeshare; + +use crate::entities::update::Update; + +use super::KomodoExecuteRequest; + +/// Clears all repos from the Core repo cache. Admin only. +/// Response: [Update] +#[typeshare] +#[derive( + Debug, + Clone, + PartialEq, + Serialize, + Deserialize, + Resolve, + EmptyTraits, + Parser, +)] +#[empty_traits(KomodoExecuteRequest)] +#[response(Update)] +#[error(serror::Error)] +pub struct ClearRepoCache {} + +/// Backs up the Komodo Core database to compressed jsonl files. +/// Admin only. Response: [Update] +/// +/// Mount a folder to `/backups`, and Core will use it to create +/// timestamped database dumps, which can be restored using +/// the Komodo CLI. +/// +/// https://komo.do/docs/setup/backup +#[typeshare] +#[derive( + Debug, + Clone, + PartialEq, + Serialize, + Deserialize, + Resolve, + EmptyTraits, + Parser, +)] +#[empty_traits(KomodoExecuteRequest)] +#[response(Update)] +#[error(serror::Error)] +pub struct BackupCoreDatabase {} + +/// Trigger a global poll for image updateson Stacks and Deployments +/// with `poll_for_updates` or `auto_update` enabled. +/// Admin only. Response: [Update] +/// +/// 1. `docker compose pull` any Stacks / Deployments with `poll_for_updates` or `auto_update` enabled. This will pick up any available updates. +/// 2. Redeploy Stacks / Deployments that have updates found. +#[typeshare] +#[derive( + Debug, + Clone, + PartialEq, + Serialize, + Deserialize, + Resolve, + EmptyTraits, + Parser, +)] +#[empty_traits(KomodoExecuteRequest)] +#[response(Update)] +#[error(serror::Error)] +pub struct GlobalAutoUpdate {} diff --git a/client/core/rs/src/api/execute/mod.rs b/client/core/rs/src/api/execute/mod.rs index e3e0ee0fa..6b9d7e44c 100644 --- a/client/core/rs/src/api/execute/mod.rs +++ b/client/core/rs/src/api/execute/mod.rs @@ -9,6 +9,7 @@ mod action; mod alerter; mod build; mod deployment; +mod maintenance; mod procedure; mod repo; mod server; @@ -19,6 +20,7 @@ pub use action::*; pub use alerter::*; pub use build::*; pub use deployment::*; +pub use maintenance::*; pub use procedure::*; pub use repo::*; pub use server::*; @@ -58,19 +60,27 @@ pub enum Execution { None(NoData), // ACTION + /// Run the target action. (alias: `action`, `ac`) + #[clap(alias = "action", alias = "ac")] RunAction(RunAction), BatchRunAction(BatchRunAction), // PROCEDURE + /// Run the target procedure. (alias: `procedure`, `pr`) + #[clap(alias = "procedure", alias = "pr")] RunProcedure(RunProcedure), BatchRunProcedure(BatchRunProcedure), // BUILD + /// Run the target build. (alias: `build`, `bd`) + #[clap(alias = "build", alias = "bd")] RunBuild(RunBuild), BatchRunBuild(BatchRunBuild), CancelBuild(CancelBuild), // DEPLOYMENT + /// Deploy the target deployment. (alias: `dp`) + #[clap(alias = "dp")] Deploy(Deploy), BatchDeploy(BatchDeploy), PullDeployment(PullDeployment), @@ -83,6 +93,8 @@ pub enum Execution { BatchDestroyDeployment(BatchDestroyDeployment), // REPO + /// Clone the target repo + #[clap(alias = "clone")] CloneRepo(CloneRepo), BatchCloneRepo(BatchCloneRepo), PullRepo(PullRepo), @@ -117,10 +129,16 @@ pub enum Execution { PruneSystem(PruneSystem), // SYNC + /// Execute a Resource Sync. (alias: `sync`) + #[clap(alias = "sync")] RunSync(RunSync), + /// Commit a Resource Sync. (alias: `commit`) + #[clap(alias = "commit")] CommitSync(CommitSync), // This is a special case, its actually a write operation. // STACK + /// Deploy the target stack. (alias: `stack`, `st`) + #[clap(alias = "stack", alias = "st")] DeployStack(DeployStack), BatchDeployStack(BatchDeployStack), DeployStackIfChanged(DeployStackIfChanged), @@ -138,10 +156,16 @@ pub enum Execution { // ALERTER TestAlerter(TestAlerter), + // MAINTENANCE + ClearRepoCache(ClearRepoCache), + BackupCoreDatabase(BackupCoreDatabase), + GlobalAutoUpdate(GlobalAutoUpdate), + // SLEEP Sleep(Sleep), } +/// Sleeps for the specified time. #[typeshare] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Parser)] pub struct Sleep { diff --git a/client/core/rs/src/api/read/mod.rs b/client/core/rs/src/api/read/mod.rs index cafb88e6e..f2884eac1 100644 --- a/client/core/rs/src/api/read/mod.rs +++ b/client/core/rs/src/api/read/mod.rs @@ -108,6 +108,8 @@ pub struct GetCoreInfoResponse { pub github_webhook_owners: Vec, /// Whether to disable websocket automatic reconnect. pub disable_websocket_reconnect: bool, + /// Whether to enable fancy toml highlighting. + pub enable_fancy_toml: bool, /// TZ identifier Core is using, if manually set. pub timezone: String, } diff --git a/client/core/rs/src/api/write/tags.rs b/client/core/rs/src/api/write/tags.rs index ceac77317..ec38f1f2e 100644 --- a/client/core/rs/src/api/write/tags.rs +++ b/client/core/rs/src/api/write/tags.rs @@ -20,6 +20,8 @@ use super::KomodoWriteRequest; pub struct CreateTag { /// The name of the tag. pub name: String, + /// Tag color. Default: Slate. + pub color: Option, } // diff --git a/client/core/rs/src/api/write/user.rs b/client/core/rs/src/api/write/user.rs index 991db9aad..91f9de5bc 100644 --- a/client/core/rs/src/api/write/user.rs +++ b/client/core/rs/src/api/write/user.rs @@ -69,6 +69,31 @@ pub type DeleteUserResponse = User; // +/// **Admin only.** Create a local user. +/// Response: [User]. +/// +/// Note. Not to be confused with /auth/SignUpLocalUser. +/// This method requires admin user credentials, and can +/// bypass disabled user registration. +#[typeshare] +#[derive( + Serialize, Deserialize, Debug, Clone, Resolve, EmptyTraits, +)] +#[empty_traits(KomodoWriteRequest)] +#[response(CreateLocalUserResponse)] +#[error(serror::Error)] +pub struct CreateLocalUser { + /// The username for the local user. + pub username: String, + /// A password for the local user. + pub password: String, +} + +#[typeshare] +pub type CreateLocalUserResponse = User; + +// + /// **Admin only.** Create a service user. /// Response: [User]. #[typeshare] diff --git a/client/core/rs/src/deserializers/forgiving_vec.rs b/client/core/rs/src/deserializers/forgiving_vec.rs new file mode 100644 index 000000000..06906612a --- /dev/null +++ b/client/core/rs/src/deserializers/forgiving_vec.rs @@ -0,0 +1,95 @@ +use serde::{ + __private::de::{Content, ContentDeserializer}, + Deserialize, Deserializer, + de::{IntoDeserializer, Visitor}, +}; + +#[derive(Debug, Clone)] +pub struct ForgivingVec(pub Vec); + +impl ForgivingVec { + pub fn iter(&self) -> std::slice::Iter<'_, T> { + self.0.iter() + } + + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } +} + +impl Default for ForgivingVec { + fn default() -> Self { + ForgivingVec(Vec::new()) + } +} + +impl IntoIterator for ForgivingVec { + type Item = T; + type IntoIter = as IntoIterator>::IntoIter; + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + +impl FromIterator for ForgivingVec { + fn from_iter>(iter: I) -> Self { + Self(Vec::from_iter(iter)) + } +} + +impl<'de, T: Deserialize<'de>> Deserialize<'de> for ForgivingVec { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_seq(ForgivingVecVisitor::( + std::marker::PhantomData, + )) + } +} + +struct ForgivingVecVisitor(std::marker::PhantomData); + +impl<'de, T: Deserialize<'de>> Visitor<'de> + for ForgivingVecVisitor +{ + type Value = ForgivingVec; + + fn expecting( + &self, + formatter: &mut std::fmt::Formatter, + ) -> std::fmt::Result { + write!(formatter, "Vec") + } + + fn visit_seq(self, mut seq: S) -> Result + where + S: serde::de::SeqAccess<'de>, + { + let mut res = + Vec::with_capacity(seq.size_hint().unwrap_or_default()); + loop { + match seq.next_element::() { + Ok(Some(content)) => { + match T::deserialize::>( + content.clone().into_deserializer(), + ) { + Ok(item) => res.push(item), + Err(e) => { + // Since this is used to parse startup config (including logging config), + // the tracing logging is not initialized. Need to use eprintln. + eprintln!( + "WARN: failed to parse item in list | {content:?} | {e:?}", + ) + } + } + } + Ok(None) => break, + Err(e) => { + eprintln!("WARN: failed to get item in list | {e:?}"); + } + } + } + Ok(ForgivingVec(res)) + } +} diff --git a/client/core/rs/src/deserializers/mod.rs b/client/core/rs/src/deserializers/mod.rs index 962997e3e..65d4ece89 100644 --- a/client/core/rs/src/deserializers/mod.rs +++ b/client/core/rs/src/deserializers/mod.rs @@ -3,6 +3,7 @@ mod conversion; mod environment; mod file_contents; +mod forgiving_vec; mod labels; mod maybe_string_i64; mod permission; @@ -12,6 +13,7 @@ mod term_signal_labels; pub use conversion::*; pub use environment::*; pub use file_contents::*; +pub use forgiving_vec::*; pub use labels::*; pub use maybe_string_i64::*; pub use string_list::*; diff --git a/client/core/rs/src/entities/action.rs b/client/core/rs/src/entities/action.rs index 8ff04988e..46d23b1f6 100644 --- a/client/core/rs/src/entities/action.rs +++ b/client/core/rs/src/entities/action.rs @@ -10,7 +10,7 @@ use crate::{ deserializers::{ file_contents_deserializer, option_file_contents_deserializer, }, - entities::{I64, NoData}, + entities::{FileFormat, I64, NoData}, }; use super::{ @@ -38,7 +38,17 @@ pub struct ActionListItemInfo { #[typeshare] #[derive( - Debug, Clone, Copy, Default, Serialize, Deserialize, Display, + Debug, + Clone, + Copy, + Default, + PartialEq, + Eq, + PartialOrd, + Ord, + Display, + Serialize, + Deserialize, )] pub enum ActionState { /// Unknown case @@ -63,6 +73,12 @@ pub type _PartialActionConfig = PartialActionConfig; #[partial_derive(Serialize, Deserialize, Debug, Clone, Default)] #[partial(skip_serializing_none, from, diff)] pub struct ActionConfig { + /// Whether this action should run at startup. + #[serde(default = "default_run_at_startup")] + #[builder(default = "default_run_at_startup()")] + #[partial_default(default_run_at_startup())] + pub run_at_startup: bool, + /// Choose whether to specify schedule as regular CRON, or using the english to CRON parser. #[serde(default)] #[builder(default)] @@ -140,6 +156,21 @@ pub struct ActionConfig { ))] #[builder(default)] pub file_contents: String, + + /// Specify the format in which the arguments are defined. + /// Default: `key_value` (like environment) + #[serde(default)] + #[builder(default)] + pub arguments_format: FileFormat, + + /// Default arguments to give to the Action for use in the script at `ARGS`. + #[serde(default, deserialize_with = "file_contents_deserializer")] + #[partial_attr(serde( + default, + deserialize_with = "option_file_contents_deserializer" + ))] + #[builder(default)] + pub arguments: String, } fn default_schedule_enabled() -> bool { @@ -154,6 +185,10 @@ fn default_failure_alert() -> bool { true } +fn default_run_at_startup() -> bool { + false +} + fn default_webhook_enabled() -> bool { true } @@ -171,12 +206,15 @@ impl Default for ActionConfig { schedule: Default::default(), schedule_enabled: default_schedule_enabled(), schedule_timezone: Default::default(), + run_at_startup: default_run_at_startup(), schedule_alert: default_schedule_alert(), failure_alert: default_failure_alert(), webhook_enabled: default_webhook_enabled(), webhook_secret: Default::default(), reload_deno_deps: Default::default(), + arguments_format: Default::default(), file_contents: Default::default(), + arguments: Default::default(), } } } diff --git a/client/core/rs/src/entities/alerter.rs b/client/core/rs/src/entities/alerter.rs index 1bde3e84f..bbbd23c3a 100644 --- a/client/core/rs/src/entities/alerter.rs +++ b/client/core/rs/src/entities/alerter.rs @@ -100,14 +100,18 @@ impl Default for AlerterConfig { Debug, Clone, PartialEq, Serialize, Deserialize, EnumVariants, )] #[variant_derive( - Serialize, - Deserialize, Debug, Clone, Copy, + PartialEq, + Eq, + PartialOrd, + Ord, Display, EnumString, - AsRefStr + AsRefStr, + Serialize, + Deserialize )] #[serde(tag = "type", content = "params")] pub enum AlerterEndpoint { diff --git a/client/core/rs/src/entities/build.rs b/client/core/rs/src/entities/build.rs index 5bb5faafc..af7eb6a91 100644 --- a/client/core/rs/src/entities/build.rs +++ b/client/core/rs/src/entities/build.rs @@ -68,15 +68,25 @@ pub struct BuildListItemInfo { #[typeshare] #[derive( - Debug, Clone, Copy, Default, Serialize, Deserialize, Display, + Debug, + Clone, + Copy, + Default, + PartialEq, + Eq, + PartialOrd, + Ord, + Serialize, + Deserialize, + Display, )] pub enum BuildState { + /// Currently building + Building, /// Last build successful (or never built) Ok, /// Last build failed Failed, - /// Currently building - Building, /// Other case #[default] Unknown, diff --git a/client/core/rs/src/entities/config/cli/args/container.rs b/client/core/rs/src/entities/config/cli/args/container.rs new file mode 100644 index 000000000..72aefaf95 --- /dev/null +++ b/client/core/rs/src/entities/config/cli/args/container.rs @@ -0,0 +1,72 @@ +#[derive(Debug, Clone, clap::Parser)] +pub struct Container { + /// Other container utilities + #[command(subcommand)] + pub command: Option, + /// List all containers, including stopped ones. + /// This overrides 'down'. + #[arg(long, short = 'a', default_value_t = false)] + pub all: bool, + /// Reverse the ordering of results, + /// so non-running containers are listed first if --all is passed. + #[arg(long, short = 'r', default_value_t = false)] + pub reverse: bool, + /// List only non-running containers. + #[arg(long, short = 'd', default_value_t = false)] + pub down: bool, + /// Include links. Makes the table very large. + #[arg(long, short = 'l', default_value_t = false)] + pub links: bool, + /// Filter containers by a particular server. + /// Supports wildcard syntax. + /// Can be specified multiple times. (alias `s`) + #[arg(name = "server", long, short = 's')] + pub servers: Vec, + /// Filter containers by a name. Supports wildcard syntax. + /// Can be specified multiple times. (alias `c`) + #[arg(name = "container", long, short = 'c')] + pub containers: Vec, + /// Filter containers by image. Supports wildcard syntax. + /// Can be specified multiple times. (alias `i`) + #[arg(name = "image", long, short = 'i')] + pub images: Vec, + /// Filter containers by image. Supports wildcard syntax. + /// Can be specified multiple times. (alias `--net`, `n`) + #[arg(name = "network", alias = "net", long, short = 'n')] + pub networks: Vec, + /// Specify the format of the output. + #[arg(long, short = 'f', default_value_t = super::CliFormat::Table)] + pub format: super::CliFormat, +} + +#[derive(Debug, Clone, clap::Subcommand)] +pub enum ContainerCommand { + /// Inspect containers + #[clap(alias = "i")] + Inspect(InspectContainer), +} + +#[derive(Debug, Clone, clap::Parser)] +pub struct InspectContainer { + /// The container name. If it matches multiple containers and no server is specified, + /// each container's inspect info will be logged. + pub container: String, + /// Select the particular server that container is on. + #[arg(name = "server", long, short = 's')] + pub servers: Vec, + /// Only show the .State part of the inspect response. + #[arg(long, short = 'u')] + pub state: bool, + /// Only show the .Mounts part of the inspect response. + #[arg(long, short = 'm')] + pub mounts: bool, + /// Only show the .HostConfig part of the inspect response. + #[arg(long, short = 'f')] + pub host_config: bool, + /// Only show the .Config part of the inspect response. + #[arg(long, short = 'c')] + pub config: bool, + /// Only show the .NetworkSettings part of the inspect response. + #[arg(long, short = 'n')] + pub network_settings: bool, +} diff --git a/client/core/rs/src/entities/config/cli/args/database.rs b/client/core/rs/src/entities/config/cli/args/database.rs new file mode 100644 index 000000000..1fe2cf556 --- /dev/null +++ b/client/core/rs/src/entities/config/cli/args/database.rs @@ -0,0 +1,73 @@ +use std::path::PathBuf; + +#[derive(Debug, Clone, clap::Subcommand)] +pub enum DatabaseCommand { + /// Triggers database backup to compressed files + /// organized by time the backup was taken. (alias: `bkp`) + #[clap(alias = "bkp")] + Backup { + /// Optionally provide a specific backups folder. + /// Default: `/backups` + #[arg(long, short = 'f')] + backups_folder: Option, + /// Always continue on user confirmation prompts. + #[arg(long, short = 'y', default_value_t = false)] + yes: bool, + }, + /// Restores the database from backup files. (alias: `rst`) + #[clap(alias = "rst")] + Restore { + /// Optionally provide a specific backups folder. + /// Default: `/backups` + #[arg(long, short = 'f')] + backups_folder: Option, + /// Optionally provide a specific restore folder. + /// If not provided, will use the most recent backup folder. + /// + /// Example: `2025-08-01_05-04-53` + #[arg(long, short = 'r')] + restore_folder: Option, + /// Whether to index the target database. Default: true + #[arg(long, short = 'i', default_value_t = true)] + index: bool, + /// Always continue on user confirmation prompts. + #[arg(long, short = 'y', default_value_t = false)] + yes: bool, + }, + /// Prunes database backups if there are greater than + /// the configured `max_backups` (KOMODO_CLI_MAX_BACKUPS). + Prune { + /// Optionally provide a specific backups folder. + /// Default: `/backups` + #[arg(long, short = 'f')] + backups_folder: Option, + /// Always continue on user confirmation prompts. + #[arg(long, short = 'y', default_value_t = false)] + yes: bool, + }, + /// Copy the database to another running database. (alias: `cp`) + #[clap(alias = "cp")] + Copy { + /// The target database uri to copy to. + #[arg(long)] + uri: Option, + /// The target database address to copy to + #[arg(long, short = 'a')] + address: Option, + /// The target database username + #[arg(long, short = 'u')] + username: Option, + /// The target database password + #[arg(long, short = 'p')] + password: Option, + /// The target db name to copy to. + #[arg(long, short = 'd')] + db_name: Option, + /// Whether to index the target database. Default: true + #[arg(long, short = 'i', default_value_t = true)] + index: bool, + /// Always continue on user confirmation prompts. + #[arg(long, short = 'y', default_value_t = false)] + yes: bool, + }, +} diff --git a/client/core/rs/src/entities/config/cli/args/list.rs b/client/core/rs/src/entities/config/cli/args/list.rs new file mode 100644 index 000000000..be124eb0b --- /dev/null +++ b/client/core/rs/src/entities/config/cli/args/list.rs @@ -0,0 +1,161 @@ +use crate::entities::resource::TemplatesQueryBehavior; + +#[derive(Debug, Clone, clap::Parser)] +pub struct List { + /// List specific resources + #[command(subcommand)] + pub command: Option, + /// List all resources, including down ones. + #[arg(long, short = 'a', default_value_t = false)] + pub all: bool, + /// Reverse the ordering of results, + /// so non-running containers are listed first if --all is passed. + #[arg(long, short = 'r', default_value_t = false)] + pub reverse: bool, + /// List only non-running / non-ok resources. + #[arg(long, short = 'd', default_value_t = false)] + pub down: bool, + /// List only "in progress" / "pending" resources, like Actions / Procedures that are running (alias: `pending`) + #[arg( + long, + short = 'p', + alias = "pending", + default_value_t = false + )] + pub in_progress: bool, + /// Include links. Makes the table very large. + #[arg(long, short = 'l', default_value_t = false)] + pub links: bool, + /// Whether to include resources marked as templates in results. Default: 'exclude'. + #[arg( + long, + short = 'm', + default_value_t = TemplatesQueryBehavior::Exclude, + )] + pub templates: TemplatesQueryBehavior, + /// Filter by a particular name. Supports wildcard. + /// Can be specified multiple times. (alias `n`) + #[arg(name = "name", long, short = 'n')] + pub names: Vec, + /// Filter by a particular tag. + /// Can be specified multiple times. (alias `t`) + #[arg(name = "tag", long, short = 't')] + pub tags: Vec, + /// Filter by a particular server. Supports wildcard. + /// Can be specified multiple times. (alias `s`) + #[arg(name = "server", long, short = 's')] + pub servers: Vec, + /// Filter by a particular builder. Supports wildcard. + /// Can be specified multiple times. (alias `b`) + #[arg(name = "builder", long, short = 'b')] + pub builders: Vec, + /// Specify the format of the output. + #[arg(long, short = 'f', default_value_t = super::CliFormat::Table)] + pub format: super::CliFormat, +} + +impl From for ResourceFilters { + fn from(value: List) -> Self { + Self { + all: value.all, + reverse: value.reverse, + down: value.down, + in_progress: value.in_progress, + links: value.links, + templates: value.templates, + names: value.names, + tags: value.tags, + servers: value.servers, + builders: value.builders, + format: value.format, + } + } +} + +#[derive(Debug, Clone, clap::Subcommand)] +pub enum ListCommand { + /// List Servers (aliases: `server`, `sv`) + #[clap(alias = "server", alias = "sv")] + Servers(ResourceFilters), + /// List Stacks (aliases: `stack`, `st`) + #[clap(alias = "stack", alias = "st")] + Stacks(ResourceFilters), + /// List Deployments (aliases: `deployment`, `dp`) + #[clap(alias = "deployment", alias = "dp")] + Deployments(ResourceFilters), + /// List Builds (aliases: `build`, `bd`) + #[clap(alias = "build", alias = "bd")] + Builds(ResourceFilters), + /// List Repos (aliases: `repo`, `rp`) + #[clap(alias = "repo", alias = "rp")] + Repos(ResourceFilters), + /// List Procedures (aliases: `procedure`, `pr`) + #[clap(alias = "procedure", alias = "pr")] + Procedures(ResourceFilters), + /// List Actions (aliases: `action`, `ac`) + #[clap(alias = "action", alias = "ac")] + Actions(ResourceFilters), + /// List Syncs (aliases: `sync`, `sn`) + #[clap(alias = "sync", alias = "sn")] + Syncs(ResourceFilters), + /// List scheduled Procedures / Actions (aliases: `sched`, `sc`) + #[clap(alias = "sched", alias = "sc")] + Schedules(ResourceFilters), + /// List Builders (aliases: `builder`, `bldr`) + #[clap(alias = "builder", alias = "bldr")] + Builders(ResourceFilters), + /// List Alerters (aliases: `alerter`, `alrt`) + #[clap(alias = "alerter", alias = "alrt")] + Alerters(ResourceFilters), +} + +#[derive(Debug, Clone, clap::Parser)] +pub struct ResourceFilters { + /// List all resources, including down ones. + #[arg(long, short = 'a', default_value_t = false)] + pub all: bool, + /// Reverse the ordering of results, + /// so non-running containers are listed first if --all is passed. + #[arg(long, short = 'r', default_value_t = false)] + pub reverse: bool, + /// List only non-running / non-ok resources. + #[arg(long, short = 'd', default_value_t = false)] + pub down: bool, + /// List only "in progress" / "pending" resources, like Actions / Procedures that are running (alias: `pending`) + #[arg( + long, + short = 'p', + alias = "pending", + default_value_t = false + )] + pub in_progress: bool, + /// Include links. Makes the table very large. + #[arg(long, short = 'l', default_value_t = false)] + pub links: bool, + /// Whether to include resources marked as templates in results. Default: 'exclude'. + #[arg( + long, + short = 'm', + default_value_t = TemplatesQueryBehavior::Exclude, + )] + pub templates: TemplatesQueryBehavior, + /// Filter by a particular name. Supports wildcard. + /// Can be specified multiple times. (alias `n`) + #[arg(name = "name", long, short = 'n')] + pub names: Vec, + /// Filter by a particular tag. + /// Can be specified multiple times. (alias `t`) + #[arg(name = "tag", long, short = 't')] + pub tags: Vec, + /// Filter by a particular server. Supports wildcard. + /// Can be specified multiple times. (alias `s`) + #[arg(name = "server", long, short = 's')] + pub servers: Vec, + /// Filter by a particular builder. Supports wildcard. + /// Can be specified multiple times. (alias `b`) + #[arg(name = "builder", long, short = 'b')] + pub builders: Vec, + /// Specify the format of the output. + #[arg(long, short = 'f', default_value_t = super::CliFormat::Table)] + pub format: super::CliFormat, +} diff --git a/client/core/rs/src/entities/config/cli/args/mod.rs b/client/core/rs/src/entities/config/cli/args/mod.rs new file mode 100644 index 000000000..03b3bc000 --- /dev/null +++ b/client/core/rs/src/entities/config/cli/args/mod.rs @@ -0,0 +1,138 @@ +//! Module for parsing the Komodo CLI arguments + +use std::path::PathBuf; + +use crate::api::execute::Execution; + +pub mod container; +pub mod database; +pub mod list; +pub mod update; + +#[derive(Debug, clap::Parser)] +#[command(name = "komodo-cli", version, about = "", author)] +pub struct CliArgs { + /// The command to run + #[command(subcommand)] + pub command: Command, + + /// Choose a custom [[profile]] name / alias set in a `komodo.cli.toml` file. + #[arg(long, short = 'p')] + pub profile: Option, + + /// Sets the path of a config file or directory to use. + /// Can use multiple times + #[arg(long, short = 'c')] + pub config_path: Option>, + + /// Sets the keywords to match directory cli config file names on. + /// Supports wildcard syntax. + /// Can use multiple times to match multiple patterns independently. + #[arg(long, short = 'm')] + pub config_keyword: Option>, + + /// Whether to debug print on configuration load (on startup) + #[arg(alias = "debug", long, short = 'd')] + pub debug_startup: Option, +} + +#[derive(Debug, Clone, clap::Subcommand)] +pub enum Command { + /// Print the CLI config being used. (aliases: `cfg`, `cf`) + #[clap(alias = "cfg", alias = "cf")] + Config { + /// Whether to print the additional profiles picked up + #[arg(long, short = 'a', default_value_t = false)] + all_profiles: bool, + + /// Whether to print unsanitized config, + /// including sensitive credentials. + #[arg(long, action)] + unsanitized: bool, + }, + + /// Container info (aliases: `ps`, `cn`, `containers`) + #[clap(alias = "ps", alias = "cn", alias = "containers")] + Container(container::Container), + + /// Inspect containers (alias: `i`) + #[clap(alias = "i")] + Inspect(container::InspectContainer), + + /// List Komodo resources (aliases: `ls`, `resources`) + #[clap(alias = "ls", alias = "resources")] + List(list::List), + + /// Run Komodo executions. (aliases: `x`, `run`, `deploy`, `dep`) + #[clap(alias = "x", alias = "run", alias = "deploy", alias = "dep")] + Execute(Execute), + + /// Update resource configuration. (alias: `set`) + #[clap(alias = "set")] + Update { + #[command(subcommand)] + command: update::UpdateCommand, + }, + + /// Database utilities. (alias: `db`) + #[clap(alias = "db")] + Database { + #[command(subcommand)] + command: database::DatabaseCommand, + }, +} + +#[derive(Debug, Clone, clap::Parser)] +pub struct Execute { + /// The execution to run. + #[command(subcommand)] + pub execution: Execution, + /// Top priority Komodo host. + /// Eg. "https://demo.komo.do" + #[arg(long, short = 'a')] + pub host: Option, + /// Top priority api key. + #[arg(long, short = 'k')] + pub key: Option, + /// Top priority api secret. + #[arg(long, short = 's')] + pub secret: Option, + /// Always continue on user confirmation prompts. + #[arg(long, short = 'y', default_value_t = false)] + pub yes: bool, +} + +#[derive( + Debug, Clone, Copy, Default, strum::Display, clap::ValueEnum, +)] +#[strum(serialize_all = "lowercase")] +pub enum CliFormat { + /// Table output format. Default. (alias: `t`) + #[default] + #[clap(alias = "t")] + Table, + /// Json output format. (alias: `j`) + #[clap(alias = "j")] + Json, +} + +#[derive( + Debug, Clone, Copy, Default, clap::ValueEnum, strum::Display, +)] +#[strum(serialize_all = "lowercase")] +pub enum CliEnabled { + #[default] + #[clap(alias = "y", alias = "true", alias = "t")] + Yes, + #[clap(alias = "n", alias = "false", alias = "f")] + No, +} + +impl From for bool { + fn from(value: CliEnabled) -> Self { + match value { + CliEnabled::Yes => true, + CliEnabled::No => false, + } + } +} diff --git a/client/core/rs/src/entities/config/cli/args/update.rs b/client/core/rs/src/entities/config/cli/args/update.rs new file mode 100644 index 000000000..a15441aab --- /dev/null +++ b/client/core/rs/src/entities/config/cli/args/update.rs @@ -0,0 +1,86 @@ +#[derive(Debug, Clone, clap::Subcommand)] +pub enum UpdateCommand { + /// Update a Build's configuration. (alias: `bld`) + #[clap(alias = "bld")] + Build(UpdateResource), + /// Update a Deployments's configuration. (alias: `dep`) + #[clap(alias = "dep")] + Deployment(UpdateResource), + /// Update a Repos's configuration. + Repo(UpdateResource), + /// Update a Servers's configuration. (alias: `srv`) + #[clap(alias = "srv")] + Server(UpdateResource), + /// Update a Stacks's configuration. (alias: `stk`) + #[clap(alias = "stk")] + Stack(UpdateResource), + /// Update a Syncs's configuration. + Sync(UpdateResource), + /// Update a Variable's value. (alias: `var`) + #[clap(alias = "var")] + Variable { + /// The name of the variable. + name: String, + /// The value to set variable to. + value: String, + /// Whether the value should be set to secret. + /// If unset, will leave the variable secret setting as-is. + #[arg(long, short = 's')] + secret: Option, + /// Always continue on user confirmation prompts. + #[arg(long, short = 'y', default_value_t = false)] + yes: bool, + }, + /// Update a user's configuration, including assigning resetting password and assigning Super Admin + User { + /// The user to update + username: String, + #[command(subcommand)] + command: UpdateUserCommand, + }, +} + +#[derive(Debug, Clone, clap::Parser)] +pub struct UpdateResource { + /// The name / id of the Resource. + pub resource: String, + /// The update string, parsed using 'https://docs.rs/serde_qs/latest/serde_qs'. + /// + /// The fields can be found here: 'https://docs.rs/komodo_client/latest/komodo_client/entities/sync/struct.ResourceSyncConfig.html' + /// + /// Example: `km update build example-build "branch=testing"` + /// + /// Note. Should be enclosed in single or double quotes. + /// Values containing complex characters (like URLs) + /// will need to be url-encoded in order to be parsed correctly. + pub update: String, + /// Always continue on user confirmation prompts. + #[arg(long, short = 'y', default_value_t = false)] + pub yes: bool, +} + +#[derive(Debug, Clone, clap::Subcommand)] +pub enum UpdateUserCommand { + /// Update the users password. Fails if user is not "Local" user (ie OIDC). (alias: `pw`) + #[clap(alias = "pw")] + Password { + /// The new password to use. + password: String, + /// Whether to print unsanitized config, + /// including sensitive credentials. + #[arg(long, action)] + unsanitized: bool, + /// Always continue on user confirmation prompts. + #[arg(long, short = 'y', default_value_t = false)] + yes: bool, + }, + /// Un/assign super admin to user. (aliases: `supa`, `sa`) + #[clap(alias = "supa", alias = "sa")] + SuperAdmin { + #[clap(default_value_t = super::CliEnabled::Yes)] + enabled: super::CliEnabled, + /// Always continue on user confirmation prompts. + #[arg(long, short = 'y', default_value_t = false)] + yes: bool, + }, +} diff --git a/client/core/rs/src/entities/config/cli/mod.rs b/client/core/rs/src/entities/config/cli/mod.rs new file mode 100644 index 000000000..c4bbb095c --- /dev/null +++ b/client/core/rs/src/entities/config/cli/mod.rs @@ -0,0 +1,334 @@ +use std::{path::PathBuf, str::FromStr}; + +use serde::{Deserialize, Serialize}; + +use crate::{ + deserializers::string_list_deserializer, + entities::{ + config::{DatabaseConfig, empty_or_redacted}, + logger::{LogConfig, LogLevel, StdioLogMode}, + }, +}; + +pub mod args; + +/// # Komodo CLI Environment Variables +/// +/// +#[derive(Debug, Clone, Deserialize)] +pub struct Env { + // ============ + // Cli specific + // ============ + /// Specify the config paths (files or folders) used to build up the + /// final [CliConfig]. + /// If not provided, will use "." (the current working directory). + /// + /// Note. This is overridden if the equivalent arg is passed in [CliArgs]. + #[serde( + default = "default_config_paths", + alias = "komodo_cli_config_path" + )] + pub komodo_cli_config_paths: Vec, + /// If specifying folders, use this to narrow down which + /// files will be matched to parse into the final [CliConfig]. + /// Only files inside the folders which have names containing all keywords + /// provided to `config_keywords` will be included. + /// + /// Note. This is overridden if the equivalent arg is passed in [CliArgs]. + #[serde( + default = "default_config_keywords", + alias = "komodo_cli_config_keyword" + )] + pub komodo_cli_config_keywords: Vec, + /// Will merge nested config object (eg. database) across multiple + /// config files. Default: `true` + /// + /// Note. This is overridden if the equivalent arg is passed in [CliArgs]. + #[serde(default = "super::default_merge_nested_config")] + pub komodo_cli_merge_nested_config: bool, + /// Will extend config arrays (eg profiles) across multiple config files. + /// Default: `true` + /// + /// Note. This is overridden if the equivalent arg is passed in [CliArgs]. + #[serde(default = "super::default_extend_config_arrays")] + pub komodo_cli_extend_config_arrays: bool, + /// Extra logs during cli config load. + #[serde(default)] + pub komodo_cli_debug_startup: bool, + // Override `default_profile`. + pub komodo_cli_default_profile: Option, + /// Override `host` and `KOMODO_HOST`. + pub komodo_cli_host: Option, + /// Override `cli_key` + pub komodo_cli_key: Option, + /// Override `cli_secret` + pub komodo_cli_secret: Option, + /// Override `table_borders` + pub komodo_cli_table_borders: Option, + /// Override `backups_folder` + pub komodo_cli_backups_folder: Option, + /// Override `max_backups` + pub komodo_cli_max_backups: Option, + + /// Override `database_target_uri` + #[serde(alias = "komodo_cli_database_copy_uri")] + pub komodo_cli_database_target_uri: Option, + /// Override `database_target_address` + #[serde(alias = "komodo_cli_database_copy_address")] + pub komodo_cli_database_target_address: Option, + /// Override `database_target_username` + #[serde(alias = "komodo_cli_database_copy_username")] + pub komodo_cli_database_target_username: Option, + /// Override `database_target_password` + #[serde(alias = "komodo_cli_database_copy_password")] + pub komodo_cli_database_target_password: Option, + /// Override `database_target_db_name` + #[serde(alias = "komodo_cli_database_copy_db_name")] + pub komodo_cli_database_target_db_name: Option, + + // LOGGING + /// Override `logging.level` + pub komodo_cli_logging_level: Option, + /// Override `logging.stdio` + pub komodo_cli_logging_stdio: Option, + /// Override `logging.pretty` + pub komodo_cli_logging_pretty: Option, + /// Override `logging.otlp_endpoint` + pub komodo_cli_logging_otlp_endpoint: Option, + /// Override `logging.opentelemetry_service_name` + pub komodo_cli_logging_opentelemetry_service_name: Option, + /// Override `pretty_startup_config` + pub komodo_cli_pretty_startup_config: Option, + + // ================ + // Same as Core env + // ================ + /// Override `host` + pub komodo_host: Option, + + // DATABASE + /// Override `database.uri` + #[serde(alias = "komodo_mongo_uri")] + pub komodo_database_uri: Option, + /// Override `database.uri` from file + #[serde(alias = "komodo_mongo_uri_file")] + pub komodo_database_uri_file: Option, + /// Override `database.address` + #[serde(alias = "komodo_mongo_address")] + pub komodo_database_address: Option, + /// Override `database.username` + #[serde(alias = "komodo_mongo_username")] + pub komodo_database_username: Option, + /// Override `database.username` with file + #[serde(alias = "komodo_mongo_username_file")] + pub komodo_database_username_file: Option, + /// Override `database.password` + #[serde(alias = "komodo_mongo_password")] + pub komodo_database_password: Option, + /// Override `database.password` with file + #[serde(alias = "komodo_mongo_password_file")] + pub komodo_database_password_file: Option, + /// Override `database.db_name` + #[serde(alias = "komodo_mongo_db_name")] + pub komodo_database_db_name: Option, +} + +fn default_config_paths() -> Vec { + if let Ok(home) = std::env::var("HOME") { + vec![ + PathBuf::from_str(&home).unwrap().join(".config/komodo"), + PathBuf::from_str(".").unwrap(), + ] + } else { + vec![PathBuf::from_str(".").unwrap()] + } +} + +fn default_config_keywords() -> Vec { + vec![String::from("*komodo.cli*.*")] +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct CliConfig { + /// Optional. Only relevant for top level CLI config. + /// Set a default profile to be used when none is provided. + /// This allows for quick switching between profiles while + /// not having to explicitly pass `-p profile`. + #[serde( + alias = "default", + skip_serializing_if = "Option::is_none" + )] + pub default_profile: Option, + /// Optional. The profile name. (alias: `name`) + /// Configure profiles with name in the komodo.cli.toml, + /// and select them using `km -p profile-name ...`. + #[serde( + default, + alias = "name", + skip_serializing_if = "String::is_empty" + )] + pub config_profile: String, + /// Optional. The profile aliases. (aliases: `aliases`, `alias`) + /// Configure profiles with alias in the komodo.cli.toml, + /// and select them using `km -p alias ...`. + #[serde( + default, + alias = "aliases", + alias = "alias", + deserialize_with = "string_list_deserializer", + skip_serializing_if = "Vec::is_empty" + )] + pub config_aliases: Vec, + // Same as Core + /// The host Komodo url. + /// Eg. "https://demo.komo.do" + #[serde(default, skip_serializing_if = "String::is_empty")] + pub host: String, + /// The api key for the CLI to use + #[serde(alias = "key", skip_serializing_if = "Option::is_none")] + pub cli_key: Option, + /// The api secret for the CLI to use + #[serde(alias = "secret", skip_serializing_if = "Option::is_none")] + pub cli_secret: Option, + /// The format for the tables. + #[serde(skip_serializing_if = "Option::is_none")] + pub table_borders: Option, + /// The root backups folder. + /// + /// Default: `/backups`. + /// + /// Backups will be created in timestamped folders eg + /// `/backups/2025-08-04_05_05_53` + #[serde(default = "default_backups_folder")] + pub backups_folder: PathBuf, + + /// Specify the maximum number of backups to keep, + /// or 0 to disable backup pruning. + /// Default: `14` + /// + /// After every backup, the CLI will prune the oldest backups + /// if there are more backups than `max_backups` + #[serde(default = "default_max_backups")] + pub max_backups: u16, + // Same as Core + /// Configure database connection + #[serde( + default = "default_database_config", + alias = "mongo", + skip_serializing_if = "database_config_is_default" + )] + pub database: DatabaseConfig, + /// Configure restore / copy database connection + #[serde( + default = "default_database_config", + alias = "database_copy", + skip_serializing_if = "database_config_is_default" + )] + pub database_target: DatabaseConfig, + /// Logging configuration + #[serde( + default = "default_log_config", + skip_serializing_if = "log_config_is_default" + )] + pub cli_logging: LogConfig, + /// Configure additional profiles. + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub profile: Vec, +} + +fn default_backups_folder() -> PathBuf { + // SAFE: /backups is a valid path. + PathBuf::from_str("/backups").unwrap() +} + +fn default_max_backups() -> u16 { + 14 +} + +fn default_database_config() -> DatabaseConfig { + DatabaseConfig { + app_name: String::from("komodo_cli"), + ..Default::default() + } +} + +fn database_config_is_default(db_config: &DatabaseConfig) -> bool { + db_config == &default_database_config() +} + +fn default_log_config() -> LogConfig { + LogConfig { + location: false, + ..Default::default() + } +} + +fn log_config_is_default(log_config: &LogConfig) -> bool { + log_config == &default_log_config() +} + +impl Default for CliConfig { + fn default() -> Self { + Self { + default_profile: Default::default(), + config_profile: Default::default(), + config_aliases: Default::default(), + cli_key: Default::default(), + cli_secret: Default::default(), + cli_logging: default_log_config(), + table_borders: Default::default(), + backups_folder: default_backups_folder(), + max_backups: default_max_backups(), + database: default_database_config(), + database_target: default_database_config(), + host: Default::default(), + profile: Default::default(), + } + } +} + +impl CliConfig { + pub fn sanitized(&self) -> CliConfig { + CliConfig { + default_profile: self.default_profile.clone(), + config_profile: self.config_profile.clone(), + config_aliases: self.config_aliases.clone(), + cli_key: self + .cli_key + .as_ref() + .map(|cli_key| empty_or_redacted(cli_key)), + cli_secret: self + .cli_secret + .as_ref() + .map(|cli_secret| empty_or_redacted(cli_secret)), + cli_logging: self.cli_logging.clone(), + table_borders: self.table_borders, + backups_folder: self.backups_folder.clone(), + max_backups: self.max_backups, + database_target: self.database_target.sanitized(), + host: self.host.clone(), + database: self.database.sanitized(), + profile: self + .profile + .iter() + .map(CliConfig::sanitized) + .collect(), + } + } +} + +#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] +pub enum CliTableBorders { + /// Only horizontal borders. Default. + #[default] + Horizontal, + /// Only vertical borders. + Vertical, + /// Only borders around the outside of the table. + Outside, + /// Only borders horizontally / vertically between the rows / columns. + Inside, + /// All borders + All, +} diff --git a/client/core/rs/src/entities/config/core.rs b/client/core/rs/src/entities/config/core.rs index 762a3392c..6e0f66f33 100644 --- a/client/core/rs/src/entities/config/core.rs +++ b/client/core/rs/src/entities/config/core.rs @@ -11,10 +11,11 @@ use std::{collections::HashMap, path::PathBuf, str::FromStr}; -use serde::{Deserialize, Serialize}; +use serde::Deserialize; use crate::entities::{ Timelength, + config::DatabaseConfig, logger::{LogConfig, LogLevel, StdioLogMode}, }; @@ -31,12 +32,36 @@ use super::{DockerRegistry, GitProvider, empty_or_redacted}; /// To configure the core api, you can either mount your own custom configuration file to /// `/config/config.toml` inside the container, /// or simply override whichever fields you need using the environment. -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Deserialize)] pub struct Env { /// Specify a custom config path for the core config toml. /// Default: `/config/config.toml` - #[serde(default = "default_config_path")] - pub komodo_config_path: String, + #[serde( + default = "default_core_config_paths", + alias = "komodo_config_path" + )] + pub komodo_config_paths: Vec, + /// If specifying folders, use this to narrow down which + /// files will be matched to parse into the final [PeripheryConfig]. + /// Only files inside the folders which have names containing a keywords + /// provided to `config_keywords` will be included. + /// Keywords support wildcard matching syntax. + #[serde( + default = "super::default_config_keywords", + alias = "komodo_config_keyword" + )] + pub komodo_config_keywords: Vec, + /// Will merge nested config object (eg. secrets, providers) across multiple + /// config files. Default: `true` + #[serde(default = "super::default_merge_nested_config")] + pub komodo_merge_nested_config: bool, + /// Will extend config arrays across multiple config files. + /// Default: `true` + #[serde(default = "super::default_extend_config_arrays")] + pub komodo_extend_config_arrays: bool, + /// Print some extra logs on startup to debug config loading issues. + #[serde(default)] + pub komodo_config_debug: bool, /// Override `title` pub komodo_title: Option, @@ -55,6 +80,8 @@ pub struct Env { pub komodo_timezone: Option, /// Override `first_server` pub komodo_first_server: Option, + /// Override `first_server_name` + pub komodo_first_server_name: Option, /// Override `frontend_path` pub komodo_frontend_path: Option, /// Override `jwt_secret` @@ -90,6 +117,8 @@ pub struct Env { pub komodo_logging_stdio: Option, /// Override `logging.pretty` pub komodo_logging_pretty: Option, + /// Override `logging.location` + pub komodo_logging_location: Option, /// Override `logging.otlp_endpoint` pub komodo_logging_otlp_endpoint: Option, /// Override `logging.opentelemetry_service_name` @@ -113,9 +142,21 @@ pub struct Env { pub komodo_disable_non_admin_create: Option, /// Override `disable_websocket_reconnect` pub komodo_disable_websocket_reconnect: Option, + /// Override `disable_init_resources` + pub komodo_disable_init_resources: Option, + /// Override `enable_fancy_toml` + pub komodo_enable_fancy_toml: Option, /// Override `local_auth` pub komodo_local_auth: Option, + /// Override `init_admin_username` + pub komodo_init_admin_username: Option, + /// Override `init_admin_username` from file + pub komodo_init_admin_username_file: Option, + /// Override `init_admin_password` + pub komodo_init_admin_password: Option, + /// Override `init_admin_password` from file + pub komodo_init_admin_password_file: Option, /// Override `oidc_enabled` pub komodo_oidc_enabled: Option, @@ -216,6 +257,9 @@ pub struct Env { /// Override `aws.secret_access_key` with file pub komodo_aws_secret_access_key_file: Option, + /// Override `internet_interface` + pub komodo_internet_interface: Option, + /// Override `ssl_enabled`. pub komodo_ssl_enabled: Option, /// Override `ssl_key_file` @@ -224,8 +268,8 @@ pub struct Env { pub komodo_ssl_cert_file: Option, } -fn default_config_path() -> String { - "/config/config.toml".to_string() +fn default_core_config_paths() -> Vec { + vec![PathBuf::from_str("/config").unwrap()] } /// # Core Configuration File @@ -241,7 +285,7 @@ fn default_config_path() -> String { /// or simply override whichever fields you need using the environment. /// /// Refer to the [example file](https://github.com/moghtech/komodo/blob/main/config/core.config.toml) for a full example. -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Deserialize)] pub struct CoreConfig { // =========== // = General = @@ -254,7 +298,7 @@ pub struct CoreConfig { /// The host to use with oauth redirect url, whatever host /// the user hits to access Komodo. eg `https://komodo.domain.com`. /// Only used if oauth used without user specifying redirect url themselves. - #[serde(default)] + #[serde(default = "default_host")] pub host: String, /// Port the core web server runs on. @@ -267,8 +311,13 @@ pub struct CoreConfig { #[serde(default = "default_core_bind_ip")] pub bind_ip: String, + /// Interface to use as default route in multi-NIC environments. + #[serde(default)] + pub internet_interface: String, + /// Sent in auth header with req to periphery. /// Should be some secure hash, maybe 20-40 chars. + #[serde(default = "default_passkey")] pub passkey: String, /// A TZ Identifier. If not provided, will use Core local timezone. @@ -289,17 +338,31 @@ pub struct CoreConfig { #[serde(default)] pub disable_websocket_reconnect: bool, + /// Disable init system resource creation on fresh Komodo launch. + /// These include the Backup Core Database and Global Auto Update procedures. + #[serde(default)] + pub disable_init_resources: bool, + + /// Enable the fancy TOML syntax highlighting + #[serde(default)] + pub enable_fancy_toml: bool, + /// If defined, ensure an enabled first server exists at this address. /// Example: `http://periphery:8120` - #[serde(default)] - pub first_server: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub first_server: Option, + + /// Give the first server this name. + /// Default: `Local` + #[serde(default = "default_first_server_name")] + pub first_server_name: String, /// The path to the built frontend folder. #[serde(default = "default_frontend_path")] pub frontend_path: String, /// Configure database connection - #[serde(alias = "mongo")] + #[serde(default, alias = "mongo")] pub database: DatabaseConfig, // ================ @@ -309,6 +372,15 @@ pub struct CoreConfig { #[serde(default)] pub local_auth: bool, + /// Upon fresh launch, initalize an Admin user with this username. + /// If this is not provided, no initial user will be created. + #[serde(skip_serializing_if = "Option::is_none")] + pub init_admin_username: Option, + /// Upon fresh launch, initalize an Admin user with this password. + /// Default: `changeme` + #[serde(default = "default_init_admin_password")] + pub init_admin_password: String, + /// Enable transparent mode, which gives all (enabled) users read access to all resources. #[serde(default)] pub transparent_mode: bool, @@ -327,7 +399,7 @@ pub struct CoreConfig { /// APIs are disabled. Used by demo to lock the 'demo' : 'demo' login. /// /// To lock the api for all users, use `lock_login_credentials_for = ["__ALL__"]` - #[serde(default)] + #[serde(default, skip_serializing_if = "Vec::is_empty")] pub lock_login_credentials_for: Vec, /// Normally all users can create resources. @@ -388,7 +460,7 @@ pub struct CoreConfig { /// Your OIDC provider may set additional audiences other than `client_id`, /// they must be added here to make claims verification work. - #[serde(default)] + #[serde(default, skip_serializing_if = "Vec::is_empty")] pub oidc_additional_audiences: Vec, // ========= @@ -478,7 +550,11 @@ pub struct CoreConfig { // ================= /// Configure git credentials used to clone private repos. /// Supports any git provider. - #[serde(default, alias = "git_provider")] + #[serde( + default, + alias = "git_provider", + skip_serializing_if = "Vec::is_empty" + )] pub git_providers: Vec, // ====================== @@ -486,7 +562,11 @@ pub struct CoreConfig { // ====================== /// Configure docker credentials used to push / pull images. /// Supports any docker image repository. - #[serde(default, alias = "docker_registry")] + #[serde( + default, + alias = "docker_registry", + skip_serializing_if = "Vec::is_empty" + )] pub docker_registries: Vec, // =========== @@ -495,7 +575,7 @@ pub struct CoreConfig { /// Configure core-based secrets. These will be preferentially interpolated into /// values if they contain a matching secret. Otherwise, the periphery will have to have the /// secret configured. - #[serde(default)] + #[serde(default, skip_serializing_if = "HashMap::is_empty")] pub secrets: HashMap, // ======= @@ -539,6 +619,10 @@ fn default_title() -> String { String::from("Komodo") } +fn default_host() -> String { + String::from("https://komodo.example.com") +} + fn default_core_port() -> u16 { 9120 } @@ -547,14 +631,26 @@ fn default_core_bind_ip() -> String { "[::]".to_string() } +fn default_passkey() -> String { + String::from("default-passkey-changeme") +} + fn default_frontend_path() -> String { "/app/frontend".to_string() } +fn default_first_server_name() -> String { + String::from("Local") +} + fn default_jwt_ttl() -> Timelength { Timelength::OneDay } +fn default_init_admin_password() -> String { + String::from("changeme") +} + fn default_sync_directory() -> PathBuf { // unwrap ok: `/syncs` will always be valid path PathBuf::from_str("/syncs").unwrap() @@ -590,6 +686,67 @@ fn default_ssl_cert_file() -> PathBuf { "/config/ssl/cert.pem".parse().unwrap() } +impl Default for CoreConfig { + fn default() -> Self { + Self { + title: default_title(), + host: default_host(), + port: default_core_port(), + bind_ip: default_core_bind_ip(), + internet_interface: Default::default(), + passkey: default_passkey(), + timezone: Default::default(), + ui_write_disabled: Default::default(), + disable_confirm_dialog: Default::default(), + disable_websocket_reconnect: Default::default(), + disable_init_resources: Default::default(), + enable_fancy_toml: Default::default(), + first_server: Default::default(), + first_server_name: default_first_server_name(), + frontend_path: default_frontend_path(), + database: Default::default(), + local_auth: Default::default(), + init_admin_username: Default::default(), + init_admin_password: default_init_admin_password(), + transparent_mode: Default::default(), + enable_new_users: Default::default(), + disable_user_registration: Default::default(), + lock_login_credentials_for: Default::default(), + disable_non_admin_create: Default::default(), + jwt_secret: Default::default(), + jwt_ttl: default_jwt_ttl(), + oidc_enabled: Default::default(), + oidc_provider: Default::default(), + oidc_redirect_host: Default::default(), + oidc_client_id: Default::default(), + oidc_client_secret: Default::default(), + oidc_use_full_email: Default::default(), + oidc_additional_audiences: Default::default(), + google_oauth: Default::default(), + github_oauth: Default::default(), + webhook_secret: Default::default(), + webhook_base_url: Default::default(), + github_webhook_app: Default::default(), + logging: Default::default(), + pretty_startup_config: Default::default(), + keep_stats_for_days: default_prune_days(), + keep_alerts_for_days: default_prune_days(), + resource_poll_interval: default_poll_interval(), + monitoring_interval: default_monitoring_interval(), + aws: Default::default(), + git_providers: Default::default(), + docker_registries: Default::default(), + secrets: Default::default(), + ssl_enabled: Default::default(), + ssl_key_file: default_ssl_key_file(), + ssl_cert_file: default_ssl_cert_file(), + sync_directory: default_sync_directory(), + repo_directory: default_repo_directory(), + action_directory: default_action_directory(), + } + } +} + impl CoreConfig { pub fn sanitized(&self) -> CoreConfig { let config = self.clone(); @@ -601,12 +758,14 @@ impl CoreConfig { passkey: empty_or_redacted(&config.passkey), timezone: config.timezone, first_server: config.first_server, + first_server_name: config.first_server_name, frontend_path: config.frontend_path, jwt_secret: empty_or_redacted(&config.jwt_secret), jwt_ttl: config.jwt_ttl, repo_directory: config.repo_directory, action_directory: config.action_directory, sync_directory: config.sync_directory, + internet_interface: config.internet_interface, resource_poll_interval: config.resource_poll_interval, monitoring_interval: config.monitoring_interval, keep_stats_for_days: config.keep_stats_for_days, @@ -617,11 +776,19 @@ impl CoreConfig { ui_write_disabled: config.ui_write_disabled, disable_confirm_dialog: config.disable_confirm_dialog, disable_websocket_reconnect: config.disable_websocket_reconnect, + disable_init_resources: config.disable_init_resources, + enable_fancy_toml: config.enable_fancy_toml, enable_new_users: config.enable_new_users, disable_user_registration: config.disable_user_registration, disable_non_admin_create: config.disable_non_admin_create, lock_login_credentials_for: config.lock_login_credentials_for, local_auth: config.local_auth, + init_admin_username: config + .init_admin_username + .map(|u| empty_or_redacted(&u)), + init_admin_password: empty_or_redacted( + &config.init_admin_password, + ), oidc_enabled: config.oidc_enabled, oidc_provider: config.oidc_provider, oidc_redirect_host: config.oidc_redirect_host, @@ -648,14 +815,7 @@ impl CoreConfig { webhook_secret: empty_or_redacted(&config.webhook_secret), webhook_base_url: config.webhook_base_url, github_webhook_app: config.github_webhook_app, - database: DatabaseConfig { - uri: empty_or_redacted(&config.database.uri), - address: config.database.address, - username: empty_or_redacted(&config.database.username), - password: empty_or_redacted(&config.database.password), - app_name: config.database.app_name, - db_name: config.database.db_name, - }, + database: config.database.sanitized(), aws: AwsCredentials { access_key_id: empty_or_redacted(&config.aws.access_key_id), secret_access_key: empty_or_redacted( @@ -696,7 +856,7 @@ impl CoreConfig { } /// Generic Oauth credentials -#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[derive(Debug, Clone, Default, Deserialize)] pub struct OauthCredentials { /// Whether this oauth method is available for usage. #[serde(default)] @@ -709,63 +869,8 @@ pub struct OauthCredentials { pub secret: String, } -/// Provide database connection information. -/// Komodo uses the MongoDB api driver for database communication, -/// and FerretDB to support Postgres and Sqlite storage options. -/// -/// Must provide ONE of: -/// 1. `uri` -/// 2. `address` + `username` + `password` -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct DatabaseConfig { - /// Full mongo uri string, eg. `mongodb://username:password@your.mongo.int:27017` - #[serde(default)] - pub uri: String, - /// Just the address part of the mongo uri, eg `your.mongo.int:27017` - #[serde(default = "default_database_address")] - pub address: String, - /// Mongo user username - #[serde(default)] - pub username: String, - /// Mongo user password - #[serde(default)] - pub password: String, - /// Mongo app name. default: `komodo_core` - #[serde(default = "default_database_app_name")] - pub app_name: String, - /// Mongo db name. Which mongo database to create the collections in. - /// Default: `komodo`. - #[serde(default = "default_database_db_name")] - pub db_name: String, -} - -fn default_database_address() -> String { - String::from("localhost:27017") -} - -fn default_database_app_name() -> String { - "komodo_core".to_string() -} - -fn default_database_db_name() -> String { - "komodo".to_string() -} - -impl Default for DatabaseConfig { - fn default() -> Self { - Self { - uri: Default::default(), - address: default_database_address(), - username: Default::default(), - password: Default::default(), - app_name: default_database_app_name(), - db_name: default_database_db_name(), - } - } -} - /// Provide AWS credentials for Komodo to use. -#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[derive(Debug, Clone, Default, Deserialize)] pub struct AwsCredentials { /// The aws ACCESS_KEY_ID pub access_key_id: String, @@ -774,7 +879,7 @@ pub struct AwsCredentials { } /// Provide configuration for a Github Webhook app. -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Deserialize)] pub struct GithubWebhookAppConfig { /// Github app id pub app_id: i64, @@ -800,7 +905,7 @@ impl Default for GithubWebhookAppConfig { } /// Provide configuration for a Github Webhook app installation. -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Deserialize)] pub struct GithubWebhookAppInstallationConfig { /// The installation ID pub id: i64, diff --git a/client/core/rs/src/entities/config/mod.rs b/client/core/rs/src/entities/config/mod.rs index 517b8b310..9487eebad 100644 --- a/client/core/rs/src/entities/config/mod.rs +++ b/client/core/rs/src/entities/config/mod.rs @@ -1,9 +1,105 @@ +use std::sync::OnceLock; + use serde::{Deserialize, Serialize}; use typeshare::typeshare; +pub mod cli; pub mod core; pub mod periphery; +fn default_config_keywords() -> Vec { + vec![String::from("*config.*")] +} + +fn default_merge_nested_config() -> bool { + true +} + +fn default_extend_config_arrays() -> bool { + true +} + +/// Provide database connection information. +/// Komodo uses the MongoDB api driver for database communication, +/// and FerretDB to support Postgres and Sqlite storage options. +/// +/// Must provide ONE of: +/// 1. `uri` +/// 2. `address` + `username` + `password` +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct DatabaseConfig { + /// Full mongo uri string, eg. `mongodb://username:password@your.mongo.int:27017` + #[serde(default, skip_serializing_if = "String::is_empty")] + pub uri: String, + /// Just the address part of the mongo uri, eg `your.mongo.int:27017` + #[serde( + default = "default_database_address", + skip_serializing_if = "String::is_empty" + )] + pub address: String, + /// Mongo user username + #[serde(default, skip_serializing_if = "String::is_empty")] + pub username: String, + /// Mongo user password + #[serde(default, skip_serializing_if = "String::is_empty")] + pub password: String, + /// Mongo app name. default: `komodo_core` + #[serde(default = "default_database_app_name")] + pub app_name: String, + /// Mongo db name. Which mongo database to create the collections in. + /// Default: `komodo`. + #[serde(default = "default_database_db_name")] + pub db_name: String, +} + +fn default_database_address() -> String { + String::from("localhost:27017") +} + +fn default_database_app_name() -> String { + "komodo_core".to_string() +} + +fn default_database_db_name() -> String { + "komodo".to_string() +} + +impl Default for DatabaseConfig { + fn default() -> Self { + Self { + uri: Default::default(), + address: default_database_address(), + username: Default::default(), + password: Default::default(), + app_name: default_database_app_name(), + db_name: default_database_db_name(), + } + } +} + +fn default_database_config() -> &'static DatabaseConfig { + static DEFAULT_DATABASE_CONFIG: OnceLock = + OnceLock::new(); + DEFAULT_DATABASE_CONFIG.get_or_init(Default::default) +} + +impl DatabaseConfig { + pub fn sanitized(&self) -> DatabaseConfig { + DatabaseConfig { + uri: empty_or_redacted(&self.uri), + address: self.address.clone(), + username: empty_or_redacted(&self.username), + password: empty_or_redacted(&self.password), + app_name: self.app_name.clone(), + db_name: self.db_name.clone(), + } + } + + pub fn is_default(&self) -> bool { + self == default_database_config() + } +} + #[typeshare] #[derive( Debug, @@ -86,7 +182,7 @@ pub struct ProviderAccount { pub token: String, } -fn empty_or_redacted(src: &str) -> String { +pub fn empty_or_redacted(src: &str) -> String { if src.is_empty() { String::new() } else { diff --git a/client/core/rs/src/entities/config/periphery.rs b/client/core/rs/src/entities/config/periphery.rs index 4b72ad6df..4219246b6 100644 --- a/client/core/rs/src/entities/config/periphery.rs +++ b/client/core/rs/src/entities/config/periphery.rs @@ -12,14 +12,17 @@ //! the configuration file. //! -use std::{collections::HashMap, net::IpAddr, path::PathBuf}; - use clap::Parser; +use ipnetwork::IpNetwork; use serde::Deserialize; +use std::{collections::HashMap, path::PathBuf}; -use crate::entities::{ - Timelength, - logger::{LogConfig, LogLevel, StdioLogMode}, +use crate::{ + deserializers::ForgivingVec, + entities::{ + Timelength, + logger::{LogConfig, LogLevel, StdioLogMode}, + }, }; use super::{ @@ -48,23 +51,24 @@ use super::{ pub struct CliArgs { /// Sets the path of a config file or directory to use. /// Can use multiple times - #[arg(short, long)] - pub config_path: Option>, + #[arg(long, short = 'c')] + pub config_path: Option>, /// Sets the keywords to match directory periphery config file names on. - /// Can use multiple times. - #[arg(long)] + /// Supports wildcard syntax. + /// Can use multiple times to match multiple patterns independently. + #[arg(long, short = 'm')] pub config_keyword: Option>, /// Merges nested configs, eg. secrets, providers. /// Will override the equivalent env configuration. - /// Default: false + /// Default: true #[arg(long)] pub merge_nested_config: Option, /// Extends config arrays, eg. allowed_ips, passkeys. /// Will override the equivalent env configuration. - /// Default: false + /// Default: true #[arg(long)] pub extend_config_arrays: Option, @@ -88,28 +92,32 @@ pub struct Env { /// /// Note. This is overridden if the equivalent arg is passed in [CliArgs]. #[serde(default, alias = "periphery_config_path")] - pub periphery_config_paths: Vec, + pub periphery_config_paths: Vec, /// If specifying folders, use this to narrow down which /// files will be matched to parse into the final [PeripheryConfig]. - /// Only files inside the folders which have names containing all keywords + /// Only files inside the folders which have names containing a keywords /// provided to `config_keywords` will be included. + /// Keywords support wildcard matching syntax. /// /// Note. This is overridden if the equivalent arg is passed in [CliArgs]. - #[serde(default, alias = "periphery_config_keyword")] + #[serde( + default = "super::default_config_keywords", + alias = "periphery_config_keyword" + )] pub periphery_config_keywords: Vec, /// Will merge nested config object (eg. secrets, providers) across multiple - /// config files. Default: `false` + /// config files. Default: `true` /// /// Note. This is overridden if the equivalent arg is passed in [CliArgs]. - #[serde(default)] + #[serde(default = "super::default_merge_nested_config")] pub periphery_merge_nested_config: bool, /// Will extend config arrays (eg. `allowed_ips`, `passkeys`) across multiple config files. - /// Default: `false` + /// Default: `true` /// /// Note. This is overridden if the equivalent arg is passed in [CliArgs]. - #[serde(default)] + #[serde(default = "super::default_extend_config_arrays")] pub periphery_extend_config_arrays: bool, /// Override `port` @@ -142,6 +150,8 @@ pub struct Env { pub periphery_logging_stdio: Option, /// Override `logging.pretty` pub periphery_logging_pretty: Option, + /// Override `logging.location` + pub periphery_logging_location: Option, /// Override `logging.otlp_endpoint` pub periphery_logging_otlp_endpoint: Option, /// Override `logging.opentelemetry_service_name` @@ -150,15 +160,15 @@ pub struct Env { pub periphery_pretty_startup_config: Option, /// Override `allowed_ips` - pub periphery_allowed_ips: Option>, + pub periphery_allowed_ips: Option>, /// Override `passkeys` pub periphery_passkeys: Option>, /// Override `passkeys` from file pub periphery_passkeys_file: Option, /// Override `include_disk_mounts` - pub periphery_include_disk_mounts: Option>, + pub periphery_include_disk_mounts: Option>, /// Override `exclude_disk_mounts` - pub periphery_exclude_disk_mounts: Option>, + pub periphery_exclude_disk_mounts: Option>, /// Override `ssl_enabled` pub periphery_ssl_enabled: Option, @@ -250,12 +260,12 @@ pub struct PeripheryConfig { #[serde(default)] pub pretty_startup_config: bool, - /// Limits which IPv4 addresses are allowed to call the api. + /// Limits which IP addresses are allowed to call the api. /// Default: none /// /// Note: this should be configured to increase security. #[serde(default)] - pub allowed_ips: Vec, + pub allowed_ips: ForgivingVec, /// Limits the accepted passkeys. /// Default: none @@ -266,11 +276,11 @@ pub struct PeripheryConfig { /// If non-empty, only includes specific mount paths in the disk report. #[serde(default)] - pub include_disk_mounts: Vec, + pub include_disk_mounts: ForgivingVec, /// Exclude specific mount paths in the disk report. #[serde(default)] - pub exclude_disk_mounts: Vec, + pub exclude_disk_mounts: ForgivingVec, /// Mapping on local periphery secrets. These can be interpolated into eg. Deployment environment variables. /// Default: none @@ -280,12 +290,12 @@ pub struct PeripheryConfig { /// Configure git credentials used to clone private repos. /// Supports any git provider. #[serde(default, alias = "git_provider")] - pub git_providers: Vec, + pub git_providers: ForgivingVec, /// Configure docker credentials used to push / pull images. /// Supports any docker image repository. #[serde(default, alias = "docker_registry")] - pub docker_registries: Vec, + pub docker_registries: ForgivingVec, /// Whether to enable ssl. /// Default: true diff --git a/client/core/rs/src/entities/deployment.rs b/client/core/rs/src/entities/deployment.rs index f2febfe6a..b2de7f3fe 100644 --- a/client/core/rs/src/entities/deployment.rs +++ b/client/core/rs/src/entities/deployment.rs @@ -329,17 +329,19 @@ pub fn conversions_from_str( /// - Running -> running. #[typeshare] #[derive( - Serialize, - Deserialize, Debug, - PartialEq, - Hash, - Eq, Clone, Copy, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, Default, Display, EnumString, + Serialize, + Deserialize, )] #[serde(rename_all = "snake_case")] #[strum(serialize_all = "snake_case")] diff --git a/client/core/rs/src/entities/docker/container.rs b/client/core/rs/src/entities/docker/container.rs index b08f145f1..9c56f50bb 100644 --- a/client/core/rs/src/entities/docker/container.rs +++ b/client/core/rs/src/entities/docker/container.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use anyhow::anyhow; use serde::{Deserialize, Serialize}; +use strum::Display; use typeshare::typeshare; use crate::entities::{I64, Usize}; @@ -15,34 +16,47 @@ use super::{ContainerConfig, GraphDriverData, PortBinding}; )] pub struct ContainerListItem { /// The Server which holds the container. + #[serde(skip_serializing_if = "Option::is_none")] pub server_id: Option, /// The first name in Names, not including the initial '/' pub name: String, /// The ID of this container + #[serde(skip_serializing_if = "Option::is_none")] pub id: Option, /// The name of the image used when creating this container + #[serde(skip_serializing_if = "Option::is_none")] pub image: Option, /// The ID of the image that this container was created from + #[serde(skip_serializing_if = "Option::is_none")] pub image_id: Option, /// When the container was created + #[serde(skip_serializing_if = "Option::is_none")] pub created: Option, /// The size of files that have been created or changed by this container + #[serde(skip_serializing_if = "Option::is_none")] pub size_rw: Option, /// The total size of all the files in this container + #[serde(skip_serializing_if = "Option::is_none")] pub size_root_fs: Option, /// The state of this container (e.g. `exited`) pub state: ContainerStateStatusEnum, /// Additional human-readable status of this container (e.g. `Exit 0`) + #[serde(skip_serializing_if = "Option::is_none")] pub status: Option, /// The network mode + #[serde(skip_serializing_if = "Option::is_none")] pub network_mode: Option, /// The network names attached to container + #[serde(default, skip_serializing_if = "Vec::is_empty")] pub networks: Vec, /// Port mappings for the container + #[serde(default, skip_serializing_if = "Vec::is_empty")] pub ports: Vec, /// The volume names attached to container + #[serde(default, skip_serializing_if = "Vec::is_empty")] pub volumes: Vec, /// The container stats, if they can be retreived. + #[serde(skip_serializing_if = "Option::is_none")] pub stats: Option, /// The labels attached to container. /// It's too big to send with container list, @@ -253,32 +267,29 @@ pub struct ContainerState { Debug, Clone, Copy, + Default, PartialEq, + Eq, PartialOrd, + Ord, + Display, Serialize, Deserialize, - Eq, - Ord, - Default, )] +#[serde(rename_all = "lowercase")] +#[strum(serialize_all = "lowercase")] pub enum ContainerStateStatusEnum { + Running, + Created, + Paused, + Restarting, + Exited, + Removing, + Dead, #[default] #[serde(rename = "")] + #[strum(serialize = "")] Empty, - #[serde(rename = "created")] - Created, - #[serde(rename = "running")] - Running, - #[serde(rename = "paused")] - Paused, - #[serde(rename = "restarting")] - Restarting, - #[serde(rename = "exited")] - Exited, - #[serde(rename = "removing")] - Removing, - #[serde(rename = "dead")] - Dead, } impl ::std::str::FromStr for ContainerStateStatusEnum { diff --git a/client/core/rs/src/entities/docker/stats.rs b/client/core/rs/src/entities/docker/stats.rs index 99e291b57..9f2e82bce 100644 --- a/client/core/rs/src/entities/docker/stats.rs +++ b/client/core/rs/src/entities/docker/stats.rs @@ -61,7 +61,7 @@ pub struct FullContainerStats { /// Network statistics for the container per interface. This field is omitted if the container has no networking enabled. #[serde(rename = "networks")] #[serde(skip_serializing_if = "Option::is_none")] - pub networks: Option, + pub networks: Option>, } /// PidsStats contains Linux-specific stats of a container's process-IDs (PIDs). This type is Linux-specific and omitted for Windows containers. diff --git a/client/core/rs/src/entities/logger.rs b/client/core/rs/src/entities/logger.rs index ce708e8c7..ed2f5219c 100644 --- a/client/core/rs/src/entities/logger.rs +++ b/client/core/rs/src/entities/logger.rs @@ -1,6 +1,8 @@ +use std::sync::OnceLock; + use serde::{Deserialize, Serialize}; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct LogConfig { /// The logging level. default: info #[serde(default)] @@ -10,9 +12,15 @@ pub struct LogConfig { #[serde(default)] pub stdio: StdioLogMode, + /// Use tracing-subscriber's pretty logging output option. #[serde(default)] pub pretty: bool, + /// Including information about the log location (ie the function which produced the log). + /// Tracing refers to this as the 'target'. + #[serde(default = "default_location")] + pub location: bool, + /// Enable opentelemetry exporting #[serde(default)] pub otlp_endpoint: String, @@ -25,12 +33,17 @@ fn default_opentelemetry_service_name() -> String { String::from("Komodo") } +fn default_location() -> bool { + true +} + impl Default for LogConfig { fn default() -> Self { Self { level: Default::default(), stdio: Default::default(), pretty: Default::default(), + location: default_location(), otlp_endpoint: Default::default(), opentelemetry_service_name: default_opentelemetry_service_name( ), @@ -38,6 +51,17 @@ impl Default for LogConfig { } } +fn default_log_config() -> &'static LogConfig { + static DEFAULT_LOG_CONFIG: OnceLock = OnceLock::new(); + DEFAULT_LOG_CONFIG.get_or_init(Default::default) +} + +impl LogConfig { + pub fn is_default(&self) -> bool { + self == default_log_config() + } +} + #[derive( Debug, Clone, diff --git a/client/core/rs/src/entities/mod.rs b/client/core/rs/src/entities/mod.rs index c08971506..7c69ee13c 100644 --- a/client/core/rs/src/entities/mod.rs +++ b/client/core/rs/src/entities/mod.rs @@ -85,6 +85,8 @@ pub type Usize = usize; pub type MongoDocument = bson::Document; #[typeshare(serialized_as = "any")] pub type JsonValue = serde_json::Value; +#[typeshare(serialized_as = "any")] +pub type JsonObject = serde_json::Map; #[typeshare(serialized_as = "MongoIdObj")] pub type MongoId = String; #[typeshare(serialized_as = "__Serror")] @@ -156,7 +158,7 @@ pub fn get_image_name( ) { // If organization and account provided, name under organization. (true, true, true) => { - format!("{domain}/{}/{name}", organization) + format!("{domain}/{organization}/{name}") } // Just domain / account provided (true, false, true) => format!("{domain}/{account}/{name}"), @@ -1161,6 +1163,11 @@ pub enum Operation { CommitSync, RunSync, + // maintenance + ClearRepoCache, + BackupCoreDatabase, + GlobalAutoUpdate, + // variable CreateVariable, UpdateVariableValue, @@ -1268,10 +1275,38 @@ pub enum ResourceTarget { } impl ResourceTarget { + pub fn system() -> ResourceTarget { + Self::System("system".to_string()) + } +} + +impl Default for ResourceTarget { + fn default() -> Self { + ResourceTarget::system() + } +} + +impl ResourceTarget { + pub fn is_empty(&self) -> bool { + match self { + ResourceTarget::System(id) => id.is_empty(), + ResourceTarget::Server(id) => id.is_empty(), + ResourceTarget::Stack(id) => id.is_empty(), + ResourceTarget::Deployment(id) => id.is_empty(), + ResourceTarget::Build(id) => id.is_empty(), + ResourceTarget::Repo(id) => id.is_empty(), + ResourceTarget::Procedure(id) => id.is_empty(), + ResourceTarget::Action(id) => id.is_empty(), + ResourceTarget::Builder(id) => id.is_empty(), + ResourceTarget::Alerter(id) => id.is_empty(), + ResourceTarget::ResourceSync(id) => id.is_empty(), + } + } + pub fn extract_variant_id( &self, ) -> (ResourceTargetVariant, &String) { - let id = match &self { + let id = match self { ResourceTarget::System(id) => id, ResourceTarget::Server(id) => id, ResourceTarget::Stack(id) => id, @@ -1286,16 +1321,6 @@ impl ResourceTarget { }; (self.extract_variant(), id) } - - pub fn system() -> ResourceTarget { - Self::System("system".to_string()) - } -} - -impl Default for ResourceTarget { - fn default() -> Self { - ResourceTarget::system() - } } impl From<&build::Build> for ResourceTarget { @@ -1387,5 +1412,55 @@ pub enum ScheduleFormat { Cron, } +#[typeshare] +#[derive( + Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize, +)] +#[serde(rename_all = "snake_case")] +pub enum FileFormat { + #[default] + KeyValue, + Toml, + Yaml, + Json, +} + /// Used with ExecuteTerminal to capture the exit code pub const KOMODO_EXIT_CODE: &str = "__KOMODO_EXIT_CODE:"; + +pub fn resource_link( + host: &str, + resource_type: ResourceTargetVariant, + id: &str, +) -> String { + let path = match resource_type { + ResourceTargetVariant::System => unreachable!(), + ResourceTargetVariant::Build => format!("/builds/{id}"), + ResourceTargetVariant::Builder => { + format!("/builders/{id}") + } + ResourceTargetVariant::Deployment => { + format!("/deployments/{id}") + } + ResourceTargetVariant::Stack => { + format!("/stacks/{id}") + } + ResourceTargetVariant::Server => { + format!("/servers/{id}") + } + ResourceTargetVariant::Repo => format!("/repos/{id}"), + ResourceTargetVariant::Alerter => { + format!("/alerters/{id}") + } + ResourceTargetVariant::Procedure => { + format!("/procedures/{id}") + } + ResourceTargetVariant::Action => { + format!("/actions/{id}") + } + ResourceTargetVariant::ResourceSync => { + format!("/resource-syncs/{id}") + } + }; + format!("{host}{path}") +} diff --git a/client/core/rs/src/entities/procedure.rs b/client/core/rs/src/entities/procedure.rs index be81721d1..623663304 100644 --- a/client/core/rs/src/entities/procedure.rs +++ b/client/core/rs/src/entities/procedure.rs @@ -35,15 +35,25 @@ pub struct ProcedureListItemInfo { #[typeshare] #[derive( - Debug, Clone, Copy, Default, Serialize, Deserialize, Display, + Debug, + Clone, + Copy, + Default, + PartialEq, + Eq, + PartialOrd, + Ord, + Serialize, + Deserialize, + Display, )] pub enum ProcedureState { + /// Currently running + Running, /// Last run successful Ok, /// Last run failed Failed, - /// Currently running - Running, /// Other case (never run) #[default] Unknown, diff --git a/client/core/rs/src/entities/resource.rs b/client/core/rs/src/entities/resource.rs index 36385284e..3c592db20 100644 --- a/client/core/rs/src/entities/resource.rs +++ b/client/core/rs/src/entities/resource.rs @@ -1,7 +1,9 @@ use bson::{Document, doc}; +use clap::ValueEnum; use derive_builder::Builder; use derive_default_builder::DefaultBuilder; use serde::{Deserialize, Serialize}; +use strum::Display; use typeshare::typeshare; use crate::{ @@ -124,7 +126,18 @@ pub struct ResourceQuery { } #[typeshare] -#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] +#[derive( + Debug, + Clone, + Copy, + Default, + Serialize, + Deserialize, + ValueEnum, + Display, +)] +// Only strum serializes lowercase for clap compat. +#[strum(serialize_all = "lowercase")] pub enum TemplatesQueryBehavior { /// Include templates in results. Default. #[default] diff --git a/client/core/rs/src/entities/server.rs b/client/core/rs/src/entities/server.rs index 8b5104959..c29539368 100644 --- a/client/core/rs/src/entities/server.rs +++ b/client/core/rs/src/entities/server.rs @@ -3,6 +3,7 @@ use std::{collections::HashMap, path::PathBuf}; use derive_builder::Builder; use partial_derive2::Partial; use serde::{Deserialize, Serialize}; +use strum::Display; use typeshare::typeshare; use crate::{ @@ -25,7 +26,7 @@ pub type Server = Resource; pub type ServerListItem = ResourceListItem; #[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ServerListItemInfo { /// The server's state. pub state: ServerState, @@ -33,6 +34,10 @@ pub struct ServerListItemInfo { pub region: String, /// Address of the server. pub address: String, + /// External address of the server (reachable by users). + /// Used with links. + #[serde(default)] // API backward compat + pub external_address: String, /// The Komodo Periphery version of the server. pub version: String, /// Whether server is configured to send unreachable alerts. @@ -65,6 +70,12 @@ pub struct ServerConfig { #[partial_default(default_address())] pub address: String, + /// The address to use with links for containers on the server. + /// If empty, will use the 'address' for links. + #[serde(default)] + #[builder(default)] + pub external_address: String, + /// An optional region label #[serde(default)] #[builder(default)] @@ -249,7 +260,8 @@ fn default_disk_critical() -> f64 { impl Default for ServerConfig { fn default() -> Self { Self { - address: Default::default(), + address: default_address(), + external_address: Default::default(), enabled: default_enabled(), timeout_seconds: default_timeout_seconds(), ignore_mounts: Default::default(), @@ -336,22 +348,26 @@ pub struct ServerActionState { #[typeshare] #[derive( - Serialize, - Deserialize, Debug, - PartialEq, - Hash, - Eq, Clone, Copy, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, Default, + Display, + Serialize, + Deserialize, )] +#[strum(serialize_all = "kebab-case")] pub enum ServerState { + /// Server health check passing. + Ok, /// Server is unreachable. #[default] NotOk, - /// Server health check passing. - Ok, /// Server is disabled. Disabled, } diff --git a/client/core/rs/src/entities/stack.rs b/client/core/rs/src/entities/stack.rs index 4db9e2946..774613e0d 100644 --- a/client/core/rs/src/entities/stack.rs +++ b/client/core/rs/src/entities/stack.rs @@ -32,10 +32,10 @@ impl Stack { /// If fresh is passed, it will bypass the deployed project name. /// and get the most up to date one from just project_name field falling back to stack name. pub fn project_name(&self, fresh: bool) -> String { - if !fresh { - if let Some(project_name) = &self.info.deployed_project_name { - return project_name.clone(); - } + if !fresh + && let Some(project_name) = &self.info.deployed_project_name + { + return project_name.clone(); } if self.config.project_name.is_empty() { self.name.clone() @@ -120,6 +120,8 @@ pub struct StackServiceWithUpdate { Default, PartialEq, Eq, + PartialOrd, + Ord, Serialize, Deserialize, Display, diff --git a/client/core/rs/src/entities/sync.rs b/client/core/rs/src/entities/sync.rs index 49a2c4cc8..739924a48 100644 --- a/client/core/rs/src/entities/sync.rs +++ b/client/core/rs/src/entities/sync.rs @@ -53,17 +53,27 @@ pub struct ResourceSyncListItemInfo { #[typeshare] #[derive( - Debug, Clone, Copy, Default, Serialize, Deserialize, Display, + Debug, + Clone, + Copy, + Default, + PartialEq, + Eq, + PartialOrd, + Ord, + Serialize, + Deserialize, + Display, )] pub enum ResourceSyncState { - /// Last sync successful (or never synced). No Changes pending - Ok, - /// Last sync failed - Failed, /// Currently syncing Syncing, /// Updates pending Pending, + /// Last sync successful (or never synced). No Changes pending + Ok, + /// Last sync failed + Failed, /// Other case #[default] Unknown, diff --git a/client/core/rs/src/entities/tag.rs b/client/core/rs/src/entities/tag.rs index 67c674e3a..309cce562 100644 --- a/client/core/rs/src/entities/tag.rs +++ b/client/core/rs/src/entities/tag.rs @@ -32,14 +32,30 @@ pub struct Tag { #[cfg_attr(feature = "mongo", unique_index)] pub name: String, - /// Hex color code with alpha for UI display - #[serde(default)] - pub color: TagColor, - #[serde(default)] #[builder(default)] #[cfg_attr(feature = "mongo", index)] pub owner: String, + + /// Hex color code with alpha for UI display + #[serde(default)] + #[builder(default)] + pub color: TagColor, + // /// This field is not stored on database, + // /// but rather populated at query time based on results from the other resources. + // #[serde(default, skip_serializing_if = "is_false")] + // #[builder(default)] + // pub unused: bool, +} + +// fn is_false(b: &bool) -> bool { +// !b +// } + +impl Tag { + pub fn builder() -> TagBuilder { + TagBuilder::default() + } } #[typeshare] diff --git a/client/core/rs/src/lib.rs b/client/core/rs/src/lib.rs index bb2b2516e..12f21c0fc 100644 --- a/client/core/rs/src/lib.rs +++ b/client/core/rs/src/lib.rs @@ -28,7 +28,7 @@ //! let update = client.execute(RunBuild { build: "test-build".to_string() }).await?: //! ``` -use std::sync::OnceLock; +use std::{sync::OnceLock, time::Duration}; use anyhow::Context; use api::read::GetVersion; @@ -189,6 +189,7 @@ impl KomodoClient { if update.status == entities::update::UpdateStatus::Complete { return Ok(update); } + tokio::time::sleep(Duration::from_millis(500)).await; } } diff --git a/client/core/ts/package.json b/client/core/ts/package.json index b4e9791a8..369f5eea0 100644 --- a/client/core/ts/package.json +++ b/client/core/ts/package.json @@ -1,6 +1,6 @@ { "name": "komodo_client", - "version": "1.18.4", + "version": "1.19.0", "description": "Komodo client package", "homepage": "https://komo.do", "main": "dist/lib.js", diff --git a/client/core/ts/runfile.toml b/client/core/ts/runfile.toml new file mode 100644 index 000000000..24301c264 --- /dev/null +++ b/client/core/ts/runfile.toml @@ -0,0 +1,3 @@ +[publish-ts-client] +description = "publish the typescript client to npm" +cmd = "npm publish" \ No newline at end of file diff --git a/client/core/ts/src/lib.ts b/client/core/ts/src/lib.ts index 18847d074..bb473a72f 100644 --- a/client/core/ts/src/lib.ts +++ b/client/core/ts/src/lib.ts @@ -443,7 +443,7 @@ export function KomodoClient(url: string, options: InitOptions) { * and gives a callback to handle the output as it comes in. * * ```ts - * const stream = await komodo.execute_terminal( + * await komodo.execute_terminal( * { * server: "my-server", * terminal: "name", @@ -499,7 +499,7 @@ export function KomodoClient(url: string, options: InitOptions) { * and gives a callback to handle the output as it comes in. * * ```ts - * const stream = await komodo.execute_container_exec( + * await komodo.execute_container_exec( * { * server: "my-server", * container: "name", @@ -550,7 +550,7 @@ export function KomodoClient(url: string, options: InitOptions) { * and gives a callback to handle the output as it comes in. * * ```ts - * const stream = await komodo.execute_deployment_exec( + * await komodo.execute_deployment_exec( * { * deployment: "my-deployment", * shell: "bash", @@ -599,7 +599,7 @@ export function KomodoClient(url: string, options: InitOptions) { * and gives a callback to handle the output as it comes in. * * ```ts - * const stream = await komodo.execute_stack_exec( + * await komodo.execute_stack_exec( * { * stack: "my-stack", * service: "database" diff --git a/client/core/ts/src/responses.ts b/client/core/ts/src/responses.ts index db0a42f53..23a5e01c0 100644 --- a/client/core/ts/src/responses.ts +++ b/client/core/ts/src/responses.ts @@ -2,7 +2,7 @@ import * as Types from "./types.js"; export type AuthResponses = { GetLoginOptions: Types.GetLoginOptionsResponse; - CreateLocalUser: Types.CreateLocalUserResponse; + SignUpLocalUser: Types.SignUpLocalUserResponse; LoginLocalUser: Types.LoginLocalUserResponse; ExchangeForJwt: Types.ExchangeForJwtResponse; GetUser: Types.GetUserResponse; @@ -179,9 +179,10 @@ export type ReadResponses = { export type WriteResponses = { // ==== USER ==== - UpdateUserUsername: Types.UpdateUserUsername; - UpdateUserPassword: Types.UpdateUserPassword; - DeleteUser: Types.DeleteUser; + CreateLocalUser: Types.CreateLocalUserResponse; + UpdateUserUsername: Types.UpdateUserUsernameResponse; + UpdateUserPassword: Types.UpdateUserPasswordResponse; + DeleteUser: Types.DeleteUserResponse; // ==== SERVICE USER ==== CreateServiceUser: Types.CreateServiceUserResponse; @@ -292,7 +293,7 @@ export type WriteResponses = { DeleteResourceSync: Types.ResourceSync; UpdateResourceSync: Types.ResourceSync; RenameResourceSync: Types.Update; - CommitSync: Types.ResourceSync; + CommitSync: Types.Update; WriteSyncFileContents: Types.Update; RefreshResourceSyncPending: Types.ResourceSync; CreateSyncWebhook: Types.CreateSyncWebhookResponse; @@ -407,4 +408,9 @@ export type ExecuteResponses = { // ==== ALERTER ==== TestAlerter: Types.Update; + + // ==== MAINTENANCE ==== + ClearRepoCache: Types.Update; + BackupCoreDatabase: Types.Update; + GlobalAutoUpdate: Types.Update; }; diff --git a/client/core/ts/src/types.ts b/client/core/ts/src/types.ts index 8713520b6..0fd3952b6 100644 --- a/client/core/ts/src/types.ts +++ b/client/core/ts/src/types.ts @@ -1,5 +1,5 @@ /* - Generated by typeshare 1.13.2 + Generated by typeshare 1.13.3 */ export interface MongoIdObj { @@ -63,7 +63,16 @@ export enum ScheduleFormat { Cron = "Cron", } +export enum FileFormat { + KeyValue = "key_value", + Toml = "toml", + Yaml = "yaml", + Json = "json", +} + export interface ActionConfig { + /** Whether this action should run at startup. */ + run_at_startup: boolean; /** Choose whether to specify schedule as regular CRON, or using the english to CRON parser. */ schedule_format?: ScheduleFormat; /** @@ -116,6 +125,13 @@ export interface ActionConfig { * Supports variable / secret interpolation. */ file_contents?: string; + /** + * Specify the format in which the arguments are defined. + * Default: `key_value` (like environment) + */ + arguments_format?: FileFormat; + /** Default arguments to give to the Action for use in the script at `ARGS`. */ + arguments?: string; } /** Represents an empty json object: `{}` */ @@ -431,6 +447,9 @@ export enum Operation { WriteSyncContents = "WriteSyncContents", CommitSync = "CommitSync", RunSync = "RunSync", + ClearRepoCache = "ClearRepoCache", + BackupCoreDatabase = "BackupCoreDatabase", + GlobalAutoUpdate = "GlobalAutoUpdate", CreateVariable = "CreateVariable", UpdateVariableValue = "UpdateVariableValue", DeleteVariable = "DeleteVariable", @@ -693,12 +712,12 @@ export interface BuildInfo { export type Build = Resource; export enum BuildState { + /** Currently building */ + Building = "Building", /** Last build successful (or never built) */ Ok = "Ok", /** Last build failed */ Failed = "Failed", - /** Currently building */ - Building = "Building", /** Other case */ Unknown = "Unknown", } @@ -780,13 +799,17 @@ export type BuilderQuery = ResourceQuery; export type Execution = /** The "null" execution. Does nothing. */ | { type: "None", params: NoData } + /** Run the target action. (alias: `action`, `ac`) */ | { type: "RunAction", params: RunAction } | { type: "BatchRunAction", params: BatchRunAction } + /** Run the target procedure. (alias: `procedure`, `pr`) */ | { type: "RunProcedure", params: RunProcedure } | { type: "BatchRunProcedure", params: BatchRunProcedure } + /** Run the target build. (alias: `build`, `bd`) */ | { type: "RunBuild", params: RunBuild } | { type: "BatchRunBuild", params: BatchRunBuild } | { type: "CancelBuild", params: CancelBuild } + /** Deploy the target deployment. (alias: `dp`) */ | { type: "Deploy", params: Deploy } | { type: "BatchDeploy", params: BatchDeploy } | { type: "PullDeployment", params: PullDeployment } @@ -797,6 +820,7 @@ export type Execution = | { type: "StopDeployment", params: StopDeployment } | { type: "DestroyDeployment", params: DestroyDeployment } | { type: "BatchDestroyDeployment", params: BatchDestroyDeployment } + /** Clone the target repo */ | { type: "CloneRepo", params: CloneRepo } | { type: "BatchCloneRepo", params: BatchCloneRepo } | { type: "PullRepo", params: PullRepo } @@ -825,8 +849,11 @@ export type Execution = | { type: "PruneDockerBuilders", params: PruneDockerBuilders } | { type: "PruneBuildx", params: PruneBuildx } | { type: "PruneSystem", params: PruneSystem } + /** Execute a Resource Sync. (alias: `sync`) */ | { type: "RunSync", params: RunSync } + /** Commit a Resource Sync. (alias: `commit`) */ | { type: "CommitSync", params: CommitSync } + /** Deploy the target stack. (alias: `stack`, `st`) */ | { type: "DeployStack", params: DeployStack } | { type: "BatchDeployStack", params: BatchDeployStack } | { type: "DeployStackIfChanged", params: DeployStackIfChanged } @@ -841,6 +868,9 @@ export type Execution = | { type: "DestroyStack", params: DestroyStack } | { type: "BatchDestroyStack", params: BatchDestroyStack } | { type: "TestAlerter", params: TestAlerter } + | { type: "ClearRepoCache", params: ClearRepoCache } + | { type: "BackupCoreDatabase", params: BackupCoreDatabase } + | { type: "GlobalAutoUpdate", params: GlobalAutoUpdate } | { type: "Sleep", params: Sleep }; /** Allows to enable / disabled procedures in the sequence / parallel vec on the fly */ @@ -994,19 +1024,6 @@ export interface GitProviderAccount { export type CreateGitProviderAccountResponse = GitProviderAccount; -/** JSON containing an authentication token. */ -export interface JwtResponse { - /** A token the user can use to authenticate their requests. */ - jwt: string; -} - -/** Response for [CreateLocalUser]. */ -export type CreateLocalUserResponse = JwtResponse; - -export type CreateProcedureResponse = Procedure; - -export type CreateRepoWebhookResponse = NoData; - export type UserConfig = /** User that logs in with username / password */ | { type: "Local", data: { @@ -1062,6 +1079,12 @@ export interface User { updated_at?: I64; } +export type CreateLocalUserResponse = User; + +export type CreateProcedureResponse = Procedure; + +export type CreateRepoWebhookResponse = NoData; + export type CreateServiceUserResponse = User; export type CreateStackWebhookResponse = NoData; @@ -1298,6 +1321,14 @@ export interface DeploymentQuerySpecifics { export type DeploymentQuery = ResourceQuery; +/** JSON containing an authentication token. */ +export interface JwtResponse { + /** User ID for signed in user. */ + user_id: string; + /** A token the user can use to authenticate their requests. */ + jwt: string; +} + /** Response for [ExchangeForJwt]. */ export type ExchangeForJwtResponse = JwtResponse; @@ -1922,6 +1953,11 @@ export interface ServerConfig { * Default: http://localhost:8120 */ address: string; + /** + * The address to use with links for containers on the server. + * If empty, will use the 'address' for links. + */ + external_address?: string; /** An optional region label */ region?: string; /** @@ -2425,9 +2461,9 @@ export interface Tag { */ _id?: MongoId; name: string; + owner?: string; /** Hex color code with alpha for UI display */ color?: TagColor; - owner?: string; } export type GetTagResponse = Tag; @@ -2468,14 +2504,14 @@ export type GetUserResponse = User; export type GetVariableResponse = Variable; export enum ContainerStateStatusEnum { - Empty = "", - Created = "created", Running = "running", + Created = "created", Paused = "paused", Restarting = "restarting", Exited = "exited", Removing = "removing", Dead = "dead", + Empty = "", } export enum HealthStatusEnum { @@ -3271,6 +3307,8 @@ export type InspectDockerVolumeResponse = Volume; export type InspectStackContainerResponse = Container; +export type JsonObject = any; + export type JsonValue = any; export type ListActionsResponse = ActionListItem[]; @@ -3320,11 +3358,11 @@ export interface ContainerListItem { /** The network mode */ network_mode?: string; /** The network names attached to container */ - networks: string[]; + networks?: string[]; /** Port mappings for the container */ - ports: Port[]; + ports?: Port[]; /** The volume names attached to container */ - volumes: string[]; + volumes?: string[]; /** The container stats, if they can be retreived. */ stats?: ContainerStats; /** @@ -3533,12 +3571,12 @@ export interface Permission { export type ListPermissionsResponse = Permission[]; export enum ProcedureState { + /** Currently running */ + Running = "Running", /** Last run successful */ Ok = "Ok", /** Last run failed */ Failed = "Failed", - /** Currently running */ - Running = "Running", /** Other case (never run) */ Unknown = "Unknown", } @@ -3615,14 +3653,14 @@ export type RepoListItem = ResourceListItem; export type ListReposResponse = RepoListItem[]; export enum ResourceSyncState { - /** Last sync successful (or never synced). No Changes pending */ - Ok = "Ok", - /** Last sync failed */ - Failed = "Failed", /** Currently syncing */ Syncing = "Syncing", /** Updates pending */ Pending = "Pending", + /** Last sync successful (or never synced). No Changes pending */ + Ok = "Ok", + /** Last sync failed */ + Failed = "Failed", /** Other case */ Unknown = "Unknown", } @@ -3692,10 +3730,10 @@ export type ListSchedulesResponse = Schedule[]; export type ListSecretsResponse = string[]; export enum ServerState { - /** Server is unreachable. */ - NotOk = "NotOk", /** Server health check passing. */ Ok = "Ok", + /** Server is unreachable. */ + NotOk = "NotOk", /** Server is disabled. */ Disabled = "Disabled", } @@ -3707,6 +3745,11 @@ export interface ServerListItemInfo { region: string; /** Address of the server. */ address: string; + /** + * External address of the server (reachable by users). + * Used with links. + */ + external_address?: string; /** The Komodo Periphery version of the server. */ version: string; /** Whether server is configured to send unreachable alerts. */ @@ -3914,6 +3957,9 @@ export type ServerQuery = ResourceQuery; export type SetLastSeenUpdateResponse = NoData; +/** Response for [SignUpLocalUser]. */ +export type SignUpLocalUserResponse = JwtResponse; + export interface StackQuerySpecifics { /** * Query only for Stacks on these Servers. @@ -4053,6 +4099,19 @@ export interface AwsBuilderConfig { secrets?: string[]; } +/** + * Backs up the Komodo Core database to compressed jsonl files. + * Admin only. Response: [Update] + * + * Mount a folder to `/backups`, and Core will use it to create + * timestamped database dumps, which can be restored using + * the Komodo CLI. + * + * TODO: Link to docs + */ +export interface BackupCoreDatabase { +} + /** Builds multiple Repos in parallel that match pattern. Response: [BatchExecutionResponse]. */ export interface BatchBuildRepo { /** @@ -4306,6 +4365,13 @@ export interface CancelRepoBuild { repo: string; } +/** + * Clears all repos from the Core repo cache. Admin only. + * Response: [Update] + */ +export interface ClearRepoCache { +} + /** * Clones the target repo. Response: [Update]. * @@ -4838,19 +4904,17 @@ export interface CreateGitProviderAccount { } /** - * Create a new local user account. Will fail if a user with the - * given username already exists. - * Response: [CreateLocalUserResponse]. + * **Admin only.** Create a local user. + * Response: [User]. * - * Note. This method is only available if the core api has `local_auth` enabled. + * Note. Not to be confused with /auth/SignUpLocalUser. + * This method requires admin user credentials, and can + * bypass disabled user registration. */ export interface CreateLocalUser { - /** The username for the new user. */ + /** The username for the local user. */ username: string; - /** - * The password for the new user. - * This cannot be retreived later. - */ + /** A password for the local user. */ password: string; } @@ -4971,6 +5035,8 @@ export interface CreateSyncWebhook { export interface CreateTag { /** The name of the tag. */ name: string; + /** Tag color. Default: Slate. */ + color?: TagColor; } /** @@ -5578,7 +5644,7 @@ export interface FullContainerStats { precpu_stats?: ContainerCpuStats; memory_stats?: ContainerMemoryStats; /** Network statistics for the container per interface. This field is omitted if the container has no networking enabled. */ - networks?: ContainerNetworkStats; + networks?: Record; } /** Get a specific action. Response: [Action]. */ @@ -5776,6 +5842,8 @@ export interface GetCoreInfoResponse { github_webhook_owners: string[]; /** Whether to disable websocket automatic reconnect. */ disable_websocket_reconnect: boolean; + /** Whether to enable fancy toml highlighting. */ + enable_fancy_toml: boolean; /** TZ identifier Core is using, if manually set. */ timezone: string; } @@ -6371,6 +6439,17 @@ export interface GetVersionResponse { version: string; } +/** + * Trigger a global poll for image updateson Stacks and Deployments + * with `poll_for_updates` or `auto_update` enabled. + * Admin only. Response: [Update] + * + * 1. `docker compose pull` any Stacks / Deployments with `poll_for_updates` or `auto_update` enabled. This will pick up any available updates. + * 2. Redeploy Stacks / Deployments that have updates found. + */ +export interface GlobalAutoUpdate { +} + /** * Inspect the docker container associated with the Deployment. * Response: [Container]. @@ -7471,15 +7550,29 @@ export interface RestartStack { export interface RunAction { /** Id or name */ action: string; + /** + * Custom arguments which are merged on top of the default arguments. + * CLI Format: `"VAR1=val1&VAR2=val2"` + * + * Webhook-triggered actions use this to pass WEBHOOK_BRANCH and WEBHOOK_BODY. + */ + args?: JsonObject; } /** * Runs the target build. Response: [Update]. * * 1. Get a handle to the builder. If using AWS builder, this means starting a builder ec2 instance. + * * 2. Clone the repo on the builder. If an `on_clone` commmand is given, it will be executed. + * * 3. Execute `docker build {...params}`, where params are determined using the builds configuration. - * 4. If a dockerhub account is attached, the build will be pushed to that account. + * + * 4. If a docker registry is configured, the build will be pushed to the registry. + * + * 5. If using AWS builder, destroy the builder ec2 instance. + * + * 6. Deploy any Deployments with *Redeploy on Build* enabled. */ export interface RunBuild { /** Can be build id or name */ @@ -7643,6 +7736,24 @@ export interface SetUsersInUserGroup { users: string[]; } +/** + * Sign up a new local user account. Will fail if a user with the + * given username already exists. + * Response: [SignUpLocalUserResponse]. + * + * Note. This method is only available if the core api has `local_auth` enabled, + * and if user registration is not disabled (after the first user). + */ +export interface SignUpLocalUser { + /** The username for the new user. */ + username: string; + /** + * The password for the new user. + * This cannot be retreived later. + */ + password: string; +} + /** Info for network interface usage. */ export interface SingleNetworkInterfaceUsage { /** The network interface name */ @@ -7659,6 +7770,7 @@ export interface SlackAlerterEndpoint { url: string; } +/** Sleeps for the specified time. */ export interface Sleep { duration_ms?: I64; } @@ -8200,7 +8312,7 @@ export interface WriteSyncFileContents { export type AuthRequest = | { type: "GetLoginOptions", params: GetLoginOptions } - | { type: "CreateLocalUser", params: CreateLocalUser } + | { type: "SignUpLocalUser", params: SignUpLocalUser } | { type: "LoginLocalUser", params: LoginLocalUser } | { type: "ExchangeForJwt", params: ExchangeForJwt } | { type: "GetUser", params: GetUser }; @@ -8276,7 +8388,10 @@ export type ExecuteRequest = | { type: "RunAction", params: RunAction } | { type: "BatchRunAction", params: BatchRunAction } | { type: "TestAlerter", params: TestAlerter } - | { type: "RunSync", params: RunSync }; + | { type: "RunSync", params: RunSync } + | { type: "ClearRepoCache", params: ClearRepoCache } + | { type: "BackupCoreDatabase", params: BackupCoreDatabase } + | { type: "GlobalAutoUpdate", params: GlobalAutoUpdate }; /** * One representative IANA zone for each distinct base UTC offset in the tz database. @@ -8538,6 +8653,7 @@ export type UserRequest = | { type: "DeleteApiKey", params: DeleteApiKey }; export type WriteRequest = + | { type: "CreateLocalUser", params: CreateLocalUser } | { type: "UpdateUserUsername", params: UpdateUserUsername } | { type: "UpdateUserPassword", params: UpdateUserPassword } | { type: "DeleteUser", params: DeleteUser } diff --git a/compose/compose.env b/compose/compose.env index b2e9dcdc9..ddc7418c0 100644 --- a/compose/compose.env +++ b/compose/compose.env @@ -38,6 +38,8 @@ KOMODO_TITLE=Komodo ## Create a server matching this address as the "first server". ## Use `https://host.docker.internal:8120` when using systemd-managed Periphery. KOMODO_FIRST_SERVER=https://periphery:8120 +## Give the first server a custom name. +KOMODO_FIRST_SERVER_NAME=Local ## Make all buttons just double-click, rather than the full confirmation dialog. KOMODO_DISABLE_CONFIRM_DIALOG=false @@ -61,6 +63,12 @@ KOMODO_JWT_TTL="1-day" ## Enable login with username + password. KOMODO_LOCAL_AUTH=true +## Set the initial admin username created upon first launch. +## Comment out to disable initial user creation, +## and create first user using signup button. +KOMODO_INIT_ADMIN_USERNAME=admin +## Set the initial admin password +KOMODO_INIT_ADMIN_PASSWORD=changeme ## Disable new user signups. KOMODO_DISABLE_USER_REGISTRATION=false ## All new logins are auto enabled diff --git a/compose/ferretdb.compose.yaml b/compose/ferretdb.compose.yaml index 973ef1721..2a6b3591b 100644 --- a/compose/ferretdb.compose.yaml +++ b/compose/ferretdb.compose.yaml @@ -9,7 +9,7 @@ services: postgres: - # Recommended: Pin to a specific version + # 🚨 Pin to a specific version. Updates can be breaking. # https://github.com/FerretDB/documentdb/pkgs/container/postgres-documentdb image: ghcr.io/ferretdb/postgres-documentdb labels: @@ -25,7 +25,7 @@ services: POSTGRES_DB: postgres ferretdb: - # Recommended: Pin to a specific version + # 🚨 Pin to a specific version. Updates can be breaking. # https://github.com/FerretDB/FerretDB/pkgs/container/ferretdb image: ghcr.io/ferretdb/ferretdb labels: @@ -54,15 +54,13 @@ services: KOMODO_DATABASE_ADDRESS: ferretdb:27017 KOMODO_DATABASE_USERNAME: ${KOMODO_DB_USERNAME} KOMODO_DATABASE_PASSWORD: ${KOMODO_DB_PASSWORD} - volumes: - ## Core cache for repos for latest commit hash / contents - - repo-cache:/repo-cache - ## Store sync files on server - # - /path/to/syncs:/syncs - ## Optionally mount a custom core.config.toml - # - /path/to/core.config.toml:/config/config.toml + # volumes: + # ## Store sync files on server + # - /path/to/syncs:/syncs + # ## Optionally mount a custom core.config.toml + # - /path/to/core.config.toml:/config/config.toml ## Allows for systemd Periphery connection at - ## "http://host.docker.internal:8120" + ## "https://host.docker.internal:8120" # extra_hosts: # - host.docker.internal:host-gateway diff --git a/compose/mongo.compose.yaml b/compose/mongo.compose.yaml index bb85f1760..5c0e71b21 100644 --- a/compose/mongo.compose.yaml +++ b/compose/mongo.compose.yaml @@ -37,15 +37,13 @@ services: KOMODO_DATABASE_ADDRESS: mongo:27017 KOMODO_DATABASE_USERNAME: ${KOMODO_DB_USERNAME} KOMODO_DATABASE_PASSWORD: ${KOMODO_DB_PASSWORD} - volumes: - ## Core cache for repos for latest commit hash / contents - - repo-cache:/repo-cache - ## Store sync files on server - # - /path/to/syncs:/syncs - ## Optionally mount a custom core.config.toml - # - /path/to/core.config.toml:/config/config.toml + # volumes: + # ## Store sync files on server + # - /path/to/syncs:/syncs + # ## Optionally mount a custom core.config.toml + # - /path/to/core.config.toml:/config/config.toml ## Allows for systemd Periphery connection at - ## "http://host.docker.internal:8120" + ## "https://host.docker.internal:8120" # extra_hosts: # - host.docker.internal:host-gateway diff --git a/config/core.config.toml b/config/core.config.toml index 365794b18..bd51e412c 100644 --- a/config/core.config.toml +++ b/config/core.config.toml @@ -10,13 +10,16 @@ ## left out of the file, the "Default" value will be used. ## This file is bundled into the official image, `ghcr.io/moghtech/komodo`, -## as the default config at `/config/config.toml`. +## as the default config at `/config/.default.config.toml`. ## Komodo can start with no external config file mounted. -## There is usually no need to create this file on your host. -## Most fields can instead be configured using environment variables. +## Most fields can also be configured using environment variables. ## Environment variables will override values set in this file. +## Can also use JSON or YAML if preffered. You can convert here: +## - YAML: https://it-tools.tech/toml-to-yaml +## - JSON: https://it-tools.tech/toml-to-json + ## This will be the document title on the web page. ## Env: KOMODO_TITLE ## Default: 'Komodo' @@ -26,7 +29,7 @@ title = "Komodo" ## Eg https://komodo.example.com or http://12.34.56.78:9120. This should match the address configured in your Oauth app. ## Env: KOMODO_HOST ## Required, no default. -host = "https://demo.komo.do" +host = "https://komodo.example.com" ## The port the core system will run on. ## Env: KOMODO_PORT @@ -44,7 +47,7 @@ bind_ip = "[::]" ## If the periphery servers don't have passkeys configured, this doesn't need to be changed. ## Env: KOMODO_PASSKEY or KOMODO_PASSKEY_FILE ## Required, no default -passkey = "a_random_passkey" +passkey = "default-passkey-changeme" ## Ensure a server with this address exists on Core ## upon first startup. Example: `https://periphery:8120` @@ -52,6 +55,11 @@ passkey = "a_random_passkey" ## Optional, no default. first_server = "" +## Give the first server a custom name. +## Env: KOMODO_FIRST_SERVER_NAME +## Default: Local +first_server_name = "Local" + ## Disables write support on resources in the UI. ## This protects users that that would normally have write priviledges during their UI usage, ## when they intend to fully rely on ResourceSyncs to manage config. @@ -71,6 +79,13 @@ disable_confirm_dialog = false ## Default: false disable_websocket_reconnect = false + +## Disable init system resource creation on fresh Komodo launch. +## These include the 'Backup Core Database' and 'Global Auto Update' procedures. +## Env: KOMODO_DISABLE_INIT_RESOURCES +## Default: false +disable_init_resources = false + ## Configure the directory for sync files (inside the container). ## There shouldn't be a need to change this, just mount a volume. ## Env: KOMODO_SYNC_DIRECTORY @@ -89,6 +104,12 @@ repo_directory = "/repo-cache" ## Default: /action-cache action_directory = "/action-cache" +## Interface to use as default route in multi-NIC environments. +## Env: KOMODO_INTERNET_INTERFACE +## Example: "eth1" +## Optional, no default. +internet_interface = "" + ################ # AUTH / LOGIN # ################ @@ -106,6 +127,16 @@ action_directory = "/action-cache" ## Default: false local_auth = false +## Initialize the first admin user when starting up Komodo for the first time. +## Env: KOMODO_INIT_ADMIN_USERNAME or KOMODO_INIT_ADMIN_USERNAME_FILE +## Default: None +# init_admin_username = "admin" + +## Set password for first admin user +## Env: KOMODO_INIT_ADMIN_PASSWORD or KOMODO_INIT_ADMIN_PASSWORD_FILE +## Default: changeme +init_admin_password = "changeme" + ## Normally new users will be registered, but not enabled until an Admin enables them. ## With `disable_user_registration = true`, only the first user to log in will registered as a user. ## Env: KOMODO_DISABLE_USER_REGISTRATION diff --git a/config/komodo.cli.toml b/config/komodo.cli.toml new file mode 100644 index 000000000..05ba38e33 --- /dev/null +++ b/config/komodo.cli.toml @@ -0,0 +1,79 @@ +########################## +# 🦎 KOMODO CLI CONFIG 🦎 # +########################## + +## This is the offical "Default" config file for the Komodo CLI. +## It serves as documentation for the meaning of the fields. +## It is located at `https://github.com/moghtech/komodo/blob/main/config/komodo.cli.toml`. + +## Most fields can also be configured using cli arguments and environment variables. +## These will will override values set in this file. (cli args > env > config files). + +## You can also use JSON or YAML if preffered. You can convert here: +## - YAML: https://it-tools.tech/toml-to-yaml +## - JSON: https://it-tools.tech/toml-to-json + +# Choose default profile to use with `km ...` +default_profile = "Default" +# default_profile = "Alt" + +# Set base values if they aren't defined in profile +# Default: 14 +max_backups = 7 + +# Options: HorizontalOnly, VeriticalOnly, OutsideOnly, InsideOnly, AllBorders +# Default: HorizontalOnly +table_format = "HorizontalOnly" + +[[profile]] +name = "Default" +aliases = ["d"] # Use `km -p d ...` +# +# Env: KOMODO_CLI_HOST > KOMODO_HOST +host = "https://komodo.example.com" +# Env: KOMODO_CLI_KEY +key = "K-..." +# Env: KOMODO_CLI_SECRET +secret = "S-..." +# +# Env: KOMODO_CLI_BACKUPS_FOLDER +backups_folder = "/backups" +# Env: KOMODO_CLI_MAX_BACKUPS +max_backups = 14 +# +# DATABASE USED TO BACKUP / COPY FROM +# +## Env: KOMODO_DATABASE_URI or KOMODO_DATABASE_URI_FILE +database.uri = "" +## ==== * OR * ==== ## +# Construct the address as mongodb://{username}:{password}@{address} +## Env: KOMODO_DATABASE_URI or KOMODO_DATABASE_URI_FILE +database.address = "localhost:27017" +## Env: KOMODO_DATABASE_USERNAME or KOMODO_DATABASE_USERNAME_FILE +database.username = "" +## Env: KOMODO_DATABASE_PASSWORD or KOMODO_DATABASE_PASSWORD_FILE +database.password = "" +## Env: KOMODO_DATABASE_DB_NAME +## Default: komodo. +database.db_name = "komodo" +# +# DATABASE USED TO RESTORE / COPY TO +# +## Env: KOMODO_CLI_DATABASE_TARGET_URI +database_target.uri = "" +## ==== * OR * ==== ## +# Construct the address as mongodb://{username}:{password}@{address} +## Env: KOMODO_CLI_DATABASE_TARGET_URI +database_target.address = "localhost:27017" +## Env: KOMODO_CLI_DATABASE_TARGET_USERNAME +database_target.username = "" +## Env: KOMODO_CLI_DATABASE_TARGET_PASSWORD +database_target.password = "" +## Env: KOMODO_CLI_DATABASE_TARGET_DB_NAME +## Default: komodo. +database_target.db_name = "komodo" + + +[[profile]] +name = "Alt" +# ... Configure same as above \ No newline at end of file diff --git a/config/periphery.config.toml b/config/periphery.config.toml index 3adcfe262..e53a8b824 100644 --- a/config/periphery.config.toml +++ b/config/periphery.config.toml @@ -13,6 +13,13 @@ ## file will be located either in `/etc/komodo/periphery.config.toml`, ## or for user installs, `$HOME/.config/komodo/periphery.config.toml`. +## Most fields can also be configured using environment variables. +## Environment variables will override values set in this file. + +## You can also use JSON or YAML if preffered. You can convert here: +## - YAML: https://it-tools.tech/toml-to-yaml +## - JSON: https://it-tools.tech/toml-to-json + ## Optional. The port the server runs on. ## Env: PERIPHERY_PORT ## Default: 8120 @@ -96,7 +103,8 @@ exclude_disk_mounts = [] ######## ## Optional. Limit the ip addresses which can call the periphery api. -## Example: allowed_ips = ["::ffff:12.34.56.78"] +## Supports Ipv4 / Ipv6 addresses and subnets. +## Examples: allowed_ips = ["::ffff:12.34.56.78", "10.0.10.0/24"] ## Env: PERIPHERY_ALLOWED_IPS ## Default: empty, which will not block any request by ip. allowed_ips = [] diff --git a/deploy/deno.json b/deploy/deno.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/deploy/deno.json @@ -0,0 +1 @@ +{} diff --git a/deploy/komodo.ts b/deploy/komodo.ts new file mode 100755 index 000000000..eff1514fe --- /dev/null +++ b/deploy/komodo.ts @@ -0,0 +1,50 @@ +import * as TOML from "jsr:@std/toml"; + +const branch = await new Deno.Command("bash", { + args: ["-c", "git rev-parse --abbrev-ref HEAD"], +}) + .output() + .then((r) => new TextDecoder("utf-8").decode(r.stdout).trim()); + +const cargo_toml_str = await Deno.readTextFile("Cargo.toml"); +const prev_version = ( + TOML.parse(cargo_toml_str) as { + workspace: { package: { version: string } }; + } +).workspace.package.version; + +const [version, tag, count] = prev_version.split("-"); +const next_count = Number(count) + 1; + +const next_version = `${version}-${tag}-${next_count}`; + +await Deno.writeTextFile( + "Cargo.toml", + cargo_toml_str.replace( + `version = "${prev_version}"`, + `version = "${next_version}"` + ) +); + +// Cargo check first here to make sure lock file is updated before commit. +const cmd = ` +cargo check +echo "" + +git add --all +git commit --all --message "deploy ${version}-${tag}-${next_count}" + +echo "" +git push +echo "" + +km run -y action deploy-komodo "KOMODO_BRANCH=${branch}&KOMODO_VERSION=${version}&KOMODO_TAG=${tag}-${next_count}" +` + .split("\n") + .map((line) => line.trim()) + .filter((line) => line.length > 0 && !line.startsWith("//")) + .join(" && "); + +new Deno.Command("bash", { + args: ["-c", cmd], +}).spawn(); diff --git a/docsite/docs/api.md b/docsite/docs/ecosystem/api.md similarity index 100% rename from docsite/docs/api.md rename to docsite/docs/ecosystem/api.md diff --git a/docsite/docs/ecosystem/cli.mdx b/docsite/docs/ecosystem/cli.mdx new file mode 100644 index 000000000..8989a99b3 --- /dev/null +++ b/docsite/docs/ecosystem/cli.mdx @@ -0,0 +1,121 @@ +# Komodo CLI + +The Komodo CLI, `km`, can be used to: + - Quickly **run executions** and update **resources** and **variables**. + - **Reset user passwords** and elevate users to **Super Admin**. + - Perform Database **backup**, **restore**, and **copy**. + +The Komodo Core image comes packaged with the Komodo CLI, +and is available for usage inside running container with `docker exec -it komodo-core km ...`. +This way, it inherits the Core database config in order to easily perform backups with `km db backup -y`. + +### Examples + + - `km --help` + - `km deploy stack my-stack` + - `km run action my-action -y` + - `km database backup` + - `km db restore` + - `km set var MY_VAR my_value -y` + - `km update build my-build "version=1.19.0&branch=release"` + - `km x commit my-sync` + - `km set user mbecks super-admin true` + - `km set user mbecks password "temp-password"` + +### Install + +There are binaries available for **Linux** (x86_64 / aarch64), **MacOS** (apple silicon), as +well as a distroless image: **`ghcr.io/moghtech/komodo-cli`**. + +#### Linux + +You can install the binary using the following command: + +System-wide, as root, to `/usr/local/bin/km`: +```bash +curl -sSL https://raw.githubusercontent.com/moghtech/komodo/main/scripts/install-cli.py | python3 +``` + +Or as non-root, to `${HOME}/.local/bin/km`: +```bash +curl -sSL https://raw.githubusercontent.com/moghtech/komodo/main/scripts/install-cli.py | python3 - --user +``` + +#### MacOS (Homebrew) + +Add the `moghtech/komodo` tap, then install `km`: +```bash +brew tap moghtech/komodo && \ + brew install km +``` + +#### Container + +You can alias a docker run command: +```bash +alias km='docker run --rm -v $HOME/.config/komodo:/config ghcr.io/moghtech/komodo-cli km' +km config +``` + +### Configure + +The CLI uses a configuration file to pass the Komodo host / api keys, database address and credentials, +and configure some other behaviors. Additionally, all configuration fields can be individually overridden +using **CLI arguments** or **environment variables**, with CLI arguments having top priority. + +Whenever you want to check how config will be loaded, you can use the `km config` command +to print it out. + +#### File detection + +When run, CLI will scan the **current working directory** in addition to `${HOME}/.config/komodo` for any files matching the wildcard pattern **`*komodo.cli*.*`**, +parse them into a general representation, and then merge them together. Files which are detected later are merged later, +meaning they will override on conflicting fields. By default, files in `${HOME}/.config/komodo` come first +in the merge ordering, meaning they are **lower priority** than those detected in the current working directory. +You can also override these default paths by passing `km -c /path/to/1/base.config.yaml -c ./overrides ...`. + +If you want `km` to find configuration files in another directory, +you can use make `.kminclude` file inside one of the configured directories. + +``` +# Supports comments + +./.komodo # relative to directory containing `kmignore` + +/etc/komodo/komodo.cli.toml +``` + +Note that wildcards in these paths are **not supported**. + +#### Profiles + +In the files, you can configure multiple profiles, each with a name / aliases. Then you +choose which config profile to use with `km -p ...`. This allows you to easily switch between +multiple Cores you want to connect to, or different database backup / restore options. + +In order to avoid passing `-p ` every time, you can set a +`default_profile` at the top level of the configuration file. Additionally, +any fields you would like to be the "default" across all profiles can be +set at the top level of the file. + +#### Example File + +The configuration can also be passed as **YAML** or **JSON**. +You can use the it-tools to convert this TOML file to your preferred format: + - YAML: https://it-tools.tech/toml-to-yaml + - JSON: https://it-tools.tech/toml-to-json + +Quick download to `./komodo/komodo.cli.toml`: +```bash +wget -P komodo https://raw.githubusercontent.com/moghtech/komodo/main/config/komodo.cli.toml +``` + +```mdx-code-block +import RemoteCodeFile from "@site/src/components/RemoteCodeFile"; + + +``` \ No newline at end of file diff --git a/docsite/docs/other-resources.md b/docsite/docs/ecosystem/community.md similarity index 84% rename from docsite/docs/other-resources.md rename to docsite/docs/ecosystem/community.md index c7325464e..9879937fb 100644 --- a/docsite/docs/other-resources.md +++ b/docsite/docs/ecosystem/community.md @@ -1,5 +1,8 @@ -# Other Resources +# Community +### 3rd party tools +- [Ansible Role Komodo](https://github.com/bpbradley/ansible-role-komodo) by [bpbradley](https://github.com/bpbradley) +- [Komodo Import](https://foxxmd.github.io/komodo-import/docs/quickstart/) by [FoxxMD](https://github.com/FoxxMD) ### Posts and Guides - [Migrating to Komodo](https://blog.foxxmd.dev/posts/migrating-to-komodo) by [FoxxMD](https://github.com/FoxxMD) - [FAQ, Tips, and Tricks](https://blog.foxxmd.dev/posts/komodo-tips-tricks) by [FoxxMD](https://github.com/FoxxMD) diff --git a/docsite/docs/development.md b/docsite/docs/ecosystem/development.md similarity index 72% rename from docsite/docs/development.md rename to docsite/docs/ecosystem/development.md index ec67e3b3e..9bdcf5101 100644 --- a/docsite/docs/development.md +++ b/docsite/docs/ecosystem/development.md @@ -22,7 +22,7 @@ Running Komodo from [source](https://github.com/moghtech/komodo) requires either ## Docker -After making changes to the project, run `run -r dev-compose-build` to rebuild Komodo and then `run -r dev-compose-exposed` to start a Komodo container with the UI accessible at `localhost:9120`. Any changes made to source files will require re-running the `dev-compose-build` and `dev-compose-exposed` commands. +After making changes to the project, run `run dev-compose-build` to rebuild Komodo and then `run dev-compose-exposed` to start a Komodo container with the UI accessible at `localhost:9120`. Any changes made to source files will require re-running the `dev-compose-build` and `dev-compose-exposed` commands. ## Devcontainer @@ -39,17 +39,17 @@ To run a full Komodo instance from a non-container environment run commands in t * Ensure dependencies are up to date * `rustup update` -- ensure rust toolchain is up to date * Build and Run backend - * `run -r dev-core` -- Build and run Core API - * `run -r dev-periphery` -- Build and run Periphery API + * `run dev-core` -- Build and run Core API + * `run dev-periphery` -- Build and run Periphery API * Build Frontend * Install **typeshare-cli**: `cargo install typeshare-cli` - * **Run this once** -- `run -r link-client` -- generates TS client and links to the frontend + * **Run this once** -- `run link-client` -- generates TS client and links to the frontend * After running the above once: - * `run -r gen-client` -- Rebuild client - * `run -r dev-frontend` -- Start in dev (watch) mode - * `run -r build-frontend` -- Typecheck and build + * `run gen-client` -- Rebuild client + * `run dev-frontend` -- Start in dev (watch) mode + * `run build-frontend` -- Typecheck and build ## Docsite Development -Use `run -r dev-docsite` to start the [Docusaurus](https://docusaurus.io/) Komodo docs site in development mode. Changes made to files in `./docsite` will be automatically reloaded by the server. \ No newline at end of file +Use `run dev-docsite` to start the [Docusaurus](https://docusaurus.io/) Komodo docs site in development mode. Changes made to files in `./docsite` will be automatically reloaded by the server. \ No newline at end of file diff --git a/docsite/docs/ecosystem/index.mdx b/docsite/docs/ecosystem/index.mdx new file mode 100644 index 000000000..802c8ce43 --- /dev/null +++ b/docsite/docs/ecosystem/index.mdx @@ -0,0 +1,11 @@ +--- +slug: /ecosystem +--- + +# Ecosystem + +```mdx-code-block +import DocCardList from '@theme/DocCardList'; + + +``` \ No newline at end of file diff --git a/docsite/docs/file-paths.md b/docsite/docs/file-paths.md deleted file mode 100644 index 78a06c95b..000000000 --- a/docsite/docs/file-paths.md +++ /dev/null @@ -1,30 +0,0 @@ -# File Paths - -When working with Komodo, you might have to configure file or directory paths. - -## Relative Paths - -Where possible, it is better to use relative file paths. Using relative file paths removes the connection between the process being run and the particular server it runs on, making it easier to move things between servers. - -Where you see relative paths: - - - setting the build directory and path of the Dockerfile - - setting a pre build command path - -For all of the above, the path can be given relative to the root of the configured repo - -The one exception is the Dockerfile path, which is given relative to the build directory (This is done by Docker itself, and this pattern matches usage of the Docker CLI). - -There are 3 kinds of paths to pass: - - 1. to specify the root of the repo, use `.` as the path - 2. to specify a folder in the repo, pass it with **no** preceding `/`. For example, `example_folder` or `folder1/folder2` - 3. to specify an absolute path on the servers filesystem, use a preceding slash, eg. `/home/ubuntu/example`. This way should only be used if absolutely necessary, like when passing host paths when configuring docker volumes. - -### Implementation - -Relative file paths are joined with the path of the repo on the system using a Rust [PathBuf](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push). - -## Docker Volume Paths - -These are passed directly to the Docker CLI using `--volume /path/on/system:/path/in/container`. So for these, the same rules apply as when using Docker on the command line. Paths here should usually be given as absolute. It's also probably best to avoid usage of `~` or environment variables like `$HOME`, as this may lead to unexpected behavior. diff --git a/docsite/docs/resources/auto-update.md b/docsite/docs/resources/auto-update.md new file mode 100644 index 000000000..be26f42f4 --- /dev/null +++ b/docsite/docs/resources/auto-update.md @@ -0,0 +1,47 @@ +# Automatic Updates + +Starting from **v1.19.0**, new Komodo installs will automatically create the +**Global Auto Update** [Procedure](../resources/procedures#procedures), scheduled daily. +If you don't have it, this is the Toml: + +```toml +[[procedure]] +name = "Global Auto Update" +description = "Pulls and auto updates Stacks and Deployments using 'poll_for_updates' or 'auto_update'." +tags = ["system"] +config.schedule = "Every day at 03:00" + +[[procedure.config.stage]] +name = "Stage 1" +enabled = true +executions = [ + { execution.type = "GlobalAutoUpdate", execution.params = {}, enabled = true } +] +``` + +:::info +You are also able to integrate `GlobalAutoUpdate` into other Procedures +to coordinate the timing with other processes, such as backup. There is +nothing special about this Procedure, it's just created by default for +guidance / convenience. +::: + +### How does it work? + +Both Stacks and Deployments allow you to configure **Poll for Updates** or **Auto Update**. +When [**GlobalAutoUpdate**](https://docs.rs/komodo_client/latest/komodo_client/api/execute/struct.GlobalAutoUpdate.html) +is run, Komodo will loop through all the resources with either of these options enabled, +and run [**PullStack**](https://docs.rs/komodo_client/latest/komodo_client/api/execute/struct.PullStack.html) / [**PullDeployment**](https://docs.rs/komodo_client/latest/komodo_client/api/execute/struct.PullDeployment.html) +in order to pick up any newer images **at the same tag**. +Note that in order to work, it requires use of a "Rolling" image tag, such as `:latest`. + +:::info +If you use git sources Stacks and want to automatically update image tags, check out +[Renovate](https://github.com/renovatebot/renovate?tab=readme-ov-file#what-is-the-mend-renovate-cli) +::: + +For resources with **Poll for Updates** enabled and an Alerter configured, it will +send an alert that a newer image is available, and display the update available indicator in the UI + +For resource with **Auto Update** enabled, it will go ahead and Redeploy *just the services* with +newer images (by default). If an Alerter is configured, it will also send an alert that this occured. \ No newline at end of file diff --git a/docsite/docs/build-images/builders.md b/docsite/docs/resources/build-images/builders.md similarity index 61% rename from docsite/docs/build-images/builders.md rename to docsite/docs/resources/build-images/builders.md index a116a9e4f..d07f5736d 100644 --- a/docsite/docs/build-images/builders.md +++ b/docsite/docs/resources/build-images/builders.md @@ -47,3 +47,48 @@ The AMI will provide a unique id starting with `ami-`, use this with the builder ### Configure security groups / firewall The builders will need inbound access on port 8120 from Komodo Core, be sure to add a security group with this rule to the Builder configuration. + +## Multi-Platform Builds with Docker Buildx + +If you need to build Docker images for multiple platforms (such as ARM and x86), Docker Buildx provides an easy way to do this. + + + Multi-platform builds can take significantly longer than single-platform builds. + When emulating a different architecture (e.g., building ARM images on an x86 host), expect additional time due to QEMU-based emulation. + + +### 1. Create and use a Buildx builder instance +```sh +docker buildx create --name builder --use --bootstrap +``` +This command creates a new builder named `builder` and sets it as the active builder for the current Docker context. + +--- + +### 2. Make Buildx the default for `docker build` +```sh +docker buildx install +``` +This replaces the default `docker build` command with Buildx, so all builds automatically use the current builder instance. + +--- + +### 3. (Optional) View available builders +```sh +docker buildx ls +``` +Use this to list all builder instances and check which one is active. + +--- + +After these steps, any `docker build` command will use Buildx by default, making it straightforward to create multi-platform images. + +--- + +### Platform selection in Komodo +When building inside **Komodo**, you can specify the target platforms (e.g., `linux/amd64`, `linux/arm64`) directly in the Komodo UI during build configuration in the build "Extra Args" field. + +**Example platform string for Extra Args:** +``` +--platform linux/amd64,linux/arm64 +``` \ No newline at end of file diff --git a/docsite/docs/build-images/configuration.md b/docsite/docs/resources/build-images/configuration.md similarity index 95% rename from docsite/docs/build-images/configuration.md rename to docsite/docs/resources/build-images/configuration.md index 512aad7d3..bc0c97060 100644 --- a/docsite/docs/build-images/configuration.md +++ b/docsite/docs/resources/build-images/configuration.md @@ -5,8 +5,8 @@ Komodo just needs a bit of information in order to build your image. ### Provider configuration Komodo supports cloning repos over http/s, from any provider that supports cloning private repos using `git clone https://@git-provider.net//`. -Accounts / access tokens can be configured in either the [core config](../setup/advanced.mdx#mount-a-config-file) -or in the [periphery config](../connect-servers.mdx#manual-install-steps---binaries). +Accounts / access tokens can be configured in either the [core config](../../setup/advanced.mdx#mount-a-config-file) +or in the [periphery config](../../setup/connect-servers.mdx#manual-install-steps---binaries). ### Repo configuration To specify the git repo to build, just give it the name of the repo and the branch under *repo config*. The name is given like `moghtech/komodo`, it includes the username / organization that owns the repo. diff --git a/docsite/docs/build-images/index.mdx b/docsite/docs/resources/build-images/index.mdx similarity index 100% rename from docsite/docs/build-images/index.mdx rename to docsite/docs/resources/build-images/index.mdx diff --git a/docsite/docs/build-images/pre-build.md b/docsite/docs/resources/build-images/pre-build.md similarity index 100% rename from docsite/docs/build-images/pre-build.md rename to docsite/docs/resources/build-images/pre-build.md diff --git a/docsite/docs/build-images/versioning.md b/docsite/docs/resources/build-images/versioning.md similarity index 100% rename from docsite/docs/build-images/versioning.md rename to docsite/docs/resources/build-images/versioning.md diff --git a/docsite/docs/deploy-containers/configuration.md b/docsite/docs/resources/deploy-containers/configuration.md similarity index 100% rename from docsite/docs/deploy-containers/configuration.md rename to docsite/docs/resources/deploy-containers/configuration.md diff --git a/docsite/docs/deploy-containers/index.mdx b/docsite/docs/resources/deploy-containers/index.mdx similarity index 100% rename from docsite/docs/deploy-containers/index.mdx rename to docsite/docs/resources/deploy-containers/index.mdx diff --git a/docsite/docs/deploy-containers/lifetime-management.md b/docsite/docs/resources/deploy-containers/lifetime-management.md similarity index 100% rename from docsite/docs/deploy-containers/lifetime-management.md rename to docsite/docs/resources/deploy-containers/lifetime-management.md diff --git a/docsite/docs/docker-compose.md b/docsite/docs/resources/docker-compose.md similarity index 100% rename from docsite/docs/docker-compose.md rename to docsite/docs/resources/docker-compose.md diff --git a/docsite/docs/resources.md b/docsite/docs/resources/index.md similarity index 88% rename from docsite/docs/resources.md rename to docsite/docs/resources/index.md index f7c07eb36..f4ea578b1 100644 --- a/docsite/docs/resources.md +++ b/docsite/docs/resources/index.md @@ -10,18 +10,18 @@ Many resources need access to git repos / docker registries. There is an in-buil All resources which depend on git repos / docker registries are able to use these credentials to access private repos. ::: -## Server +## [Server](connect-servers) - Configure the connection to periphery agents. - Set alerting thresholds. - Can be attached to by **Deployments**, **Stacks**, **Repos**, and **Builders**. -## Deployment +## [Deployment](resources/deploy-containers/index.mdx) - Deploy a docker container on the attached Server. - Manage services at the container level, perform orchestration using **Procedures** and **ResourceSyncs**. -## Stack +## [Stack](resources/docker-compose) - Deploy with docker compose. - Provide the compose file in UI, or move the files to a git repo and use a webhook for auto redeploy on push. @@ -33,29 +33,29 @@ All resources which depend on git repos / docker registries are able to use thes - Put scripts in git repos, and run them on a Server, or using a Builder. - Can build binaries, perform automation, really whatever you can think of. -## Build +## [Build](resources/build-images/index.mdx) - Build application source into docker images, and push them to the configured registry. - The source can be any git repo containing a Dockerfile. -## Builder +## [Builder](resources/build-images/builders) - Either points to a connected server, or holds configuration to launch a single-use AWS instance to build the image. - Can be attached to **Builds** and **Repos**. -## Procedure +## [Procedure](resources/procedures#procedures) - Compose many actions on other resource type, like `RunBuild` or `DeployStack`, and run it on button push (or with a webhook). - Can run one or more actions in parallel "stages", and compose a series of parallel stages to run sequentially. -## Action +## [Action](resources/procedures#actions) - Write scripts calling the Komodo API in Typescript - Use a pre-initialized Komodo client within the script, no api keys necessary. - Type aware in UI editor. Get suggestions and see in depth docs as you type. - The Typescript client is also [published on NPM](https://www.npmjs.com/package/komodo_client). -## ResourceSync +## [Resource Sync](resources/sync-resources) - Orchestrate all your configuration declaratively by defining it in `toml` files, which are checked into a git repo. - Can deploy **Deployments** and **Stacks** if changes are suggested. diff --git a/docsite/docs/permissioning.md b/docsite/docs/resources/permissioning.md similarity index 100% rename from docsite/docs/permissioning.md rename to docsite/docs/resources/permissioning.md diff --git a/docsite/docs/procedures.md b/docsite/docs/resources/procedures.md similarity index 95% rename from docsite/docs/procedures.md rename to docsite/docs/resources/procedures.md index d77cbf4b0..a727ad92b 100644 --- a/docsite/docs/procedures.md +++ b/docsite/docs/resources/procedures.md @@ -1,6 +1,7 @@ # Procedures and Actions -For orchestrations involving multiple Resources, Komodo offers the `Procedure` and `Action` resource types. +For orchestrations involving multiple resources and executions, +Komodo offers the `Procedure` and `Action` resource types. ## Procedures diff --git a/docsite/docs/sync-resources.md b/docsite/docs/resources/sync-resources.md similarity index 100% rename from docsite/docs/sync-resources.md rename to docsite/docs/resources/sync-resources.md diff --git a/docsite/docs/variables.md b/docsite/docs/resources/variables.md similarity index 92% rename from docsite/docs/variables.md rename to docsite/docs/resources/variables.md index e1d0b2b49..7835c7ab4 100644 --- a/docsite/docs/variables.md +++ b/docsite/docs/resources/variables.md @@ -6,7 +6,9 @@ A variable / secret in Komodo is just a key-value pair. KEY_1 = "value_1" ``` -You can interpolate the value into any Environment (and most other user configurable inputs, such as Repo `On Clone` and `On Pull`, or Stack `Extra Args`) using double brackets around the key to trigger interpolation: +You can interpolate the value into any resource Environment +(and most other user configurable inputs, such as Repo `On Clone` and `On Pull`, or Stack `Extra Args`) +using double brackets around the key to trigger interpolation: ```toml # Before interpolation diff --git a/docsite/docs/webhooks.md b/docsite/docs/resources/webhooks.md similarity index 100% rename from docsite/docs/webhooks.md rename to docsite/docs/resources/webhooks.md diff --git a/docsite/docs/setup/advanced.mdx b/docsite/docs/setup/advanced.mdx index 8b00a8544..db35fd441 100644 --- a/docsite/docs/setup/advanced.mdx +++ b/docsite/docs/setup/advanced.mdx @@ -32,6 +32,11 @@ Komodo also supports self hosted Oauth2 providers like [Authentik](https://docs. If you prefer to keep sensitive information out of environment variables, you can optionally write a config file on your host, and mount it to `/config/config.toml` in the Komodo core container. +The configuration can also be passed as **YAML** or **JSON**. +You can use the it-tools to convert this TOML file to your preferred format: + - YAML: https://it-tools.tech/toml-to-yaml + - JSON: https://it-tools.tech/toml-to-json + :::info Configuration can still be passed in environment variables, and will take precedent over what is passed in the file. ::: diff --git a/docsite/docs/setup/backup.md b/docsite/docs/setup/backup.md new file mode 100644 index 000000000..85c90f0b5 --- /dev/null +++ b/docsite/docs/setup/backup.md @@ -0,0 +1,127 @@ +# Backup and Restore + +:::info +Database backup and restore is actually a function of the [Komodo CLI](../ecosystem/cli), +which is packaged in with the Komodo Core image for convenience. +::: + +Starting from **v1.19.0**, new Komodo installs will automatically create the +**Backup Core Database** [Procedure](../resources/procedures#procedures), scheduled daily. +If you don't have it, this is the Toml: + +```toml +[[procedure]] +name = "Backup Core Database" +description = "Triggers the Core database backup at the scheduled time." +tags = ["system"] +config.schedule = "Every day at 01:00" + +[[procedure.config.stage]] +name = "Stage 1" +enabled = true +executions = [ + { execution.type = "BackupCoreDatabase", execution.params = {}, enabled = true } +] +``` + +:::info +You are also able to integrate `BackupCoreDatabase` into other Procedures, for example to trigger +this process before launching a backup container. There is nothing special about this Procedure, +it's just created by default for guidance / convenience. +::: + +## Backups + +When Komodo takes a database backup, it creates a **folder named for the time the backup was taken**, +and dumps the gzip-compressed documents to files in this folder. +In order to store the backups to disk, **mount a host path to `/backups`** in the Komodo Core container. + +Due to its larger size and relative unimportance, the `Stats` collection (containing historical server cpu / mem / disk usage) +is not included in dated backups. Just latest Stats are maintained at the top level of the backup folder. + +In order to prevent unbounded growth, the backup process implements a pruning feature which will ensure +only the most recent 14 backup folders are kept. To change this number, set `max_backups` (`KOMODO_CLI_MAX_BACKUPS`) +in `core.config.toml`, `komodo.cli.toml`, or in the Core container environment. + +``` +# Folder structure +/backups +| 2025-08-12_03-00-01 +| | Action.gz +| | Alerter.gz +| | ... +| 2025-08-13_03-00-01 +| 2025-08-14_03-00-01 +| ... +| Stats.gz +``` + +:::warning +Currently no encryption is supported, +so you may want to encrypt the files before backing up remotely if your backup solution doesn't support that natively. +::: + +## Remote Backups + +Since database backup is actually a function of the [Komodo CLI](../cli), you can also backup directly to +a remote server using the `ghcr.io/moghtech/komodo-cli` image. This service will backup once and then exit, so the scheduled deployment should still happen using a Procedure or Action: + +```yaml +services: + cli: + image: ghcr.io/moghtech/komodo-cli + command: km database backup -y + volumes: + - /path/to/komodo/backups:/backups + environment: + ## Database port must be reachable. + KOMODO_DATABASE_ADDRESS: komodo.example.com:27017 + KOMODO_DATABASE_USERNAME: + KOMODO_DATABASE_PASSWORD: + KOMODO_DATABASE_DB_NAME: komodo + KOMODO_CLI_MAX_BACKUPS: 30 # set to your preference +``` + +## Restore + +The Komodo CLI handles database restores as well. + +```yaml +services: + cli: + image: ghcr.io/moghtech/komodo-cli + ## Optionally specify a specific folder with `--restore-folder`, + ## otherwise restores the most recent backup. + command: km database restore -y # --restore-folder 2025-08-14_03-00-01 + volumes: + # Same mount to backup files as above + - /path/to/komodo/backups:/backups + environment: + ## Database port must be reachable. + ## Note the different env vars needed compared to backup. + ## This is to prevent any accidental restores. + KOMODO_CLI_DATABASE_TARGET_ADDRESS: komodo.example.com:27017 + KOMODO_CLI_DATABASE_TARGET_USERNAME: + KOMODO_CLI_DATABASE_TARGET_PASSWORD: + KOMODO_CLI_DATABASE_TARGET_DB_NAME: komodo-restore +``` + +:::warning +The restore process can be run multiple times with same backup files, and won't create any extra copies. +HOWEVER it will not "clear" the target database beforehand. If the restore database is already populated, +those old documents will also remain. You may want to drop / delete the target database +before restoring to it in this case. +::: + +## Consistency + +So long as the backup process completes successfully, the files produces can always be restored +no matter how active the Komodo instance is at the time of backup. However writes that happen during +the backup process, such as updates to the resource configuration, may or may not be included in the backup +depending on the timing. + +While it should be rare that this causes any kind of issue when it comes to restoring, if your +Komodo undergoes a lot of usage at all hours and you are worried about consistency, +you could consider [locking](https://www.mongodb.com/docs/manual/reference/method/db.fsyncLock/#mongodb-method-db.fsyncLock) +Mongo before the backup. Just make sure to [unlock](https://www.mongodb.com/docs/manual/reference/method/db.fsyncUnlock/) +the database afterwards. \ No newline at end of file diff --git a/docsite/docs/connect-servers.mdx b/docsite/docs/setup/connect-servers.mdx similarity index 77% rename from docsite/docs/connect-servers.mdx rename to docsite/docs/setup/connect-servers.mdx index ef3e18a1e..089682dde 100644 --- a/docsite/docs/connect-servers.mdx +++ b/docsite/docs/setup/connect-servers.mdx @@ -39,6 +39,11 @@ You can find more information (and view the script) in the [readme](https://gith This script can be run multiple times without issue, and it won't change existing config after the first run. Just run it again after a Komodo version release, and it will update the periphery version. ::: +:::tip +For deployment to many servers, a tool like [Ansible](https://docs.ansible.com/) should be used. +An example of such a setup can be found here: https://github.com/bpbradley/ansible-role-komodo +::: + ### Install the Periphery agent - container You can use a docker compose file: @@ -94,13 +99,20 @@ command: periphery --config-path /path/in/container/to/periphery.config.base.tom ### Passing config files -Either file paths or directory paths can be passed to `--config-path`. +Either file paths or directory paths can be passed to `--config-path` (alias: `-c`). By default, no paths will be used, meaning the configuration is entirely +loaded via environment variables. -When using directories, the file entries can be filtered by name with the `--config-keyword` argument, which can be passed multiple times to add more keywords. If passed, then only config files with file names that contain all keywords will be merged. +When using directories, the file entries can be filtered by name with the `--config-keyword` argument, which can be passed multiple times to add more keywords. +These are each wildcard patterns to match file names. +Only config files with file names that contain a keyword will be merged, with files matching later defined keywords having higher priority on field conflicts. +By default, the only keyword is `*config*.*`. This matches files like `config.toml`, `periphery.config.yaml`, etc. -When passing multiple config files, later --config-path given in the command will always override previous ones. Directory config files are merged in alphabetical order by name, so `config_b.toml` will override `config_a.toml`. +When passing multiple config files, later --config-path given in the command will always override previous ones. +Directory config files are merged in alphabetical order by name, so `config_b.toml` will override `config_a.toml`. -There are two ways to merge config files. The default behavior is to completely replace any base fields with whatever fields are present in the override config. So if you pass `allowed_ips = []` in your override config, the final allowed_ips will be an empty list as well. +There are two ways to merge config files. +The default behavior is to completely replace any base fields with whatever fields are present in the override config. +So if you pass `allowed_ips = []` in your override config, the final allowed_ips will be an empty list as well. `--merge-nested-config true` will merge config fields recursively and extend config array fields. @@ -110,6 +122,11 @@ Similarly, you can specify a base docker / github account pair, and extend them ## Configuration +The configuration can also be passed as **YAML** or **JSON**. +You can use the it-tools to convert this TOML file to your preferred format: + - YAML: https://it-tools.tech/toml-to-yaml + - JSON: https://it-tools.tech/toml-to-json + Quick download to `./komodo/periphery.config.toml`: ```bash wget -P komodo https://raw.githubusercontent.com/moghtech/komodo/main/config/periphery.config.toml diff --git a/docsite/docs/setup/ferretdb.mdx b/docsite/docs/setup/ferretdb.mdx index c74ff2c5f..a3ba26787 100644 --- a/docsite/docs/setup/ferretdb.mdx +++ b/docsite/docs/setup/ferretdb.mdx @@ -14,7 +14,7 @@ wget -P komodo https://raw.githubusercontent.com/moghtech/komodo/main/compose/fe wget -P komodo https://raw.githubusercontent.com/moghtech/komodo/main/compose/compose.env ``` 2. Edit the variables in `komodo/compose.env`. -3. Deploy: +3. Deploy using command: ```bash docker compose -p komodo -f komodo/ferretdb.compose.yaml --env-file komodo/compose.env up -d diff --git a/docsite/docs/setup/index.mdx b/docsite/docs/setup/index.mdx index efd620d4e..470b0ee76 100644 --- a/docsite/docs/setup/index.mdx +++ b/docsite/docs/setup/index.mdx @@ -1,4 +1,4 @@ -# Setup Komodo +# Setup Komodo Core To run Komodo, you will need Docker. See [the docker install docs](https://docs.docker.com/engine/install/). diff --git a/docsite/docs/setup/mongo.mdx b/docsite/docs/setup/mongo.mdx index 5035b719a..d418c775c 100644 --- a/docsite/docs/setup/mongo.mdx +++ b/docsite/docs/setup/mongo.mdx @@ -1,6 +1,6 @@ # MongoDB -[**MongoDB**](https://www.mongodb.com) is the traditional database for Komodo. +[**MongoDB**](https://www.mongodb.com) is the standard database for Komodo. Komodo Core communicates with the database using the MongoDB driver. 1. Copy `komodo/mongo.compose.yaml` and `komodo/compose.env` to your host: @@ -9,7 +9,7 @@ wget -P komodo https://raw.githubusercontent.com/moghtech/komodo/main/compose/mo wget -P komodo https://raw.githubusercontent.com/moghtech/komodo/main/compose/compose.env ``` 2. Edit the variables in `komodo/compose.env`. -3. Deploy: +3. Deploy using command: ```bash docker compose -p komodo -f komodo/mongo.compose.yaml --env-file komodo/compose.env up -d diff --git a/docsite/docs/version-upgrades.md b/docsite/docs/setup/version-upgrades.md similarity index 100% rename from docsite/docs/version-upgrades.md rename to docsite/docs/setup/version-upgrades.md diff --git a/docsite/package-lock.json b/docsite/package-lock.json deleted file mode 100644 index 4528ac8a4..000000000 --- a/docsite/package-lock.json +++ /dev/null @@ -1,14649 +0,0 @@ -{ - "name": "docsite", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "docsite", - "version": "0.0.0", - "dependencies": { - "@docusaurus/core": "^3.5.2", - "@docusaurus/preset-classic": "^3.5.2", - "@mdx-js/react": "^3.0.1", - "clsx": "^2.1.1", - "prism-react-renderer": "^2.3.1", - "react": "^18.3.1", - "react-dom": "^18.3.1" - }, - "devDependencies": { - "@docusaurus/module-type-aliases": "^3.5.2", - "@docusaurus/tsconfig": "^3.5.2", - "@docusaurus/types": "^3.5.2", - "dotenv": "^16.4.5", - "typescript": "^5.4.5" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@algolia/autocomplete-core": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", - "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", - "dependencies": { - "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", - "@algolia/autocomplete-shared": "1.9.3" - } - }, - "node_modules/@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", - "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", - "dependencies": { - "@algolia/autocomplete-shared": "1.9.3" - }, - "peerDependencies": { - "search-insights": ">= 1 < 3" - } - }, - "node_modules/@algolia/autocomplete-preset-algolia": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", - "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", - "dependencies": { - "@algolia/autocomplete-shared": "1.9.3" - }, - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/autocomplete-shared": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", - "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/cache-browser-local-storage": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz", - "integrity": "sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==", - "dependencies": { - "@algolia/cache-common": "4.24.0" - } - }, - "node_modules/@algolia/cache-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz", - "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==" - }, - "node_modules/@algolia/cache-in-memory": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz", - "integrity": "sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==", - "dependencies": { - "@algolia/cache-common": "4.24.0" - } - }, - "node_modules/@algolia/client-account": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", - "integrity": "sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-account/node_modules/@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "dependencies": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-account/node_modules/@algolia/client-search": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", - "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-analytics": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz", - "integrity": "sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-analytics/node_modules/@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "dependencies": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-analytics/node_modules/@algolia/client-search": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", - "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-common": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.2.3.tgz", - "integrity": "sha512-zqfcbgjYR72Y/rx/+/6g5Li/eV33yhRq5mkGbU06JYBzvGq6viy0gZl1ckCFhLLifKzXZ4yzUQTw/KG6FV+smg==", - "peer": true, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-personalization": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz", - "integrity": "sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-personalization/node_modules/@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "dependencies": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/client-search": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.2.3.tgz", - "integrity": "sha512-xXdCg8vpiwE8gqSyvjxq8V3qbFa+gHasY5epIz718IByWv3WKLLi/n4SMIfB/zRwXTLVWeGOH/UJSz5VCnAAqg==", - "peer": true, - "dependencies": { - "@algolia/client-common": "5.2.3", - "@algolia/requester-browser-xhr": "5.2.3", - "@algolia/requester-node-http": "5.2.3" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/events": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", - "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" - }, - "node_modules/@algolia/logger-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", - "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==" - }, - "node_modules/@algolia/logger-console": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz", - "integrity": "sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==", - "dependencies": { - "@algolia/logger-common": "4.24.0" - } - }, - "node_modules/@algolia/recommend": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", - "integrity": "sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==", - "dependencies": { - "@algolia/cache-browser-local-storage": "4.24.0", - "@algolia/cache-common": "4.24.0", - "@algolia/cache-in-memory": "4.24.0", - "@algolia/client-common": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/logger-console": "4.24.0", - "@algolia/requester-browser-xhr": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/requester-node-http": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/recommend/node_modules/@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "dependencies": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/recommend/node_modules/@algolia/client-search": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", - "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/@algolia/recommend/node_modules/@algolia/requester-browser-xhr": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", - "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", - "dependencies": { - "@algolia/requester-common": "4.24.0" - } - }, - "node_modules/@algolia/recommend/node_modules/@algolia/requester-node-http": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", - "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", - "dependencies": { - "@algolia/requester-common": "4.24.0" - } - }, - "node_modules/@algolia/requester-browser-xhr": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.2.3.tgz", - "integrity": "sha512-lezcE4E7ax7JkDGDKA/xAnyAY9p9LZ4AxzsyL0pksqUpOvn4U0msP553M2yJRfsxxdGDp15noCnPuRsh7u8dMg==", - "peer": true, - "dependencies": { - "@algolia/client-common": "5.2.3" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz", - "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==" - }, - "node_modules/@algolia/requester-node-http": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.2.3.tgz", - "integrity": "sha512-xTxsRnJqxG1dylIkxmflrHO9LJfJKjSHqEF5yGdRrtnqIEvb2hiQPCHm2XwqxMa3NBcf6lmydGfJqhPLnRJwtw==", - "peer": true, - "dependencies": { - "@algolia/client-common": "5.2.3" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/transporter": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz", - "integrity": "sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==", - "dependencies": { - "@algolia/cache-common": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/requester-common": "4.24.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.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==", - "dependencies": { - "@babel/highlight": "^7.24.2", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz", - "integrity": "sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.5.tgz", - "integrity": "sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.2", - "@babel/generator": "^7.24.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.24.5", - "@babel/helpers": "^7.24.5", - "@babel/parser": "^7.24.5", - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.5", - "@babel/types": "^7.24.5", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.5.tgz", - "integrity": "sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==", - "dependencies": { - "@babel/types": "^7.24.5", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", - "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", - "dependencies": { - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", - "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", - "browserslist": "^4.22.2", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.5.tgz", - "integrity": "sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-member-expression-to-functions": "^7.24.5", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.24.5", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", - "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "regexpu-core": "^5.3.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", - "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.5.tgz", - "integrity": "sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA==", - "dependencies": { - "@babel/types": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", - "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", - "dependencies": { - "@babel/types": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.5.tgz", - "integrity": "sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.24.3", - "@babel/helper-simple-access": "^7.24.5", - "@babel/helper-split-export-declaration": "^7.24.5", - "@babel/helper-validator-identifier": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", - "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", - "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-wrap-function": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", - "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.5.tgz", - "integrity": "sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==", - "dependencies": { - "@babel/types": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz", - "integrity": "sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==", - "dependencies": { - "@babel/types": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", - "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz", - "integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.5.tgz", - "integrity": "sha512-/xxzuNvgRl4/HLNKvnFwdhdgN3cpLxgLROeLDl83Yx0AJ1SGvq1ak0OszTOjDfiB8Vx03eJbeDWh9r+jCCWttw==", - "dependencies": { - "@babel/helper-function-name": "^7.23.0", - "@babel/template": "^7.24.0", - "@babel/types": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.5.tgz", - "integrity": "sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q==", - "dependencies": { - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.5", - "@babel/types": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.5.tgz", - "integrity": "sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.5", - "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==", - "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==", - "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==", - "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==" - }, - "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==", - "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==", - "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==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz", - "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.5.tgz", - "integrity": "sha512-LdXRi1wEMTrHVR4Zc9F8OewC3vdm5h4QB6L71zy6StmYeqGi1b3ttIO8UC+BfZKcH9jdr4aI249rBkm+3+YvHw==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz", - "integrity": "sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz", - "integrity": "sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.24.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz", - "integrity": "sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz", - "integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz", - "integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz", - "integrity": "sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.1.tgz", - "integrity": "sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz", - "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz", - "integrity": "sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-remap-async-to-generator": "^7.22.20", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz", - "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==", - "dependencies": { - "@babel/helper-module-imports": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-remap-async-to-generator": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz", - "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.5.tgz", - "integrity": "sha512-sMfBc3OxghjC95BkYrYocHL3NaOplrcaunblzwXhGmlPwpmfsxr4vK+mBBt49r+S240vahmv+kUxkeKgs+haCw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz", - "integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.4.tgz", - "integrity": "sha512-B8q7Pz870Hz/q9UgP8InNpY01CSLDSCyqX7zcRuv3FcPl87A2G17lASroHWaCtbdIcbYzOZ7kWmXFKbijMSmFg==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.4", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.5.tgz", - "integrity": "sha512-gWkLP25DFj2dwe9Ck8uwMOpko4YsqyfZJrOmqqcegeDYEbp7rmn4U6UQZNj08UF6MaX39XenSpKRCvpDRBtZ7Q==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-split-export-declaration": "^7.24.5", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz", - "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/template": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.5.tgz", - "integrity": "sha512-SZuuLyfxvsm+Ah57I/i1HVjveBENYK9ue8MJ7qkc7ndoNjqquJiElzA7f5yaAXjyW2hKojosOTAQQRX50bPSVg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz", - "integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz", - "integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz", - "integrity": "sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz", - "integrity": "sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==", - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz", - "integrity": "sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz", - "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz", - "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz", - "integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz", - "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz", - "integrity": "sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz", - "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz", - "integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==", - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz", - "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==", - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-simple-access": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz", - "integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==", - "dependencies": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-identifier": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz", - "integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==", - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", - "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz", - "integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz", - "integrity": "sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz", - "integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.5.tgz", - "integrity": "sha512-7EauQHszLGM3ay7a161tTQH7fj+3vVM/gThlz5HpFtnygTxjrlvoeq7MPVA1Vy9Q555OB8SnAOsMkLShNkkrHA==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz", - "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-replace-supers": "^7.24.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz", - "integrity": "sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.5.tgz", - "integrity": "sha512-xWCkmwKT+ihmA6l7SSTpk8e4qQl/274iNbSKRRS8mpqFR32ksy36+a+LWY8OXCCEefF8WFlnOHVsaDI2231wBg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.5.tgz", - "integrity": "sha512-9Co00MqZ2aoky+4j2jhofErthm6QVLKbpQrvz20c3CH9KQCLHyNB+t2ya4/UrRpQGR+Wrwjg9foopoeSdnHOkA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz", - "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.5.tgz", - "integrity": "sha512-JM4MHZqnWR04jPMujQDTBVRnqxpLLpx2tkn7iPn+Hmsc0Gnb79yvRWOkvqFOx3Z7P7VxiRIR22c4eGSNj87OBQ==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.24.5", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz", - "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.25.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.25.1.tgz", - "integrity": "sha512-SLV/giH/V4SmloZ6Dt40HjTGTAIkxn33TVIHxNGNvo8ezMhrxBkzisj4op1KZYPIOHFLqhv60OHvX+YRu4xbmQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.1.tgz", - "integrity": "sha512-mvoQg2f9p2qlpDQRBC7M3c3XTr0k7cp/0+kFKKO/7Gtu0LSw16eKB+Fabe2bDT/UpsyasTBBkAnbdsLrkD5XMw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", - "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.23.3", - "@babel/types": "^7.23.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", - "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", - "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.1.tgz", - "integrity": "sha512-+pWEAaDJvSm9aFvJNpLiM2+ktl2Sn2U5DdyiWdZBxmLc6+xGt88dvFqsHiAiDS+8WqUwbDfkKz9jRxK3M0k+kA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz", - "integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "regenerator-transform": "^0.15.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz", - "integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.3.tgz", - "integrity": "sha512-J0BuRPNlNqlMTRJ72eVptpt9VcInbxO6iP3jaxr+1NPhC0UkKL+6oeX6VXMEYdADnuqmMmsBspt4d5w8Y/TCbQ==", - "dependencies": { - "@babel/helper-module-imports": "^7.24.3", - "@babel/helper-plugin-utils": "^7.24.0", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.1", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz", - "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz", - "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz", - "integrity": "sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz", - "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.5.tgz", - "integrity": "sha512-UTGnhYVZtTAjdwOTzT+sCyXmTn8AhaxOS/MjG9REclZ6ULHWF9KoCZur0HSGU7hk8PdBFKKbYe6+gqdXWz84Jg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.5.tgz", - "integrity": "sha512-E0VWu/hk83BIFUWnsKZ4D81KXjN5L3MobvevOHErASk9IPwKHOkTgvqzvNo1yP/ePJWqqK2SpUR5z+KQbl6NVw==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.24.5", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/plugin-syntax-typescript": "^7.24.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz", - "integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz", - "integrity": "sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz", - "integrity": "sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz", - "integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.5.tgz", - "integrity": "sha512-UGK2ifKtcC8i5AI4cH+sbLLuLc2ktYSFJgBAXorKAsHUZmrQ1q6aQ6i3BvU24wWs2AAKqQB6kq3N9V9Gw1HiMQ==", - "dependencies": { - "@babel/compat-data": "^7.24.4", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.24.1", - "@babel/plugin-syntax-import-attributes": "^7.24.1", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.24.1", - "@babel/plugin-transform-async-generator-functions": "^7.24.3", - "@babel/plugin-transform-async-to-generator": "^7.24.1", - "@babel/plugin-transform-block-scoped-functions": "^7.24.1", - "@babel/plugin-transform-block-scoping": "^7.24.5", - "@babel/plugin-transform-class-properties": "^7.24.1", - "@babel/plugin-transform-class-static-block": "^7.24.4", - "@babel/plugin-transform-classes": "^7.24.5", - "@babel/plugin-transform-computed-properties": "^7.24.1", - "@babel/plugin-transform-destructuring": "^7.24.5", - "@babel/plugin-transform-dotall-regex": "^7.24.1", - "@babel/plugin-transform-duplicate-keys": "^7.24.1", - "@babel/plugin-transform-dynamic-import": "^7.24.1", - "@babel/plugin-transform-exponentiation-operator": "^7.24.1", - "@babel/plugin-transform-export-namespace-from": "^7.24.1", - "@babel/plugin-transform-for-of": "^7.24.1", - "@babel/plugin-transform-function-name": "^7.24.1", - "@babel/plugin-transform-json-strings": "^7.24.1", - "@babel/plugin-transform-literals": "^7.24.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.1", - "@babel/plugin-transform-member-expression-literals": "^7.24.1", - "@babel/plugin-transform-modules-amd": "^7.24.1", - "@babel/plugin-transform-modules-commonjs": "^7.24.1", - "@babel/plugin-transform-modules-systemjs": "^7.24.1", - "@babel/plugin-transform-modules-umd": "^7.24.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.24.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1", - "@babel/plugin-transform-numeric-separator": "^7.24.1", - "@babel/plugin-transform-object-rest-spread": "^7.24.5", - "@babel/plugin-transform-object-super": "^7.24.1", - "@babel/plugin-transform-optional-catch-binding": "^7.24.1", - "@babel/plugin-transform-optional-chaining": "^7.24.5", - "@babel/plugin-transform-parameters": "^7.24.5", - "@babel/plugin-transform-private-methods": "^7.24.1", - "@babel/plugin-transform-private-property-in-object": "^7.24.5", - "@babel/plugin-transform-property-literals": "^7.24.1", - "@babel/plugin-transform-regenerator": "^7.24.1", - "@babel/plugin-transform-reserved-words": "^7.24.1", - "@babel/plugin-transform-shorthand-properties": "^7.24.1", - "@babel/plugin-transform-spread": "^7.24.1", - "@babel/plugin-transform-sticky-regex": "^7.24.1", - "@babel/plugin-transform-template-literals": "^7.24.1", - "@babel/plugin-transform-typeof-symbol": "^7.24.5", - "@babel/plugin-transform-unicode-escapes": "^7.24.1", - "@babel/plugin-transform-unicode-property-regex": "^7.24.1", - "@babel/plugin-transform-unicode-regex": "^7.24.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.24.1", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.4", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.31.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/preset-react": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.1.tgz", - "integrity": "sha512-eFa8up2/8cZXLIpkafhaADTXSnl7IsUFCYenRWrARBz0/qZwcT0RBXpys0LJU4+WfPoF2ZG6ew6s2V6izMCwRA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-transform-react-display-name": "^7.24.1", - "@babel/plugin-transform-react-jsx": "^7.23.4", - "@babel/plugin-transform-react-jsx-development": "^7.22.5", - "@babel/plugin-transform-react-pure-annotations": "^7.24.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-typescript": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.1.tgz", - "integrity": "sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-syntax-jsx": "^7.24.1", - "@babel/plugin-transform-modules-commonjs": "^7.24.1", - "@babel/plugin-transform-typescript": "^7.24.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" - }, - "node_modules/@babel/runtime": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", - "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.24.5.tgz", - "integrity": "sha512-GWO0mgzNMLWaSYM4z4NVIuY0Cd1fl8cPnuetuddu5w/qGuvt5Y7oUi/kvvQGK9xgOkFJDQX2heIvTRn/OQ1XTg==", - "dependencies": { - "core-js-pure": "^3.30.2", - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", - "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", - "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.24.0", - "@babel/types": "^7.24.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.5.tgz", - "integrity": "sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==", - "dependencies": { - "@babel/code-frame": "^7.24.2", - "@babel/generator": "^7.24.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.24.5", - "@babel/parser": "^7.24.5", - "@babel/types": "^7.24.5", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.5.tgz", - "integrity": "sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==", - "dependencies": { - "@babel/helper-string-parser": "^7.24.1", - "@babel/helper-validator-identifier": "^7.24.5", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@docsearch/css": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.1.tgz", - "integrity": "sha512-VtVb5DS+0hRIprU2CO6ZQjK2Zg4QU5HrDM1+ix6rT0umsYvFvatMAnf97NHZlVWDaaLlx7GRfR/7FikANiM2Fg==" - }, - "node_modules/@docsearch/react": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.1.tgz", - "integrity": "sha512-qXZkEPvybVhSXj0K7U3bXc233tk5e8PfhoZ6MhPOiik/qUQxYC+Dn9DnoS7CxHQQhHfCvTiN0eY9M12oRghEXw==", - "dependencies": { - "@algolia/autocomplete-core": "1.9.3", - "@algolia/autocomplete-preset-algolia": "1.9.3", - "@docsearch/css": "3.6.1", - "algoliasearch": "^4.19.1" - }, - "peerDependencies": { - "@types/react": ">= 16.8.0 < 19.0.0", - "react": ">= 16.8.0 < 19.0.0", - "react-dom": ">= 16.8.0 < 19.0.0", - "search-insights": ">= 1 < 3" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "search-insights": { - "optional": true - } - } - }, - "node_modules/@docusaurus/core": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.5.2.tgz", - "integrity": "sha512-4Z1WkhCSkX4KO0Fw5m/Vuc7Q3NxBG53NE5u59Rs96fWkMPZVSrzEPP16/Nk6cWb/shK7xXPndTmalJtw7twL/w==", - "dependencies": { - "@babel/core": "^7.23.3", - "@babel/generator": "^7.23.3", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.22.9", - "@babel/preset-env": "^7.22.9", - "@babel/preset-react": "^7.22.5", - "@babel/preset-typescript": "^7.22.5", - "@babel/runtime": "^7.22.6", - "@babel/runtime-corejs3": "^7.22.6", - "@babel/traverse": "^7.22.8", - "@docusaurus/cssnano-preset": "3.5.2", - "@docusaurus/logger": "3.5.2", - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "autoprefixer": "^10.4.14", - "babel-loader": "^9.1.3", - "babel-plugin-dynamic-import-node": "^2.3.3", - "boxen": "^6.2.1", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "clean-css": "^5.3.2", - "cli-table3": "^0.6.3", - "combine-promises": "^1.1.0", - "commander": "^5.1.0", - "copy-webpack-plugin": "^11.0.0", - "core-js": "^3.31.1", - "css-loader": "^6.8.1", - "css-minimizer-webpack-plugin": "^5.0.1", - "cssnano": "^6.1.2", - "del": "^6.1.1", - "detect-port": "^1.5.1", - "escape-html": "^1.0.3", - "eta": "^2.2.0", - "eval": "^0.1.8", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "html-minifier-terser": "^7.2.0", - "html-tags": "^3.3.1", - "html-webpack-plugin": "^5.5.3", - "leven": "^3.1.0", - "lodash": "^4.17.21", - "mini-css-extract-plugin": "^2.7.6", - "p-map": "^4.0.0", - "postcss": "^8.4.26", - "postcss-loader": "^7.3.3", - "prompts": "^2.4.2", - "react-dev-utils": "^12.0.1", - "react-helmet-async": "^1.3.0", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", - "react-loadable-ssr-addon-v5-slorber": "^1.0.1", - "react-router": "^5.3.4", - "react-router-config": "^5.1.1", - "react-router-dom": "^5.3.4", - "rtl-detect": "^1.0.4", - "semver": "^7.5.4", - "serve-handler": "^6.1.5", - "shelljs": "^0.8.5", - "terser-webpack-plugin": "^5.3.9", - "tslib": "^2.6.0", - "update-notifier": "^6.0.2", - "url-loader": "^4.1.1", - "webpack": "^5.88.1", - "webpack-bundle-analyzer": "^4.9.0", - "webpack-dev-server": "^4.15.1", - "webpack-merge": "^5.9.0", - "webpackbar": "^5.0.2" - }, - "bin": { - "docusaurus": "bin/docusaurus.mjs" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@mdx-js/react": "^3.0.0", - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/cssnano-preset": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.5.2.tgz", - "integrity": "sha512-D3KiQXOMA8+O0tqORBrTOEQyQxNIfPm9jEaJoALjjSjc2M/ZAWcUfPQEnwr2JB2TadHw2gqWgpZckQmrVWkytA==", - "dependencies": { - "cssnano-preset-advanced": "^6.1.2", - "postcss": "^8.4.38", - "postcss-sort-media-queries": "^5.2.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/logger": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.5.2.tgz", - "integrity": "sha512-LHC540SGkeLfyT3RHK3gAMK6aS5TRqOD4R72BEU/DE2M/TY8WwEUAMY576UUc/oNJXv8pGhBmQB6N9p3pt8LQw==", - "dependencies": { - "chalk": "^4.1.2", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/mdx-loader": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.5.2.tgz", - "integrity": "sha512-ku3xO9vZdwpiMIVd8BzWV0DCqGEbCP5zs1iHfKX50vw6jX8vQo0ylYo1YJMZyz6e+JFJ17HYHT5FzVidz2IflA==", - "dependencies": { - "@docusaurus/logger": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "@mdx-js/mdx": "^3.0.0", - "@slorber/remark-comment": "^1.0.0", - "escape-html": "^1.0.3", - "estree-util-value-to-estree": "^3.0.1", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "image-size": "^1.0.2", - "mdast-util-mdx": "^3.0.0", - "mdast-util-to-string": "^4.0.0", - "rehype-raw": "^7.0.0", - "remark-directive": "^3.0.0", - "remark-emoji": "^4.0.0", - "remark-frontmatter": "^5.0.0", - "remark-gfm": "^4.0.0", - "stringify-object": "^3.3.0", - "tslib": "^2.6.0", - "unified": "^11.0.3", - "unist-util-visit": "^5.0.0", - "url-loader": "^4.1.1", - "vfile": "^6.0.1", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/module-type-aliases": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.5.2.tgz", - "integrity": "sha512-Z+Xu3+2rvKef/YKTMxZHsEXp1y92ac0ngjDiExRdqGTmEKtCUpkbNYH8v5eXo5Ls+dnW88n6WTa+Q54kLOkwPg==", - "dependencies": { - "@docusaurus/types": "3.5.2", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "@types/react-router-dom": "*", - "react-helmet-async": "*", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, - "node_modules/@docusaurus/plugin-content-blog": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.5.2.tgz", - "integrity": "sha512-R7ghWnMvjSf+aeNDH0K4fjyQnt5L0KzUEnUhmf1e3jZrv3wogeytZNN6n7X8yHcMsuZHPOrctQhXWnmxu+IRRg==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/logger": "3.5.2", - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/theme-common": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "cheerio": "1.0.0-rc.12", - "feed": "^4.2.2", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "reading-time": "^1.5.0", - "srcset": "^4.0.0", - "tslib": "^2.6.0", - "unist-util-visit": "^5.0.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/plugin-content-docs": "*", - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-docs": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.5.2.tgz", - "integrity": "sha512-Bt+OXn/CPtVqM3Di44vHjE7rPCEsRCB/DMo2qoOuozB9f7+lsdrHvD0QCHdBs0uhz6deYJDppAr2VgqybKPlVQ==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/logger": "3.5.2", - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/module-type-aliases": "3.5.2", - "@docusaurus/theme-common": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "@types/react-router-config": "^5.0.7", - "combine-promises": "^1.1.0", - "fs-extra": "^11.1.1", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "tslib": "^2.6.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-pages": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.5.2.tgz", - "integrity": "sha512-WzhHjNpoQAUz/ueO10cnundRz+VUtkjFhhaQ9jApyv1a46FPURO4cef89pyNIOMny1fjDz/NUN2z6Yi+5WUrCw==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "fs-extra": "^11.1.1", - "tslib": "^2.6.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-debug": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.5.2.tgz", - "integrity": "sha512-kBK6GlN0itCkrmHuCS6aX1wmoWc5wpd5KJlqQ1FyrF0cLDnvsYSnh7+ftdwzt7G6lGBho8lrVwkkL9/iQvaSOA==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "fs-extra": "^11.1.1", - "react-json-view-lite": "^1.2.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-analytics": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.5.2.tgz", - "integrity": "sha512-rjEkJH/tJ8OXRE9bwhV2mb/WP93V441rD6XnM6MIluu7rk8qg38iSxS43ga2V2Q/2ib53PcqbDEJDG/yWQRJhQ==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-gtag": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.5.2.tgz", - "integrity": "sha512-lm8XL3xLkTPHFKKjLjEEAHUrW0SZBSHBE1I+i/tmYMBsjCcUB5UJ52geS5PSiOCFVR74tbPGcPHEV/gaaxFeSA==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "@types/gtag.js": "^0.0.12", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-tag-manager": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.5.2.tgz", - "integrity": "sha512-QkpX68PMOMu10Mvgvr5CfZAzZQFx8WLlOiUQ/Qmmcl6mjGK6H21WLT5x7xDmcpCoKA/3CegsqIqBR+nA137lQg==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/plugin-sitemap": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.5.2.tgz", - "integrity": "sha512-DnlqYyRAdQ4NHY28TfHuVk414ft2uruP4QWCH//jzpHjqvKyXjj2fmDtI8RPUBh9K8iZKFMHRnLtzJKySPWvFA==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/logger": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "fs-extra": "^11.1.1", - "sitemap": "^7.1.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/preset-classic": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.5.2.tgz", - "integrity": "sha512-3ihfXQ95aOHiLB5uCu+9PRy2gZCeSZoDcqpnDvf3B+sTrMvMTr8qRUzBvWkoIqc82yG5prCboRjk1SVILKx6sg==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/plugin-content-blog": "3.5.2", - "@docusaurus/plugin-content-docs": "3.5.2", - "@docusaurus/plugin-content-pages": "3.5.2", - "@docusaurus/plugin-debug": "3.5.2", - "@docusaurus/plugin-google-analytics": "3.5.2", - "@docusaurus/plugin-google-gtag": "3.5.2", - "@docusaurus/plugin-google-tag-manager": "3.5.2", - "@docusaurus/plugin-sitemap": "3.5.2", - "@docusaurus/theme-classic": "3.5.2", - "@docusaurus/theme-common": "3.5.2", - "@docusaurus/theme-search-algolia": "3.5.2", - "@docusaurus/types": "3.5.2" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-classic": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.5.2.tgz", - "integrity": "sha512-XRpinSix3NBv95Rk7xeMF9k4safMkwnpSgThn0UNQNumKvmcIYjfkwfh2BhwYh/BxMXQHJ/PdmNh22TQFpIaYg==", - "dependencies": { - "@docusaurus/core": "3.5.2", - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/module-type-aliases": "3.5.2", - "@docusaurus/plugin-content-blog": "3.5.2", - "@docusaurus/plugin-content-docs": "3.5.2", - "@docusaurus/plugin-content-pages": "3.5.2", - "@docusaurus/theme-common": "3.5.2", - "@docusaurus/theme-translations": "3.5.2", - "@docusaurus/types": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "@mdx-js/react": "^3.0.0", - "clsx": "^2.0.0", - "copy-text-to-clipboard": "^3.2.0", - "infima": "0.2.0-alpha.44", - "lodash": "^4.17.21", - "nprogress": "^0.2.0", - "postcss": "^8.4.26", - "prism-react-renderer": "^2.3.0", - "prismjs": "^1.29.0", - "react-router-dom": "^5.3.4", - "rtlcss": "^4.1.0", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-common": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.5.2.tgz", - "integrity": "sha512-QXqlm9S6x9Ibwjs7I2yEDgsCocp708DrCrgHgKwg2n2AY0YQ6IjU0gAK35lHRLOvAoJUfCKpQAwUykB0R7+Eew==", - "dependencies": { - "@docusaurus/mdx-loader": "3.5.2", - "@docusaurus/module-type-aliases": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "clsx": "^2.0.0", - "parse-numeric-range": "^1.3.0", - "prism-react-renderer": "^2.3.0", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/plugin-content-docs": "*", - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-search-algolia": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.5.2.tgz", - "integrity": "sha512-qW53kp3VzMnEqZGjakaV90sst3iN1o32PH+nawv1uepROO8aEGxptcq2R5rsv7aBShSRbZwIobdvSYKsZ5pqvA==", - "dependencies": { - "@docsearch/react": "^3.5.2", - "@docusaurus/core": "3.5.2", - "@docusaurus/logger": "3.5.2", - "@docusaurus/plugin-content-docs": "3.5.2", - "@docusaurus/theme-common": "3.5.2", - "@docusaurus/theme-translations": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-validation": "3.5.2", - "algoliasearch": "^4.18.0", - "algoliasearch-helper": "^3.13.3", - "clsx": "^2.0.0", - "eta": "^2.2.0", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/theme-translations": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.5.2.tgz", - "integrity": "sha512-GPZLcu4aT1EmqSTmbdpVrDENGR2yObFEX8ssEFYTCiAIVc0EihNSdOIBTazUvgNqwvnoU1A8vIs1xyzc3LITTw==", - "dependencies": { - "fs-extra": "^11.1.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/tsconfig": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.5.2.tgz", - "integrity": "sha512-rQ7toURCFnWAIn8ubcquDs0ewhPwviMzxh6WpRjBW7sJVCXb6yzwUaY3HMNa0VXCFw+qkIbFywrMTf+Pb4uHWQ==", - "dev": true - }, - "node_modules/@docusaurus/types": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.5.2.tgz", - "integrity": "sha512-N6GntLXoLVUwkZw7zCxwy9QiuEXIcTVzA9AkmNw16oc0AP3SXLrMmDMMBIfgqwuKWa6Ox6epHol9kMtJqekACw==", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "^1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1", - "webpack-merge": "^5.9.0" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@docusaurus/utils": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.5.2.tgz", - "integrity": "sha512-33QvcNFh+Gv+C2dP9Y9xWEzMgf3JzrpL2nW9PopidiohS1nDcyknKRx2DWaFvyVTTYIkkABVSr073VTj/NITNA==", - "dependencies": { - "@docusaurus/logger": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "@svgr/webpack": "^8.1.0", - "escape-string-regexp": "^4.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "github-slugger": "^1.5.0", - "globby": "^11.1.0", - "gray-matter": "^4.0.3", - "jiti": "^1.20.0", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "micromatch": "^4.0.5", - "prompts": "^2.4.2", - "resolve-pathname": "^3.0.0", - "shelljs": "^0.8.5", - "tslib": "^2.6.0", - "url-loader": "^4.1.1", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, - "node_modules/@docusaurus/utils-common": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.5.2.tgz", - "integrity": "sha512-i0AZjHiRgJU6d7faQngIhuHKNrszpL/SHQPgF1zH4H+Ij6E9NBYGy6pkcGWToIv7IVPbs+pQLh1P3whn0gWXVg==", - "dependencies": { - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } - } - }, - "node_modules/@docusaurus/utils-validation": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.5.2.tgz", - "integrity": "sha512-m+Foq7augzXqB6HufdS139PFxDC5d5q2QKZy8q0qYYvGdI6nnlNsGH4cIGsgBnV7smz+mopl3g4asbSDvMV0jA==", - "dependencies": { - "@docusaurus/logger": "3.5.2", - "@docusaurus/utils": "3.5.2", - "@docusaurus/utils-common": "3.5.2", - "fs-extra": "^11.2.0", - "joi": "^17.9.2", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@hapi/hoek": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" - }, - "node_modules/@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==" - }, - "node_modules/@mdx-js/mdx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.1.tgz", - "integrity": "sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdx": "^2.0.0", - "collapse-white-space": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-build-jsx": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-util-to-js": "^2.0.0", - "estree-walker": "^3.0.0", - "hast-util-to-estree": "^3.0.0", - "hast-util-to-jsx-runtime": "^2.0.0", - "markdown-extensions": "^2.0.0", - "periscopic": "^3.0.0", - "remark-mdx": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "source-map": "^0.7.0", - "unified": "^11.0.0", - "unist-util-position-from-estree": "^2.0.0", - "unist-util-stringify-position": "^4.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/react": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.0.1.tgz", - "integrity": "sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A==", - "dependencies": { - "@types/mdx": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "@types/react": ">=16", - "react": ">=16" - } - }, - "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==", - "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==", - "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==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pnpm/config.env-replace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", - "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", - "engines": { - "node": ">=12.22.0" - } - }, - "node_modules/@pnpm/network.ca-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", - "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", - "dependencies": { - "graceful-fs": "4.2.10" - }, - "engines": { - "node": ">=12.22.0" - } - }, - "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" - }, - "node_modules/@pnpm/npm-conf": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", - "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", - "dependencies": { - "@pnpm/config.env-replace": "^1.1.0", - "@pnpm/network.ca-file": "^1.0.1", - "config-chain": "^1.1.11" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@polka/url": { - "version": "1.0.0-next.25", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz", - "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==" - }, - "node_modules/@sideway/address": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", - "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@sideway/formula": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" - }, - "node_modules/@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" - }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@slorber/remark-comment": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", - "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.1.0", - "micromark-util-symbol": "^1.0.1" - } - }, - "node_modules/@svgr/babel-plugin-add-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", - "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", - "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-svg-dynamic-title": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", - "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-svg-em-dimensions": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", - "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-transform-react-native-svg": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", - "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-transform-svg-component": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", - "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", - "engines": { - "node": ">=12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-preset": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", - "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", - "dependencies": { - "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", - "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", - "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", - "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", - "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", - "@svgr/babel-plugin-transform-svg-component": "8.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/core": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", - "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", - "dependencies": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^8.1.3", - "snake-case": "^3.0.4" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/hast-util-to-babel-ast": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", - "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", - "dependencies": { - "@babel/types": "^7.21.3", - "entities": "^4.4.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/plugin-jsx": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", - "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", - "dependencies": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "@svgr/hast-util-to-babel-ast": "8.0.0", - "svg-parser": "^2.0.4" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "*" - } - }, - "node_modules/@svgr/plugin-svgo": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", - "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", - "dependencies": { - "cosmiconfig": "^8.1.3", - "deepmerge": "^4.3.1", - "svgo": "^3.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "*" - } - }, - "node_modules/@svgr/webpack": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", - "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", - "dependencies": { - "@babel/core": "^7.21.3", - "@babel/plugin-transform-react-constant-elements": "^7.21.3", - "@babel/preset-env": "^7.20.2", - "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.21.0", - "@svgr/core": "8.1.0", - "@svgr/plugin-jsx": "8.1.0", - "@svgr/plugin-svgo": "8.1.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "dependencies": { - "defer-to-connect": "^2.0.1" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@types/acorn": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", - "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "dependencies": { - "@types/ms": "*" - } - }, - "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==" - }, - "node_modules/@types/estree-jsx": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", - "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz", - "integrity": "sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/gtag.js": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", - "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==" - }, - "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/history": { - "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==" - }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" - }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" - }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" - }, - "node_modules/@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "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==" - }, - "node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/mdx": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", - "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==" - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" - }, - "node_modules/@types/ms": { - "version": "0.7.34", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" - }, - "node_modules/@types/node": { - "version": "20.12.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.8.tgz", - "integrity": "sha512-NU0rJLJnshZWdE/097cdCBbyW1h4hEg0xpovcoAQYHl8dnEyp/NAOiE45pvc+Bd1Dt+2r94v2eGFpQJ4R7g+2w==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/node-forge": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", - "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" - }, - "node_modules/@types/prismjs": { - "version": "1.26.3", - "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.3.tgz", - "integrity": "sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==" - }, - "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" - }, - "node_modules/@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" - }, - "node_modules/@types/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.1.tgz", - "integrity": "sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==", - "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-router": { - "version": "5.1.20", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", - "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*" - } - }, - "node_modules/@types/react-router-config": { - "version": "5.0.11", - "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", - "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "^5.1.0" - } - }, - "node_modules/@types/react-router-dom": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", - "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "*" - } - }, - "node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" - }, - "node_modules/@types/sax": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", - "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, - "node_modules/@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" - }, - "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" - }, - "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==" - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/accepts/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==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/accepts/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==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "peerDependencies": { - "acorn": "^8" - } - }, - "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==", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", - "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/algoliasearch": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", - "integrity": "sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==", - "dependencies": { - "@algolia/cache-browser-local-storage": "4.24.0", - "@algolia/cache-common": "4.24.0", - "@algolia/cache-in-memory": "4.24.0", - "@algolia/client-account": "4.24.0", - "@algolia/client-analytics": "4.24.0", - "@algolia/client-common": "4.24.0", - "@algolia/client-personalization": "4.24.0", - "@algolia/client-search": "4.24.0", - "@algolia/logger-common": "4.24.0", - "@algolia/logger-console": "4.24.0", - "@algolia/recommend": "4.24.0", - "@algolia/requester-browser-xhr": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/requester-node-http": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/algoliasearch-helper": { - "version": "3.22.4", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.22.4.tgz", - "integrity": "sha512-fvBCywguW9f+939S6awvRMstqMF1XXcd2qs1r1aGqL/PJ1go/DqN06tWmDVmhCDqBJanm++imletrQWf0G2S1g==", - "dependencies": { - "@algolia/events": "^4.0.1" - }, - "peerDependencies": { - "algoliasearch": ">= 3.1 < 6" - } - }, - "node_modules/algoliasearch/node_modules/@algolia/client-common": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", - "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "dependencies": { - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/algoliasearch/node_modules/@algolia/client-search": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", - "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "dependencies": { - "@algolia/client-common": "4.24.0", - "@algolia/requester-common": "4.24.0", - "@algolia/transporter": "4.24.0" - } - }, - "node_modules/algoliasearch/node_modules/@algolia/requester-browser-xhr": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", - "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", - "dependencies": { - "@algolia/requester-common": "4.24.0" - } - }, - "node_modules/algoliasearch/node_modules/@algolia/requester-node-http": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", - "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", - "dependencies": { - "@algolia/requester-common": "4.24.0" - } - }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dependencies": { - "string-width": "^4.1.0" - } - }, - "node_modules/ansi-align/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==" - }, - "node_modules/ansi-align/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==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "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==", - "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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" - }, - "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==" - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/astring": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", - "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", - "bin": { - "astring": "bin/astring" - } - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/autoprefixer": { - "version": "10.4.20", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", - "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "browserslist": "^4.23.3", - "caniuse-lite": "^1.0.30001646", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/babel-loader": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", - "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", - "dependencies": { - "find-cache-dir": "^4.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0", - "webpack": ">=5" - } - }, - "node_modules/babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dependencies": { - "object.assign": "^4.1.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", - "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", - "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", - "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1", - "core-js-compat": "^3.36.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", - "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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==" - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/bonjour-service": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", - "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" - }, - "node_modules/boxen": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", - "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^6.2.0", - "chalk": "^4.1.2", - "cli-boxes": "^3.0.0", - "string-width": "^5.0.1", - "type-fest": "^2.5.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "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==", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", - "engines": { - "node": ">=14.16" - } - }, - "node_modules/cacheable-request": { - "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", - "dependencies": { - "@types/http-cache-semantics": "^4.0.2", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.3", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "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==", - "engines": { - "node": ">=6" - } - }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001655", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz", - "integrity": "sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" - }, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/clean-css": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", - "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 10.0" - } - }, - "node_modules/clean-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-table3": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.4.tgz", - "integrity": "sha512-Lm3L0p+/npIQWNIiyF/nAn7T5dnOwR3xNTHXYEBFBFVPXzCVNZ5lqEC/1eo/EVfpDsQ1I+TX4ORPQgp+UI0CRw==", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/cli-table3/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==" - }, - "node_modules/cli-table3/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==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/collapse-white-space": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", - "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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==", - "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==" - }, - "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" - }, - "node_modules/combine-promises": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", - "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compressible/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==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "node_modules/configstore": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", - "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", - "dependencies": { - "dot-prop": "^6.0.1", - "graceful-fs": "^4.2.6", - "unique-string": "^3.0.0", - "write-file-atomic": "^3.0.3", - "xdg-basedir": "^5.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/yeoman/configstore?sponsor=1" - } - }, - "node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/consola": { - "version": "2.15.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", - "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" - }, - "node_modules/content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", - "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==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" - }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/copy-text-to-clipboard": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", - "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/copy-webpack-plugin": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", - "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", - "dependencies": { - "fast-glob": "^3.2.11", - "glob-parent": "^6.0.1", - "globby": "^13.1.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "node_modules/copy-webpack-plugin/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==", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/copy-webpack-plugin/node_modules/globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", - "dependencies": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", - "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/copy-webpack-plugin/node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/core-js": { - "version": "3.37.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.0.tgz", - "integrity": "sha512-fu5vHevQ8ZG4og+LXug8ulUtVxjOcEYvifJr7L5Bfq9GOztVqsKd9/59hUk2ZSbCrS3BqUr3EpaYGIYzq7g3Ug==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-compat": { - "version": "3.37.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.0.tgz", - "integrity": "sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==", - "dependencies": { - "browserslist": "^4.23.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-pure": { - "version": "3.37.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.37.0.tgz", - "integrity": "sha512-d3BrpyFr5eD4KcbRvQ3FTUx/KWmaDesr7+a3+1+P46IUnNoEt+oiLijPINZMEon7w9oGkIINWxrBAU9DEciwFQ==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "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==", - "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==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-random-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", - "dependencies": { - "type-fest": "^1.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/crypto-random-string/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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/css-declaration-sorter": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", - "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", - "engines": { - "node": "^14 || ^16 || >=18" - }, - "peerDependencies": { - "postcss": "^8.0.9" - } - }, - "node_modules/css-loader": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", - "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", - "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.33", - "postcss-modules-extract-imports": "^3.1.0", - "postcss-modules-local-by-default": "^4.0.5", - "postcss-modules-scope": "^3.2.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/css-minimizer-webpack-plugin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", - "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "cssnano": "^6.0.1", - "jest-worker": "^29.4.3", - "postcss": "^8.4.24", - "schema-utils": "^4.0.1", - "serialize-javascript": "^6.0.1" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@parcel/css": { - "optional": true - }, - "@swc/css": { - "optional": true - }, - "clean-css": { - "optional": true - }, - "csso": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "lightningcss": { - "optional": true - } - } - }, - "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "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==", - "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/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "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==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", - "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", - "dependencies": { - "cssnano-preset-default": "^6.1.2", - "lilconfig": "^3.1.1" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/cssnano" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/cssnano-preset-advanced": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", - "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", - "dependencies": { - "autoprefixer": "^10.4.19", - "browserslist": "^4.23.0", - "cssnano-preset-default": "^6.1.2", - "postcss-discard-unused": "^6.0.5", - "postcss-merge-idents": "^6.0.3", - "postcss-reduce-idents": "^6.0.3", - "postcss-zindex": "^6.0.2" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/cssnano-preset-default": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", - "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", - "dependencies": { - "browserslist": "^4.23.0", - "css-declaration-sorter": "^7.2.0", - "cssnano-utils": "^4.0.2", - "postcss-calc": "^9.0.1", - "postcss-colormin": "^6.1.0", - "postcss-convert-values": "^6.1.0", - "postcss-discard-comments": "^6.0.2", - "postcss-discard-duplicates": "^6.0.3", - "postcss-discard-empty": "^6.0.3", - "postcss-discard-overridden": "^6.0.2", - "postcss-merge-longhand": "^6.0.5", - "postcss-merge-rules": "^6.1.1", - "postcss-minify-font-values": "^6.1.0", - "postcss-minify-gradients": "^6.0.3", - "postcss-minify-params": "^6.1.0", - "postcss-minify-selectors": "^6.0.4", - "postcss-normalize-charset": "^6.0.2", - "postcss-normalize-display-values": "^6.0.2", - "postcss-normalize-positions": "^6.0.2", - "postcss-normalize-repeat-style": "^6.0.2", - "postcss-normalize-string": "^6.0.2", - "postcss-normalize-timing-functions": "^6.0.2", - "postcss-normalize-unicode": "^6.1.0", - "postcss-normalize-url": "^6.0.2", - "postcss-normalize-whitespace": "^6.0.2", - "postcss-ordered-values": "^6.0.2", - "postcss-reduce-initial": "^6.1.0", - "postcss-reduce-transforms": "^6.0.2", - "postcss-svgo": "^6.0.3", - "postcss-unique-selectors": "^6.0.4" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/cssnano-utils": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", - "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "dependencies": { - "css-tree": "~2.2.0" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==" - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" - }, - "node_modules/debounce": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-named-character-reference": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", - "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "engines": { - "node": ">=8" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/del": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", - "dependencies": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" - }, - "node_modules/detect-port": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", - "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", - "dependencies": { - "address": "^1.0.1", - "debug": "4" - }, - "bin": { - "detect": "bin/detect-port.js", - "detect-port": "bin/detect-port.js" - } - }, - "node_modules/detect-port-alt": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", - "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", - "dependencies": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "bin": { - "detect": "bin/detect-port", - "detect-port": "bin/detect-port" - }, - "engines": { - "node": ">= 4.2.1" - } - }, - "node_modules/detect-port-alt/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/detect-port-alt/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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==", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dependencies": { - "utila": "~0.4" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dot-prop/node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" - }, - "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==" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz", - "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==" - }, - "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==" - }, - "node_modules/emojilib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", - "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==" - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/emoticon": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.1.0.tgz", - "integrity": "sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "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==", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "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==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-module-lexer": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.2.tgz", - "integrity": "sha512-l60ETUTmLqbVbVHv1J4/qj+M8nq7AwMzEcg3kmJDt9dCNrTk+yHcYFf/Kw75pMDwd9mPcIGCG5LcS20SxYRzFA==" - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-goat": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", - "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==" - }, - "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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "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==", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-util-attach-comments": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", - "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", - "dependencies": { - "@types/estree": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-build-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", - "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-walker": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-is-identifier-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", - "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-to-js": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", - "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "astring": "^1.8.0", - "source-map": "^0.7.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-value-to-estree": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.1.2.tgz", - "integrity": "sha512-S0gW2+XZkmsx00tU2uJ4L9hUT7IFabbml9pHh2WQqFmAbxit++YGZne0sKJbNwkj9Wvg9E4uqWl4nCIFQMmfag==", - "dependencies": { - "@types/estree": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/remcohaszing" - } - }, - "node_modules/estree-util-visit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", - "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dependencies": { - "@types/estree": "^1.0.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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eta": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", - "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "url": "https://github.com/eta-dev/eta?sponsor=1" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eval": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", - "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", - "dependencies": { - "@types/node": "*", - "require-like": ">= 0.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "node_modules/express/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==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "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==" - }, - "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==", - "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-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==" - }, - "node_modules/fast-url-parser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", - "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", - "dependencies": { - "punycode": "^1.3.2" - } - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fault": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", - "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", - "dependencies": { - "format": "^0.2.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/feed": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", - "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", - "dependencies": { - "xml-js": "^1.6.11" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/file-loader/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "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/file-loader/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/file-loader/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==" - }, - "node_modules/file-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/filesize": { - "version": "8.0.7", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", - "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", - "engines": { - "node": ">= 0.4.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==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/find-cache-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", - "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", - "dependencies": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/fork-ts-checker-webpack-plugin": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", - "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "chokidar": "^3.4.2", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "glob": "^7.1.6", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=10", - "yarn": ">=1.0.0" - }, - "peerDependencies": { - "eslint": ">= 6", - "typescript": ">= 2.7", - "vue-template-compiler": "*", - "webpack": ">= 4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - }, - "vue-template-compiler": { - "optional": true - } - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "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/fork-ts-checker-webpack-plugin/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/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==" - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "dependencies": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/form-data-encoder": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", - "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", - "engines": { - "node": ">= 14.17" - } - }, - "node_modules/format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/fs-monkey": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", - "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==" - }, - "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==" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "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==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/github-slugger": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", - "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "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": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "node_modules/global-dirs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/global-dirs/node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "engines": { - "node": ">=10" - } - }, - "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==", - "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==", - "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==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "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/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/got": { - "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", - "dependencies": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/got/node_modules/@sindresorhus/is": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "node_modules/gray-matter": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", - "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", - "dependencies": { - "js-yaml": "^3.13.1", - "kind-of": "^6.0.2", - "section-matter": "^1.0.0", - "strip-bom-string": "^1.0.0" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/gray-matter/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/gray-matter/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "dependencies": { - "duplexer": "^0.1.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-yarn": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", - "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hast-util-from-parse5": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", - "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "hastscript": "^8.0.0", - "property-information": "^6.0.0", - "vfile": "^6.0.0", - "vfile-location": "^5.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.4.tgz", - "integrity": "sha512-LHE65TD2YiNsHD3YuXcKPHXPLuYh/gjp12mOfU8jxSrm1f/yJpsb0F/KKljS6U9LJoP0Ux+tCe8iJ2AsPzTdgA==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-from-parse5": "^8.0.0", - "hast-util-to-parse5": "^8.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "parse5": "^7.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-estree": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", - "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-attach-comments": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^0.4.0", - "unist-util-position": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-jsx-runtime": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz", - "integrity": "sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^1.0.0", - "unist-util-position": "^5.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/inline-style-parser": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.3.tgz", - "integrity": "sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g==" - }, - "node_modules/hast-util-to-jsx-runtime/node_modules/style-to-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.7.tgz", - "integrity": "sha512-uSjr59G5u6fbxUfKbb8GcqMGT3Xs9v5IbPkjb0S16GyOeBLAzSRK0CixBv5YrYvzO6TDLzIS6QCn78tkqWngPw==", - "dependencies": { - "inline-style-parser": "0.2.3" - } - }, - "node_modules/hast-util-to-parse5": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", - "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hastscript": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", - "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "bin": { - "he": "bin/he" - } - }, - "node_modules/history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "dependencies": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "node_modules/hpack.js/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/hpack.js/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/html-entities": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", - "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ] - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" - }, - "node_modules/html-minifier-terser": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", - "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "~5.3.2", - "commander": "^10.0.0", - "entities": "^4.4.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.15.1" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": "^14.13.1 || >=16.0.0" - } - }, - "node_modules/html-minifier-terser/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "engines": { - "node": ">=14" - } - }, - "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==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/html-webpack-plugin": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", - "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", - "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.20.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/html-webpack-plugin/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "engines": { - "node": ">= 12" - } - }, - "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" - }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" - }, - "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==", - "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/http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "engines": { - "node": ">=10.17.0" - } - }, - "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==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/image-size": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", - "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", - "dependencies": { - "queue": "6.0.2" - }, - "bin": { - "image-size": "bin/image-size.js" - }, - "engines": { - "node": ">=16.x" - } - }, - "node_modules/immer": { - "version": "9.0.21", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", - "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/immer" - } - }, - "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==", - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/infima": { - "version": "0.2.0-alpha.44", - "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.44.tgz", - "integrity": "sha512-tuRkUSO/lB3rEhLJk25atwAjgLuzq070+pOW8XcvpHky/YbENnRRdPd85IBkyeTgttmOy5ah+yHYsK1HhUd4lQ==", - "engines": { - "node": ">=12" - } - }, - "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==", - "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==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/inline-style-parser": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", - "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/ipaddr.js": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", - "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-alphanumerical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "dependencies": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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==" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "dependencies": { - "ci-info": "^3.2.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "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==", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "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==", - "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==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-npm": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", - "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "engines": { - "node": ">=6" - } - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-reference": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", - "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-root": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", - "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-yarn-global": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", - "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jiti": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/joi": { - "version": "17.13.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", - "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", - "dependencies": { - "@hapi/hoek": "^9.3.0", - "@hapi/topo": "^5.1.0", - "@sideway/address": "^4.1.5", - "@sideway/formula": "^3.0.1", - "@sideway/pinpoint": "^2.0.0" - } - }, - "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==" - }, - "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==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "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==" - }, - "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==" - }, - "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==" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "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==", - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "engines": { - "node": ">=6" - } - }, - "node_modules/latest-version": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", - "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", - "dependencies": { - "package-json": "^8.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/launch-editor": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", - "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", - "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/lilconfig": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", - "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "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==" - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" - }, - "node_modules/longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/markdown-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", - "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/markdown-table": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", - "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/mdast-util-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", - "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", - "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-from-markdown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", - "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-frontmatter": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", - "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "escape-string-regexp": "^5.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", - "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-gfm-autolink-literal": "^2.0.0", - "mdast-util-gfm-footnote": "^2.0.0", - "mdast-util-gfm-strikethrough": "^2.0.0", - "mdast-util-gfm-table": "^2.0.0", - "mdast-util-gfm-task-list-item": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", - "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-find-and-replace": "^3.0.0", - "micromark-util-character": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/mdast-util-gfm-footnote": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", - "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-expression": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", - "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-jsx": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.3.tgz", - "integrity": "sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdxjs-esm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", - "dependencies": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", - "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", - "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "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==" - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", - "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", - "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-directive": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.1.tgz", - "integrity": "sha512-VGV2uxUzhEZmaP7NSFo2vtq7M2nUD+WfmYQD+d8i/1nHbzE+rMy9uzTvUybBbNiVbrhOZibg3gbyoARGqgDWyg==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "parse-entities": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-frontmatter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", - "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", - "dependencies": { - "fault": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", - "dependencies": { - "micromark-extension-gfm-autolink-literal": "^2.0.0", - "micromark-extension-gfm-footnote": "^2.0.0", - "micromark-extension-gfm-strikethrough": "^2.0.0", - "micromark-extension-gfm-table": "^2.0.0", - "micromark-extension-gfm-tagfilter": "^2.0.0", - "micromark-extension-gfm-task-list-item": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", - "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-strikethrough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", - "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-table": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz", - "integrity": "sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-gfm-tagfilter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", - "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-mdx-expression": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", - "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-expression/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-mdx-jsx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.0.tgz", - "integrity": "sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==", - "dependencies": { - "@types/acorn": "^4.0.0", - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-extension-mdx-md": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", - "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", - "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", - "dependencies": { - "acorn": "^8.0.0", - "acorn-jsx": "^5.0.0", - "micromark-extension-mdx-expression": "^3.0.0", - "micromark-extension-mdx-jsx": "^3.0.0", - "micromark-extension-mdx-md": "^2.0.0", - "micromark-extension-mdxjs-esm": "^3.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs-esm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", - "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-factory-mdx-expression": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.1.tgz", - "integrity": "sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - } - }, - "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-factory-space": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", - "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/micromark-factory-space/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-character": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/micromark-util-character/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-events-to-acorn": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", - "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/acorn": "^4.0.0", - "@types/estree": "^1.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "estree-util-visit": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - } - }, - "node_modules/micromark-util-events-to-acorn/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-resolve-all": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-subtokenize": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", - "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-symbol": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark/node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark/node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark/node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dependencies": { - "mime-db": "~1.33.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/mimic-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mini-css-extract-plugin": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", - "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", - "dependencies": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mrmime": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", - "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", - "engines": { - "node": ">=10" - } - }, - "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==" - }, - "node_modules/multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/node-emoji": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", - "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", - "dependencies": { - "@sindresorhus/is": "^4.6.0", - "char-regex": "^1.0.2", - "emojilib": "^2.4.0", - "skin-tone": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" - }, - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", - "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nprogress": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==" - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" - }, - "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==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "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==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "bin": { - "opener": "bin/opener-bin.js" - } - }, - "node_modules/p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "engines": { - "node": ">=12.20" - } - }, - "node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "dependencies": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/package-json": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", - "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", - "dependencies": { - "got": "^12.1.0", - "registry-auth-token": "^5.0.1", - "registry-url": "^6.0.0", - "semver": "^7.3.7" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "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==", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-entities": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", - "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", - "dependencies": { - "@types/unist": "^2.0.0", - "character-entities": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/parse-entities/node_modules/@types/unist": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", - "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" - }, - "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==", - "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/parse-numeric-range": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", - "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" - }, - "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", - "dependencies": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dependencies": { - "isarray": "0.0.1" - } - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/periscopic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^3.0.0", - "is-reference": "^3.0.0" - } - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-dir": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", - "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", - "dependencies": { - "find-up": "^6.3.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-up/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-up/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "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" - } - ], - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-calc": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", - "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.11", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.2" - } - }, - "node_modules/postcss-colormin": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", - "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0", - "colord": "^2.9.3", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-convert-values": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", - "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-comments": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", - "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-duplicates": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", - "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-empty": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", - "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-overridden": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", - "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-unused": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", - "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-loader": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", - "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", - "dependencies": { - "cosmiconfig": "^8.3.5", - "jiti": "^1.20.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "postcss": "^7.0.0 || ^8.0.1", - "webpack": "^5.0.0" - } - }, - "node_modules/postcss-merge-idents": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", - "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", - "dependencies": { - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-merge-longhand": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", - "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^6.1.1" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-merge-rules": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", - "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^4.0.2", - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-font-values": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", - "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-gradients": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", - "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", - "dependencies": { - "colord": "^2.9.3", - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-params": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", - "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", - "dependencies": { - "browserslist": "^4.23.0", - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-selectors": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", - "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", - "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", - "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", - "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-scope": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", - "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "dependencies": { - "icss-utils": "^5.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-normalize-charset": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", - "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-display-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", - "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-positions": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", - "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-repeat-style": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", - "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-string": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", - "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-timing-functions": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", - "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-unicode": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", - "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-url": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", - "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-whitespace": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", - "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-ordered-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", - "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", - "dependencies": { - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-reduce-idents": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", - "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-reduce-initial": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", - "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-reduce-transforms": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", - "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "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==", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-sort-media-queries": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", - "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", - "dependencies": { - "sort-css-media-queries": "2.2.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.4.23" - } - }, - "node_modules/postcss-svgo": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", - "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "svgo": "^3.2.0" - }, - "engines": { - "node": "^14 || ^16 || >= 18" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-unique-selectors": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", - "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "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==" - }, - "node_modules/postcss-zindex": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", - "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, - "node_modules/pretty-time": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", - "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/prism-react-renderer": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.3.1.tgz", - "integrity": "sha512-Rdf+HzBLR7KYjzpJ1rSoxT9ioO85nZngQEoFIhL07XhtJHlCU3SOz0GJ6+qvMyQe0Se+BV3qpe6Yd/NmQF5Juw==", - "dependencies": { - "@types/prismjs": "^1.26.0", - "clsx": "^2.0.0" - }, - "peerDependencies": { - "react": ">=16.0.0" - } - }, - "node_modules/prismjs": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", - "engines": { - "node": ">=6" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/property-information": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", - "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" - }, - "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==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-addr/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==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" - }, - "node_modules/pupa": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", - "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", - "dependencies": { - "escape-goat": "^4.0.0" - }, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", - "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", - "dependencies": { - "inherits": "~2.0.3" - } - }, - "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" - } - ] - }, - "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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dev-utils": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", - "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", - "dependencies": { - "@babel/code-frame": "^7.16.0", - "address": "^1.1.2", - "browserslist": "^4.18.1", - "chalk": "^4.1.2", - "cross-spawn": "^7.0.3", - "detect-port-alt": "^1.1.6", - "escape-string-regexp": "^4.0.0", - "filesize": "^8.0.6", - "find-up": "^5.0.0", - "fork-ts-checker-webpack-plugin": "^6.5.0", - "global-modules": "^2.0.0", - "globby": "^11.0.4", - "gzip-size": "^6.0.0", - "immer": "^9.0.7", - "is-root": "^2.1.0", - "loader-utils": "^3.2.0", - "open": "^8.4.0", - "pkg-up": "^3.1.0", - "prompts": "^2.4.2", - "react-error-overlay": "^6.0.11", - "recursive-readdir": "^2.2.2", - "shell-quote": "^1.7.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/react-dev-utils/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==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/loader-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", - "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", - "engines": { - "node": ">= 12.13.0" - } - }, - "node_modules/react-dev-utils/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==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/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==", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/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==", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/react-dev-utils/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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - }, - "peerDependencies": { - "react": "^18.3.1" - } - }, - "node_modules/react-error-overlay": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", - "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" - }, - "node_modules/react-fast-compare": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", - "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" - }, - "node_modules/react-helmet-async": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", - "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "invariant": "^2.2.4", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.2.0", - "shallowequal": "^1.1.0" - }, - "peerDependencies": { - "react": "^16.6.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/react-json-view-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.4.0.tgz", - "integrity": "sha512-wh6F6uJyYAmQ4fK0e8dSQMEWuvTs2Wr3el3sLD9bambX1+pSWUVXIz1RFaoy3TI1mZ0FqdpKq9YgbgTTgyrmXA==", - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/react-loadable": { - "name": "@docusaurus/react-loadable", - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", - "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", - "dependencies": { - "@types/react": "*" - }, - "peerDependencies": { - "react": "*" - } - }, - "node_modules/react-loadable-ssr-addon-v5-slorber": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", - "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", - "dependencies": { - "@babel/runtime": "^7.10.3" - }, - "engines": { - "node": ">=10.13.0" - }, - "peerDependencies": { - "react-loadable": "*", - "webpack": ">=4.41.1 || 5.x" - } - }, - "node_modules/react-router": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", - "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", - "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - }, - "peerDependencies": { - "react": ">=15" - } - }, - "node_modules/react-router-config": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", - "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", - "dependencies": { - "@babel/runtime": "^7.1.2" - }, - "peerDependencies": { - "react": ">=15", - "react-router": ">=5" - } - }, - "node_modules/react-router-dom": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", - "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", - "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.3.4", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - }, - "peerDependencies": { - "react": ">=15" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/reading-time": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", - "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==" - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/recursive-readdir": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "dependencies": { - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" - }, - "node_modules/regenerator-transform": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", - "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", - "dependencies": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/registry-auth-token": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", - "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", - "dependencies": { - "@pnpm/npm-conf": "^2.1.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/registry-url": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", - "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", - "dependencies": { - "rc": "1.2.8" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/rehype-raw": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", - "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-raw": "^9.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/remark-directive": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz", - "integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-directive": "^3.0.0", - "micromark-extension-directive": "^3.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-emoji": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", - "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", - "dependencies": { - "@types/mdast": "^4.0.2", - "emoticon": "^4.0.1", - "mdast-util-find-and-replace": "^3.0.1", - "node-emoji": "^2.1.0", - "unified": "^11.0.4" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/remark-frontmatter": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", - "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-frontmatter": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", - "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-gfm": "^3.0.0", - "micromark-extension-gfm": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-mdx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.1.tgz", - "integrity": "sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==", - "dependencies": { - "mdast-util-mdx": "^3.0.0", - "micromark-extension-mdxjs": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.0.tgz", - "integrity": "sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-to-markdown": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, - "node_modules/renderkid/node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/renderkid/node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-like": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", - "engines": { - "node": "*" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" - }, - "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==", - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" - }, - "node_modules/responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", - "dependencies": { - "lowercase-keys": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "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==", - "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==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rtl-detect": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.1.2.tgz", - "integrity": "sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==" - }, - "node_modules/rtlcss": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", - "integrity": "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==", - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0", - "postcss": "^8.4.21", - "strip-json-comments": "^3.1.1" - }, - "bin": { - "rtlcss": "bin/rtlcss.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "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" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==" - }, - "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/search-insights": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.0.tgz", - "integrity": "sha512-AskayU3QNsXQzSL6v4LTYST7NNfs2HWyHHB+sdORP9chsytAhro5XRfToAMI/LAVYgNbzowVZTMfBRodgbUHKg==", - "peer": true - }, - "node_modules/section-matter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", - "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", - "dependencies": { - "extend-shallow": "^2.0.1", - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" - }, - "node_modules/selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", - "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } - }, - "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==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", - "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semver/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==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/send/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==" - }, - "node_modules/send/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==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-handler": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz", - "integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==", - "dependencies": { - "bytes": "3.0.0", - "content-disposition": "0.5.2", - "fast-url-parser": "1.1.3", - "mime-types": "2.1.18", - "minimatch": "3.1.2", - "path-is-inside": "1.0.2", - "path-to-regexp": "2.2.1", - "range-parser": "1.2.0" - } - }, - "node_modules/serve-handler/node_modules/path-to-regexp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", - "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==" - }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" - }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - }, - "node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" - }, - "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==", - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "node_modules/sirv": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", - "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", - "dependencies": { - "@polka/url": "^1.0.0-next.24", - "mrmime": "^2.0.0", - "totalist": "^3.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" - }, - "node_modules/sitemap": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", - "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", - "dependencies": { - "@types/node": "^17.0.5", - "@types/sax": "^1.2.1", - "arg": "^5.0.0", - "sax": "^1.2.4" - }, - "bin": { - "sitemap": "dist/cli.js" - }, - "engines": { - "node": ">=12.0.0", - "npm": ">=5.6.0" - } - }, - "node_modules/sitemap/node_modules/@types/node": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" - }, - "node_modules/skin-tone": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", - "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", - "dependencies": { - "unicode-emoji-modifier-base": "^1.0.0" - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/snake-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", - "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "node_modules/sort-css-media-queries": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", - "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==", - "engines": { - "node": ">= 6.3.0" - } - }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "engines": { - "node": ">= 8" - } - }, - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" - }, - "node_modules/srcset": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", - "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==" - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "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==", - "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/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-width/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==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/stringify-entities": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", - "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", - "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "dependencies": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "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==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "engines": { - "node": ">=6" - } - }, - "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==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/style-to-object": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", - "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", - "dependencies": { - "inline-style-parser": "0.1.1" - } - }, - "node_modules/stylehacks": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", - "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svg-parser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" - }, - "node_modules/svgo": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz", - "integrity": "sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ==", - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^5.1.0", - "css-tree": "^2.3.1", - "css-what": "^6.1.0", - "csso": "^5.0.5", - "picocolors": "^1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/svgo" - } - }, - "node_modules/svgo/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/terser": { - "version": "5.31.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz", - "integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser-webpack-plugin/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "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/terser-webpack-plugin/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/terser-webpack-plugin/node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/terser-webpack-plugin/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==" - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/terser-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "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==" - }, - "node_modules/thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" - }, - "node_modules/tiny-invariant": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", - "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" - }, - "node_modules/tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "engines": { - "node": ">=4" - } - }, - "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==", - "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==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/trough": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", - "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/type-is/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==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/type-is/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==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", - "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/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-emoji-modifier-base": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", - "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unified": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", - "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unique-string": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", - "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", - "dependencies": { - "crypto-random-string": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position-from-estree": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", - "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "engines": { - "node": ">= 10.0.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==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/update-notifier": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", - "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", - "dependencies": { - "boxen": "^7.0.0", - "chalk": "^5.0.1", - "configstore": "^6.0.0", - "has-yarn": "^3.0.0", - "import-lazy": "^4.0.0", - "is-ci": "^3.0.1", - "is-installed-globally": "^0.4.0", - "is-npm": "^6.0.0", - "is-yarn-global": "^0.4.0", - "latest-version": "^7.0.0", - "pupa": "^3.1.0", - "semver": "^7.3.7", - "semver-diff": "^4.0.0", - "xdg-basedir": "^5.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/yeoman/update-notifier?sponsor=1" - } - }, - "node_modules/update-notifier/node_modules/boxen": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", - "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^7.0.1", - "chalk": "^5.2.0", - "cli-boxes": "^3.0.0", - "string-width": "^5.1.2", - "type-fest": "^2.13.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/update-notifier/node_modules/camelcase": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/update-notifier/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/uri-js/node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/url-loader": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", - "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", - "dependencies": { - "loader-utils": "^2.0.0", - "mime-types": "^2.1.27", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "file-loader": "*", - "webpack": "^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "file-loader": { - "optional": true - } - } - }, - "node_modules/url-loader/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "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/url-loader/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/url-loader/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==" - }, - "node_modules/url-loader/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==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/url-loader/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==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/url-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "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==" - }, - "node_modules/utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" - }, - "node_modules/utility-types": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", - "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" - }, - "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==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/vfile": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", - "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-location": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", - "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/watchpack": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", - "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/web-namespaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/webpack": { - "version": "5.94.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", - "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", - "dependencies": { - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.1", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-bundle-analyzer": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", - "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", - "dependencies": { - "@discoveryjs/json-ext": "0.5.7", - "acorn": "^8.0.4", - "acorn-walk": "^8.0.0", - "commander": "^7.2.0", - "debounce": "^1.2.1", - "escape-string-regexp": "^4.0.0", - "gzip-size": "^6.0.0", - "html-escaper": "^2.0.2", - "opener": "^1.5.2", - "picocolors": "^1.0.0", - "sirv": "^2.0.3", - "ws": "^7.3.1" - }, - "bin": { - "webpack-bundle-analyzer": "lib/bin/analyzer.js" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/webpack-dev-middleware/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==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpack-dev-middleware/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==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpack-dev-middleware/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==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpack-dev-server": { - "version": "4.15.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", - "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.4", - "ws": "^8.13.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "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/webpack/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/webpack/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==" - }, - "node_modules/webpack/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==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpack/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==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/webpackbar": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-5.0.2.tgz", - "integrity": "sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==", - "dependencies": { - "chalk": "^4.1.0", - "consola": "^2.15.3", - "pretty-time": "^1.1.0", - "std-env": "^3.0.1" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "webpack": "3 || 4 || 5" - } - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/widest-line": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", - "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", - "dependencies": { - "string-width": "^5.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" - }, - "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==", - "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/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/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==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/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==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "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==" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xdg-basedir": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", - "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/xml-js": { - "version": "1.6.11", - "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", - "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", - "dependencies": { - "sax": "^1.2.4" - }, - "bin": { - "xml-js": "bin/cli.js" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - } -} diff --git a/docsite/package.json b/docsite/package.json index 94daf25ea..47338a735 100644 --- a/docsite/package.json +++ b/docsite/package.json @@ -15,20 +15,20 @@ "typecheck": "tsc" }, "dependencies": { - "@docusaurus/core": "^3.5.2", - "@docusaurus/preset-classic": "^3.5.2", - "@mdx-js/react": "^3.0.1", + "@docusaurus/core": "^3.8.1", + "@docusaurus/preset-classic": "^3.8.1", + "@mdx-js/react": "^3.1.0", "clsx": "^2.1.1", - "prism-react-renderer": "^2.3.1", - "react": "^18.3.1", - "react-dom": "^18.3.1" + "prism-react-renderer": "^2.4.1", + "react": "^19.1.1", + "react-dom": "^19.1.1" }, "devDependencies": { - "@docusaurus/module-type-aliases": "^3.5.2", - "@docusaurus/tsconfig": "^3.5.2", - "@docusaurus/types": "^3.5.2", - "dotenv": "^16.4.5", - "typescript": "^5.4.5" + "@docusaurus/module-type-aliases": "^3.8.1", + "@docusaurus/tsconfig": "^3.8.1", + "@docusaurus/types": "^3.8.1", + "dotenv": "^17.2.1", + "typescript": "^5.9.2" }, "browserslist": { "production": [ diff --git a/docsite/runfile.toml b/docsite/runfile.toml new file mode 100644 index 000000000..fbfb5c454 --- /dev/null +++ b/docsite/runfile.toml @@ -0,0 +1,8 @@ +[dev-docsite] +alias = "dd" +description = "starts the documentation site (https://komo.do) in dev mode" +cmd = "yarn && yarn start" + +[publish-docsite] +description = "publishes the documentation site (https://komo.do) to github pages" +cmd = "yarn && yarn deploy" \ No newline at end of file diff --git a/docsite/sidebars.ts b/docsite/sidebars.ts index 1d32730dd..e7cc28772 100644 --- a/docsite/sidebars.ts +++ b/docsite/sidebars.ts @@ -1,4 +1,4 @@ -import type {SidebarsConfig} from '@docusaurus/plugin-content-docs'; +import type { SidebarsConfig } from "@docusaurus/plugin-content-docs"; /** * Creating a sidebar enables you to: @@ -13,10 +13,9 @@ import type {SidebarsConfig} from '@docusaurus/plugin-content-docs'; const sidebars: SidebarsConfig = { docs: [ "intro", - "resources", { type: "category", - label: "Setup Komodo Core", + label: "Setup", link: { type: "doc", id: "setup/index", @@ -24,48 +23,69 @@ const sidebars: SidebarsConfig = { items: [ "setup/mongo", "setup/ferretdb", + "setup/connect-servers", + "setup/backup", "setup/advanced", - ], - }, - "connect-servers", - { - type: "category", - label: "Build Images", - link: { - type: "doc", - id: "build-images/index", - }, - items: [ - "build-images/configuration", - "build-images/pre-build", - "build-images/builders", - "build-images/versioning", + "setup/version-upgrades", ], }, { type: "category", - label: "Deploy Containers", + label: "Resources", link: { type: "doc", - id: "deploy-containers/index", + id: "resources/index", }, items: [ - "deploy-containers/configuration", - "deploy-containers/lifetime-management", - // "deploy-containers/choosing-builder", - // "deploy-containers/versioning", + { + type: "category", + label: "Build Images", + link: { + type: "doc", + id: "resources/build-images/index", + }, + items: [ + "resources/build-images/configuration", + "resources/build-images/pre-build", + "resources/build-images/builders", + "resources/build-images/versioning", + ], + }, + { + type: "category", + label: "Deploy Containers", + link: { + type: "doc", + id: "resources/deploy-containers/index", + }, + items: [ + "resources/deploy-containers/configuration", + "resources/deploy-containers/lifetime-management", + ], + }, + "resources/docker-compose", + "resources/auto-update", + "resources/variables", + "resources/procedures", + "resources/sync-resources", + "resources/webhooks", + "resources/permissioning", + ], + }, + { + type: "category", + label: "Ecosystem", + link: { + type: "doc", + id: "ecosystem/index", + }, + items: [ + "ecosystem/cli", + "ecosystem/api", + "ecosystem/community", + "ecosystem/development", ], }, - "docker-compose", - "variables", - "procedures", - "permissioning", - "sync-resources", - "webhooks", - "version-upgrades", - "api", - "development", - "other-resources" ], }; diff --git a/docsite/yarn.lock b/docsite/yarn.lock index 3e742b2a0..fe45a51a2 100644 --- a/docsite/yarn.lock +++ b/docsite/yarn.lock @@ -2,6 +2,16 @@ # yarn lockfile v1 +"@algolia/abtesting@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@algolia/abtesting/-/abtesting-1.1.0.tgz#32c84876956727dcdca8df03c567f12fb39edf0d" + integrity sha512-sEyWjw28a/9iluA37KLGu8vjxEIlb60uxznfTUmXImy7H5NvbpSO6yYgmgH5KiD7j+zTUUihiST0jEP12IoXow== + dependencies: + "@algolia/client-common" "5.35.0" + "@algolia/requester-browser-xhr" "5.35.0" + "@algolia/requester-fetch" "5.35.0" + "@algolia/requester-node-http" "5.35.0" + "@algolia/autocomplete-core@1.17.9": version "1.17.9" resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.17.9.tgz#83374c47dc72482aa45d6b953e89377047f0dcdc" @@ -29,126 +39,126 @@ resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.9.tgz#5f38868f7cb1d54b014b17a10fc4f7e79d427fa8" integrity sha512-iDf05JDQ7I0b7JEA/9IektxN/80a2MZ1ToohfmNS3rfeuQnIKI3IJlIafD0xu4StbtQTghx9T3Maa97ytkXenQ== -"@algolia/client-abtesting@5.21.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@algolia/client-abtesting/-/client-abtesting-5.21.0.tgz#565c79275769c614ecf75bd8679dbd510a0c88c1" - integrity sha512-I239aSmXa3pXDhp3AWGaIfesqJBNFA7drUM8SIfNxMIzvQXUnHRf4rW1o77QXLI/nIClNsb8KOLaB62gO9LnlQ== +"@algolia/client-abtesting@5.35.0": + version "5.35.0" + resolved "https://registry.yarnpkg.com/@algolia/client-abtesting/-/client-abtesting-5.35.0.tgz#e4cb9ad90357c8b26fb6fbcd0157cc8bd1b600ed" + integrity sha512-uUdHxbfHdoppDVflCHMxRlj49/IllPwwQ2cQ8DLC4LXr3kY96AHBpW0dMyi6ygkn2MtFCc6BxXCzr668ZRhLBQ== dependencies: - "@algolia/client-common" "5.21.0" - "@algolia/requester-browser-xhr" "5.21.0" - "@algolia/requester-fetch" "5.21.0" - "@algolia/requester-node-http" "5.21.0" + "@algolia/client-common" "5.35.0" + "@algolia/requester-browser-xhr" "5.35.0" + "@algolia/requester-fetch" "5.35.0" + "@algolia/requester-node-http" "5.35.0" -"@algolia/client-analytics@5.21.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-5.21.0.tgz#4c4863b3cb7380de5bd1ba82691516e0a60ad167" - integrity sha512-OxoUfeG9G4VE4gS7B4q65KkHzdGsQsDwxQfR5J9uKB8poSGuNlHJWsF3ABqCkc5VliAR0m8KMjsQ9o/kOpEGnQ== +"@algolia/client-analytics@5.35.0": + version "5.35.0" + resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-5.35.0.tgz#ff0b9d9cbda074472d727a2d0a6b18bcc47076be" + integrity sha512-SunAgwa9CamLcRCPnPHx1V2uxdQwJGqb1crYrRWktWUdld0+B2KyakNEeVn5lln4VyeNtW17Ia7V7qBWyM/Skw== dependencies: - "@algolia/client-common" "5.21.0" - "@algolia/requester-browser-xhr" "5.21.0" - "@algolia/requester-fetch" "5.21.0" - "@algolia/requester-node-http" "5.21.0" + "@algolia/client-common" "5.35.0" + "@algolia/requester-browser-xhr" "5.35.0" + "@algolia/requester-fetch" "5.35.0" + "@algolia/requester-node-http" "5.35.0" -"@algolia/client-common@5.21.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-5.21.0.tgz#f32c28d25ccaf2954aca5ae5954a810fdef5b85e" - integrity sha512-iHLgDQFyZNe9M16vipbx6FGOA8NoMswHrfom/QlCGoyh7ntjGvfMb+J2Ss8rRsAlOWluv8h923Ku3QVaB0oWDQ== +"@algolia/client-common@5.35.0": + version "5.35.0" + resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-5.35.0.tgz#1d72b36308ceaa53d7d488cd3a161506ddeb0c42" + integrity sha512-ipE0IuvHu/bg7TjT2s+187kz/E3h5ssfTtjpg1LbWMgxlgiaZIgTTbyynM7NfpSJSKsgQvCQxWjGUO51WSCu7w== -"@algolia/client-insights@5.21.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@algolia/client-insights/-/client-insights-5.21.0.tgz#971c76f795923c1210f89c830d43bc14fa76de61" - integrity sha512-y7XBO9Iwb75FLDl95AYcWSLIViJTpR5SUUCyKsYhpP9DgyUqWbISqDLXc96TS9shj+H+7VsTKA9cJK8NUfVN6g== +"@algolia/client-insights@5.35.0": + version "5.35.0" + resolved "https://registry.yarnpkg.com/@algolia/client-insights/-/client-insights-5.35.0.tgz#8fd51eead7d89925522d48b5c164b3d7b656707c" + integrity sha512-UNbCXcBpqtzUucxExwTSfAe8gknAJ485NfPN6o1ziHm6nnxx97piIbcBQ3edw823Tej2Wxu1C0xBY06KgeZ7gA== dependencies: - "@algolia/client-common" "5.21.0" - "@algolia/requester-browser-xhr" "5.21.0" - "@algolia/requester-fetch" "5.21.0" - "@algolia/requester-node-http" "5.21.0" + "@algolia/client-common" "5.35.0" + "@algolia/requester-browser-xhr" "5.35.0" + "@algolia/requester-fetch" "5.35.0" + "@algolia/requester-node-http" "5.35.0" -"@algolia/client-personalization@5.21.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-5.21.0.tgz#0ab7c370a115d0b83edd8db55a4ea2f2b9212190" - integrity sha512-6KU658lD9Tss4oCX6c/O15tNZxw7vR+WAUG95YtZzYG/KGJHTpy2uckqbMmC2cEK4a86FAq4pH5azSJ7cGMjuw== +"@algolia/client-personalization@5.35.0": + version "5.35.0" + resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-5.35.0.tgz#a661767851269b8ff091eaa900fe0b65b3937382" + integrity sha512-/KWjttZ6UCStt4QnWoDAJ12cKlQ+fkpMtyPmBgSS2WThJQdSV/4UWcqCUqGH7YLbwlj3JjNirCu3Y7uRTClxvA== dependencies: - "@algolia/client-common" "5.21.0" - "@algolia/requester-browser-xhr" "5.21.0" - "@algolia/requester-fetch" "5.21.0" - "@algolia/requester-node-http" "5.21.0" + "@algolia/client-common" "5.35.0" + "@algolia/requester-browser-xhr" "5.35.0" + "@algolia/requester-fetch" "5.35.0" + "@algolia/requester-node-http" "5.35.0" -"@algolia/client-query-suggestions@5.21.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@algolia/client-query-suggestions/-/client-query-suggestions-5.21.0.tgz#14291a63db8ccd53e415d46578390fa5e1d1d35f" - integrity sha512-pG6MyVh1v0X+uwrKHn3U+suHdgJ2C+gug+UGkNHfMELHMsEoWIAQhxMBOFg7hCnWBFjQnuq6qhM3X9X5QO3d9Q== +"@algolia/client-query-suggestions@5.35.0": + version "5.35.0" + resolved "https://registry.yarnpkg.com/@algolia/client-query-suggestions/-/client-query-suggestions-5.35.0.tgz#b8704f3cdb2b49b8f0348bb77a3821a5ffa5b73b" + integrity sha512-8oCuJCFf/71IYyvQQC+iu4kgViTODbXDk3m7yMctEncRSRV+u2RtDVlpGGfPlJQOrAY7OONwJlSHkmbbm2Kp/w== dependencies: - "@algolia/client-common" "5.21.0" - "@algolia/requester-browser-xhr" "5.21.0" - "@algolia/requester-fetch" "5.21.0" - "@algolia/requester-node-http" "5.21.0" + "@algolia/client-common" "5.35.0" + "@algolia/requester-browser-xhr" "5.35.0" + "@algolia/requester-fetch" "5.35.0" + "@algolia/requester-node-http" "5.35.0" -"@algolia/client-search@5.21.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-5.21.0.tgz#37807d286a18e59b32af06dc62d4bd853d50121c" - integrity sha512-nZfgJH4njBK98tFCmCW1VX/ExH4bNOl9DSboxeXGgvhoL0fG1+4DDr/mrLe21OggVCQqHwXBMh6fFInvBeyhiQ== +"@algolia/client-search@5.35.0": + version "5.35.0" + resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-5.35.0.tgz#61441c4de212d8a1af93ab1406f46fd3386c35a0" + integrity sha512-FfmdHTrXhIduWyyuko1YTcGLuicVbhUyRjO3HbXE4aP655yKZgdTIfMhZ/V5VY9bHuxv/fGEh3Od1Lvv2ODNTg== dependencies: - "@algolia/client-common" "5.21.0" - "@algolia/requester-browser-xhr" "5.21.0" - "@algolia/requester-fetch" "5.21.0" - "@algolia/requester-node-http" "5.21.0" + "@algolia/client-common" "5.35.0" + "@algolia/requester-browser-xhr" "5.35.0" + "@algolia/requester-fetch" "5.35.0" + "@algolia/requester-node-http" "5.35.0" "@algolia/events@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@algolia/events/-/events-4.0.1.tgz#fd39e7477e7bc703d7f893b556f676c032af3950" integrity sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ== -"@algolia/ingestion@1.21.0": - version "1.21.0" - resolved "https://registry.yarnpkg.com/@algolia/ingestion/-/ingestion-1.21.0.tgz#7524dcc848abc44656508ea0951cceaf18e3f51b" - integrity sha512-k6MZxLbZphGN5uRri9J/krQQBjUrqNcScPh985XXEFXbSCRvOPKVtjjLdVjGVHXXPOQgKrIZHxIdRNbHS+wVuA== +"@algolia/ingestion@1.35.0": + version "1.35.0" + resolved "https://registry.yarnpkg.com/@algolia/ingestion/-/ingestion-1.35.0.tgz#fb263cc190da421756f8f52e3fe5e5afdc89f68c" + integrity sha512-gPzACem9IL1Co8mM1LKMhzn1aSJmp+Vp434An4C0OBY4uEJRcqsLN3uLBlY+bYvFg8C8ImwM9YRiKczJXRk0XA== dependencies: - "@algolia/client-common" "5.21.0" - "@algolia/requester-browser-xhr" "5.21.0" - "@algolia/requester-fetch" "5.21.0" - "@algolia/requester-node-http" "5.21.0" + "@algolia/client-common" "5.35.0" + "@algolia/requester-browser-xhr" "5.35.0" + "@algolia/requester-fetch" "5.35.0" + "@algolia/requester-node-http" "5.35.0" -"@algolia/monitoring@1.21.0": - version "1.21.0" - resolved "https://registry.yarnpkg.com/@algolia/monitoring/-/monitoring-1.21.0.tgz#9daab7fe728b44ae998c2425d12e4bd77efe07f5" - integrity sha512-FiW5nnmyHvaGdorqLClw3PM6keXexAMiwbwJ9xzQr4LcNefLG3ln82NafRPgJO/z0dETAOKjds5aSmEFMiITHQ== +"@algolia/monitoring@1.35.0": + version "1.35.0" + resolved "https://registry.yarnpkg.com/@algolia/monitoring/-/monitoring-1.35.0.tgz#6be2b3e2a48328b57d98827da9c85ec2b42d49da" + integrity sha512-w9MGFLB6ashI8BGcQoVt7iLgDIJNCn4OIu0Q0giE3M2ItNrssvb8C0xuwJQyTy1OFZnemG0EB1OvXhIHOvQwWw== dependencies: - "@algolia/client-common" "5.21.0" - "@algolia/requester-browser-xhr" "5.21.0" - "@algolia/requester-fetch" "5.21.0" - "@algolia/requester-node-http" "5.21.0" + "@algolia/client-common" "5.35.0" + "@algolia/requester-browser-xhr" "5.35.0" + "@algolia/requester-fetch" "5.35.0" + "@algolia/requester-node-http" "5.35.0" -"@algolia/recommend@5.21.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-5.21.0.tgz#4c9a2e90bab87c9d63f8eebaf56c12e4f9e517c0" - integrity sha512-+JXavbbliaLmah5QNgc/TDW/+r0ALa+rGhg5Y7+pF6GpNnzO0L+nlUaDNE8QbiJfz54F9BkwFUnJJeRJAuzTFw== +"@algolia/recommend@5.35.0": + version "5.35.0" + resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-5.35.0.tgz#03c3d1dbbd1b5b07dda98350b45640c819081211" + integrity sha512-AhrVgaaXAb8Ue0u2nuRWwugt0dL5UmRgS9LXe0Hhz493a8KFeZVUE56RGIV3hAa6tHzmAV7eIoqcWTQvxzlJeQ== dependencies: - "@algolia/client-common" "5.21.0" - "@algolia/requester-browser-xhr" "5.21.0" - "@algolia/requester-fetch" "5.21.0" - "@algolia/requester-node-http" "5.21.0" + "@algolia/client-common" "5.35.0" + "@algolia/requester-browser-xhr" "5.35.0" + "@algolia/requester-fetch" "5.35.0" + "@algolia/requester-node-http" "5.35.0" -"@algolia/requester-browser-xhr@5.21.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.21.0.tgz#7840e52a45fd8a7b58340470c4700492d32fdf7d" - integrity sha512-Iw+Yj5hOmo/iixHS94vEAQ3zi5GPpJywhfxn1el/zWo4AvPIte/+1h9Ywgw/+3M7YBj4jgAkScxjxQCxzLBsjA== +"@algolia/requester-browser-xhr@5.35.0": + version "5.35.0" + resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.35.0.tgz#b1c26fc9be80a0ddde6b2e45fb50d52c7c6c05f4" + integrity sha512-diY415KLJZ6x1Kbwl9u96Jsz0OstE3asjXtJ9pmk1d+5gPuQ5jQyEsgC+WmEXzlec3iuVszm8AzNYYaqw6B+Zw== dependencies: - "@algolia/client-common" "5.21.0" + "@algolia/client-common" "5.35.0" -"@algolia/requester-fetch@5.21.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@algolia/requester-fetch/-/requester-fetch-5.21.0.tgz#8c4caf767995aaf24c8fc5f873e9075df98fbf44" - integrity sha512-Z00SRLlIFj3SjYVfsd9Yd3kB3dUwQFAkQG18NunWP7cix2ezXpJqA+xAoEf9vc4QZHdxU3Gm8gHAtRiM2iVaTQ== +"@algolia/requester-fetch@5.35.0": + version "5.35.0" + resolved "https://registry.yarnpkg.com/@algolia/requester-fetch/-/requester-fetch-5.35.0.tgz#29815c5bf501148ea619ed96bae09c099a5cced4" + integrity sha512-uydqnSmpAjrgo8bqhE9N1wgcB98psTRRQXcjc4izwMB7yRl9C8uuAQ/5YqRj04U0mMQ+fdu2fcNF6m9+Z1BzDQ== dependencies: - "@algolia/client-common" "5.21.0" + "@algolia/client-common" "5.35.0" -"@algolia/requester-node-http@5.21.0": - version "5.21.0" - resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-5.21.0.tgz#c1a8cd0f33e375c147bc5efda73f9677a47416c9" - integrity sha512-WqU0VumUILrIeVYCTGZlyyZoC/tbvhiyPxfGRRO1cSjxN558bnJLlR2BvS0SJ5b75dRNK7HDvtXo2QoP9eLfiA== +"@algolia/requester-node-http@5.35.0": + version "5.35.0" + resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-5.35.0.tgz#9095b80a0ae77f574036261f44053636e31d1baf" + integrity sha512-RgLX78ojYOrThJHrIiPzT4HW3yfQa0D7K+MQ81rhxqaNyNBu4F1r+72LNHYH/Z+y9I1Mrjrd/c/Ue5zfDgAEjQ== dependencies: - "@algolia/client-common" "5.21.0" + "@algolia/client-common" "5.35.0" "@ampproject/remapping@^2.2.0": version "2.3.0" @@ -158,243 +168,248 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.26.2", "@babel/code-frame@^7.8.3": - version "7.26.2" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85" - integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be" + integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== dependencies: - "@babel/helper-validator-identifier" "^7.25.9" + "@babel/helper-validator-identifier" "^7.27.1" js-tokens "^4.0.0" - picocolors "^1.0.0" + picocolors "^1.1.1" -"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.26.5", "@babel/compat-data@^7.26.8": - version "7.26.8" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.8.tgz#821c1d35641c355284d4a870b8a4a7b0c141e367" - integrity sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ== +"@babel/compat-data@^7.27.2", "@babel/compat-data@^7.27.7", "@babel/compat-data@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.0.tgz#9fc6fd58c2a6a15243cd13983224968392070790" + integrity sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw== "@babel/core@^7.21.3", "@babel/core@^7.25.9": - version "7.26.10" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.10.tgz#5c876f83c8c4dcb233ee4b670c0606f2ac3000f9" - integrity sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ== + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.0.tgz#55dad808d5bf3445a108eefc88ea3fdf034749a4" + integrity sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ== dependencies: "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.26.2" - "@babel/generator" "^7.26.10" - "@babel/helper-compilation-targets" "^7.26.5" - "@babel/helper-module-transforms" "^7.26.0" - "@babel/helpers" "^7.26.10" - "@babel/parser" "^7.26.10" - "@babel/template" "^7.26.9" - "@babel/traverse" "^7.26.10" - "@babel/types" "^7.26.10" + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.28.0" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-module-transforms" "^7.27.3" + "@babel/helpers" "^7.27.6" + "@babel/parser" "^7.28.0" + "@babel/template" "^7.27.2" + "@babel/traverse" "^7.28.0" + "@babel/types" "^7.28.0" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.25.9", "@babel/generator@^7.26.10": - version "7.26.10" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.10.tgz#a60d9de49caca16744e6340c3658dfef6138c3f7" - integrity sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang== +"@babel/generator@^7.25.9", "@babel/generator@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.0.tgz#9cc2f7bd6eb054d77dc66c2664148a0c5118acd2" + integrity sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg== dependencies: - "@babel/parser" "^7.26.10" - "@babel/types" "^7.26.10" - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.25" + "@babel/parser" "^7.28.0" + "@babel/types" "^7.28.0" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" jsesc "^3.0.2" -"@babel/helper-annotate-as-pure@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz#d8eac4d2dc0d7b6e11fa6e535332e0d3184f06b4" - integrity sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g== +"@babel/helper-annotate-as-pure@^7.27.1", "@babel/helper-annotate-as-pure@^7.27.3": + version "7.27.3" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz#f31fd86b915fc4daf1f3ac6976c59be7084ed9c5" + integrity sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg== dependencies: - "@babel/types" "^7.25.9" + "@babel/types" "^7.27.3" -"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.25.9", "@babel/helper-compilation-targets@^7.26.5": - version "7.26.5" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz#75d92bb8d8d51301c0d49e52a65c9a7fe94514d8" - integrity sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA== +"@babel/helper-compilation-targets@^7.27.1", "@babel/helper-compilation-targets@^7.27.2": + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz#46a0f6efab808d51d29ce96858dd10ce8732733d" + integrity sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ== dependencies: - "@babel/compat-data" "^7.26.5" - "@babel/helper-validator-option" "^7.25.9" + "@babel/compat-data" "^7.27.2" + "@babel/helper-validator-option" "^7.27.1" browserslist "^4.24.0" lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.25.9": - version "7.26.9" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.26.9.tgz#d6f83e3039547fbb39967e78043cd3c8b7820c71" - integrity sha512-ubbUqCofvxPRurw5L8WTsCLSkQiVpov4Qx0WMA+jUN+nXBK8ADPlJO1grkFw5CWKC5+sZSOfuGMdX1aI1iT9Sg== +"@babel/helper-create-class-features-plugin@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.1.tgz#5bee4262a6ea5ddc852d0806199eb17ca3de9281" + integrity sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A== dependencies: - "@babel/helper-annotate-as-pure" "^7.25.9" - "@babel/helper-member-expression-to-functions" "^7.25.9" - "@babel/helper-optimise-call-expression" "^7.25.9" - "@babel/helper-replace-supers" "^7.26.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" - "@babel/traverse" "^7.26.9" + "@babel/helper-annotate-as-pure" "^7.27.1" + "@babel/helper-member-expression-to-functions" "^7.27.1" + "@babel/helper-optimise-call-expression" "^7.27.1" + "@babel/helper-replace-supers" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + "@babel/traverse" "^7.27.1" semver "^6.3.1" -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.25.9": - version "7.26.3" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz#5169756ecbe1d95f7866b90bb555b022595302a0" - integrity sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong== +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz#05b0882d97ba1d4d03519e4bce615d70afa18c53" + integrity sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ== dependencies: - "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-annotate-as-pure" "^7.27.1" regexpu-core "^6.2.0" semver "^6.3.1" -"@babel/helper-define-polyfill-provider@^0.6.3", "@babel/helper-define-polyfill-provider@^0.6.4": - version "0.6.4" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.4.tgz#15e8746368bfa671785f5926ff74b3064c291fab" - integrity sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw== +"@babel/helper-define-polyfill-provider@^0.6.5": + version "0.6.5" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz#742ccf1cb003c07b48859fc9fa2c1bbe40e5f753" + integrity sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg== dependencies: - "@babel/helper-compilation-targets" "^7.22.6" - "@babel/helper-plugin-utils" "^7.22.5" - debug "^4.1.1" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-plugin-utils" "^7.27.1" + debug "^4.4.1" lodash.debounce "^4.0.8" - resolve "^1.14.2" + resolve "^1.22.10" -"@babel/helper-member-expression-to-functions@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz#9dfffe46f727005a5ea29051ac835fb735e4c1a3" - integrity sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ== +"@babel/helper-globals@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz#b9430df2aa4e17bc28665eadeae8aa1d985e6674" + integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== + +"@babel/helper-member-expression-to-functions@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz#ea1211276be93e798ce19037da6f06fbb994fa44" + integrity sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA== dependencies: - "@babel/traverse" "^7.25.9" - "@babel/types" "^7.25.9" + "@babel/traverse" "^7.27.1" + "@babel/types" "^7.27.1" -"@babel/helper-module-imports@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz#e7f8d20602ebdbf9ebbea0a0751fb0f2a4141715" - integrity sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw== +"@babel/helper-module-imports@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz#7ef769a323e2655e126673bb6d2d6913bbead204" + integrity sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w== dependencies: - "@babel/traverse" "^7.25.9" - "@babel/types" "^7.25.9" + "@babel/traverse" "^7.27.1" + "@babel/types" "^7.27.1" -"@babel/helper-module-transforms@^7.25.9", "@babel/helper-module-transforms@^7.26.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz#8ce54ec9d592695e58d84cd884b7b5c6a2fdeeae" - integrity sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw== +"@babel/helper-module-transforms@^7.27.1", "@babel/helper-module-transforms@^7.27.3": + version "7.27.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz#db0bbcfba5802f9ef7870705a7ef8788508ede02" + integrity sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg== dependencies: - "@babel/helper-module-imports" "^7.25.9" - "@babel/helper-validator-identifier" "^7.25.9" - "@babel/traverse" "^7.25.9" + "@babel/helper-module-imports" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" + "@babel/traverse" "^7.27.3" -"@babel/helper-optimise-call-expression@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz#3324ae50bae7e2ab3c33f60c9a877b6a0146b54e" - integrity sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ== +"@babel/helper-optimise-call-expression@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz#c65221b61a643f3e62705e5dd2b5f115e35f9200" + integrity sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw== dependencies: - "@babel/types" "^7.25.9" + "@babel/types" "^7.27.1" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.25.9", "@babel/helper-plugin-utils@^7.26.5", "@babel/helper-plugin-utils@^7.8.0": - version "7.26.5" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz#18580d00c9934117ad719392c4f6585c9333cc35" - integrity sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.8.0": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz#ddb2f876534ff8013e6c2b299bf4d39b3c51d44c" + integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw== -"@babel/helper-remap-async-to-generator@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz#e53956ab3d5b9fb88be04b3e2f31b523afd34b92" - integrity sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw== +"@babel/helper-remap-async-to-generator@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz#4601d5c7ce2eb2aea58328d43725523fcd362ce6" + integrity sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA== dependencies: - "@babel/helper-annotate-as-pure" "^7.25.9" - "@babel/helper-wrap-function" "^7.25.9" - "@babel/traverse" "^7.25.9" + "@babel/helper-annotate-as-pure" "^7.27.1" + "@babel/helper-wrap-function" "^7.27.1" + "@babel/traverse" "^7.27.1" -"@babel/helper-replace-supers@^7.25.9", "@babel/helper-replace-supers@^7.26.5": - version "7.26.5" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz#6cb04e82ae291dae8e72335dfe438b0725f14c8d" - integrity sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg== +"@babel/helper-replace-supers@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz#b1ed2d634ce3bdb730e4b52de30f8cccfd692bc0" + integrity sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA== dependencies: - "@babel/helper-member-expression-to-functions" "^7.25.9" - "@babel/helper-optimise-call-expression" "^7.25.9" - "@babel/traverse" "^7.26.5" + "@babel/helper-member-expression-to-functions" "^7.27.1" + "@babel/helper-optimise-call-expression" "^7.27.1" + "@babel/traverse" "^7.27.1" -"@babel/helper-skip-transparent-expression-wrappers@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz#0b2e1b62d560d6b1954893fd2b705dc17c91f0c9" - integrity sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA== +"@babel/helper-skip-transparent-expression-wrappers@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz#62bb91b3abba8c7f1fec0252d9dbea11b3ee7a56" + integrity sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg== dependencies: - "@babel/traverse" "^7.25.9" - "@babel/types" "^7.25.9" + "@babel/traverse" "^7.27.1" + "@babel/types" "^7.27.1" -"@babel/helper-string-parser@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c" - integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== +"@babel/helper-string-parser@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" + integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== -"@babel/helper-validator-identifier@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" - integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== +"@babel/helper-validator-identifier@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8" + integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== -"@babel/helper-validator-option@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz#86e45bd8a49ab7e03f276577f96179653d41da72" - integrity sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw== +"@babel/helper-validator-option@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f" + integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== -"@babel/helper-wrap-function@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz#d99dfd595312e6c894bd7d237470025c85eea9d0" - integrity sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g== +"@babel/helper-wrap-function@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.27.1.tgz#b88285009c31427af318d4fe37651cd62a142409" + integrity sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ== dependencies: - "@babel/template" "^7.25.9" - "@babel/traverse" "^7.25.9" - "@babel/types" "^7.25.9" + "@babel/template" "^7.27.1" + "@babel/traverse" "^7.27.1" + "@babel/types" "^7.27.1" -"@babel/helpers@^7.26.10": - version "7.26.10" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.26.10.tgz#6baea3cd62ec2d0c1068778d63cb1314f6637384" - integrity sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g== +"@babel/helpers@^7.27.6": + version "7.28.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.2.tgz#80f0918fecbfebea9af856c419763230040ee850" + integrity sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw== dependencies: - "@babel/template" "^7.26.9" - "@babel/types" "^7.26.10" + "@babel/template" "^7.27.2" + "@babel/types" "^7.28.2" -"@babel/parser@^7.26.10", "@babel/parser@^7.26.9": - version "7.26.10" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.10.tgz#e9bdb82f14b97df6569b0b038edd436839c57749" - integrity sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA== +"@babel/parser@^7.27.2", "@babel/parser@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.0.tgz#979829fbab51a29e13901e5a80713dbcb840825e" + integrity sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g== dependencies: - "@babel/types" "^7.26.10" + "@babel/types" "^7.28.0" -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz#cc2e53ebf0a0340777fff5ed521943e253b4d8fe" - integrity sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g== +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz#61dd8a8e61f7eb568268d1b5f129da3eee364bf9" + integrity sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/traverse" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/traverse" "^7.27.1" -"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz#af9e4fb63ccb8abcb92375b2fcfe36b60c774d30" - integrity sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw== +"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz#43f70a6d7efd52370eefbdf55ae03d91b293856d" + integrity sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz#e8dc26fcd616e6c5bf2bd0d5a2c151d4f92a9137" - integrity sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz#beb623bd573b8b6f3047bd04c32506adc3e58a72" + integrity sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz#807a667f9158acac6f6164b4beb85ad9ebc9e1d1" - integrity sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz#e134a5479eb2ba9c02714e8c1ebf1ec9076124fd" + integrity sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" - "@babel/plugin-transform-optional-chaining" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + "@babel/plugin-transform-optional-chaining" "^7.27.1" -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz#de7093f1e7deaf68eadd7cc6b07f2ab82543269e" - integrity sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg== +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.27.1.tgz#bb1c25af34d75115ce229a1de7fa44bf8f955670" + integrity sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/traverse" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/traverse" "^7.27.1" "@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": version "7.21.0-placeholder-for-preset-env.2" @@ -408,33 +423,33 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-import-assertions@^7.26.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz#620412405058efa56e4a564903b79355020f445f" - integrity sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg== +"@babel/plugin-syntax-import-assertions@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz#88894aefd2b03b5ee6ad1562a7c8e1587496aecd" + integrity sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-syntax-import-attributes@^7.26.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz#3b1412847699eea739b4f2602c74ce36f6b0b0f7" - integrity sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A== +"@babel/plugin-syntax-import-attributes@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz#34c017d54496f9b11b61474e7ea3dfd5563ffe07" + integrity sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-syntax-jsx@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz#a34313a178ea56f1951599b929c1ceacee719290" - integrity sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA== +"@babel/plugin-syntax-jsx@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz#2f9beb5eff30fa507c5532d107daac7b888fa34c" + integrity sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-syntax-typescript@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz#67dda2b74da43727cf21d46cf9afef23f4365399" - integrity sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ== +"@babel/plugin-syntax-typescript@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz#5147d29066a793450f220c63fa3a9431b7e6dd18" + integrity sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-syntax-unicode-sets-regex@^7.18.6": version "7.18.6" @@ -444,529 +459,540 @@ "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-arrow-functions@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz#7821d4410bee5daaadbb4cdd9a6649704e176845" - integrity sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg== +"@babel/plugin-transform-arrow-functions@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz#6e2061067ba3ab0266d834a9f94811196f2aba9a" + integrity sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-async-generator-functions@^7.26.8": - version "7.26.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz#5e3991135e3b9c6eaaf5eff56d1ae5a11df45ff8" - integrity sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg== +"@babel/plugin-transform-async-generator-functions@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz#1276e6c7285ab2cd1eccb0bc7356b7a69ff842c2" + integrity sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q== dependencies: - "@babel/helper-plugin-utils" "^7.26.5" - "@babel/helper-remap-async-to-generator" "^7.25.9" - "@babel/traverse" "^7.26.8" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-remap-async-to-generator" "^7.27.1" + "@babel/traverse" "^7.28.0" -"@babel/plugin-transform-async-to-generator@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz#c80008dacae51482793e5a9c08b39a5be7e12d71" - integrity sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ== +"@babel/plugin-transform-async-to-generator@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz#9a93893b9379b39466c74474f55af03de78c66e7" + integrity sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA== dependencies: - "@babel/helper-module-imports" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-remap-async-to-generator" "^7.25.9" + "@babel/helper-module-imports" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-remap-async-to-generator" "^7.27.1" -"@babel/plugin-transform-block-scoped-functions@^7.26.5": - version "7.26.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz#3dc4405d31ad1cbe45293aa57205a6e3b009d53e" - integrity sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ== +"@babel/plugin-transform-block-scoped-functions@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz#558a9d6e24cf72802dd3b62a4b51e0d62c0f57f9" + integrity sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg== dependencies: - "@babel/helper-plugin-utils" "^7.26.5" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-block-scoping@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz#c33665e46b06759c93687ca0f84395b80c0473a1" - integrity sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg== +"@babel/plugin-transform-block-scoping@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.0.tgz#e7c50cbacc18034f210b93defa89638666099451" + integrity sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-class-properties@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz#a8ce84fedb9ad512549984101fa84080a9f5f51f" - integrity sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q== +"@babel/plugin-transform-class-properties@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz#dd40a6a370dfd49d32362ae206ddaf2bb082a925" + integrity sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA== dependencies: - "@babel/helper-create-class-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-create-class-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-class-static-block@^7.26.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz#6c8da219f4eb15cae9834ec4348ff8e9e09664a0" - integrity sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ== +"@babel/plugin-transform-class-static-block@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.27.1.tgz#7e920d5625b25bbccd3061aefbcc05805ed56ce4" + integrity sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA== dependencies: - "@babel/helper-create-class-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-create-class-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-classes@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz#7152457f7880b593a63ade8a861e6e26a4469f52" - integrity sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg== +"@babel/plugin-transform-classes@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.0.tgz#12fa46cffc32a6e084011b650539e880add8a0f8" + integrity sha512-IjM1IoJNw72AZFlj33Cu8X0q2XK/6AaVC3jQu+cgQ5lThWD5ajnuUAml80dqRmOhmPkTH8uAwnpMu9Rvj0LTRA== dependencies: - "@babel/helper-annotate-as-pure" "^7.25.9" - "@babel/helper-compilation-targets" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-replace-supers" "^7.25.9" - "@babel/traverse" "^7.25.9" - globals "^11.1.0" + "@babel/helper-annotate-as-pure" "^7.27.3" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-globals" "^7.28.0" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-replace-supers" "^7.27.1" + "@babel/traverse" "^7.28.0" -"@babel/plugin-transform-computed-properties@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz#db36492c78460e534b8852b1d5befe3c923ef10b" - integrity sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA== +"@babel/plugin-transform-computed-properties@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz#81662e78bf5e734a97982c2b7f0a793288ef3caa" + integrity sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/template" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/template" "^7.27.1" -"@babel/plugin-transform-destructuring@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz#966ea2595c498224340883602d3cfd7a0c79cea1" - integrity sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ== +"@babel/plugin-transform-destructuring@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz#0f156588f69c596089b7d5b06f5af83d9aa7f97a" + integrity sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/traverse" "^7.28.0" -"@babel/plugin-transform-dotall-regex@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz#bad7945dd07734ca52fe3ad4e872b40ed09bb09a" - integrity sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA== +"@babel/plugin-transform-dotall-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz#aa6821de864c528b1fecf286f0a174e38e826f4d" + integrity sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-duplicate-keys@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz#8850ddf57dce2aebb4394bb434a7598031059e6d" - integrity sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw== +"@babel/plugin-transform-duplicate-keys@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz#f1fbf628ece18e12e7b32b175940e68358f546d1" + integrity sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz#6f7259b4de127721a08f1e5165b852fcaa696d31" - integrity sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog== +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz#5043854ca620a94149372e69030ff8cb6a9eb0ec" + integrity sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-dynamic-import@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz#23e917de63ed23c6600c5dd06d94669dce79f7b8" - integrity sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg== +"@babel/plugin-transform-dynamic-import@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz#4c78f35552ac0e06aa1f6e3c573d67695e8af5a4" + integrity sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-exponentiation-operator@^7.26.3": - version "7.26.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz#e29f01b6de302c7c2c794277a48f04a9ca7f03bc" - integrity sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ== +"@babel/plugin-transform-explicit-resource-management@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz#45be6211b778dbf4b9d54c4e8a2b42fa72e09a1a" + integrity sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/plugin-transform-destructuring" "^7.28.0" -"@babel/plugin-transform-export-namespace-from@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz#90745fe55053394f554e40584cda81f2c8a402a2" - integrity sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww== +"@babel/plugin-transform-exponentiation-operator@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz#fc497b12d8277e559747f5a3ed868dd8064f83e1" + integrity sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-for-of@^7.26.9": - version "7.26.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.26.9.tgz#27231f79d5170ef33b5111f07fe5cafeb2c96a56" - integrity sha512-Hry8AusVm8LW5BVFgiyUReuoGzPUpdHQQqJY5bZnbbf+ngOHWuCuYFKw/BqaaWlvEUrF91HMhDtEaI1hZzNbLg== +"@babel/plugin-transform-export-namespace-from@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz#71ca69d3471edd6daa711cf4dfc3400415df9c23" + integrity sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ== dependencies: - "@babel/helper-plugin-utils" "^7.26.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-function-name@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz#939d956e68a606661005bfd550c4fc2ef95f7b97" - integrity sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA== +"@babel/plugin-transform-for-of@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz#bc24f7080e9ff721b63a70ac7b2564ca15b6c40a" + integrity sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw== dependencies: - "@babel/helper-compilation-targets" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/traverse" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" -"@babel/plugin-transform-json-strings@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz#c86db407cb827cded902a90c707d2781aaa89660" - integrity sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw== +"@babel/plugin-transform-function-name@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz#4d0bf307720e4dce6d7c30fcb1fd6ca77bdeb3a7" + integrity sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-compilation-targets" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/traverse" "^7.27.1" -"@babel/plugin-transform-literals@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz#1a1c6b4d4aa59bc4cad5b6b3a223a0abd685c9de" - integrity sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ== +"@babel/plugin-transform-json-strings@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz#a2e0ce6ef256376bd527f290da023983527a4f4c" + integrity sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-logical-assignment-operators@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz#b19441a8c39a2fda0902900b306ea05ae1055db7" - integrity sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q== +"@babel/plugin-transform-literals@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz#baaefa4d10a1d4206f9dcdda50d7d5827bb70b24" + integrity sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-member-expression-literals@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz#63dff19763ea64a31f5e6c20957e6a25e41ed5de" - integrity sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA== +"@babel/plugin-transform-logical-assignment-operators@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz#890cb20e0270e0e5bebe3f025b434841c32d5baa" + integrity sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-modules-amd@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz#49ba478f2295101544abd794486cd3088dddb6c5" - integrity sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw== +"@babel/plugin-transform-member-expression-literals@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz#37b88ba594d852418e99536f5612f795f23aeaf9" + integrity sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ== dependencies: - "@babel/helper-module-transforms" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-modules-commonjs@^7.25.9", "@babel/plugin-transform-modules-commonjs@^7.26.3": - version "7.26.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz#8f011d44b20d02c3de44d8850d971d8497f981fb" - integrity sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ== +"@babel/plugin-transform-modules-amd@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz#a4145f9d87c2291fe2d05f994b65dba4e3e7196f" + integrity sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA== dependencies: - "@babel/helper-module-transforms" "^7.26.0" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-module-transforms" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-modules-systemjs@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz#8bd1b43836269e3d33307151a114bcf3ba6793f8" - integrity sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA== +"@babel/plugin-transform-modules-commonjs@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz#8e44ed37c2787ecc23bdc367f49977476614e832" + integrity sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw== dependencies: - "@babel/helper-module-transforms" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-validator-identifier" "^7.25.9" - "@babel/traverse" "^7.25.9" + "@babel/helper-module-transforms" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-modules-umd@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz#6710079cdd7c694db36529a1e8411e49fcbf14c9" - integrity sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw== +"@babel/plugin-transform-modules-systemjs@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz#00e05b61863070d0f3292a00126c16c0e024c4ed" + integrity sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA== dependencies: - "@babel/helper-module-transforms" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-module-transforms" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" + "@babel/traverse" "^7.27.1" -"@babel/plugin-transform-named-capturing-groups-regex@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz#454990ae6cc22fd2a0fa60b3a2c6f63a38064e6a" - integrity sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA== +"@babel/plugin-transform-modules-umd@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz#63f2cf4f6dc15debc12f694e44714863d34cd334" + integrity sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-module-transforms" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-new-target@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz#42e61711294b105c248336dcb04b77054ea8becd" - integrity sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ== +"@babel/plugin-transform-named-capturing-groups-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz#f32b8f7818d8fc0cc46ee20a8ef75f071af976e1" + integrity sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-nullish-coalescing-operator@^7.26.6": - version "7.26.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz#fbf6b3c92cb509e7b319ee46e3da89c5bedd31fe" - integrity sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw== +"@babel/plugin-transform-new-target@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz#259c43939728cad1706ac17351b7e6a7bea1abeb" + integrity sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ== dependencies: - "@babel/helper-plugin-utils" "^7.26.5" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-numeric-separator@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz#bfed75866261a8b643468b0ccfd275f2033214a1" - integrity sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q== +"@babel/plugin-transform-nullish-coalescing-operator@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz#4f9d3153bf6782d73dd42785a9d22d03197bc91d" + integrity sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-object-rest-spread@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz#0203725025074164808bcf1a2cfa90c652c99f18" - integrity sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg== +"@babel/plugin-transform-numeric-separator@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz#614e0b15cc800e5997dadd9bd6ea524ed6c819c6" + integrity sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw== dependencies: - "@babel/helper-compilation-targets" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/plugin-transform-parameters" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-object-super@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz#385d5de135162933beb4a3d227a2b7e52bb4cf03" - integrity sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A== +"@babel/plugin-transform-object-rest-spread@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.0.tgz#d23021857ffd7cd809f54d624299b8086402ed8d" + integrity sha512-9VNGikXxzu5eCiQjdE4IZn8sb9q7Xsk5EXLDBKUYg1e/Tve8/05+KJEtcxGxAgCY5t/BpKQM+JEL/yT4tvgiUA== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-replace-supers" "^7.25.9" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/plugin-transform-destructuring" "^7.28.0" + "@babel/plugin-transform-parameters" "^7.27.7" + "@babel/traverse" "^7.28.0" -"@babel/plugin-transform-optional-catch-binding@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz#10e70d96d52bb1f10c5caaac59ac545ea2ba7ff3" - integrity sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g== +"@babel/plugin-transform-object-super@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz#1c932cd27bf3874c43a5cac4f43ebf970c9871b5" + integrity sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-replace-supers" "^7.27.1" -"@babel/plugin-transform-optional-chaining@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz#e142eb899d26ef715435f201ab6e139541eee7dd" - integrity sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A== +"@babel/plugin-transform-optional-catch-binding@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz#84c7341ebde35ccd36b137e9e45866825072a30c" + integrity sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-parameters@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz#b856842205b3e77e18b7a7a1b94958069c7ba257" - integrity sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g== +"@babel/plugin-transform-optional-chaining@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz#874ce3c4f06b7780592e946026eb76a32830454f" + integrity sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" -"@babel/plugin-transform-private-methods@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz#847f4139263577526455d7d3223cd8bda51e3b57" - integrity sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw== +"@babel/plugin-transform-parameters@^7.27.7": + version "7.27.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz#1fd2febb7c74e7d21cf3b05f7aebc907940af53a" + integrity sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-private-property-in-object@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz#9c8b73e64e6cc3cbb2743633885a7dd2c385fe33" - integrity sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw== +"@babel/plugin-transform-private-methods@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz#fdacbab1c5ed81ec70dfdbb8b213d65da148b6af" + integrity sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA== dependencies: - "@babel/helper-annotate-as-pure" "^7.25.9" - "@babel/helper-create-class-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-create-class-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-property-literals@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz#d72d588bd88b0dec8b62e36f6fda91cedfe28e3f" - integrity sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA== +"@babel/plugin-transform-private-property-in-object@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz#4dbbef283b5b2f01a21e81e299f76e35f900fb11" + integrity sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-annotate-as-pure" "^7.27.1" + "@babel/helper-create-class-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-property-literals@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz#07eafd618800591e88073a0af1b940d9a42c6424" + integrity sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-react-constant-elements@^7.21.3": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.25.9.tgz#08a1de35a301929b60fdf2788a54b46cd8ecd0ef" - integrity sha512-Ncw2JFsJVuvfRsa2lSHiC55kETQVLSnsYGQ1JDDwkUeWGTL/8Tom8aLTnlqgoeuopWrbbGndrc9AlLYrIosrow== + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.27.1.tgz#6c6b50424e749a6e48afd14cf7b92f98cb9383f9" + integrity sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-react-display-name@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.25.9.tgz#4b79746b59efa1f38c8695065a92a9f5afb24f7d" - integrity sha512-KJfMlYIUxQB1CJfO3e0+h0ZHWOTLCPP115Awhaz8U0Zpq36Gl/cXlpoyMRnUWlhNUBAzldnCiAZNvCDj7CrKxQ== +"@babel/plugin-transform-react-display-name@^7.27.1": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz#6f20a7295fea7df42eb42fed8f896813f5b934de" + integrity sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-react-jsx-development@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.25.9.tgz#8fd220a77dd139c07e25225a903b8be8c829e0d7" - integrity sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw== +"@babel/plugin-transform-react-jsx-development@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz#47ff95940e20a3a70e68ad3d4fcb657b647f6c98" + integrity sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q== dependencies: - "@babel/plugin-transform-react-jsx" "^7.25.9" + "@babel/plugin-transform-react-jsx" "^7.27.1" -"@babel/plugin-transform-react-jsx@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.9.tgz#06367940d8325b36edff5e2b9cbe782947ca4166" - integrity sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw== +"@babel/plugin-transform-react-jsx@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz#1023bc94b78b0a2d68c82b5e96aed573bcfb9db0" + integrity sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw== dependencies: - "@babel/helper-annotate-as-pure" "^7.25.9" - "@babel/helper-module-imports" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/plugin-syntax-jsx" "^7.25.9" - "@babel/types" "^7.25.9" + "@babel/helper-annotate-as-pure" "^7.27.1" + "@babel/helper-module-imports" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/plugin-syntax-jsx" "^7.27.1" + "@babel/types" "^7.27.1" -"@babel/plugin-transform-react-pure-annotations@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.25.9.tgz#ea1c11b2f9dbb8e2d97025f43a3b5bc47e18ae62" - integrity sha512-KQ/Takk3T8Qzj5TppkS1be588lkbTp5uj7w6a0LeQaTMSckU/wK0oJ/pih+T690tkgI5jfmg2TqDJvd41Sj1Cg== +"@babel/plugin-transform-react-pure-annotations@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz#339f1ce355eae242e0649f232b1c68907c02e879" + integrity sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA== dependencies: - "@babel/helper-annotate-as-pure" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-annotate-as-pure" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-regenerator@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz#03a8a4670d6cebae95305ac6defac81ece77740b" - integrity sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg== +"@babel/plugin-transform-regenerator@^7.28.0": + version "7.28.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.1.tgz#bde80603442ff4bb4e910bc8b35485295d556ab1" + integrity sha512-P0QiV/taaa3kXpLY+sXla5zec4E+4t4Aqc9ggHlfZ7a2cp8/x/Gv08jfwEtn9gnnYIMvHx6aoOZ8XJL8eU71Dg== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - regenerator-transform "^0.15.2" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-regexp-modifiers@^7.26.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz#2f5837a5b5cd3842a919d8147e9903cc7455b850" - integrity sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw== +"@babel/plugin-transform-regexp-modifiers@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz#df9ba5577c974e3f1449888b70b76169998a6d09" + integrity sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-reserved-words@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz#0398aed2f1f10ba3f78a93db219b27ef417fb9ce" - integrity sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg== +"@babel/plugin-transform-reserved-words@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz#40fba4878ccbd1c56605a4479a3a891ac0274bb4" + integrity sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-runtime@^7.25.9": - version "7.26.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.10.tgz#6b4504233de8238e7d666c15cde681dc62adff87" - integrity sha512-NWaL2qG6HRpONTnj4JvDU6th4jYeZOJgu3QhmFTCihib0ermtOJqktA5BduGm3suhhVe9EMP9c9+mfJ/I9slqw== + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.0.tgz#462e79008cc7bdac03e4c5e1765b9de2bcd31c21" + integrity sha512-dGopk9nZrtCs2+nfIem25UuHyt5moSJamArzIoh9/vezUQPmYDOzjaHDCkAzuGJibCIkPup8rMT2+wYB6S73cA== dependencies: - "@babel/helper-module-imports" "^7.25.9" - "@babel/helper-plugin-utils" "^7.26.5" - babel-plugin-polyfill-corejs2 "^0.4.10" - babel-plugin-polyfill-corejs3 "^0.11.0" - babel-plugin-polyfill-regenerator "^0.6.1" + "@babel/helper-module-imports" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + babel-plugin-polyfill-corejs2 "^0.4.14" + babel-plugin-polyfill-corejs3 "^0.13.0" + babel-plugin-polyfill-regenerator "^0.6.5" semver "^6.3.1" -"@babel/plugin-transform-shorthand-properties@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz#bb785e6091f99f826a95f9894fc16fde61c163f2" - integrity sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng== +"@babel/plugin-transform-shorthand-properties@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz#532abdacdec87bfee1e0ef8e2fcdee543fe32b90" + integrity sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-spread@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz#24a35153931b4ba3d13cec4a7748c21ab5514ef9" - integrity sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A== +"@babel/plugin-transform-spread@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz#1a264d5fc12750918f50e3fe3e24e437178abb08" + integrity sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" -"@babel/plugin-transform-sticky-regex@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz#c7f02b944e986a417817b20ba2c504dfc1453d32" - integrity sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA== +"@babel/plugin-transform-sticky-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz#18984935d9d2296843a491d78a014939f7dcd280" + integrity sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-template-literals@^7.26.8": - version "7.26.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.26.8.tgz#966b15d153a991172a540a69ad5e1845ced990b5" - integrity sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q== +"@babel/plugin-transform-template-literals@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz#1a0eb35d8bb3e6efc06c9fd40eb0bcef548328b8" + integrity sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg== dependencies: - "@babel/helper-plugin-utils" "^7.26.5" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-typeof-symbol@^7.26.7": - version "7.26.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.26.7.tgz#d0e33acd9223744c1e857dbd6fa17bd0a3786937" - integrity sha512-jfoTXXZTgGg36BmhqT3cAYK5qkmqvJpvNrPhaK/52Vgjhw4Rq29s9UqpWWV0D6yuRmgiFH/BUVlkl96zJWqnaw== +"@babel/plugin-transform-typeof-symbol@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz#70e966bb492e03509cf37eafa6dcc3051f844369" + integrity sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw== dependencies: - "@babel/helper-plugin-utils" "^7.26.5" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-typescript@^7.25.9": - version "7.26.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.8.tgz#2e9caa870aa102f50d7125240d9dbf91334b0950" - integrity sha512-bME5J9AC8ChwA7aEPJ6zym3w7aObZULHhbNLU0bKUhKsAkylkzUdq+0kdymh9rzi8nlNFl2bmldFBCKNJBUpuw== +"@babel/plugin-transform-typescript@^7.27.1": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.0.tgz#796cbd249ab56c18168b49e3e1d341b72af04a6b" + integrity sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg== dependencies: - "@babel/helper-annotate-as-pure" "^7.25.9" - "@babel/helper-create-class-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.26.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" - "@babel/plugin-syntax-typescript" "^7.25.9" + "@babel/helper-annotate-as-pure" "^7.27.3" + "@babel/helper-create-class-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + "@babel/plugin-syntax-typescript" "^7.27.1" -"@babel/plugin-transform-unicode-escapes@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz#a75ef3947ce15363fccaa38e2dd9bc70b2788b82" - integrity sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q== +"@babel/plugin-transform-unicode-escapes@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz#3e3143f8438aef842de28816ece58780190cf806" + integrity sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-unicode-property-regex@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz#a901e96f2c1d071b0d1bb5dc0d3c880ce8f53dd3" - integrity sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg== +"@babel/plugin-transform-unicode-property-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz#bdfe2d3170c78c5691a3c3be934c8c0087525956" + integrity sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-unicode-regex@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz#5eae747fe39eacf13a8bd006a4fb0b5d1fa5e9b1" - integrity sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA== +"@babel/plugin-transform-unicode-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz#25948f5c395db15f609028e370667ed8bae9af97" + integrity sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-unicode-sets-regex@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz#65114c17b4ffc20fa5b163c63c70c0d25621fabe" - integrity sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ== +"@babel/plugin-transform-unicode-sets-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz#6ab706d10f801b5c72da8bb2548561fa04193cd1" + integrity sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.9" - "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" "@babel/preset-env@^7.20.2", "@babel/preset-env@^7.25.9": - version "7.26.9" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.26.9.tgz#2ec64e903d0efe743699f77a10bdf7955c2123c3" - integrity sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ== + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.28.0.tgz#d23a6bc17b43227d11db77081a0779c706b5569c" + integrity sha512-VmaxeGOwuDqzLl5JUkIRM1X2Qu2uKGxHEQWh+cvvbl7JuJRgKGJSfsEF/bUaxFhJl/XAyxBe7q7qSuTbKFuCyg== dependencies: - "@babel/compat-data" "^7.26.8" - "@babel/helper-compilation-targets" "^7.26.5" - "@babel/helper-plugin-utils" "^7.26.5" - "@babel/helper-validator-option" "^7.25.9" - "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.25.9" - "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.25.9" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.25.9" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.25.9" - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.25.9" + "@babel/compat-data" "^7.28.0" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-validator-option" "^7.27.1" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.27.1" + "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.27.1" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.27.1" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.27.1" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.27.1" "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" - "@babel/plugin-syntax-import-assertions" "^7.26.0" - "@babel/plugin-syntax-import-attributes" "^7.26.0" + "@babel/plugin-syntax-import-assertions" "^7.27.1" + "@babel/plugin-syntax-import-attributes" "^7.27.1" "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" - "@babel/plugin-transform-arrow-functions" "^7.25.9" - "@babel/plugin-transform-async-generator-functions" "^7.26.8" - "@babel/plugin-transform-async-to-generator" "^7.25.9" - "@babel/plugin-transform-block-scoped-functions" "^7.26.5" - "@babel/plugin-transform-block-scoping" "^7.25.9" - "@babel/plugin-transform-class-properties" "^7.25.9" - "@babel/plugin-transform-class-static-block" "^7.26.0" - "@babel/plugin-transform-classes" "^7.25.9" - "@babel/plugin-transform-computed-properties" "^7.25.9" - "@babel/plugin-transform-destructuring" "^7.25.9" - "@babel/plugin-transform-dotall-regex" "^7.25.9" - "@babel/plugin-transform-duplicate-keys" "^7.25.9" - "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.25.9" - "@babel/plugin-transform-dynamic-import" "^7.25.9" - "@babel/plugin-transform-exponentiation-operator" "^7.26.3" - "@babel/plugin-transform-export-namespace-from" "^7.25.9" - "@babel/plugin-transform-for-of" "^7.26.9" - "@babel/plugin-transform-function-name" "^7.25.9" - "@babel/plugin-transform-json-strings" "^7.25.9" - "@babel/plugin-transform-literals" "^7.25.9" - "@babel/plugin-transform-logical-assignment-operators" "^7.25.9" - "@babel/plugin-transform-member-expression-literals" "^7.25.9" - "@babel/plugin-transform-modules-amd" "^7.25.9" - "@babel/plugin-transform-modules-commonjs" "^7.26.3" - "@babel/plugin-transform-modules-systemjs" "^7.25.9" - "@babel/plugin-transform-modules-umd" "^7.25.9" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.25.9" - "@babel/plugin-transform-new-target" "^7.25.9" - "@babel/plugin-transform-nullish-coalescing-operator" "^7.26.6" - "@babel/plugin-transform-numeric-separator" "^7.25.9" - "@babel/plugin-transform-object-rest-spread" "^7.25.9" - "@babel/plugin-transform-object-super" "^7.25.9" - "@babel/plugin-transform-optional-catch-binding" "^7.25.9" - "@babel/plugin-transform-optional-chaining" "^7.25.9" - "@babel/plugin-transform-parameters" "^7.25.9" - "@babel/plugin-transform-private-methods" "^7.25.9" - "@babel/plugin-transform-private-property-in-object" "^7.25.9" - "@babel/plugin-transform-property-literals" "^7.25.9" - "@babel/plugin-transform-regenerator" "^7.25.9" - "@babel/plugin-transform-regexp-modifiers" "^7.26.0" - "@babel/plugin-transform-reserved-words" "^7.25.9" - "@babel/plugin-transform-shorthand-properties" "^7.25.9" - "@babel/plugin-transform-spread" "^7.25.9" - "@babel/plugin-transform-sticky-regex" "^7.25.9" - "@babel/plugin-transform-template-literals" "^7.26.8" - "@babel/plugin-transform-typeof-symbol" "^7.26.7" - "@babel/plugin-transform-unicode-escapes" "^7.25.9" - "@babel/plugin-transform-unicode-property-regex" "^7.25.9" - "@babel/plugin-transform-unicode-regex" "^7.25.9" - "@babel/plugin-transform-unicode-sets-regex" "^7.25.9" + "@babel/plugin-transform-arrow-functions" "^7.27.1" + "@babel/plugin-transform-async-generator-functions" "^7.28.0" + "@babel/plugin-transform-async-to-generator" "^7.27.1" + "@babel/plugin-transform-block-scoped-functions" "^7.27.1" + "@babel/plugin-transform-block-scoping" "^7.28.0" + "@babel/plugin-transform-class-properties" "^7.27.1" + "@babel/plugin-transform-class-static-block" "^7.27.1" + "@babel/plugin-transform-classes" "^7.28.0" + "@babel/plugin-transform-computed-properties" "^7.27.1" + "@babel/plugin-transform-destructuring" "^7.28.0" + "@babel/plugin-transform-dotall-regex" "^7.27.1" + "@babel/plugin-transform-duplicate-keys" "^7.27.1" + "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.27.1" + "@babel/plugin-transform-dynamic-import" "^7.27.1" + "@babel/plugin-transform-explicit-resource-management" "^7.28.0" + "@babel/plugin-transform-exponentiation-operator" "^7.27.1" + "@babel/plugin-transform-export-namespace-from" "^7.27.1" + "@babel/plugin-transform-for-of" "^7.27.1" + "@babel/plugin-transform-function-name" "^7.27.1" + "@babel/plugin-transform-json-strings" "^7.27.1" + "@babel/plugin-transform-literals" "^7.27.1" + "@babel/plugin-transform-logical-assignment-operators" "^7.27.1" + "@babel/plugin-transform-member-expression-literals" "^7.27.1" + "@babel/plugin-transform-modules-amd" "^7.27.1" + "@babel/plugin-transform-modules-commonjs" "^7.27.1" + "@babel/plugin-transform-modules-systemjs" "^7.27.1" + "@babel/plugin-transform-modules-umd" "^7.27.1" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.27.1" + "@babel/plugin-transform-new-target" "^7.27.1" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.27.1" + "@babel/plugin-transform-numeric-separator" "^7.27.1" + "@babel/plugin-transform-object-rest-spread" "^7.28.0" + "@babel/plugin-transform-object-super" "^7.27.1" + "@babel/plugin-transform-optional-catch-binding" "^7.27.1" + "@babel/plugin-transform-optional-chaining" "^7.27.1" + "@babel/plugin-transform-parameters" "^7.27.7" + "@babel/plugin-transform-private-methods" "^7.27.1" + "@babel/plugin-transform-private-property-in-object" "^7.27.1" + "@babel/plugin-transform-property-literals" "^7.27.1" + "@babel/plugin-transform-regenerator" "^7.28.0" + "@babel/plugin-transform-regexp-modifiers" "^7.27.1" + "@babel/plugin-transform-reserved-words" "^7.27.1" + "@babel/plugin-transform-shorthand-properties" "^7.27.1" + "@babel/plugin-transform-spread" "^7.27.1" + "@babel/plugin-transform-sticky-regex" "^7.27.1" + "@babel/plugin-transform-template-literals" "^7.27.1" + "@babel/plugin-transform-typeof-symbol" "^7.27.1" + "@babel/plugin-transform-unicode-escapes" "^7.27.1" + "@babel/plugin-transform-unicode-property-regex" "^7.27.1" + "@babel/plugin-transform-unicode-regex" "^7.27.1" + "@babel/plugin-transform-unicode-sets-regex" "^7.27.1" "@babel/preset-modules" "0.1.6-no-external-plugins" - babel-plugin-polyfill-corejs2 "^0.4.10" - babel-plugin-polyfill-corejs3 "^0.11.0" - babel-plugin-polyfill-regenerator "^0.6.1" - core-js-compat "^3.40.0" + babel-plugin-polyfill-corejs2 "^0.4.14" + babel-plugin-polyfill-corejs3 "^0.13.0" + babel-plugin-polyfill-regenerator "^0.6.5" + core-js-compat "^3.43.0" semver "^6.3.1" "@babel/preset-modules@0.1.6-no-external-plugins": @@ -979,164 +1005,172 @@ esutils "^2.0.2" "@babel/preset-react@^7.18.6", "@babel/preset-react@^7.25.9": - version "7.26.3" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.26.3.tgz#7c5e028d623b4683c1f83a0bd4713b9100560caa" - integrity sha512-Nl03d6T9ky516DGK2YMxrTqvnpUW63TnJMOMonj+Zae0JiPC5BC9xPMSL6L8fiSpA5vP88qfygavVQvnLp+6Cw== + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.27.1.tgz#86ea0a5ca3984663f744be2fd26cb6747c3fd0ec" + integrity sha512-oJHWh2gLhU9dW9HHr42q0cI0/iHHXTLGe39qvpAZZzagHy0MzYLCnCVV0symeRvzmjHyVU7mw2K06E6u/JwbhA== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-validator-option" "^7.25.9" - "@babel/plugin-transform-react-display-name" "^7.25.9" - "@babel/plugin-transform-react-jsx" "^7.25.9" - "@babel/plugin-transform-react-jsx-development" "^7.25.9" - "@babel/plugin-transform-react-pure-annotations" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-validator-option" "^7.27.1" + "@babel/plugin-transform-react-display-name" "^7.27.1" + "@babel/plugin-transform-react-jsx" "^7.27.1" + "@babel/plugin-transform-react-jsx-development" "^7.27.1" + "@babel/plugin-transform-react-pure-annotations" "^7.27.1" "@babel/preset-typescript@^7.21.0", "@babel/preset-typescript@^7.25.9": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz#4a570f1b8d104a242d923957ffa1eaff142a106d" - integrity sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg== + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz#190742a6428d282306648a55b0529b561484f912" + integrity sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.9" - "@babel/helper-validator-option" "^7.25.9" - "@babel/plugin-syntax-jsx" "^7.25.9" - "@babel/plugin-transform-modules-commonjs" "^7.25.9" - "@babel/plugin-transform-typescript" "^7.25.9" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-validator-option" "^7.27.1" + "@babel/plugin-syntax-jsx" "^7.27.1" + "@babel/plugin-transform-modules-commonjs" "^7.27.1" + "@babel/plugin-transform-typescript" "^7.27.1" "@babel/runtime-corejs3@^7.25.9": - version "7.26.10" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.26.10.tgz#5a3185ca2813f8de8ae68622572086edf5cf51f2" - integrity sha512-uITFQYO68pMEYR46AHgQoyBg7KPPJDAbGn4jUTIRgCFJIp88MIBUianVOplhZDEec07bp9zIyr4Kp0FCyQzmWg== + version "7.28.2" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.28.2.tgz#1382be38259226003575d9597a57f1eb467de2e7" + integrity sha512-FVFaVs2/dZgD3Y9ZD+AKNKjyGKzwu0C54laAXWUXgLcVXcCX6YZ6GhK2cp7FogSN2OA0Fu+QT8dP3FUdo9ShSQ== dependencies: - core-js-pure "^3.30.2" - regenerator-runtime "^0.14.0" + core-js-pure "^3.43.0" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.25.9", "@babel/runtime@^7.8.4": - version "7.26.10" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.10.tgz#a07b4d8fa27af131a633d7b3524db803eb4764c2" - integrity sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw== - dependencies: - regenerator-runtime "^0.14.0" +"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.25.9": + version "7.28.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.2.tgz#2ae5a9d51cc583bd1f5673b3bb70d6d819682473" + integrity sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA== -"@babel/template@^7.25.9", "@babel/template@^7.26.9": - version "7.26.9" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.26.9.tgz#4577ad3ddf43d194528cff4e1fa6b232fa609bb2" - integrity sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA== +"@babel/template@^7.27.1", "@babel/template@^7.27.2": + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.2.tgz#fa78ceed3c4e7b63ebf6cb39e5852fca45f6809d" + integrity sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw== dependencies: - "@babel/code-frame" "^7.26.2" - "@babel/parser" "^7.26.9" - "@babel/types" "^7.26.9" + "@babel/code-frame" "^7.27.1" + "@babel/parser" "^7.27.2" + "@babel/types" "^7.27.1" -"@babel/traverse@^7.25.9", "@babel/traverse@^7.26.10", "@babel/traverse@^7.26.5", "@babel/traverse@^7.26.8", "@babel/traverse@^7.26.9": - version "7.26.10" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.26.10.tgz#43cca33d76005dbaa93024fae536cc1946a4c380" - integrity sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A== +"@babel/traverse@^7.25.9", "@babel/traverse@^7.27.1", "@babel/traverse@^7.27.3", "@babel/traverse@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.0.tgz#518aa113359b062042379e333db18380b537e34b" + integrity sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg== dependencies: - "@babel/code-frame" "^7.26.2" - "@babel/generator" "^7.26.10" - "@babel/parser" "^7.26.10" - "@babel/template" "^7.26.9" - "@babel/types" "^7.26.10" + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.28.0" + "@babel/helper-globals" "^7.28.0" + "@babel/parser" "^7.28.0" + "@babel/template" "^7.27.2" + "@babel/types" "^7.28.0" debug "^4.3.1" - globals "^11.1.0" -"@babel/types@^7.21.3", "@babel/types@^7.25.9", "@babel/types@^7.26.10", "@babel/types@^7.26.9", "@babel/types@^7.4.4": - version "7.26.10" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.10.tgz#396382f6335bd4feb65741eacfc808218f859259" - integrity sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ== +"@babel/types@^7.21.3", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.0", "@babel/types@^7.28.2", "@babel/types@^7.4.4": + version "7.28.2" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.2.tgz#da9db0856a9a88e0a13b019881d7513588cf712b" + integrity sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ== dependencies: - "@babel/helper-string-parser" "^7.25.9" - "@babel/helper-validator-identifier" "^7.25.9" + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== -"@csstools/cascade-layer-name-parser@^2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-2.0.4.tgz#64d128529397aa1e1c986f685713363b262b81b1" - integrity sha512-7DFHlPuIxviKYZrOiwVU/PiHLm3lLUR23OMuEEtfEOQTOp9hzQ2JjdY6X5H18RVuUPJqSCI+qNnD5iOLMVE0bA== +"@csstools/cascade-layer-name-parser@^2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-2.0.5.tgz#43f962bebead0052a9fed1a2deeb11f85efcbc72" + integrity sha512-p1ko5eHgV+MgXFVa4STPKpvPxr6ReS8oS2jzTukjR74i5zJNyWO1ZM1m8YKBXnzDKWfBN1ztLYlHxbVemDD88A== "@csstools/color-helpers@^5.0.2": version "5.0.2" resolved "https://registry.yarnpkg.com/@csstools/color-helpers/-/color-helpers-5.0.2.tgz#82592c9a7c2b83c293d9161894e2a6471feb97b8" integrity sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA== -"@csstools/css-calc@^2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@csstools/css-calc/-/css-calc-2.1.2.tgz#bffd55f002dab119b76d4023f95cd943e6c8c11e" - integrity sha512-TklMyb3uBB28b5uQdxjReG4L80NxAqgrECqLZFQbyLekwwlcDDS8r3f07DKqeo8C4926Br0gf/ZDe17Zv4wIuw== +"@csstools/css-calc@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@csstools/css-calc/-/css-calc-2.1.4.tgz#8473f63e2fcd6e459838dd412401d5948f224c65" + integrity sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ== -"@csstools/css-color-parser@^3.0.8": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@csstools/css-color-parser/-/css-color-parser-3.0.8.tgz#5fe9322920851450bf5e065c2b0e731b9e165394" - integrity sha512-pdwotQjCCnRPuNi06jFuP68cykU1f3ZWExLe/8MQ1LOs8Xq+fTkYgd+2V8mWUWMrOn9iS2HftPVaMZDaXzGbhQ== +"@csstools/css-color-parser@^3.0.10": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@csstools/css-color-parser/-/css-color-parser-3.0.10.tgz#79fc68864dd43c3b6782d2b3828bc0fa9d085c10" + integrity sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg== dependencies: "@csstools/color-helpers" "^5.0.2" - "@csstools/css-calc" "^2.1.2" + "@csstools/css-calc" "^2.1.4" -"@csstools/css-parser-algorithms@^3.0.4": +"@csstools/css-parser-algorithms@^3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz#5755370a9a29abaec5515b43c8b3f2cf9c2e3076" + integrity sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ== + +"@csstools/css-tokenizer@^3.0.4": version "3.0.4" - resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz#74426e93bd1c4dcab3e441f5cc7ba4fb35d94356" - integrity sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A== + resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz#333fedabc3fd1a8e5d0100013731cf19e6a8c5d3" + integrity sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw== -"@csstools/css-tokenizer@^3.0.3": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz#a5502c8539265fecbd873c1e395a890339f119c2" - integrity sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw== +"@csstools/media-query-list-parser@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz#7aec77bcb89c2da80ef207e73f474ef9e1b3cdf1" + integrity sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ== -"@csstools/media-query-list-parser@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.2.tgz#e80e17eba1693fceafb8d6f2cfc68c0e7a9ab78a" - integrity sha512-EUos465uvVvMJehckATTlNqGj4UJWkTmdWuDMjqvSUkjGpmOyFZBVwb4knxCm/k2GMTXY+c/5RkdndzFYWeX5A== - -"@csstools/postcss-cascade-layers@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.1.tgz#9640313e64b5e39133de7e38a5aa7f40dc259597" - integrity sha512-XOfhI7GShVcKiKwmPAnWSqd2tBR0uxt+runAxttbSp/LY2U16yAVPmAf7e9q4JJ0d+xMNmpwNDLBXnmRCl3HMQ== +"@csstools/postcss-cascade-layers@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.2.tgz#dd2c70db3867b88975f2922da3bfbae7d7a2cae7" + integrity sha512-nWBE08nhO8uWl6kSAeCx4im7QfVko3zLrtgWZY4/bP87zrSPpSyN/3W3TDqz1jJuH+kbKOHXg5rJnK+ZVYcFFg== dependencies: "@csstools/selector-specificity" "^5.0.0" postcss-selector-parser "^7.0.0" -"@csstools/postcss-color-function@^4.0.8": - version "4.0.8" - resolved "https://registry.yarnpkg.com/@csstools/postcss-color-function/-/postcss-color-function-4.0.8.tgz#4c16ea78abfdfd62c947616c6e68836e50f2441c" - integrity sha512-9dUvP2qpZI6PlGQ/sob+95B3u5u7nkYt9yhZFCC7G9HBRHBxj+QxS/wUlwaMGYW0waf+NIierI8aoDTssEdRYw== +"@csstools/postcss-color-function@^4.0.10": + version "4.0.10" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-function/-/postcss-color-function-4.0.10.tgz#11ad43a66ef2cc794ab826a07df8b5fa9fb47a3a" + integrity sha512-4dY0NBu7NVIpzxZRgh/Q/0GPSz/jLSw0i/u3LTUor0BkQcz/fNhN10mSWBDsL0p9nDb0Ky1PD6/dcGbhACuFTQ== dependencies: - "@csstools/css-color-parser" "^3.0.8" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/css-color-parser" "^3.0.10" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.1.0" "@csstools/utilities" "^2.0.0" -"@csstools/postcss-color-mix-function@^3.0.8": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.8.tgz#45a006dfcc65f2a61ae60f2df7ebc108fdb9eaf1" - integrity sha512-yuZpgWUzqZWQhEqfvtJufhl28DgO9sBwSbXbf/59gejNuvZcoUTRGQZhzhwF4ccqb53YAGB+u92z9+eSKoB4YA== +"@csstools/postcss-color-mix-function@^3.0.10": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.10.tgz#8c9d0ccfae5c45a9870dd84807ea2995c7a3a514" + integrity sha512-P0lIbQW9I4ShE7uBgZRib/lMTf9XMjJkFl/d6w4EMNHu2qvQ6zljJGEcBkw/NsBtq/6q3WrmgxSS8kHtPMkK4Q== dependencies: - "@csstools/css-color-parser" "^3.0.8" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/css-color-parser" "^3.0.10" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.1.0" "@csstools/utilities" "^2.0.0" -"@csstools/postcss-content-alt-text@^2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@csstools/postcss-content-alt-text/-/postcss-content-alt-text-2.0.4.tgz#76f4687fb15ed45bc1139bb71e5775779762897a" - integrity sha512-YItlZUOuZJCBlRaCf8Aucc1lgN41qYGALMly0qQllrxYJhiyzlI6RxOTMUvtWk+KhS8GphMDsDhKQ7KTPfEMSw== +"@csstools/postcss-color-mix-variadic-function-arguments@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-mix-variadic-function-arguments/-/postcss-color-mix-variadic-function-arguments-1.0.0.tgz#0b29cb9b4630d7ed68549db265662d41554a17ed" + integrity sha512-Z5WhouTyD74dPFPrVE7KydgNS9VvnjB8qcdes9ARpCOItb4jTnm7cHp4FhxCRUoyhabD0WVv43wbkJ4p8hLAlQ== dependencies: - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/css-color-parser" "^3.0.10" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.1.0" "@csstools/utilities" "^2.0.0" -"@csstools/postcss-exponential-functions@^2.0.7": - version "2.0.7" - resolved "https://registry.yarnpkg.com/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-2.0.7.tgz#c369f241c6645a5e8a184bfd02cdcc65bd22fcbd" - integrity sha512-XTb6Mw0v2qXtQYRW9d9duAjDnoTbBpsngD7sRNLmYDjvwU2ebpIHplyxgOeo6jp/Kr52gkLi5VaK5RDCqzMzZQ== +"@csstools/postcss-content-alt-text@^2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@csstools/postcss-content-alt-text/-/postcss-content-alt-text-2.0.6.tgz#548862226eac54bab0ee5f1bf3a9981393ab204b" + integrity sha512-eRjLbOjblXq+byyaedQRSrAejKGNAFued+LcbzT+LCL78fabxHkxYjBbxkroONxHHYu2qxhFK2dBStTLPG3jpQ== dependencies: - "@csstools/css-calc" "^2.1.2" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.1.0" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-exponential-functions@^2.0.9": + version "2.0.9" + resolved "https://registry.yarnpkg.com/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-2.0.9.tgz#fc03d1272888cb77e64cc1a7d8a33016e4f05c69" + integrity sha512-abg2W/PI3HXwS/CZshSa79kNWNZHdJPMBXeZNyPQFbbj8sKO3jXxOt/wF7juJVjyDTc6JrvaUZYFcSBZBhaxjw== + dependencies: + "@csstools/css-calc" "^2.1.4" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" "@csstools/postcss-font-format-keywords@^4.0.0": version "4.0.0" @@ -1146,43 +1180,43 @@ "@csstools/utilities" "^2.0.0" postcss-value-parser "^4.2.0" -"@csstools/postcss-gamut-mapping@^2.0.8": - version "2.0.8" - resolved "https://registry.yarnpkg.com/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.8.tgz#e9441e7b5a7b0d3cc1a92486378824abb76ef849" - integrity sha512-/K8u9ZyGMGPjmwCSIjgaOLKfic2RIGdFHHes84XW5LnmrvdhOTVxo255NppHi3ROEvoHPW7MplMJgjZK5Q+TxA== +"@csstools/postcss-gamut-mapping@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.10.tgz#f518d941231d721dbecf5b41e3c441885ff2f28b" + integrity sha512-QDGqhJlvFnDlaPAfCYPsnwVA6ze+8hhrwevYWlnUeSjkkZfBpcCO42SaUD8jiLlq7niouyLgvup5lh+f1qessg== dependencies: - "@csstools/css-color-parser" "^3.0.8" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" + "@csstools/css-color-parser" "^3.0.10" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" -"@csstools/postcss-gradients-interpolation-method@^5.0.8": - version "5.0.8" - resolved "https://registry.yarnpkg.com/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.8.tgz#f7f0324fd564c092ac13ce35b5a09ffda0165a90" - integrity sha512-CoHQ/0UXrvxLovu0ZeW6c3/20hjJ/QRg6lyXm3dZLY/JgvRU6bdbQZF/Du30A4TvowfcgvIHQmP1bNXUxgDrAw== +"@csstools/postcss-gradients-interpolation-method@^5.0.10": + version "5.0.10" + resolved "https://registry.yarnpkg.com/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.10.tgz#3146da352c31142a721fdba062ac3a6d11dbbec3" + integrity sha512-HHPauB2k7Oits02tKFUeVFEU2ox/H3OQVrP3fSOKDxvloOikSal+3dzlyTZmYsb9FlY9p5EUpBtz0//XBmy+aw== dependencies: - "@csstools/css-color-parser" "^3.0.8" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/css-color-parser" "^3.0.10" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.1.0" "@csstools/utilities" "^2.0.0" -"@csstools/postcss-hwb-function@^4.0.8": - version "4.0.8" - resolved "https://registry.yarnpkg.com/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.8.tgz#13a85203601b3db97a6672e16f6699fe464827b0" - integrity sha512-LpFKjX6hblpeqyych1cKmk+3FJZ19QmaJtqincySoMkbkG/w2tfbnO5oE6mlnCTXcGUJ0rCEuRHvTqKK0nHYUQ== +"@csstools/postcss-hwb-function@^4.0.10": + version "4.0.10" + resolved "https://registry.yarnpkg.com/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.10.tgz#f93f3c457e6440ac37ef9b908feb5d901b417d50" + integrity sha512-nOKKfp14SWcdEQ++S9/4TgRKchooLZL0TUFdun3nI4KPwCjETmhjta1QT4ICQcGVWQTvrsgMM/aLB5We+kMHhQ== dependencies: - "@csstools/css-color-parser" "^3.0.8" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/css-color-parser" "^3.0.10" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.1.0" "@csstools/utilities" "^2.0.0" -"@csstools/postcss-ic-unit@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@csstools/postcss-ic-unit/-/postcss-ic-unit-4.0.0.tgz#b60ec06500717c337447c39ae7fe7952eeb9d48f" - integrity sha512-9QT5TDGgx7wD3EEMN3BSUG6ckb6Eh5gSPT5kZoVtUuAonfPmLDJyPhqR4ntPpMYhUKAMVKAg3I/AgzqHMSeLhA== +"@csstools/postcss-ic-unit@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-ic-unit/-/postcss-ic-unit-4.0.2.tgz#7561e09db65fac8304ceeab9dd3e5c6e43414587" + integrity sha512-lrK2jjyZwh7DbxaNnIUjkeDmU8Y6KyzRBk91ZkI5h8nb1ykEfZrtIVArdIjX4DHMIBGpdHrgP0n4qXDr7OHaKA== dependencies: - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/postcss-progressive-custom-properties" "^4.1.0" "@csstools/utilities" "^2.0.0" postcss-value-parser "^4.2.0" @@ -1191,22 +1225,22 @@ resolved "https://registry.yarnpkg.com/@csstools/postcss-initial/-/postcss-initial-2.0.1.tgz#c385bd9d8ad31ad159edd7992069e97ceea4d09a" integrity sha512-L1wLVMSAZ4wovznquK0xmC7QSctzO4D0Is590bxpGqhqjboLXYA16dWZpfwImkdOgACdQ9PqXsuRroW6qPlEsg== -"@csstools/postcss-is-pseudo-class@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-5.0.1.tgz#12041448fedf01090dd4626022c28b7f7623f58e" - integrity sha512-JLp3POui4S1auhDR0n8wHd/zTOWmMsmK3nQd3hhL6FhWPaox5W7j1se6zXOG/aP07wV2ww0lxbKYGwbBszOtfQ== +"@csstools/postcss-is-pseudo-class@^5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-5.0.3.tgz#d34e850bcad4013c2ed7abe948bfa0448aa8eb74" + integrity sha512-jS/TY4SpG4gszAtIg7Qnf3AS2pjcUM5SzxpApOrlndMeGhIbaTzWBzzP/IApXoNWEW7OhcjkRT48jnAUIFXhAQ== dependencies: "@csstools/selector-specificity" "^5.0.0" postcss-selector-parser "^7.0.0" -"@csstools/postcss-light-dark-function@^2.0.7": - version "2.0.7" - resolved "https://registry.yarnpkg.com/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.7.tgz#807c170cd28eebb0c00e64dfc6ab0bf418f19209" - integrity sha512-ZZ0rwlanYKOHekyIPaU+sVm3BEHCe+Ha0/px+bmHe62n0Uc1lL34vbwrLYn6ote8PHlsqzKeTQdIejQCJ05tfw== +"@csstools/postcss-light-dark-function@^2.0.9": + version "2.0.9" + resolved "https://registry.yarnpkg.com/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.9.tgz#9fb080188907539734a9d5311d2a1cb82531ef38" + integrity sha512-1tCZH5bla0EAkFAI2r0H33CDnIBeLUaJh1p+hvvsylJ4svsv2wOmJjJn+OXwUZLXef37GYbRIVKX+X+g6m+3CQ== dependencies: - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.1.0" "@csstools/utilities" "^2.0.0" "@csstools/postcss-logical-float-and-clear@^3.0.0": @@ -1231,32 +1265,32 @@ dependencies: postcss-value-parser "^4.2.0" -"@csstools/postcss-logical-viewport-units@^3.0.3": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-3.0.3.tgz#f6cc63520ca2a6eb76b9cd946070c38dda66d733" - integrity sha512-OC1IlG/yoGJdi0Y+7duz/kU/beCwO+Gua01sD6GtOtLi7ByQUpcIqs7UE/xuRPay4cHgOMatWdnDdsIDjnWpPw== +"@csstools/postcss-logical-viewport-units@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-3.0.4.tgz#016d98a8b7b5f969e58eb8413447eb801add16fc" + integrity sha512-q+eHV1haXA4w9xBwZLKjVKAWn3W2CMqmpNpZUk5kRprvSiBEGMgrNH3/sJZ8UA3JgyHaOt3jwT9uFa4wLX4EqQ== dependencies: - "@csstools/css-tokenizer" "^3.0.3" + "@csstools/css-tokenizer" "^3.0.4" "@csstools/utilities" "^2.0.0" -"@csstools/postcss-media-minmax@^2.0.7": - version "2.0.7" - resolved "https://registry.yarnpkg.com/@csstools/postcss-media-minmax/-/postcss-media-minmax-2.0.7.tgz#42816871decf0a092af3f6c8500e04d9918cc342" - integrity sha512-LB6tIP7iBZb5CYv8iRenfBZmbaG3DWNEziOnPjGoQX5P94FBPvvTBy68b/d9NnS5PELKwFmmOYsAEIgEhDPCHA== +"@csstools/postcss-media-minmax@^2.0.9": + version "2.0.9" + resolved "https://registry.yarnpkg.com/@csstools/postcss-media-minmax/-/postcss-media-minmax-2.0.9.tgz#184252d5b93155ae526689328af6bdf3fc113987" + integrity sha512-af9Qw3uS3JhYLnCbqtZ9crTvvkR+0Se+bBqSr7ykAnl9yKhk6895z9rf+2F4dClIDJWxgn0iZZ1PSdkhrbs2ig== dependencies: - "@csstools/css-calc" "^2.1.2" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/media-query-list-parser" "^4.0.2" + "@csstools/css-calc" "^2.1.4" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/media-query-list-parser" "^4.0.3" -"@csstools/postcss-media-queries-aspect-ratio-number-values@^3.0.4": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-3.0.4.tgz#d71102172c74baf3f892fac88cf1ea46a961600d" - integrity sha512-AnGjVslHMm5xw9keusQYvjVWvuS7KWK+OJagaG0+m9QnIjZsrysD2kJP/tr/UJIyYtMCtu8OkUd+Rajb4DqtIQ== +"@csstools/postcss-media-queries-aspect-ratio-number-values@^3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-3.0.5.tgz#f485c31ec13d6b0fb5c528a3474334a40eff5f11" + integrity sha512-zhAe31xaaXOY2Px8IYfoVTB3wglbJUVigGphFLj6exb7cjZRH9A6adyE22XfFK3P2PzwRk0VDeTJmaxpluyrDg== dependencies: - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/media-query-list-parser" "^4.0.2" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/media-query-list-parser" "^4.0.3" "@csstools/postcss-nested-calc@^4.0.0": version "4.0.0" @@ -1273,42 +1307,42 @@ dependencies: postcss-value-parser "^4.2.0" -"@csstools/postcss-oklab-function@^4.0.8": - version "4.0.8" - resolved "https://registry.yarnpkg.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.8.tgz#9d723e0db69703f3df549ebedfd605f849217fff" - integrity sha512-+5aPsNWgxohXoYNS1f+Ys0x3Qnfehgygv3qrPyv+Y25G0yX54/WlVB+IXprqBLOXHM1gsVF+QQSjlArhygna0Q== +"@csstools/postcss-oklab-function@^4.0.10": + version "4.0.10" + resolved "https://registry.yarnpkg.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.10.tgz#d4c23c51dd0be45e6dedde22432d7d0003710780" + integrity sha512-ZzZUTDd0fgNdhv8UUjGCtObPD8LYxMH+MJsW9xlZaWTV8Ppr4PtxlHYNMmF4vVWGl0T6f8tyWAKjoI6vePSgAg== dependencies: - "@csstools/css-color-parser" "^3.0.8" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/css-color-parser" "^3.0.10" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.1.0" "@csstools/utilities" "^2.0.0" -"@csstools/postcss-progressive-custom-properties@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.0.0.tgz#ecdb85bcdb1852d73970a214a376684a91f82bdc" - integrity sha512-XQPtROaQjomnvLUSy/bALTR5VCtTVUFwYs1SblvYgLSeTo2a/bMNwUwo2piXw5rTv/FEYiy5yPSXBqg9OKUx7Q== +"@csstools/postcss-progressive-custom-properties@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.1.0.tgz#70c8d41b577f4023633b7e3791604e0b7f3775bc" + integrity sha512-YrkI9dx8U4R8Sz2EJaoeD9fI7s7kmeEBfmO+UURNeL6lQI7VxF6sBE+rSqdCBn4onwqmxFdBU3lTwyYb/lCmxA== dependencies: postcss-value-parser "^4.2.0" -"@csstools/postcss-random-function@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@csstools/postcss-random-function/-/postcss-random-function-1.0.3.tgz#f737f5bab3826fc71fd663b21e70ee392b144f20" - integrity sha512-dbNeEEPHxAwfQJ3duRL5IPpuD77QAHtRl4bAHRs0vOVhVbHrsL7mHnwe0irYjbs9kYwhAHZBQTLBgmvufPuRkA== +"@csstools/postcss-random-function@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-random-function/-/postcss-random-function-2.0.1.tgz#3191f32fe72936e361dadf7dbfb55a0209e2691e" + integrity sha512-q+FQaNiRBhnoSNo+GzqGOIBKoHQ43lYz0ICrV+UudfWnEF6ksS6DsBIJSISKQT2Bvu3g4k6r7t0zYrk5pDlo8w== dependencies: - "@csstools/css-calc" "^2.1.2" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" + "@csstools/css-calc" "^2.1.4" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" -"@csstools/postcss-relative-color-syntax@^3.0.8": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.8.tgz#833cdea06e5cbec2702f939d1aadfd280e4f4c07" - integrity sha512-eGE31oLnJDoUysDdjS9MLxNZdtqqSxjDXMdISpLh80QMaYrKs7VINpid34tWQ+iU23Wg5x76qAzf1Q/SLLbZVg== +"@csstools/postcss-relative-color-syntax@^3.0.10": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.10.tgz#daa840583969461e1e06b12e9c591e52a790ec86" + integrity sha512-8+0kQbQGg9yYG8hv0dtEpOMLwB9M+P7PhacgIzVzJpixxV4Eq9AUQtQw8adMmAJU1RBBmIlpmtmm3XTRd/T00g== dependencies: - "@csstools/css-color-parser" "^3.0.8" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/css-color-parser" "^3.0.10" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.1.0" "@csstools/utilities" "^2.0.0" "@csstools/postcss-scope-pseudo-class@^4.0.1": @@ -1318,23 +1352,23 @@ dependencies: postcss-selector-parser "^7.0.0" -"@csstools/postcss-sign-functions@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@csstools/postcss-sign-functions/-/postcss-sign-functions-1.1.2.tgz#9664762870de4f8d189829a86798e532bbaad053" - integrity sha512-4EcAvXTUPh7n6UoZZkCzgtCf/wPzMlTNuddcKg7HG8ozfQkUcHsJ2faQKeLmjyKdYPyOUn4YA7yDPf8K/jfIxw== +"@csstools/postcss-sign-functions@^1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@csstools/postcss-sign-functions/-/postcss-sign-functions-1.1.4.tgz#a9ac56954014ae4c513475b3f1b3e3424a1e0c12" + integrity sha512-P97h1XqRPcfcJndFdG95Gv/6ZzxUBBISem0IDqPZ7WMvc/wlO+yU0c5D/OCpZ5TJoTt63Ok3knGk64N+o6L2Pg== dependencies: - "@csstools/css-calc" "^2.1.2" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" + "@csstools/css-calc" "^2.1.4" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" -"@csstools/postcss-stepped-value-functions@^4.0.7": - version "4.0.7" - resolved "https://registry.yarnpkg.com/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-4.0.7.tgz#c681fbcdb8a2fcfeaea2bb0ea9d497832bab9ef7" - integrity sha512-rdrRCKRnWtj5FyRin0u/gLla7CIvZRw/zMGI1fVJP0Sg/m1WGicjPVHRANL++3HQtsiXKAbPrcPr+VkyGck0IA== +"@csstools/postcss-stepped-value-functions@^4.0.9": + version "4.0.9" + resolved "https://registry.yarnpkg.com/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-4.0.9.tgz#36036f1a0e5e5ee2308e72f3c9cb433567c387b9" + integrity sha512-h9btycWrsex4dNLeQfyU3y3w40LMQooJWFMm/SK9lrKguHDcFl4VMkncKKoXi2z5rM9YGWbUQABI8BT2UydIcA== dependencies: - "@csstools/css-calc" "^2.1.2" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" + "@csstools/css-calc" "^2.1.4" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" "@csstools/postcss-text-decoration-shorthand@^4.0.2": version "4.0.2" @@ -1344,24 +1378,24 @@ "@csstools/color-helpers" "^5.0.2" postcss-value-parser "^4.2.0" -"@csstools/postcss-trigonometric-functions@^4.0.7": - version "4.0.7" - resolved "https://registry.yarnpkg.com/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-4.0.7.tgz#8941a4c99dc1fec31daf052ac0fb6e7bf7c92403" - integrity sha512-qTrZgLju3AV7Djhzuh2Bq/wjFqbcypnk0FhHjxW8DWJQcZLS1HecIus4X2/RLch1ukX7b+YYCdqbEnpIQO5ccg== +"@csstools/postcss-trigonometric-functions@^4.0.9": + version "4.0.9" + resolved "https://registry.yarnpkg.com/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-4.0.9.tgz#3f94ed2e319b57f2c59720b64e4d0a8a6fb8c3b2" + integrity sha512-Hnh5zJUdpNrJqK9v1/E3BbrQhaDTj5YiX7P61TOvUhoDHnUmsNNxcDAgkQ32RrcWx9GVUvfUNPcUkn8R3vIX6A== dependencies: - "@csstools/css-calc" "^2.1.2" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" + "@csstools/css-calc" "^2.1.4" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" "@csstools/postcss-unset-value@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@csstools/postcss-unset-value/-/postcss-unset-value-4.0.0.tgz#7caa981a34196d06a737754864baf77d64de4bba" integrity sha512-cBz3tOCI5Fw6NIFEwU3RiwK6mn3nKegjpJuzCndoGq3BZPkUjnsq7uQmIeMNeMbMk7YD2MfKcgCpZwX5jyXqCA== -"@csstools/selector-resolve-nested@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.0.0.tgz#704a9b637975680e025e069a4c58b3beb3e2752a" - integrity sha512-ZoK24Yku6VJU1gS79a5PFmC8yn3wIapiKmPgun0hZgEI5AOqgH2kiPRsPz1qkGv4HL+wuDLH83yQyk6inMYrJQ== +"@csstools/selector-resolve-nested@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.1.0.tgz#848c6f44cb65e3733e478319b9342b7aa436fac7" + integrity sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g== "@csstools/selector-specificity@^5.0.0": version "5.0.0" @@ -1383,7 +1417,7 @@ resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.9.0.tgz#3bc29c96bf024350d73b0cfb7c2a7b71bf251cd5" integrity sha512-cQbnVbq0rrBwNAKegIac/t6a8nWoUAn8frnkLFW6YARaRmAQr5/Eoe6Ln2fqkUCZ40KpdrKbpSAmgrkviOxuWA== -"@docsearch/react@^3.8.1": +"@docsearch/react@^3.9.0": version "3.9.0" resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.9.0.tgz#d0842b700c3ee26696786f3c8ae9f10c1a3f0db3" integrity sha512-mb5FOZYZIkRQ6s/NWnM98k879vu5pscWqTLubLFBO87igYYT4VzVazh4h5o/zCvTIZgEt3PvsCOMOswOUo9yHQ== @@ -1393,10 +1427,10 @@ "@docsearch/css" "3.9.0" algoliasearch "^5.14.2" -"@docusaurus/babel@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/babel/-/babel-3.7.0.tgz#770dd5da525a9d6a2fee7d3212ec62040327f776" - integrity sha512-0H5uoJLm14S/oKV3Keihxvh8RV+vrid+6Gv+2qhuzbqHanawga8tYnsdpjEyt36ucJjqlby2/Md2ObWjA02UXQ== +"@docusaurus/babel@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/babel/-/babel-3.8.1.tgz#db329ac047184214e08e2dbc809832c696c18506" + integrity sha512-3brkJrml8vUbn9aeoZUlJfsI/GqyFcDgQJwQkmBtclJgWDEQBKKeagZfOgx0WfUQhagL1sQLNW0iBdxnI863Uw== dependencies: "@babel/core" "^7.25.9" "@babel/generator" "^7.25.9" @@ -1408,55 +1442,54 @@ "@babel/runtime" "^7.25.9" "@babel/runtime-corejs3" "^7.25.9" "@babel/traverse" "^7.25.9" - "@docusaurus/logger" "3.7.0" - "@docusaurus/utils" "3.7.0" + "@docusaurus/logger" "3.8.1" + "@docusaurus/utils" "3.8.1" babel-plugin-dynamic-import-node "^2.3.3" fs-extra "^11.1.1" tslib "^2.6.0" -"@docusaurus/bundler@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/bundler/-/bundler-3.7.0.tgz#d8e7867b3b2c43a1e320ed429f8dfe873c38506d" - integrity sha512-CUUT9VlSGukrCU5ctZucykvgCISivct+cby28wJwCC/fkQFgAHRp/GKv2tx38ZmXb7nacrKzFTcp++f9txUYGg== +"@docusaurus/bundler@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/bundler/-/bundler-3.8.1.tgz#e2b11d615f09a6e470774bb36441b8d06736b94c" + integrity sha512-/z4V0FRoQ0GuSLToNjOSGsk6m2lQUG4FRn8goOVoZSRsTrU8YR2aJacX5K3RG18EaX9b+52pN4m1sL3MQZVsQA== dependencies: "@babel/core" "^7.25.9" - "@docusaurus/babel" "3.7.0" - "@docusaurus/cssnano-preset" "3.7.0" - "@docusaurus/logger" "3.7.0" - "@docusaurus/types" "3.7.0" - "@docusaurus/utils" "3.7.0" + "@docusaurus/babel" "3.8.1" + "@docusaurus/cssnano-preset" "3.8.1" + "@docusaurus/logger" "3.8.1" + "@docusaurus/types" "3.8.1" + "@docusaurus/utils" "3.8.1" babel-loader "^9.2.1" - clean-css "^5.3.2" + clean-css "^5.3.3" copy-webpack-plugin "^11.0.0" - css-loader "^6.8.1" + css-loader "^6.11.0" css-minimizer-webpack-plugin "^5.0.1" cssnano "^6.1.2" file-loader "^6.2.0" html-minifier-terser "^7.2.0" - mini-css-extract-plugin "^2.9.1" + mini-css-extract-plugin "^2.9.2" null-loader "^4.0.1" - postcss "^8.4.26" - postcss-loader "^7.3.3" - postcss-preset-env "^10.1.0" - react-dev-utils "^12.0.1" + postcss "^8.5.4" + postcss-loader "^7.3.4" + postcss-preset-env "^10.2.1" terser-webpack-plugin "^5.3.9" tslib "^2.6.0" url-loader "^4.1.1" webpack "^5.95.0" webpackbar "^6.0.1" -"@docusaurus/core@3.7.0", "@docusaurus/core@^3.5.2": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/core/-/core-3.7.0.tgz#e871586d099093723dfe6de81c1ce610aeb20292" - integrity sha512-b0fUmaL+JbzDIQaamzpAFpTviiaU4cX3Qz8cuo14+HGBCwa0evEK0UYCBFY3n4cLzL8Op1BueeroUD2LYAIHbQ== +"@docusaurus/core@3.8.1", "@docusaurus/core@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/core/-/core-3.8.1.tgz#c22e47c16a22cb7d245306c64bc54083838ff3db" + integrity sha512-ENB01IyQSqI2FLtOzqSI3qxG2B/jP4gQPahl2C3XReiLebcVh5B5cB9KYFvdoOqOWPyr5gXK4sjgTKv7peXCrA== dependencies: - "@docusaurus/babel" "3.7.0" - "@docusaurus/bundler" "3.7.0" - "@docusaurus/logger" "3.7.0" - "@docusaurus/mdx-loader" "3.7.0" - "@docusaurus/utils" "3.7.0" - "@docusaurus/utils-common" "3.7.0" - "@docusaurus/utils-validation" "3.7.0" + "@docusaurus/babel" "3.8.1" + "@docusaurus/bundler" "3.8.1" + "@docusaurus/logger" "3.8.1" + "@docusaurus/mdx-loader" "3.8.1" + "@docusaurus/utils" "3.8.1" + "@docusaurus/utils-common" "3.8.1" + "@docusaurus/utils-validation" "3.8.1" boxen "^6.2.1" chalk "^4.1.2" chokidar "^3.5.3" @@ -1464,19 +1497,19 @@ combine-promises "^1.1.0" commander "^5.1.0" core-js "^3.31.1" - del "^6.1.1" detect-port "^1.5.1" escape-html "^1.0.3" eta "^2.2.0" eval "^0.1.8" + execa "5.1.1" fs-extra "^11.1.1" html-tags "^3.3.1" html-webpack-plugin "^5.6.0" leven "^3.1.0" lodash "^4.17.21" + open "^8.4.0" p-map "^4.0.0" prompts "^2.4.2" - react-dev-utils "^12.0.1" react-helmet-async "npm:@slorber/react-helmet-async@1.3.0" react-loadable "npm:@docusaurus/react-loadable@6.0.0" react-loadable-ssr-addon-v5-slorber "^1.0.1" @@ -1485,7 +1518,7 @@ react-router-dom "^5.3.4" semver "^7.5.4" serve-handler "^6.1.6" - shelljs "^0.8.5" + tinypool "^1.0.2" tslib "^2.6.0" update-notifier "^6.0.2" webpack "^5.95.0" @@ -1493,39 +1526,39 @@ webpack-dev-server "^4.15.2" webpack-merge "^6.0.1" -"@docusaurus/cssnano-preset@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/cssnano-preset/-/cssnano-preset-3.7.0.tgz#8fe8f2c3acbd32384b69e14983b9a63c98cae34e" - integrity sha512-X9GYgruZBSOozg4w4dzv9uOz8oK/EpPVQXkp0MM6Tsgp/nRIU9hJzJ0Pxg1aRa3xCeEQTOimZHcocQFlLwYajQ== +"@docusaurus/cssnano-preset@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/cssnano-preset/-/cssnano-preset-3.8.1.tgz#bd55026251a6ab8e2194839a2042458ef9880c44" + integrity sha512-G7WyR2N6SpyUotqhGznERBK+x84uyhfMQM2MmDLs88bw4Flom6TY46HzkRkSEzaP9j80MbTN8naiL1fR17WQug== dependencies: cssnano-preset-advanced "^6.1.2" - postcss "^8.4.38" + postcss "^8.5.4" postcss-sort-media-queries "^5.2.0" tslib "^2.6.0" -"@docusaurus/logger@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/logger/-/logger-3.7.0.tgz#07ecc2f460c4d2382df4991f9ce4e348e90af04c" - integrity sha512-z7g62X7bYxCYmeNNuO9jmzxLQG95q9QxINCwpboVcNff3SJiHJbGrarxxOVMVmAh1MsrSfxWkVGv4P41ktnFsA== +"@docusaurus/logger@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/logger/-/logger-3.8.1.tgz#45321b2e2e14695d0dbd8b4104ea7b0fbaa98700" + integrity sha512-2wjeGDhKcExEmjX8k1N/MRDiPKXGF2Pg+df/bDDPnnJWHXnVEZxXj80d6jcxp1Gpnksl0hF8t/ZQw9elqj2+ww== dependencies: chalk "^4.1.2" tslib "^2.6.0" -"@docusaurus/mdx-loader@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-3.7.0.tgz#5890c6e7a5b68cb1d066264ac5290cdcd59d4ecc" - integrity sha512-OFBG6oMjZzc78/U3WNPSHs2W9ZJ723ewAcvVJaqS0VgyeUfmzUV8f1sv+iUHA0DtwiR5T5FjOxj6nzEE8LY6VA== +"@docusaurus/mdx-loader@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-3.8.1.tgz#74309b3614bbcef1d55fb13e6cc339b7fb000b5f" + integrity sha512-DZRhagSFRcEq1cUtBMo4TKxSNo/W6/s44yhr8X+eoXqCLycFQUylebOMPseHi5tc4fkGJqwqpWJLz6JStU9L4w== dependencies: - "@docusaurus/logger" "3.7.0" - "@docusaurus/utils" "3.7.0" - "@docusaurus/utils-validation" "3.7.0" + "@docusaurus/logger" "3.8.1" + "@docusaurus/utils" "3.8.1" + "@docusaurus/utils-validation" "3.8.1" "@mdx-js/mdx" "^3.0.0" "@slorber/remark-comment" "^1.0.0" escape-html "^1.0.3" estree-util-value-to-estree "^3.0.1" file-loader "^6.2.0" fs-extra "^11.1.1" - image-size "^1.0.2" + image-size "^2.0.2" mdast-util-mdx "^3.0.0" mdast-util-to-string "^4.0.0" rehype-raw "^7.0.0" @@ -1541,197 +1574,210 @@ vfile "^6.0.1" webpack "^5.88.1" -"@docusaurus/module-type-aliases@3.7.0", "@docusaurus/module-type-aliases@^3.5.2": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/module-type-aliases/-/module-type-aliases-3.7.0.tgz#15c0745b829c6966c5b3b2c2527c72b54830b0e5" - integrity sha512-g7WdPqDNaqA60CmBrr0cORTrsOit77hbsTj7xE2l71YhBn79sxdm7WMK7wfhcaafkbpIh7jv5ef5TOpf1Xv9Lg== +"@docusaurus/module-type-aliases@3.8.1", "@docusaurus/module-type-aliases@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/module-type-aliases/-/module-type-aliases-3.8.1.tgz#454de577bd7f50b5eae16db0f76b49ca5e4e281a" + integrity sha512-6xhvAJiXzsaq3JdosS7wbRt/PwEPWHr9eM4YNYqVlbgG1hSK3uQDXTVvQktasp3VO6BmfYWPozueLWuj4gB+vg== dependencies: - "@docusaurus/types" "3.7.0" + "@docusaurus/types" "3.8.1" "@types/history" "^4.7.11" "@types/react" "*" "@types/react-router-config" "*" "@types/react-router-dom" "*" - react-helmet-async "npm:@slorber/react-helmet-async@*" + react-helmet-async "npm:@slorber/react-helmet-async@1.3.0" react-loadable "npm:@docusaurus/react-loadable@6.0.0" -"@docusaurus/plugin-content-blog@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.7.0.tgz#7bd69de87a1f3adb652e1473ef5b7ccc9468f47e" - integrity sha512-EFLgEz6tGHYWdPU0rK8tSscZwx+AsyuBW/r+tNig2kbccHYGUJmZtYN38GjAa3Fda4NU+6wqUO5kTXQSRBQD3g== +"@docusaurus/plugin-content-blog@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.8.1.tgz#88d842b562b04cf59df900d9f6984b086f821525" + integrity sha512-vNTpMmlvNP9n3hGEcgPaXyvTljanAKIUkuG9URQ1DeuDup0OR7Ltvoc8yrmH+iMZJbcQGhUJF+WjHLwuk8HSdw== dependencies: - "@docusaurus/core" "3.7.0" - "@docusaurus/logger" "3.7.0" - "@docusaurus/mdx-loader" "3.7.0" - "@docusaurus/theme-common" "3.7.0" - "@docusaurus/types" "3.7.0" - "@docusaurus/utils" "3.7.0" - "@docusaurus/utils-common" "3.7.0" - "@docusaurus/utils-validation" "3.7.0" + "@docusaurus/core" "3.8.1" + "@docusaurus/logger" "3.8.1" + "@docusaurus/mdx-loader" "3.8.1" + "@docusaurus/theme-common" "3.8.1" + "@docusaurus/types" "3.8.1" + "@docusaurus/utils" "3.8.1" + "@docusaurus/utils-common" "3.8.1" + "@docusaurus/utils-validation" "3.8.1" cheerio "1.0.0-rc.12" feed "^4.2.2" fs-extra "^11.1.1" lodash "^4.17.21" - reading-time "^1.5.0" + schema-dts "^1.1.2" srcset "^4.0.0" tslib "^2.6.0" unist-util-visit "^5.0.0" utility-types "^3.10.0" webpack "^5.88.1" -"@docusaurus/plugin-content-docs@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.7.0.tgz#297a549e926ee2b1147b5242af6f21532c7b107c" - integrity sha512-GXg5V7kC9FZE4FkUZA8oo/NrlRb06UwuICzI6tcbzj0+TVgjq/mpUXXzSgKzMS82YByi4dY2Q808njcBCyy6tQ== +"@docusaurus/plugin-content-docs@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.8.1.tgz#40686a206abb6373bee5638de100a2c312f112a4" + integrity sha512-oByRkSZzeGNQByCMaX+kif5Nl2vmtj2IHQI2fWjCfCootsdKZDPFLonhIp5s3IGJO7PLUfe0POyw0Xh/RrGXJA== dependencies: - "@docusaurus/core" "3.7.0" - "@docusaurus/logger" "3.7.0" - "@docusaurus/mdx-loader" "3.7.0" - "@docusaurus/module-type-aliases" "3.7.0" - "@docusaurus/theme-common" "3.7.0" - "@docusaurus/types" "3.7.0" - "@docusaurus/utils" "3.7.0" - "@docusaurus/utils-common" "3.7.0" - "@docusaurus/utils-validation" "3.7.0" + "@docusaurus/core" "3.8.1" + "@docusaurus/logger" "3.8.1" + "@docusaurus/mdx-loader" "3.8.1" + "@docusaurus/module-type-aliases" "3.8.1" + "@docusaurus/theme-common" "3.8.1" + "@docusaurus/types" "3.8.1" + "@docusaurus/utils" "3.8.1" + "@docusaurus/utils-common" "3.8.1" + "@docusaurus/utils-validation" "3.8.1" "@types/react-router-config" "^5.0.7" combine-promises "^1.1.0" fs-extra "^11.1.1" js-yaml "^4.1.0" lodash "^4.17.21" + schema-dts "^1.1.2" tslib "^2.6.0" utility-types "^3.10.0" webpack "^5.88.1" -"@docusaurus/plugin-content-pages@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.7.0.tgz#c4a8f7237872236aacb77665822c474c0a00e91a" - integrity sha512-YJSU3tjIJf032/Aeao8SZjFOrXJbz/FACMveSMjLyMH4itQyZ2XgUIzt4y+1ISvvk5zrW4DABVT2awTCqBkx0Q== +"@docusaurus/plugin-content-pages@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.8.1.tgz#41b684dbd15390b7bb6a627f78bf81b6324511ac" + integrity sha512-a+V6MS2cIu37E/m7nDJn3dcxpvXb6TvgdNI22vJX8iUTp8eoMoPa0VArEbWvCxMY/xdC26WzNv4wZ6y0iIni/w== dependencies: - "@docusaurus/core" "3.7.0" - "@docusaurus/mdx-loader" "3.7.0" - "@docusaurus/types" "3.7.0" - "@docusaurus/utils" "3.7.0" - "@docusaurus/utils-validation" "3.7.0" + "@docusaurus/core" "3.8.1" + "@docusaurus/mdx-loader" "3.8.1" + "@docusaurus/types" "3.8.1" + "@docusaurus/utils" "3.8.1" + "@docusaurus/utils-validation" "3.8.1" fs-extra "^11.1.1" tslib "^2.6.0" webpack "^5.88.1" -"@docusaurus/plugin-debug@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-debug/-/plugin-debug-3.7.0.tgz#a4fd45132e40cffe96bb51f48e89982a1cb8e194" - integrity sha512-Qgg+IjG/z4svtbCNyTocjIwvNTNEwgRjSXXSJkKVG0oWoH0eX/HAPiu+TS1HBwRPQV+tTYPWLrUypYFepfujZA== +"@docusaurus/plugin-css-cascade-layers@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-css-cascade-layers/-/plugin-css-cascade-layers-3.8.1.tgz#cb414b4a82aa60fc64ef2a435ad0105e142a6c71" + integrity sha512-VQ47xRxfNKjHS5ItzaVXpxeTm7/wJLFMOPo1BkmoMG4Cuz4nuI+Hs62+RMk1OqVog68Swz66xVPK8g9XTrBKRw== dependencies: - "@docusaurus/core" "3.7.0" - "@docusaurus/types" "3.7.0" - "@docusaurus/utils" "3.7.0" + "@docusaurus/core" "3.8.1" + "@docusaurus/types" "3.8.1" + "@docusaurus/utils" "3.8.1" + "@docusaurus/utils-validation" "3.8.1" + tslib "^2.6.0" + +"@docusaurus/plugin-debug@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-debug/-/plugin-debug-3.8.1.tgz#45b107e46b627caaae66995f53197ace78af3491" + integrity sha512-nT3lN7TV5bi5hKMB7FK8gCffFTBSsBsAfV84/v293qAmnHOyg1nr9okEw8AiwcO3bl9vije5nsUvP0aRl2lpaw== + dependencies: + "@docusaurus/core" "3.8.1" + "@docusaurus/types" "3.8.1" + "@docusaurus/utils" "3.8.1" fs-extra "^11.1.1" - react-json-view-lite "^1.2.0" + react-json-view-lite "^2.3.0" tslib "^2.6.0" -"@docusaurus/plugin-google-analytics@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.7.0.tgz#d20f665e810fb2295d1c1bbfe13398c5ff42eb24" - integrity sha512-otIqiRV/jka6Snjf+AqB360XCeSv7lQC+DKYW+EUZf6XbuE8utz5PeUQ8VuOcD8Bk5zvT1MC4JKcd5zPfDuMWA== +"@docusaurus/plugin-google-analytics@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.8.1.tgz#64a302e62fe5cb6e007367c964feeef7b056764a" + integrity sha512-Hrb/PurOJsmwHAsfMDH6oVpahkEGsx7F8CWMjyP/dw1qjqmdS9rcV1nYCGlM8nOtD3Wk/eaThzUB5TSZsGz+7Q== dependencies: - "@docusaurus/core" "3.7.0" - "@docusaurus/types" "3.7.0" - "@docusaurus/utils-validation" "3.7.0" + "@docusaurus/core" "3.8.1" + "@docusaurus/types" "3.8.1" + "@docusaurus/utils-validation" "3.8.1" tslib "^2.6.0" -"@docusaurus/plugin-google-gtag@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.7.0.tgz#a48638dfd132858060458b875a440b6cbda6bf8f" - integrity sha512-M3vrMct1tY65ModbyeDaMoA+fNJTSPe5qmchhAbtqhDD/iALri0g9LrEpIOwNaoLmm6lO88sfBUADQrSRSGSWA== +"@docusaurus/plugin-google-gtag@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.8.1.tgz#8c76f8a1d96448f2f0f7b10e6bde451c40672b95" + integrity sha512-tKE8j1cEZCh8KZa4aa80zpSTxsC2/ZYqjx6AAfd8uA8VHZVw79+7OTEP2PoWi0uL5/1Is0LF5Vwxd+1fz5HlKg== dependencies: - "@docusaurus/core" "3.7.0" - "@docusaurus/types" "3.7.0" - "@docusaurus/utils-validation" "3.7.0" + "@docusaurus/core" "3.8.1" + "@docusaurus/types" "3.8.1" + "@docusaurus/utils-validation" "3.8.1" "@types/gtag.js" "^0.0.12" tslib "^2.6.0" -"@docusaurus/plugin-google-tag-manager@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.7.0.tgz#0a4390f4b0e760d073bdb1905436bfa7bd71356b" - integrity sha512-X8U78nb8eiMiPNg3jb9zDIVuuo/rE1LjGDGu+5m5CX4UBZzjMy+klOY2fNya6x8ACyE/L3K2erO1ErheP55W/w== +"@docusaurus/plugin-google-tag-manager@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.8.1.tgz#88241ffd06369f4a4d5fb982ff3ac2777561ae37" + integrity sha512-iqe3XKITBquZq+6UAXdb1vI0fPY5iIOitVjPQ581R1ZKpHr0qe+V6gVOrrcOHixPDD/BUKdYwkxFjpNiEN+vBw== dependencies: - "@docusaurus/core" "3.7.0" - "@docusaurus/types" "3.7.0" - "@docusaurus/utils-validation" "3.7.0" + "@docusaurus/core" "3.8.1" + "@docusaurus/types" "3.8.1" + "@docusaurus/utils-validation" "3.8.1" tslib "^2.6.0" -"@docusaurus/plugin-sitemap@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.7.0.tgz#2c1bf9de26aeda455df6f77748e5887ace39b2d7" - integrity sha512-bTRT9YLZ/8I/wYWKMQke18+PF9MV8Qub34Sku6aw/vlZ/U+kuEuRpQ8bTcNOjaTSfYsWkK4tTwDMHK2p5S86cA== +"@docusaurus/plugin-sitemap@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.8.1.tgz#3aebd39186dc30e53023f1aab44625bc0bdac892" + integrity sha512-+9YV/7VLbGTq8qNkjiugIelmfUEVkTyLe6X8bWq7K5qPvGXAjno27QAfFq63mYfFFbJc7z+pudL63acprbqGzw== dependencies: - "@docusaurus/core" "3.7.0" - "@docusaurus/logger" "3.7.0" - "@docusaurus/types" "3.7.0" - "@docusaurus/utils" "3.7.0" - "@docusaurus/utils-common" "3.7.0" - "@docusaurus/utils-validation" "3.7.0" + "@docusaurus/core" "3.8.1" + "@docusaurus/logger" "3.8.1" + "@docusaurus/types" "3.8.1" + "@docusaurus/utils" "3.8.1" + "@docusaurus/utils-common" "3.8.1" + "@docusaurus/utils-validation" "3.8.1" fs-extra "^11.1.1" sitemap "^7.1.1" tslib "^2.6.0" -"@docusaurus/plugin-svgr@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-svgr/-/plugin-svgr-3.7.0.tgz#018e89efd615d5fde77b891a8c2aadf203013f5d" - integrity sha512-HByXIZTbc4GV5VAUkZ2DXtXv1Qdlnpk3IpuImwSnEzCDBkUMYcec5282hPjn6skZqB25M1TYCmWS91UbhBGxQg== +"@docusaurus/plugin-svgr@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-svgr/-/plugin-svgr-3.8.1.tgz#6f340be8eae418a2cce540d8ece096ffd9c9b6ab" + integrity sha512-rW0LWMDsdlsgowVwqiMb/7tANDodpy1wWPwCcamvhY7OECReN3feoFwLjd/U4tKjNY3encj0AJSTxJA+Fpe+Gw== dependencies: - "@docusaurus/core" "3.7.0" - "@docusaurus/types" "3.7.0" - "@docusaurus/utils" "3.7.0" - "@docusaurus/utils-validation" "3.7.0" + "@docusaurus/core" "3.8.1" + "@docusaurus/types" "3.8.1" + "@docusaurus/utils" "3.8.1" + "@docusaurus/utils-validation" "3.8.1" "@svgr/core" "8.1.0" "@svgr/webpack" "^8.1.0" tslib "^2.6.0" webpack "^5.88.1" -"@docusaurus/preset-classic@^3.5.2": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-3.7.0.tgz#f6656a04ae6a4877523dbd04f7c491632e4003b9" - integrity sha512-nPHj8AxDLAaQXs+O6+BwILFuhiWbjfQWrdw2tifOClQoNfuXDjfjogee6zfx6NGHWqshR23LrcN115DmkHC91Q== +"@docusaurus/preset-classic@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-3.8.1.tgz#bb79fd12f3211363720c569a526c7e24d3aa966b" + integrity sha512-yJSjYNHXD8POMGc2mKQuj3ApPrN+eG0rO1UPgSx7jySpYU+n4WjBikbrA2ue5ad9A7aouEtMWUoiSRXTH/g7KQ== dependencies: - "@docusaurus/core" "3.7.0" - "@docusaurus/plugin-content-blog" "3.7.0" - "@docusaurus/plugin-content-docs" "3.7.0" - "@docusaurus/plugin-content-pages" "3.7.0" - "@docusaurus/plugin-debug" "3.7.0" - "@docusaurus/plugin-google-analytics" "3.7.0" - "@docusaurus/plugin-google-gtag" "3.7.0" - "@docusaurus/plugin-google-tag-manager" "3.7.0" - "@docusaurus/plugin-sitemap" "3.7.0" - "@docusaurus/plugin-svgr" "3.7.0" - "@docusaurus/theme-classic" "3.7.0" - "@docusaurus/theme-common" "3.7.0" - "@docusaurus/theme-search-algolia" "3.7.0" - "@docusaurus/types" "3.7.0" + "@docusaurus/core" "3.8.1" + "@docusaurus/plugin-content-blog" "3.8.1" + "@docusaurus/plugin-content-docs" "3.8.1" + "@docusaurus/plugin-content-pages" "3.8.1" + "@docusaurus/plugin-css-cascade-layers" "3.8.1" + "@docusaurus/plugin-debug" "3.8.1" + "@docusaurus/plugin-google-analytics" "3.8.1" + "@docusaurus/plugin-google-gtag" "3.8.1" + "@docusaurus/plugin-google-tag-manager" "3.8.1" + "@docusaurus/plugin-sitemap" "3.8.1" + "@docusaurus/plugin-svgr" "3.8.1" + "@docusaurus/theme-classic" "3.8.1" + "@docusaurus/theme-common" "3.8.1" + "@docusaurus/theme-search-algolia" "3.8.1" + "@docusaurus/types" "3.8.1" -"@docusaurus/theme-classic@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-3.7.0.tgz#b483bd8e2923b6994b5f47238884b9f8984222c5" - integrity sha512-MnLxG39WcvLCl4eUzHr0gNcpHQfWoGqzADCly54aqCofQX6UozOS9Th4RK3ARbM9m7zIRv3qbhggI53dQtx/hQ== +"@docusaurus/theme-classic@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-3.8.1.tgz#1e45c66d89ded359225fcd29bf3258d9205765c1" + integrity sha512-bqDUCNqXeYypMCsE1VcTXSI1QuO4KXfx8Cvl6rYfY0bhhqN6d2WZlRkyLg/p6pm+DzvanqHOyYlqdPyP0iz+iw== dependencies: - "@docusaurus/core" "3.7.0" - "@docusaurus/logger" "3.7.0" - "@docusaurus/mdx-loader" "3.7.0" - "@docusaurus/module-type-aliases" "3.7.0" - "@docusaurus/plugin-content-blog" "3.7.0" - "@docusaurus/plugin-content-docs" "3.7.0" - "@docusaurus/plugin-content-pages" "3.7.0" - "@docusaurus/theme-common" "3.7.0" - "@docusaurus/theme-translations" "3.7.0" - "@docusaurus/types" "3.7.0" - "@docusaurus/utils" "3.7.0" - "@docusaurus/utils-common" "3.7.0" - "@docusaurus/utils-validation" "3.7.0" + "@docusaurus/core" "3.8.1" + "@docusaurus/logger" "3.8.1" + "@docusaurus/mdx-loader" "3.8.1" + "@docusaurus/module-type-aliases" "3.8.1" + "@docusaurus/plugin-content-blog" "3.8.1" + "@docusaurus/plugin-content-docs" "3.8.1" + "@docusaurus/plugin-content-pages" "3.8.1" + "@docusaurus/theme-common" "3.8.1" + "@docusaurus/theme-translations" "3.8.1" + "@docusaurus/types" "3.8.1" + "@docusaurus/utils" "3.8.1" + "@docusaurus/utils-common" "3.8.1" + "@docusaurus/utils-validation" "3.8.1" "@mdx-js/react" "^3.0.0" clsx "^2.0.0" copy-text-to-clipboard "^3.2.0" infima "0.2.0-alpha.45" lodash "^4.17.21" nprogress "^0.2.0" - postcss "^8.4.26" + postcss "^8.5.4" prism-react-renderer "^2.3.0" prismjs "^1.29.0" react-router-dom "^5.3.4" @@ -1739,15 +1785,15 @@ tslib "^2.6.0" utility-types "^3.10.0" -"@docusaurus/theme-common@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-3.7.0.tgz#18bf5c6b149a701f4bd865715ee8b595aa40b354" - integrity sha512-8eJ5X0y+gWDsURZnBfH0WabdNm8XMCXHv8ENy/3Z/oQKwaB/EHt5lP9VsTDTf36lKEp0V6DjzjFyFIB+CetL0A== +"@docusaurus/theme-common@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-3.8.1.tgz#17c23316fbe3ee3f7e707c7298cb59a0fff38b4b" + integrity sha512-UswMOyTnPEVRvN5Qzbo+l8k4xrd5fTFu2VPPfD6FcW/6qUtVLmJTQCktbAL3KJ0BVXGm5aJXz/ZrzqFuZERGPw== dependencies: - "@docusaurus/mdx-loader" "3.7.0" - "@docusaurus/module-type-aliases" "3.7.0" - "@docusaurus/utils" "3.7.0" - "@docusaurus/utils-common" "3.7.0" + "@docusaurus/mdx-loader" "3.8.1" + "@docusaurus/module-type-aliases" "3.8.1" + "@docusaurus/utils" "3.8.1" + "@docusaurus/utils-common" "3.8.1" "@types/history" "^4.7.11" "@types/react" "*" "@types/react-router-config" "*" @@ -1757,19 +1803,19 @@ tslib "^2.6.0" utility-types "^3.10.0" -"@docusaurus/theme-search-algolia@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.7.0.tgz#2108ddf0b300b82de7c2b9ff9fcf62121b66ea37" - integrity sha512-Al/j5OdzwRU1m3falm+sYy9AaB93S1XF1Lgk9Yc6amp80dNxJVplQdQTR4cYdzkGtuQqbzUA8+kaoYYO0RbK6g== +"@docusaurus/theme-search-algolia@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.8.1.tgz#3aa3d99c35cc2d4b709fcddd4df875a9b536e29b" + integrity sha512-NBFH5rZVQRAQM087aYSRKQ9yGEK9eHd+xOxQjqNpxMiV85OhJDD4ZGz6YJIod26Fbooy54UWVdzNU0TFeUUUzQ== dependencies: - "@docsearch/react" "^3.8.1" - "@docusaurus/core" "3.7.0" - "@docusaurus/logger" "3.7.0" - "@docusaurus/plugin-content-docs" "3.7.0" - "@docusaurus/theme-common" "3.7.0" - "@docusaurus/theme-translations" "3.7.0" - "@docusaurus/utils" "3.7.0" - "@docusaurus/utils-validation" "3.7.0" + "@docsearch/react" "^3.9.0" + "@docusaurus/core" "3.8.1" + "@docusaurus/logger" "3.8.1" + "@docusaurus/plugin-content-docs" "3.8.1" + "@docusaurus/theme-common" "3.8.1" + "@docusaurus/theme-translations" "3.8.1" + "@docusaurus/utils" "3.8.1" + "@docusaurus/utils-validation" "3.8.1" algoliasearch "^5.17.1" algoliasearch-helper "^3.22.6" clsx "^2.0.0" @@ -1779,23 +1825,23 @@ tslib "^2.6.0" utility-types "^3.10.0" -"@docusaurus/theme-translations@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-translations/-/theme-translations-3.7.0.tgz#0891aedc7c7040afcb3a1b34051d3a69096d0d25" - integrity sha512-Ewq3bEraWDmienM6eaNK7fx+/lHMtGDHQyd1O+4+3EsDxxUmrzPkV7Ct3nBWTuE0MsoZr3yNwQVKjllzCMuU3g== +"@docusaurus/theme-translations@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-translations/-/theme-translations-3.8.1.tgz#4b1d76973eb53861e167c7723485e059ba4ffd0a" + integrity sha512-OTp6eebuMcf2rJt4bqnvuwmm3NVXfzfYejL+u/Y1qwKhZPrjPoKWfk1CbOP5xH5ZOPkiAsx4dHdQBRJszK3z2g== dependencies: fs-extra "^11.1.1" tslib "^2.6.0" -"@docusaurus/tsconfig@^3.5.2": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/tsconfig/-/tsconfig-3.7.0.tgz#654dcc524e25b8809af0f1b0b42485c18c047ab5" - integrity sha512-vRsyj3yUZCjscgfgcFYjIsTcAru/4h4YH2/XAE8Rs7wWdnng98PgWKvP5ovVc4rmRpRg2WChVW0uOy2xHDvDBQ== +"@docusaurus/tsconfig@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/tsconfig/-/tsconfig-3.8.1.tgz#a1f7daadfc93455289200647f4ee10cdca540f7b" + integrity sha512-XBWCcqhRHhkhfolnSolNL+N7gj3HVE3CoZVqnVjfsMzCoOsuQw2iCLxVVHtO+rePUUfouVZHURDgmqIySsF66A== -"@docusaurus/types@3.7.0", "@docusaurus/types@^3.5.2": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/types/-/types-3.7.0.tgz#3f5a68a60f80ecdcb085666da1d68f019afda943" - integrity sha512-kOmZg5RRqJfH31m+6ZpnwVbkqMJrPOG5t0IOl4i/+3ruXyNfWzZ0lVtVrD0u4ONc/0NOsS9sWYaxxWNkH1LdLQ== +"@docusaurus/types@3.8.1", "@docusaurus/types@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/types/-/types-3.8.1.tgz#83ab66c345464e003b576a49f78897482061fc26" + integrity sha512-ZPdW5AB+pBjiVrcLuw3dOS6BFlrG0XkS2lDGsj8TizcnREQg3J8cjsgfDviszOk4CweNfwo1AEELJkYaMUuOPg== dependencies: "@mdx-js/mdx" "^3.0.0" "@types/history" "^4.7.11" @@ -1807,37 +1853,38 @@ webpack "^5.95.0" webpack-merge "^5.9.0" -"@docusaurus/utils-common@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/utils-common/-/utils-common-3.7.0.tgz#1bef52837d321db5dd2361fc07f3416193b5d029" - integrity sha512-IZeyIfCfXy0Mevj6bWNg7DG7B8G+S6o6JVpddikZtWyxJguiQ7JYr0SIZ0qWd8pGNuMyVwriWmbWqMnK7Y5PwA== +"@docusaurus/utils-common@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/utils-common/-/utils-common-3.8.1.tgz#c369b8c3041afb7dcd595d4172beb1cc1015c85f" + integrity sha512-zTZiDlvpvoJIrQEEd71c154DkcriBecm4z94OzEE9kz7ikS3J+iSlABhFXM45mZ0eN5pVqqr7cs60+ZlYLewtg== dependencies: - "@docusaurus/types" "3.7.0" + "@docusaurus/types" "3.8.1" tslib "^2.6.0" -"@docusaurus/utils-validation@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-3.7.0.tgz#dc0786fb633ae5cef8e93337bf21c2a826c7ecbd" - integrity sha512-w8eiKk8mRdN+bNfeZqC4nyFoxNyI1/VExMKAzD9tqpJfLLbsa46Wfn5wcKH761g9WkKh36RtFV49iL9lh1DYBA== +"@docusaurus/utils-validation@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-3.8.1.tgz#0499c0d151a4098a0963237057993282cfbd538e" + integrity sha512-gs5bXIccxzEbyVecvxg6upTwaUbfa0KMmTj7HhHzc016AGyxH2o73k1/aOD0IFrdCsfJNt37MqNI47s2MgRZMA== dependencies: - "@docusaurus/logger" "3.7.0" - "@docusaurus/utils" "3.7.0" - "@docusaurus/utils-common" "3.7.0" + "@docusaurus/logger" "3.8.1" + "@docusaurus/utils" "3.8.1" + "@docusaurus/utils-common" "3.8.1" fs-extra "^11.2.0" joi "^17.9.2" js-yaml "^4.1.0" lodash "^4.17.21" tslib "^2.6.0" -"@docusaurus/utils@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-3.7.0.tgz#dfdebd63524c52b498f36b2907a3b2261930b9bb" - integrity sha512-e7zcB6TPnVzyUaHMJyLSArKa2AG3h9+4CfvKXKKWNx6hRs+p0a+u7HHTJBgo6KW2m+vqDnuIHK4X+bhmoghAFA== +"@docusaurus/utils@3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-3.8.1.tgz#2ac1e734106e2f73dbd0f6a8824d525f9064e9f0" + integrity sha512-P1ml0nvOmEFdmu0smSXOqTS1sxU5tqvnc0dA4MTKV39kye+bhQnjkIKEE18fNOvxjyB86k8esoCIFM3x4RykOQ== dependencies: - "@docusaurus/logger" "3.7.0" - "@docusaurus/types" "3.7.0" - "@docusaurus/utils-common" "3.7.0" + "@docusaurus/logger" "3.8.1" + "@docusaurus/types" "3.8.1" + "@docusaurus/utils-common" "3.8.1" escape-string-regexp "^4.0.0" + execa "5.1.1" file-loader "^6.2.0" fs-extra "^11.1.1" github-slugger "^1.5.0" @@ -1847,9 +1894,9 @@ js-yaml "^4.1.0" lodash "^4.17.21" micromatch "^4.0.5" + p-queue "^6.6.2" prompts "^2.4.2" resolve-pathname "^3.0.0" - shelljs "^0.8.5" tslib "^2.6.0" url-loader "^4.1.1" utility-types "^3.10.0" @@ -1886,13 +1933,12 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" -"@jridgewell/gen-mapping@^0.3.5": - version "0.3.8" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz#4f0e06362e01362f823d348f1872b08f666d8142" - integrity sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA== +"@jridgewell/gen-mapping@^0.3.12", "@jridgewell/gen-mapping@^0.3.5": + version "0.3.12" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz#2234ce26c62889f03db3d7fea43c1932ab3e927b" + integrity sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg== dependencies: - "@jridgewell/set-array" "^1.2.1" - "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/sourcemap-codec" "^1.5.0" "@jridgewell/trace-mapping" "^0.3.24" "@jridgewell/resolve-uri@^3.1.0": @@ -1900,28 +1946,23 @@ resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== -"@jridgewell/set-array@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" - integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== - "@jridgewell/source-map@^0.3.3": - version "0.3.6" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.6.tgz#9d71ca886e32502eb9362c9a74a46787c36df81a" - integrity sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ== + version "0.3.10" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.10.tgz#a35714446a2e84503ff9bfe66f1d1d4846f2075b" + integrity sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q== dependencies: "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" - integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== +"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.4" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz#7358043433b2e5da569aa02cbc4c121da3af27d7" + integrity sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw== -"@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": - version "0.3.25" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" - integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== +"@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.28": + version "0.3.29" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz#a58d31eaadaf92c6695680b2e1d464a9b8fbf7fc" + integrity sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ== dependencies: "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" @@ -1961,7 +2002,7 @@ unist-util-visit "^5.0.0" vfile "^6.0.0" -"@mdx-js/react@^3.0.0", "@mdx-js/react@^3.0.1": +"@mdx-js/react@^3.0.0", "@mdx-js/react@^3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-3.1.0.tgz#c4522e335b3897b9a845db1dbdd2f966ae8fb0ed" integrity sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ== @@ -2011,9 +2052,9 @@ config-chain "^1.1.11" "@polka/url@^1.0.0-next.24": - version "1.0.0-next.28" - resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.28.tgz#d45e01c4a56f143ee69c54dd6b12eade9e270a73" - integrity sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw== + version "1.0.0-next.29" + resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.29.tgz#5a40109a1ab5f84d6fd8fc928b19f367cbe7e7b1" + integrity sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww== "@sideway/address@^4.1.5": version "4.1.5" @@ -2174,17 +2215,10 @@ resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== -"@types/acorn@^4.0.0": - version "4.0.6" - resolved "https://registry.yarnpkg.com/@types/acorn/-/acorn-4.0.6.tgz#d61ca5480300ac41a7d973dd5b84d0a591154a22" - integrity sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ== - dependencies: - "@types/estree" "*" - "@types/body-parser@*": - version "1.19.5" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" - integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== + version "1.19.6" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.6.tgz#1859bebb8fd7dac9918a45d54c1971ab8b5af474" + integrity sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g== dependencies: "@types/connect" "*" "@types/node" "*" @@ -2241,15 +2275,15 @@ dependencies: "@types/estree" "*" -"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.6": - version "1.0.6" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" - integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== +"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.8": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" + integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== "@types/express-serve-static-core@*", "@types/express-serve-static-core@^5.0.0": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz#41fec4ea20e9c7b22f024ab88a95c6bb288f51b8" - integrity sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA== + version "5.0.7" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.0.7.tgz#2fa94879c9d46b11a5df4c74ac75befd6b283de6" + integrity sha512-R+33OsgWw7rOhD1emjU7dzCDHucJrgJXMA5PYCzJxVil0dsyx5iBEPHqpPfiKNJQb7lZ1vxwoLR4Z87bBUpeGQ== dependencies: "@types/node" "*" "@types/qs" "*" @@ -2267,18 +2301,18 @@ "@types/send" "*" "@types/express@*": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@types/express/-/express-5.0.1.tgz#138d741c6e5db8cc273bec5285cd6e9d0779fc9f" - integrity sha512-UZUw8vjpWFXuDnjFTh7/5c2TWDlQqeXHi6hcN7F2XSVT5P+WmUnnbFS3KA6Jnc6IsEqI2qCVu2bK0R0J4A8ZQQ== + version "5.0.3" + resolved "https://registry.yarnpkg.com/@types/express/-/express-5.0.3.tgz#6c4bc6acddc2e2a587142e1d8be0bce20757e956" + integrity sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw== dependencies: "@types/body-parser" "*" "@types/express-serve-static-core" "^5.0.0" "@types/serve-static" "*" "@types/express@^4.17.13": - version "4.17.21" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" - integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== + version "4.17.23" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.23.tgz#35af3193c640bfd4d7fe77191cd0ed411a433bef" + integrity sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ== dependencies: "@types/body-parser" "*" "@types/express-serve-static-core" "^4.17.33" @@ -2313,9 +2347,9 @@ integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== "@types/http-errors@*": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" - integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== + version "2.0.5" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.5.tgz#5b749ab2b16ba113423feb1a64a95dcd30398472" + integrity sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg== "@types/http-proxy@^1.17.8": version "1.17.16" @@ -2343,7 +2377,7 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -2371,38 +2405,33 @@ integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA== "@types/node-forge@^1.3.0": - version "1.3.11" - resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.11.tgz#0972ea538ddb0f4d9c2fa0ec5db5724773a604da" - integrity sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ== + version "1.3.13" + resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.13.tgz#1797af20f7eccaf5f37b4d1739923bb0519d95b6" + integrity sha512-zePQJSW5QkwSHKRApqWCVKeKoSOt4xvEnLENZPjyvm9Ezdf/EyDeJM7jqLzOwjVICQQzvLZ63T55MKdJB5H6ww== dependencies: "@types/node" "*" "@types/node@*": - version "22.13.11" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.13.11.tgz#f0ed6b302dcf0f4229d44ea707e77484ad46d234" - integrity sha512-iEUCUJoU0i3VnrCmgoWCXttklWcvoCIx4jzcP22fioIVSdTmjgoEvmAO/QPw6TcS9k5FrNgn4w7q5lGOd1CT5g== + version "24.2.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-24.2.1.tgz#83e41543f0a518e006594bb394e2cd961de56727" + integrity sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ== dependencies: - undici-types "~6.20.0" + undici-types "~7.10.0" "@types/node@^17.0.5": version "17.0.45" resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190" integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw== -"@types/parse-json@^4.0.0": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" - integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== - "@types/prismjs@^1.26.0": version "1.26.5" resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.5.tgz#72499abbb4c4ec9982446509d2f14fb8483869d6" integrity sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ== "@types/qs@*": - version "6.9.18" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.18.tgz#877292caa91f7c1b213032b34626505b746624c2" - integrity sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA== + version "6.14.0" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.14.0.tgz#d8b60cecf62f2db0fb68e5e006077b9178b85de5" + integrity sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ== "@types/range-parser@*": version "1.2.7" @@ -2436,9 +2465,9 @@ "@types/react" "*" "@types/react@*": - version "19.0.12" - resolved "https://registry.yarnpkg.com/@types/react/-/react-19.0.12.tgz#338b3f7854adbb784be454b3a83053127af96bd3" - integrity sha512-V6Ar115dBDrjbtXSrS+/Oruobc+qVbbUxDFC1RSbRqLt5SYvxxyIDrSC85RWml54g+jfNeEMZhEj7wW07ONQhA== + version "19.1.9" + resolved "https://registry.yarnpkg.com/@types/react/-/react-19.1.9.tgz#f42b24f35474566a39b5c3a98e4d0c425b79a849" + integrity sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA== dependencies: csstype "^3.0.2" @@ -2455,9 +2484,9 @@ "@types/node" "*" "@types/send@*": - version "0.17.4" - resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" - integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== + version "0.17.5" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.5.tgz#d991d4f2b16f2b1ef497131f00a9114290791e74" + integrity sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w== dependencies: "@types/mime" "^1" "@types/node" "*" @@ -2470,9 +2499,9 @@ "@types/express" "*" "@types/serve-static@*", "@types/serve-static@^1.13.10": - version "1.15.7" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.7.tgz#22174bbd74fb97fe303109738e9b5c2f3064f714" - integrity sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw== + version "1.15.8" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.8.tgz#8180c3fbe4a70e8f00b9f70b9ba7f08f35987877" + integrity sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg== dependencies: "@types/http-errors" "*" "@types/node" "*" @@ -2496,9 +2525,9 @@ integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA== "@types/ws@^8.5.5": - version "8.18.0" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.0.tgz#8a2ec491d6f0685ceaab9a9b7ff44146236993b5" - integrity sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw== + version "8.18.1" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9" + integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg== dependencies: "@types/node" "*" @@ -2658,6 +2687,11 @@ accepts@~1.3.4, accepts@~1.3.8: mime-types "~2.1.34" negotiator "0.6.3" +acorn-import-phases@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz#16eb850ba99a056cb7cbfe872ffb8972e18c8bd7" + integrity sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ== + acorn-jsx@^5.0.0: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" @@ -2670,12 +2704,12 @@ acorn-walk@^8.0.0: dependencies: acorn "^8.11.0" -acorn@^8.0.0, acorn@^8.0.4, acorn@^8.11.0, acorn@^8.14.0, acorn@^8.8.2: - version "8.14.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb" - integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg== +acorn@^8.0.0, acorn@^8.0.4, acorn@^8.11.0, acorn@^8.14.0, acorn@^8.15.0: + version "8.15.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" + integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== -address@^1.0.1, address@^1.1.2: +address@^1.0.1: version "1.2.2" resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== @@ -2695,7 +2729,7 @@ ajv-formats@^2.1.1: dependencies: ajv "^8.0.0" -ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: +ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== @@ -2707,7 +2741,7 @@ ajv-keywords@^5.1.0: dependencies: fast-deep-equal "^3.1.3" -ajv@^6.12.2, ajv@^6.12.5: +ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -2728,30 +2762,31 @@ ajv@^8.0.0, ajv@^8.9.0: require-from-string "^2.0.2" algoliasearch-helper@^3.22.6: - version "3.24.2" - resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.24.2.tgz#332f9813b63442b13b8eaae19f313fe3db1047af" - integrity sha512-vBw/INZDfyh/THbVeDy8On8lZqd2qiUAHde5N4N1ygL4SoeLqLGJ4GHneHrDAYsjikRwTTtodEP0fiXl5MxHFQ== + version "3.26.0" + resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.26.0.tgz#d6e283396a9fc5bf944f365dc3b712570314363f" + integrity sha512-Rv2x3GXleQ3ygwhkhJubhhYGsICmShLAiqtUuJTUkr9uOCOXyF2E71LVT4XDnVffbknv8XgScP4U0Oxtgm+hIw== dependencies: "@algolia/events" "^4.0.1" algoliasearch@^5.14.2, algoliasearch@^5.17.1: - version "5.21.0" - resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-5.21.0.tgz#0517971eba0c03efda8586213294a554db2d3ac9" - integrity sha512-hexLq2lSO1K5SW9j21Ubc+q9Ptx7dyRTY7se19U8lhIlVMLCNXWCyQ6C22p9ez8ccX0v7QVmwkl2l1CnuGoO2Q== + version "5.35.0" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-5.35.0.tgz#ce12d1d287d6f4a80b9998568f806c92dabba566" + integrity sha512-Y+moNhsqgLmvJdgTsO4GZNgsaDWv8AOGAaPeIeHKlDn/XunoAqYbA+XNpBd1dW8GOXAUDyxC9Rxc7AV4kpFcIg== dependencies: - "@algolia/client-abtesting" "5.21.0" - "@algolia/client-analytics" "5.21.0" - "@algolia/client-common" "5.21.0" - "@algolia/client-insights" "5.21.0" - "@algolia/client-personalization" "5.21.0" - "@algolia/client-query-suggestions" "5.21.0" - "@algolia/client-search" "5.21.0" - "@algolia/ingestion" "1.21.0" - "@algolia/monitoring" "1.21.0" - "@algolia/recommend" "5.21.0" - "@algolia/requester-browser-xhr" "5.21.0" - "@algolia/requester-fetch" "5.21.0" - "@algolia/requester-node-http" "5.21.0" + "@algolia/abtesting" "1.1.0" + "@algolia/client-abtesting" "5.35.0" + "@algolia/client-analytics" "5.35.0" + "@algolia/client-common" "5.35.0" + "@algolia/client-insights" "5.35.0" + "@algolia/client-personalization" "5.35.0" + "@algolia/client-query-suggestions" "5.35.0" + "@algolia/client-search" "5.35.0" + "@algolia/ingestion" "1.35.0" + "@algolia/monitoring" "1.35.0" + "@algolia/recommend" "5.35.0" + "@algolia/requester-browser-xhr" "5.35.0" + "@algolia/requester-fetch" "5.35.0" + "@algolia/requester-node-http" "5.35.0" ansi-align@^3.0.1: version "3.0.1" @@ -2834,12 +2869,7 @@ astring@^1.8.0: resolved "https://registry.yarnpkg.com/astring/-/astring-1.9.0.tgz#cc73e6062a7eb03e7d19c22d8b0b3451fd9bfeef" integrity sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg== -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== - -autoprefixer@^10.4.19: +autoprefixer@^10.4.19, autoprefixer@^10.4.21: version "10.4.21" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.21.tgz#77189468e7a8ad1d9a37fbc08efc9f480cf0a95d" integrity sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ== @@ -2866,29 +2896,29 @@ babel-plugin-dynamic-import-node@^2.3.3: dependencies: object.assign "^4.1.0" -babel-plugin-polyfill-corejs2@^0.4.10: - version "0.4.13" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.13.tgz#7d445f0e0607ebc8fb6b01d7e8fb02069b91dd8b" - integrity sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g== +babel-plugin-polyfill-corejs2@^0.4.14: + version "0.4.14" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz#8101b82b769c568835611542488d463395c2ef8f" + integrity sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg== dependencies: - "@babel/compat-data" "^7.22.6" - "@babel/helper-define-polyfill-provider" "^0.6.4" + "@babel/compat-data" "^7.27.7" + "@babel/helper-define-polyfill-provider" "^0.6.5" semver "^6.3.1" -babel-plugin-polyfill-corejs3@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz#4e4e182f1bb37c7ba62e2af81d8dd09df31344f6" - integrity sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ== +babel-plugin-polyfill-corejs3@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz#bb7f6aeef7addff17f7602a08a6d19a128c30164" + integrity sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A== dependencies: - "@babel/helper-define-polyfill-provider" "^0.6.3" - core-js-compat "^3.40.0" + "@babel/helper-define-polyfill-provider" "^0.6.5" + core-js-compat "^3.43.0" -babel-plugin-polyfill-regenerator@^0.6.1: - version "0.6.4" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.4.tgz#428c615d3c177292a22b4f93ed99e358d7906a9b" - integrity sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw== +babel-plugin-polyfill-regenerator@^0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz#32752e38ab6f6767b92650347bf26a31b16ae8c5" + integrity sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg== dependencies: - "@babel/helper-define-polyfill-provider" "^0.6.4" + "@babel/helper-define-polyfill-provider" "^0.6.5" bail@^2.0.0: version "2.0.2" @@ -2975,9 +3005,9 @@ boxen@^7.0.0: wrap-ansi "^8.1.0" brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + version "1.1.12" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843" + integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" @@ -2989,15 +3019,15 @@ braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" -browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.24.4: - version "4.24.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.4.tgz#c6b2865a3f08bcb860a0e827389003b9fe686e4b" - integrity sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A== +browserslist@^4.0.0, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.24.4, browserslist@^4.25.0, browserslist@^4.25.1: + version "4.25.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.2.tgz#90c1507143742d743544ae6e92bca3348adff667" + integrity sha512-0si2SJK3ooGzIawRu61ZdPCO1IncZwS8IzuX73sPZsXW6EQ/w/DAfPyKI8l1ETTCr2MnvqWitmlCUxgdul45jA== dependencies: - caniuse-lite "^1.0.30001688" - electron-to-chromium "^1.5.73" + caniuse-lite "^1.0.30001733" + electron-to-chromium "^1.5.199" node-releases "^2.0.19" - update-browserslist-db "^1.1.1" + update-browserslist-db "^1.1.3" buffer-from@^1.0.0: version "1.1.2" @@ -3091,17 +3121,17 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001688, caniuse-lite@^1.0.30001702: - version "1.0.30001707" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001707.tgz#c5e104d199e6f4355a898fcd995a066c7eb9bf41" - integrity sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001702, caniuse-lite@^1.0.30001733: + version "1.0.30001733" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001733.tgz#918405ed6647a62840fb328832cf5a03f986974b" + integrity sha512-e4QKw/O2Kavj2VQTKZWrwzkt3IxOmIlU6ajRb6LP64LHpBo1J67k2Hi4Vu/TgJWsNtynurfS0uK3MaUTCPfu5Q== ccount@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: +chalk@^4.0.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -3110,9 +3140,9 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: supports-color "^7.1.0" chalk@^5.0.1, chalk@^5.2.0: - version "5.4.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.4.1.tgz#1b48bf0963ec158dce2aacf69c093ae2dd2092d8" - integrity sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w== + version "5.5.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.5.0.tgz#67ada1df5ca809dc84c9b819d76418ddcf128428" + integrity sha512-1tm8DTaJhPBG3bIkVeZt1iZM9GfSX2lzOeDVZH9R9ffRHpmHvxZ/QhgQH/aDTkswQVt+YHdXAdS/In/30OjCbg== char-regex@^1.0.2: version "1.0.2" @@ -3164,7 +3194,7 @@ cheerio@1.0.0-rc.12: parse5 "^7.0.0" parse5-htmlparser2-tree-adapter "^7.0.0" -chokidar@^3.4.2, chokidar@^3.5.3: +chokidar@^3.5.3: version "3.6.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== @@ -3189,7 +3219,7 @@ ci-info@^3.2.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== -clean-css@^5.2.2, clean-css@^5.3.2, clean-css@~5.3.2: +clean-css@^5.2.2, clean-css@^5.3.3, clean-css@~5.3.2: version "5.3.3" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.3.tgz#b330653cd3bd6b75009cc25c714cae7b93351ccd" integrity sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg== @@ -3304,15 +3334,15 @@ compressible@~2.0.18: mime-db ">= 1.43.0 < 2" compression@^1.7.4: - version "1.8.0" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.8.0.tgz#09420efc96e11a0f44f3a558de59e321364180f7" - integrity sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA== + version "1.8.1" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.8.1.tgz#4a45d909ac16509195a9a28bd91094889c180d79" + integrity sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w== dependencies: bytes "3.1.2" compressible "~2.0.18" debug "2.6.9" negotiator "~0.6.4" - on-headers "~1.0.2" + on-headers "~1.1.0" safe-buffer "5.2.1" vary "~1.1.2" @@ -3399,39 +3429,28 @@ copy-webpack-plugin@^11.0.0: schema-utils "^4.0.0" serialize-javascript "^6.0.0" -core-js-compat@^3.40.0: - version "3.41.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.41.0.tgz#4cdfce95f39a8f27759b667cf693d96e5dda3d17" - integrity sha512-RFsU9LySVue9RTwdDVX/T0e2Y6jRYWXERKElIjpuEOEnxaXffI0X7RUwVzfYLfzuLXSNJDYoRYUAmRUcyln20A== +core-js-compat@^3.43.0: + version "3.45.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.45.0.tgz#bc0017525dcb7a42ba3241d02f6fce9bae8e5c33" + integrity sha512-gRoVMBawZg0OnxaVv3zpqLLxaHmsubEGyTnqdpI/CEBvX4JadI1dMSHxagThprYRtSVbuQxvi6iUatdPxohHpA== dependencies: - browserslist "^4.24.4" + browserslist "^4.25.1" -core-js-pure@^3.30.2: - version "3.41.0" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.41.0.tgz#349fecad168d60807a31e83c99d73d786fe80811" - integrity sha512-71Gzp96T9YPk63aUvE5Q5qP+DryB4ZloUZPSOebGM88VNw8VNfvdA7z6kGA8iGOTEzAomsRidp4jXSmUIJsL+Q== +core-js-pure@^3.43.0: + version "3.45.0" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.45.0.tgz#c753b80daf1bf732e56bf0b8cbd62797c0c1f235" + integrity sha512-OtwjqcDpY2X/eIIg1ol/n0y/X8A9foliaNt1dSK0gV3J2/zw+89FcNG3mPK+N8YWts4ZFUPxnrAzsxs/lf8yDA== core-js@^3.31.1: - version "3.41.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.41.0.tgz#57714dafb8c751a6095d028a7428f1fb5834a776" - integrity sha512-SJ4/EHwS36QMJd6h/Rg+GyR4A5xE0FSI3eZ+iBVpfqf1x0eTSg1smWLHrA+2jQThZSh97fmSgFSU8B61nxosxA== + version "3.45.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.45.0.tgz#556c2af44a2d9c73ea7b49504392474a9f7c947e" + integrity sha512-c2KZL9lP4DjkN3hk/an4pWn5b5ZefhRJnAc42n6LJ19kSnbeRbdQZE5dSeE2LBol1OwJD3X1BQvFTAsa8ReeDA== core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -cosmiconfig@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" - integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.1.0" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.7.2" - cosmiconfig@^8.1.3, cosmiconfig@^8.3.5: version "8.3.6" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" @@ -3479,7 +3498,7 @@ css-has-pseudo@^7.0.2: postcss-selector-parser "^7.0.0" postcss-value-parser "^4.2.0" -css-loader@^6.8.1: +css-loader@^6.11.0: version "6.11.0" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.11.0.tgz#33bae3bf6363d0a7c2cf9031c96c744ff54d85ba" integrity sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g== @@ -3522,9 +3541,9 @@ css-select@^4.1.3: nth-check "^2.0.1" css-select@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" - integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + version "5.2.2" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.2.2.tgz#01b6e8d163637bb2dd6c982ca4ed65863682786e" + integrity sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw== dependencies: boolbase "^1.0.0" css-what "^6.1.0" @@ -3549,14 +3568,14 @@ css-tree@~2.2.0: source-map-js "^1.0.1" css-what@^6.0.1, css-what@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" - integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + version "6.2.2" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.2.2.tgz#cdcc8f9b6977719fdfbd1de7aec24abf756b9dea" + integrity sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA== -cssdb@^8.2.3: - version "8.2.4" - resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-8.2.4.tgz#f806c6cdca76dbaaf76e0c3bd3c4b50528186633" - integrity sha512-3KSCVkjZJe/QxicVXnbyYSY26WsFc1YoMY7jep1ZKWMEVc7jEm6V2Xq2r+MX8WKQIuB7ofGbnr5iVI+aZpoSzg== +cssdb@^8.3.0: + version "8.3.1" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-8.3.1.tgz#0ac96395b7092ffee14563e948cf43c2019b051e" + integrity sha512-XnDRQMXucLueX92yDe0LPKupXetWoFOgawr4O4X41l5TltgK2NVbJJVDnnOywDYfW1sTJ28AcXGKOqdRKwCcmQ== cssesc@^3.0.0: version "3.0.0" @@ -3642,24 +3661,24 @@ debounce@^1.2.1: resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== -debug@2.6.9, debug@^2.6.0: +debug@2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: - version "4.4.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" - integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== +debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.3.1, debug@^4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" + integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== dependencies: ms "^2.1.3" decode-named-character-reference@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz#5d6ce68792808901210dac42a8e9853511e2b8bf" - integrity sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w== + version "1.2.0" + resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz#25c32ae6dd5e21889549d40f676030e9514cc0ed" + integrity sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q== dependencies: character-entities "^2.0.0" @@ -3675,7 +3694,7 @@ deep-extend@^0.6.0: resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== -deepmerge@^4.2.2, deepmerge@^4.3.1: +deepmerge@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== @@ -3715,20 +3734,6 @@ define-properties@^1.2.1: has-property-descriptors "^1.0.0" object-keys "^1.1.1" -del@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/del/-/del-6.1.1.tgz#3b70314f1ec0aa325c6b14eb36b95786671edb7a" - integrity sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg== - dependencies: - globby "^11.0.1" - graceful-fs "^4.2.4" - is-glob "^4.0.1" - is-path-cwd "^2.2.0" - is-path-inside "^3.0.2" - p-map "^4.0.0" - rimraf "^3.0.2" - slash "^3.0.0" - depd@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" @@ -3754,14 +3759,6 @@ detect-node@^2.0.4: resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== -detect-port-alt@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275" - integrity sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q== - dependencies: - address "^1.0.1" - debug "^2.6.0" - detect-port@^1.5.1: version "1.6.1" resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.6.1.tgz#45e4073997c5f292b957cb678fb0bb8ed4250a67" @@ -3868,10 +3865,10 @@ dot-prop@^6.0.1: dependencies: is-obj "^2.0.0" -dotenv@^16.4.5: - version "16.4.7" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.7.tgz#0e20c5b82950140aa99be360a8a5f52335f53c26" - integrity sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ== +dotenv@^17.2.1: + version "17.2.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-17.2.1.tgz#6f32e10faf014883515538dc922a0fb8765d9b32" + integrity sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ== dunder-proto@^1.0.1: version "1.0.1" @@ -3897,10 +3894,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -electron-to-chromium@^1.5.73: - version "1.5.123" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.123.tgz#fae5bdba0ba27045895176327aa79831aba0790c" - integrity sha512-refir3NlutEZqlKaBLK0tzlVLe5P2wDKS7UQt/3SpibizgsRAPOsqQC3ffw1nlv3ze5gjRQZYHoPymgVZkplFA== +electron-to-chromium@^1.5.199: + version "1.5.199" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.199.tgz#4d8be9c78362c05f095eb7392e9a54f1fb14fd3a" + integrity sha512-3gl0S7zQd88kCAZRO/DnxtBKuhMO4h0EaQIN3YgZfV6+pW+5+bf2AdQeHNESCoaQqo/gjGVYEf2YM4O5HJQqpQ== emoji-regex@^8.0.0: version "8.0.0" @@ -3937,10 +3934,10 @@ encodeurl@~2.0.0: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== -enhanced-resolve@^5.17.1: - version "5.18.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz#728ab082f8b7b6836de51f1637aab5d3b9568faf" - integrity sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg== +enhanced-resolve@^5.17.2: + version "5.18.3" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz#9b5f4c5c076b8787c78fe540392ce76a88855b44" + integrity sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -3950,11 +3947,16 @@ entities@^2.0.0: resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== -entities@^4.2.0, entities@^4.4.0, entities@^4.5.0: +entities@^4.2.0, entities@^4.4.0: version "4.5.0" resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== +entities@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-6.0.1.tgz#c28c34a43379ca7f61d074130b2f5f7020a30694" + integrity sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g== + error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" @@ -3973,9 +3975,9 @@ es-errors@^1.3.0: integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== es-module-lexer@^1.2.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.6.0.tgz#da49f587fd9e68ee2404fe4e256c0c7d3a81be21" - integrity sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ== + version "1.7.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz#9159601561880a85f2734560a9099b2c31e5372a" + integrity sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA== es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: version "1.1.1" @@ -4104,9 +4106,9 @@ estree-util-to-js@^2.0.0: source-map "^0.7.0" estree-util-value-to-estree@^3.0.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/estree-util-value-to-estree/-/estree-util-value-to-estree-3.3.2.tgz#75bb2263850b6f5ac35edd343929c36b51a69806" - integrity sha512-hYH1aSvQI63Cvq3T3loaem6LW4u72F187zW4FHpTrReJSm6W66vYTFNO1vH/chmcOulp1HlAj1pxn8Ag0oXI5Q== + version "3.4.0" + resolved "https://registry.yarnpkg.com/estree-util-value-to-estree/-/estree-util-value-to-estree-3.4.0.tgz#827122e40c3a756d3c4cf5d5d296fa06026a1a4f" + integrity sha512-Zlp+gxis+gCfK12d3Srl2PdX2ybsEA8ZYy6vQGVQTNNYLEGRQQ56XB64bjemN8kxIKXP1nC9ip4Z+ILy9LGzvQ== dependencies: "@types/estree" "^1.0.0" @@ -4148,7 +4150,7 @@ eval@^0.1.8: "@types/node" "*" require-like ">= 0.1.1" -eventemitter3@^4.0.0: +eventemitter3@^4.0.0, eventemitter3@^4.0.4: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== @@ -4158,7 +4160,7 @@ events@^3.2.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -execa@^5.0.0: +execa@5.1.1, execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== @@ -4291,11 +4293,6 @@ file-loader@^6.2.0: loader-utils "^2.0.0" schema-utils "^3.0.0" -filesize@^8.0.6: - version "8.0.7" - resolved "https://registry.yarnpkg.com/filesize/-/filesize-8.0.7.tgz#695e70d80f4e47012c132d57a059e80c6b580bd8" - integrity sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ== - fill-range@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" @@ -4324,21 +4321,6 @@ find-cache-dir@^4.0.0: common-path-prefix "^3.0.0" pkg-dir "^7.0.0" -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - find-up@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-6.3.0.tgz#2abab3d3280b2dc7ac10199ef324c4e002c8c790" @@ -4353,28 +4335,9 @@ flat@^5.0.2: integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== follow-redirects@^1.0.0: - version "1.15.9" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" - integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== - -fork-ts-checker-webpack-plugin@^6.5.0: - version "6.5.3" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz#eda2eff6e22476a2688d10661688c47f611b37f3" - integrity sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ== - dependencies: - "@babel/code-frame" "^7.8.3" - "@types/json-schema" "^7.0.5" - chalk "^4.1.0" - chokidar "^3.4.2" - cosmiconfig "^6.0.0" - deepmerge "^4.2.2" - fs-extra "^9.0.0" - glob "^7.1.6" - memfs "^3.1.2" - minimatch "^3.0.4" - schema-utils "2.7.0" - semver "^7.3.2" - tapable "^1.0.0" + version "1.15.11" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.11.tgz#777d73d72a92f8ec4d2e410eb47352a56b8e8340" + integrity sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ== form-data-encoder@^2.1.2: version "2.1.4" @@ -4402,28 +4365,18 @@ fresh@0.5.2: integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== fs-extra@^11.1.1, fs-extra@^11.2.0: - version "11.3.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.0.tgz#0daced136bbaf65a555a326719af931adc7a314d" - integrity sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew== + version "11.3.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.1.tgz#ba7a1f97a85f94c6db2e52ff69570db3671d5a74" + integrity sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^9.0.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - fs-monkey@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.6.tgz#8ead082953e88d992cf3ff844faa907b26756da2" - integrity sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg== + version "1.1.0" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.1.0.tgz#632aa15a20e71828ed56b24303363fb1414e5997" + integrity sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw== fs.realpath@^1.0.0: version "1.0.0" @@ -4503,7 +4456,7 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@^7.0.0, glob@^7.1.3, glob@^7.1.6: +glob@^7.1.3: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -4522,28 +4475,7 @@ global-dirs@^3.0.0: dependencies: ini "2.0.0" -global-modules@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" - integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== - dependencies: - global-prefix "^3.0.0" - -global-prefix@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" - integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== - dependencies: - ini "^1.3.5" - kind-of "^6.0.2" - which "^1.3.1" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globby@^11.0.1, globby@^11.0.4, globby@^11.1.0: +globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -4798,9 +4730,9 @@ hpack.js@^2.1.6: wbuf "^1.1.0" html-entities@^2.3.2: - version "2.5.3" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.5.3.tgz#d8a0680bd24ee35af8c74d6d4b695627dde61c00" - integrity sha512-D3AfvN7SjhTgBSA8L1BN4FpPzuEd06uy4lHwSoRWr0lndi9BKaNzPLKGOWZ2ocSGguozr08TTb2jhCLHaemruw== + version "2.6.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.6.0.tgz#7c64f1ea3b36818ccae3d3fb48b6974208e984f8" + integrity sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ== html-escaper@^2.0.2: version "2.0.2" @@ -4875,9 +4807,9 @@ htmlparser2@^8.0.1: entities "^4.4.0" http-cache-semantics@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" - integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + version "4.2.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#205f4db64f8562b76a4ff9235aa5279839a09dd5" + integrity sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ== http-deceiver@^1.2.7: version "1.2.7" @@ -4906,14 +4838,14 @@ http-errors@~1.6.2: statuses ">= 1.4.0 < 2" http-parser-js@>=0.5.1: - version "0.5.9" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.9.tgz#b817b3ca0edea6236225000d795378707c169cec" - integrity sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw== + version "0.5.10" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.10.tgz#b3277bd6d7ed5588e20ea73bf724fcbe44609075" + integrity sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA== http-proxy-middleware@^2.0.3: - version "2.0.7" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz#915f236d92ae98ef48278a95dedf17e991936ec6" - integrity sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA== + version "2.0.9" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz#e9e63d68afaa4eee3d147f39149ab84c0c2815ef" + integrity sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q== dependencies: "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1" @@ -4960,19 +4892,12 @@ ignore@^5.2.0, ignore@^5.2.4: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== -image-size@^1.0.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.2.0.tgz#312af27a2ff4ff58595ad00b9344dd684c910df6" - integrity sha512-4S8fwbO6w3GeCVN6OPtA9I5IGKkcDMPcKndtUlpJuCwu7JLjtj7JZpwqLuyY2nrmQT3AWsCJLSKPsc2mPBSl3w== - dependencies: - queue "6.0.2" +image-size@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-2.0.2.tgz#84a7b43704db5736f364bf0d1b029821299b4bdc" + integrity sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w== -immer@^9.0.7: - version "9.0.21" - resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" - integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== - -import-fresh@^3.1.0, import-fresh@^3.3.0: +import-fresh@^3.3.0: version "3.3.1" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.1.tgz#9cecb56503c0ada1f2741dbbd6546e4b13b57ccf" integrity sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ== @@ -5023,7 +4948,7 @@ ini@2.0.0: resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== -ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: +ini@^1.3.4, ini@~1.3.0: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== @@ -5033,11 +4958,6 @@ inline-style-parser@0.2.4: resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.2.4.tgz#f4af5fe72e612839fcd453d989a586566d695f22" integrity sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q== -interpret@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" - integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== - invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -5159,11 +5079,6 @@ is-obj@^2.0.0: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== -is-path-cwd@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== - is-path-inside@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" @@ -5191,11 +5106,6 @@ is-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== -is-root@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" - integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== - is-stream@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" @@ -5374,12 +5284,12 @@ latest-version@^7.0.0: package-json "^8.1.0" launch-editor@^2.6.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.10.0.tgz#5ca3edfcb9667df1e8721310f3a40f1127d4bc42" - integrity sha512-D7dBRJo/qcGX9xlvt/6wUYzQxjh5G1RvZPgPv8vi4KRU99DVQL/oW7tnVOCCTm2HGeo3C5HvGE5Yrh6UBoZ0vA== + version "2.11.1" + resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.11.1.tgz#61a0b7314a42fd84a6cbb564573d9e9ffcf3d72b" + integrity sha512-SEET7oNfgSaB6Ym0jufAdCeo3meJVeCaaDyzRygy0xsp2BFKCprcfHljTq4QkzTLUxEKkFK6OK4811YM2oSrRg== dependencies: - picocolors "^1.0.0" - shell-quote "^1.8.1" + picocolors "^1.1.1" + shell-quote "^1.8.3" leven@^3.1.0: version "3.1.0" @@ -5410,26 +5320,6 @@ loader-utils@^2.0.0: emojis-list "^3.0.0" json5 "^2.1.2" -loader-utils@^3.2.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.3.1.tgz#735b9a19fd63648ca7adbd31c2327dfe281304e5" - integrity sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg== - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - locate-path@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-7.2.0.tgz#69cb1779bd90b35ab1e771e1f2f89a202c2a8a8a" @@ -5462,7 +5352,7 @@ longest-streak@^3.0.0: resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4" integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g== -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -5743,7 +5633,7 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== -memfs@^3.1.2, memfs@^3.4.3: +memfs@^3.4.3: version "3.6.0" resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== @@ -5895,9 +5785,9 @@ micromark-extension-gfm@^3.0.0: micromark-util-types "^2.0.0" micromark-extension-mdx-expression@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz#1407b9ce69916cf5e03a196ad9586889df25302a" - integrity sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ== + version "3.0.1" + resolved "https://registry.yarnpkg.com/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz#43d058d999532fb3041195a3c3c05c46fa84543b" + integrity sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q== dependencies: "@types/estree" "^1.0.0" devlop "^1.0.0" @@ -5909,11 +5799,10 @@ micromark-extension-mdx-expression@^3.0.0: micromark-util-types "^2.0.0" micromark-extension-mdx-jsx@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.1.tgz#5abb83da5ddc8e473a374453e6ea56fbd66b59ad" - integrity sha512-vNuFb9czP8QCtAQcEJn0UJQJZA8Dk6DXKBqx+bg/w0WGuSxDxNr7hErW89tHUY31dUW4NqEOWwmEUNhjTFmHkg== + version "3.0.2" + resolved "https://registry.yarnpkg.com/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz#ffc98bdb649798902fa9fc5689f67f9c1c902044" + integrity sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ== dependencies: - "@types/acorn" "^4.0.0" "@types/estree" "^1.0.0" devlop "^1.0.0" estree-util-is-identifier-name "^3.0.0" @@ -5981,9 +5870,9 @@ micromark-factory-label@^2.0.0: micromark-util-types "^2.0.0" micromark-factory-mdx-expression@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.2.tgz#2afaa8ba6d5f63e0cead3e4dee643cad184ca260" - integrity sha512-5E5I2pFzJyg2CtemqAbcyCktpHXuJbABnsb32wX2U8IQKhhVFBqkcZR5LRm1WVoFqa4kTueZK4abep7wdo9nrw== + version "2.0.3" + resolved "https://registry.yarnpkg.com/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz#bb09988610589c07d1c1e4425285895041b3dfa9" + integrity sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ== dependencies: "@types/estree" "^1.0.0" devlop "^1.0.0" @@ -6094,11 +5983,10 @@ micromark-util-encode@^2.0.0: integrity sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw== micromark-util-events-to-acorn@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz#4275834f5453c088bd29cd72dfbf80e3327cec07" - integrity sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA== + version "2.0.3" + resolved "https://registry.yarnpkg.com/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz#e7a8a6b55a47e5a06c720d5a1c4abae8c37c98f3" + integrity sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg== dependencies: - "@types/acorn" "^4.0.0" "@types/estree" "^1.0.0" "@types/unist" "^3.0.0" devlop "^1.0.0" @@ -6245,10 +6133,10 @@ mimic-response@^4.0.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-4.0.0.tgz#35468b19e7c75d10f5165ea25e75a5ceea7cf70f" integrity sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg== -mini-css-extract-plugin@^2.9.1: - version "2.9.2" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz#966031b468917a5446f4c24a80854b2947503c5b" - integrity sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w== +mini-css-extract-plugin@^2.9.2: + version "2.9.3" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.3.tgz#3dcb896f21cdcbd24528eb7e9b89f91635508198" + integrity sha512-tRA0+PsS4kLVijnN1w9jUu5lkxBwUk9E8SbgEB5dBJqchE6pVYdawROG6uQtpmAri7tdCK9i7b1bULeVWqS6Ag== dependencies: schema-utils "^4.0.0" tapable "^2.2.1" @@ -6258,7 +6146,7 @@ minimalistic-assert@^1.0.0: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@3.1.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1: +minimatch@3.1.2, minimatch@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -6293,7 +6181,7 @@ multicast-dns@^7.2.5: dns-packet "^5.2.2" thunky "^1.0.2" -nanoid@^3.3.8: +nanoid@^3.3.11: version "3.3.11" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== @@ -6352,9 +6240,9 @@ normalize-range@^0.1.2: integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== normalize-url@^8.0.0: - version "8.0.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-8.0.1.tgz#9b7d96af9836577c58f5883e939365fa15623a4a" - integrity sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w== + version "8.0.2" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-8.0.2.tgz#3b343a42f837e4dae2b01917c04e8de3782e9170" + integrity sha512-Ee/R3SyN4BuynXcnTaekmaVdbDAEiNrHqjQIA37mHU8G9pf7aaAD4ZX3XjBLo6rsdcxA/gtkcNYZLt30ACgynw== npm-run-path@^4.0.1: version "4.0.1" @@ -6422,10 +6310,10 @@ on-finished@2.4.1: dependencies: ee-first "1.1.1" -on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== +on-headers@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.1.0.tgz#59da4f91c45f5f989c6e4bcedc5a3b0aed70ff65" + integrity sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A== once@^1.3.0: version "1.4.0" @@ -6460,19 +6348,10 @@ p-cancelable@^3.0.0: resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050" integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw== -p-limit@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== p-limit@^4.0.0: version "4.0.0" @@ -6481,20 +6360,6 @@ p-limit@^4.0.0: dependencies: yocto-queue "^1.0.0" -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - p-locate@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-6.0.0.tgz#3da9a49d4934b901089dca3302fa65dc5a05c04f" @@ -6509,6 +6374,14 @@ p-map@^4.0.0: dependencies: aggregate-error "^3.0.0" +p-queue@^6.6.2: + version "6.6.2" + resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.6.2.tgz#2068a9dcf8e67dd0ec3e7a2bcb76810faa85e426" + integrity sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ== + dependencies: + eventemitter3 "^4.0.4" + p-timeout "^3.2.0" + p-retry@^4.5.0: version "4.6.2" resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" @@ -6517,10 +6390,12 @@ p-retry@^4.5.0: "@types/retry" "0.12.0" retry "^0.13.1" -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +p-timeout@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" package-json@^8.1.0: version "8.1.1" @@ -6560,7 +6435,7 @@ parse-entities@^4.0.0: is-decimal "^2.0.0" is-hexadecimal "^2.0.0" -parse-json@^5.0.0, parse-json@^5.2.0: +parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -6584,11 +6459,11 @@ parse5-htmlparser2-tree-adapter@^7.0.0: parse5 "^7.0.0" parse5@^7.0.0: - version "7.2.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.2.1.tgz#8928f55915e6125f430cc44309765bf17556a33a" - integrity sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ== + version "7.3.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.3.0.tgz#d7e224fa72399c7a175099f45fc2ad024b05ec05" + integrity sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw== dependencies: - entities "^4.5.0" + entities "^6.0.0" parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" @@ -6603,16 +6478,6 @@ pascal-case@^3.1.2: no-case "^3.0.4" tslib "^2.0.3" -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - path-exists@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7" @@ -6677,13 +6542,6 @@ pkg-dir@^7.0.0: dependencies: find-up "^6.3.0" -pkg-up@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" - integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== - dependencies: - find-up "^3.0.0" - postcss-attribute-case-insensitive@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-7.0.1.tgz#0c4500e3bcb2141848e89382c05b5a31c23033a3" @@ -6706,15 +6564,15 @@ postcss-clamp@^4.1.0: dependencies: postcss-value-parser "^4.2.0" -postcss-color-functional-notation@^7.0.8: - version "7.0.8" - resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.8.tgz#b62a253d478f69b41e9343c983876a592578581c" - integrity sha512-S/TpMKVKofNvsxfau/+bw+IA6cSfB6/kmzFj5szUofHOVnFFMB2WwK+Zu07BeMD8T0n+ZnTO5uXiMvAKe2dPkA== +postcss-color-functional-notation@^7.0.10: + version "7.0.10" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.10.tgz#f1e9c3e4371889dcdfeabfa8515464fd8338cedc" + integrity sha512-k9qX+aXHBiLTRrWoCJuUFI6F1iF6QJQUXNVWJVSbqZgj57jDhBlOvD8gNUGl35tgqDivbGLhZeW3Ongz4feuKA== dependencies: - "@csstools/css-color-parser" "^3.0.8" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/css-color-parser" "^3.0.10" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.1.0" "@csstools/utilities" "^2.0.0" postcss-color-hex-alpha@^10.0.0: @@ -6751,35 +6609,35 @@ postcss-convert-values@^6.1.0: browserslist "^4.23.0" postcss-value-parser "^4.2.0" -postcss-custom-media@^11.0.5: - version "11.0.5" - resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-11.0.5.tgz#2fcd88a9b1d4da41c67dac6f2def903063a3377d" - integrity sha512-SQHhayVNgDvSAdX9NQ/ygcDQGEY+aSF4b/96z7QUX6mqL5yl/JgG/DywcF6fW9XbnCRE+aVYk+9/nqGuzOPWeQ== +postcss-custom-media@^11.0.6: + version "11.0.6" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-11.0.6.tgz#6b450e5bfa209efb736830066682e6567bd04967" + integrity sha512-C4lD4b7mUIw+RZhtY7qUbf4eADmb7Ey8BFA2px9jUbwg7pjTZDl4KY4bvlUV+/vXQvzQRfiGEVJyAbtOsCMInw== dependencies: - "@csstools/cascade-layer-name-parser" "^2.0.4" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/media-query-list-parser" "^4.0.2" + "@csstools/cascade-layer-name-parser" "^2.0.5" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/media-query-list-parser" "^4.0.3" -postcss-custom-properties@^14.0.4: - version "14.0.4" - resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-14.0.4.tgz#de9c663285a98833a946d7003a34369d3ce373a9" - integrity sha512-QnW8FCCK6q+4ierwjnmXF9Y9KF8q0JkbgVfvQEMa93x1GT8FvOiUevWCN2YLaOWyByeDX8S6VFbZEeWoAoXs2A== +postcss-custom-properties@^14.0.6: + version "14.0.6" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-14.0.6.tgz#1af73a650bf115ba052cf915287c9982825fc90e" + integrity sha512-fTYSp3xuk4BUeVhxCSJdIPhDLpJfNakZKoiTDx7yRGCdlZrSJR7mWKVOBS4sBF+5poPQFMj2YdXx1VHItBGihQ== dependencies: - "@csstools/cascade-layer-name-parser" "^2.0.4" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" + "@csstools/cascade-layer-name-parser" "^2.0.5" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" "@csstools/utilities" "^2.0.0" postcss-value-parser "^4.2.0" -postcss-custom-selectors@^8.0.4: - version "8.0.4" - resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-8.0.4.tgz#95ef8268fdbbbd84f34cf84a4517c9d99d419c5a" - integrity sha512-ASOXqNvDCE0dAJ/5qixxPeL1aOVGHGW2JwSy7HyjWNbnWTQCl+fDc968HY1jCmZI0+BaYT5CxsOiUhavpG/7eg== +postcss-custom-selectors@^8.0.5: + version "8.0.5" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-8.0.5.tgz#9448ed37a12271d7ab6cb364b6f76a46a4a323e8" + integrity sha512-9PGmckHQswiB2usSO6XMSswO2yFWVoCAuih1yl9FVcwkscLjRKjwsjM3t+NIWpSU2Jx3eOiK2+t4vVTQaoCHHg== dependencies: - "@csstools/cascade-layer-name-parser" "^2.0.4" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" + "@csstools/cascade-layer-name-parser" "^2.0.5" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" postcss-selector-parser "^7.0.0" postcss-dir-pseudo-class@^9.0.1: @@ -6816,12 +6674,12 @@ postcss-discard-unused@^6.0.5: dependencies: postcss-selector-parser "^6.0.16" -postcss-double-position-gradients@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-6.0.0.tgz#eddd424ec754bb543d057d4d2180b1848095d4d2" - integrity sha512-JkIGah3RVbdSEIrcobqj4Gzq0h53GG4uqDPsho88SgY84WnpkTpI0k50MFK/sX7XqVisZ6OqUfFnoUO6m1WWdg== +postcss-double-position-gradients@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-6.0.2.tgz#185f8eab2db9cf4e34be69b5706c905895bb52ae" + integrity sha512-7qTqnL7nfLRyJK/AHSVrrXOuvDDzettC+wGoienURV8v2svNbu6zJC52ruZtHaO6mfcagFmuTGFdzRsJKB3k5Q== dependencies: - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/postcss-progressive-custom-properties" "^4.1.0" "@csstools/utilities" "^2.0.0" postcss-value-parser "^4.2.0" @@ -6857,18 +6715,18 @@ postcss-image-set-function@^7.0.0: "@csstools/utilities" "^2.0.0" postcss-value-parser "^4.2.0" -postcss-lab-function@^7.0.8: - version "7.0.8" - resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-7.0.8.tgz#ab0b210c5f6552347efa0311f7a7dfe34af9e6b4" - integrity sha512-plV21I86Hg9q8omNz13G9fhPtLopIWH06bt/Cb5cs1XnaGU2kUtEitvVd4vtQb/VqCdNUHK5swKn3QFmMRbpDg== +postcss-lab-function@^7.0.10: + version "7.0.10" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-7.0.10.tgz#0537bd7245b935fc133298c8896bcbd160540cae" + integrity sha512-tqs6TCEv9tC1Riq6fOzHuHcZyhg4k3gIAMB8GGY/zA1ssGdm6puHMVE7t75aOSoFg7UD2wyrFFhbldiCMyyFTQ== dependencies: - "@csstools/css-color-parser" "^3.0.8" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/css-color-parser" "^3.0.10" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.1.0" "@csstools/utilities" "^2.0.0" -postcss-loader@^7.3.3: +postcss-loader@^7.3.4: version "7.3.4" resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-7.3.4.tgz#aed9b79ce4ed7e9e89e56199d25ad1ec8f606209" integrity sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A== @@ -6970,12 +6828,12 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-nesting@^13.0.1: - version "13.0.1" - resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-13.0.1.tgz#c405796d7245a3e4c267a9956cacfe9670b5d43e" - integrity sha512-VbqqHkOBOt4Uu3G8Dm8n6lU5+9cJFxiuty9+4rcoyRPO9zZS1JIs6td49VIoix3qYqELHlJIn46Oih9SAKo+yQ== +postcss-nesting@^13.0.2: + version "13.0.2" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-13.0.2.tgz#fde0d4df772b76d03b52eccc84372e8d1ca1402e" + integrity sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ== dependencies: - "@csstools/selector-resolve-nested" "^3.0.0" + "@csstools/selector-resolve-nested" "^3.1.0" "@csstools/selector-specificity" "^5.0.0" postcss-selector-parser "^7.0.0" @@ -7073,67 +6931,68 @@ postcss-place@^10.0.0: dependencies: postcss-value-parser "^4.2.0" -postcss-preset-env@^10.1.0: - version "10.1.5" - resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-10.1.5.tgz#1e12d050a5dbebc4230cc73c0d2e122c30a6a937" - integrity sha512-LQybafF/K7H+6fAs4SIkgzkSCixJy0/h0gubDIAP3Ihz+IQBRwsjyvBnAZ3JUHD+A/ITaxVRPDxn//a3Qy4pDw== +postcss-preset-env@^10.2.1: + version "10.2.4" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-10.2.4.tgz#17d386b5a86b136dfbca89b52ef03a95ad9e32fa" + integrity sha512-q+lXgqmTMdB0Ty+EQ31SuodhdfZetUlwCA/F0zRcd/XdxjzI+Rl2JhZNz5US2n/7t9ePsvuhCnEN4Bmu86zXlA== dependencies: - "@csstools/postcss-cascade-layers" "^5.0.1" - "@csstools/postcss-color-function" "^4.0.8" - "@csstools/postcss-color-mix-function" "^3.0.8" - "@csstools/postcss-content-alt-text" "^2.0.4" - "@csstools/postcss-exponential-functions" "^2.0.7" + "@csstools/postcss-cascade-layers" "^5.0.2" + "@csstools/postcss-color-function" "^4.0.10" + "@csstools/postcss-color-mix-function" "^3.0.10" + "@csstools/postcss-color-mix-variadic-function-arguments" "^1.0.0" + "@csstools/postcss-content-alt-text" "^2.0.6" + "@csstools/postcss-exponential-functions" "^2.0.9" "@csstools/postcss-font-format-keywords" "^4.0.0" - "@csstools/postcss-gamut-mapping" "^2.0.8" - "@csstools/postcss-gradients-interpolation-method" "^5.0.8" - "@csstools/postcss-hwb-function" "^4.0.8" - "@csstools/postcss-ic-unit" "^4.0.0" + "@csstools/postcss-gamut-mapping" "^2.0.10" + "@csstools/postcss-gradients-interpolation-method" "^5.0.10" + "@csstools/postcss-hwb-function" "^4.0.10" + "@csstools/postcss-ic-unit" "^4.0.2" "@csstools/postcss-initial" "^2.0.1" - "@csstools/postcss-is-pseudo-class" "^5.0.1" - "@csstools/postcss-light-dark-function" "^2.0.7" + "@csstools/postcss-is-pseudo-class" "^5.0.3" + "@csstools/postcss-light-dark-function" "^2.0.9" "@csstools/postcss-logical-float-and-clear" "^3.0.0" "@csstools/postcss-logical-overflow" "^2.0.0" "@csstools/postcss-logical-overscroll-behavior" "^2.0.0" "@csstools/postcss-logical-resize" "^3.0.0" - "@csstools/postcss-logical-viewport-units" "^3.0.3" - "@csstools/postcss-media-minmax" "^2.0.7" - "@csstools/postcss-media-queries-aspect-ratio-number-values" "^3.0.4" + "@csstools/postcss-logical-viewport-units" "^3.0.4" + "@csstools/postcss-media-minmax" "^2.0.9" + "@csstools/postcss-media-queries-aspect-ratio-number-values" "^3.0.5" "@csstools/postcss-nested-calc" "^4.0.0" "@csstools/postcss-normalize-display-values" "^4.0.0" - "@csstools/postcss-oklab-function" "^4.0.8" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" - "@csstools/postcss-random-function" "^1.0.3" - "@csstools/postcss-relative-color-syntax" "^3.0.8" + "@csstools/postcss-oklab-function" "^4.0.10" + "@csstools/postcss-progressive-custom-properties" "^4.1.0" + "@csstools/postcss-random-function" "^2.0.1" + "@csstools/postcss-relative-color-syntax" "^3.0.10" "@csstools/postcss-scope-pseudo-class" "^4.0.1" - "@csstools/postcss-sign-functions" "^1.1.2" - "@csstools/postcss-stepped-value-functions" "^4.0.7" + "@csstools/postcss-sign-functions" "^1.1.4" + "@csstools/postcss-stepped-value-functions" "^4.0.9" "@csstools/postcss-text-decoration-shorthand" "^4.0.2" - "@csstools/postcss-trigonometric-functions" "^4.0.7" + "@csstools/postcss-trigonometric-functions" "^4.0.9" "@csstools/postcss-unset-value" "^4.0.0" - autoprefixer "^10.4.19" - browserslist "^4.24.4" + autoprefixer "^10.4.21" + browserslist "^4.25.0" css-blank-pseudo "^7.0.1" css-has-pseudo "^7.0.2" css-prefers-color-scheme "^10.0.0" - cssdb "^8.2.3" + cssdb "^8.3.0" postcss-attribute-case-insensitive "^7.0.1" postcss-clamp "^4.1.0" - postcss-color-functional-notation "^7.0.8" + postcss-color-functional-notation "^7.0.10" postcss-color-hex-alpha "^10.0.0" postcss-color-rebeccapurple "^10.0.0" - postcss-custom-media "^11.0.5" - postcss-custom-properties "^14.0.4" - postcss-custom-selectors "^8.0.4" + postcss-custom-media "^11.0.6" + postcss-custom-properties "^14.0.6" + postcss-custom-selectors "^8.0.5" postcss-dir-pseudo-class "^9.0.1" - postcss-double-position-gradients "^6.0.0" + postcss-double-position-gradients "^6.0.2" postcss-focus-visible "^10.0.1" postcss-focus-within "^9.0.1" postcss-font-variant "^5.0.0" postcss-gap-properties "^6.0.0" postcss-image-set-function "^7.0.0" - postcss-lab-function "^7.0.8" + postcss-lab-function "^7.0.10" postcss-logical "^8.1.0" - postcss-nesting "^13.0.1" + postcss-nesting "^13.0.2" postcss-opacity-percentage "^3.0.0" postcss-overflow-shorthand "^6.0.0" postcss-page-break "^3.0.4" @@ -7231,12 +7090,12 @@ postcss-zindex@^6.0.2: resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-6.0.2.tgz#e498304b83a8b165755f53db40e2ea65a99b56e1" integrity sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg== -postcss@^8.4.21, postcss@^8.4.24, postcss@^8.4.26, postcss@^8.4.33, postcss@^8.4.38: - version "8.5.3" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.3.tgz#1463b6f1c7fb16fe258736cba29a2de35237eafb" - integrity sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A== +postcss@^8.4.21, postcss@^8.4.24, postcss@^8.4.33, postcss@^8.5.4: + version "8.5.6" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c" + integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== dependencies: - nanoid "^3.3.8" + nanoid "^3.3.11" picocolors "^1.1.1" source-map-js "^1.2.1" @@ -7253,7 +7112,7 @@ pretty-time@^1.1.0: resolved "https://registry.yarnpkg.com/pretty-time/-/pretty-time-1.1.0.tgz#ffb7429afabb8535c346a34e41873adf3d74dd0e" integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA== -prism-react-renderer@^2.3.0, prism-react-renderer@^2.3.1: +prism-react-renderer@^2.3.0, prism-react-renderer@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-2.4.1.tgz#ac63b7f78e56c8f2b5e76e823a976d5ede77e35f" integrity sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig== @@ -7294,9 +7153,9 @@ property-information@^6.0.0: integrity sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig== property-information@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/property-information/-/property-information-7.0.0.tgz#3508a6d6b0b8eb3ca6eb2c6623b164d2ed2ab112" - integrity sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg== + version "7.1.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-7.1.0.tgz#b622e8646e02b580205415586b40804d3e8bfd5d" + integrity sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ== proto-list@~1.2.1: version "1.2.4" @@ -7335,13 +7194,6 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -queue@6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/queue/-/queue-6.0.2.tgz#b91525283e2315c7553d2efa18d83e76432fed65" - integrity sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA== - dependencies: - inherits "~2.0.3" - quick-lru@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" @@ -7384,55 +7236,19 @@ rc@1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-dev-utils@^12.0.1: - version "12.0.1" - resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-12.0.1.tgz#ba92edb4a1f379bd46ccd6bcd4e7bc398df33e73" - integrity sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ== +react-dom@^19.1.1: + version "19.1.1" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.1.1.tgz#2daa9ff7f3ae384aeb30e76d5ee38c046dc89893" + integrity sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw== dependencies: - "@babel/code-frame" "^7.16.0" - address "^1.1.2" - browserslist "^4.18.1" - chalk "^4.1.2" - cross-spawn "^7.0.3" - detect-port-alt "^1.1.6" - escape-string-regexp "^4.0.0" - filesize "^8.0.6" - find-up "^5.0.0" - fork-ts-checker-webpack-plugin "^6.5.0" - global-modules "^2.0.0" - globby "^11.0.4" - gzip-size "^6.0.0" - immer "^9.0.7" - is-root "^2.1.0" - loader-utils "^3.2.0" - open "^8.4.0" - pkg-up "^3.1.0" - prompts "^2.4.2" - react-error-overlay "^6.0.11" - recursive-readdir "^2.2.2" - shell-quote "^1.7.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" - -react-dom@^18.3.1: - version "18.3.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" - integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== - dependencies: - loose-envify "^1.1.0" - scheduler "^0.23.2" - -react-error-overlay@^6.0.11: - version "6.1.0" - resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.1.0.tgz#22b86256beb1c5856f08a9a228adb8121dd985f2" - integrity sha512-SN/U6Ytxf1QGkw/9ve5Y+NxBbZM6Ht95tuXNMKs8EJyFa/Vy/+Co3stop3KBHARfn/giv+Lj1uUnTfOJ3moFEQ== + scheduler "^0.26.0" react-fast-compare@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== -"react-helmet-async@npm:@slorber/react-helmet-async@*", "react-helmet-async@npm:@slorber/react-helmet-async@1.3.0": +"react-helmet-async@npm:@slorber/react-helmet-async@1.3.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@slorber/react-helmet-async/-/react-helmet-async-1.3.0.tgz#11fbc6094605cf60aa04a28c17e0aab894b4ecff" integrity sha512-e9/OK8VhwUSc67diWI8Rb3I0YgI9/SBQtnhe9aEuK6MhZm7ntZZimXgwXnd8W96YTmSOb9M4d8LwhRZyhWr/1A== @@ -7448,10 +7264,10 @@ react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-json-view-lite@^1.2.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/react-json-view-lite/-/react-json-view-lite-1.5.0.tgz#377cc302821717ac79a1b6d099e1891df54c8662" - integrity sha512-nWqA1E4jKPklL2jvHWs6s+7Na0qNgw9HCP6xehdQJeg6nPBTFZgGwyko9Q0oj+jQWKTTVRS30u0toM5wiuL3iw== +react-json-view-lite@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/react-json-view-lite/-/react-json-view-lite-2.4.2.tgz#796ed6c650c29123d87b9484889445d1a8a88ede" + integrity sha512-m7uTsXDgPQp8R9bJO4HD/66+i218eyQPAb+7/dGQpwg8i4z2afTFqtHJPQFHvJfgDCjGQ1HSGlL3HtrZDa3Tdg== react-loadable-ssr-addon-v5-slorber@^1.0.1: version "1.0.1" @@ -7502,12 +7318,10 @@ react-router@5.3.4, react-router@^5.3.4: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react@^18.3.1: - version "18.3.1" - resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" - integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== - dependencies: - loose-envify "^1.1.0" +react@^19.1.1: + version "19.1.1" + resolved "https://registry.yarnpkg.com/react/-/react-19.1.1.tgz#06d9149ec5e083a67f9a1e39ce97b06a03b644af" + integrity sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ== readable-stream@^2.0.1: version "2.3.8" @@ -7538,18 +7352,6 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -reading-time@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/reading-time/-/reading-time-1.5.0.tgz#d2a7f1b6057cb2e169beaf87113cc3411b5bc5bb" - integrity sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg== - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== - dependencies: - resolve "^1.1.6" - recma-build-jsx@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz#c02f29e047e103d2fab2054954e1761b8ea253c4" @@ -7560,9 +7362,9 @@ recma-build-jsx@^1.0.0: vfile "^6.0.0" recma-jsx@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/recma-jsx/-/recma-jsx-1.0.0.tgz#f7bef02e571a49d6ba3efdfda8e2efab48dbe3aa" - integrity sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q== + version "1.0.1" + resolved "https://registry.yarnpkg.com/recma-jsx/-/recma-jsx-1.0.1.tgz#58e718f45e2102ed0bf2fa994f05b70d76801a1a" + integrity sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w== dependencies: acorn-jsx "^5.0.0" estree-util-to-js "^2.0.0" @@ -7590,13 +7392,6 @@ recma-stringify@^1.0.0: unified "^11.0.0" vfile "^6.0.0" -recursive-readdir@^2.2.2: - version "2.2.3" - resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz#e726f328c0d69153bcabd5c322d3195252379372" - integrity sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA== - dependencies: - minimatch "^3.0.5" - regenerate-unicode-properties@^10.2.0: version "10.2.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz#626e39df8c372338ea9b8028d1f99dc3fd9c3db0" @@ -7609,18 +7404,6 @@ regenerate@^1.4.2: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.14.0: - version "0.14.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" - integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== - -regenerator-transform@^0.15.2: - version "0.15.2" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" - integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== - dependencies: - "@babel/runtime" "^7.8.4" - regexpu-core@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.2.0.tgz#0e5190d79e542bf294955dccabae04d3c7d53826" @@ -7744,9 +7527,9 @@ remark-parse@^11.0.0: unified "^11.0.0" remark-rehype@^11.0.0: - version "11.1.1" - resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-11.1.1.tgz#f864dd2947889a11997c0a2667cd6b38f685bca7" - integrity sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ== + version "11.1.2" + resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-11.1.2.tgz#2addaadda80ca9bd9aa0da763e74d16327683b37" + integrity sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw== dependencies: "@types/hast" "^3.0.0" "@types/mdast" "^4.0.0" @@ -7809,7 +7592,7 @@ resolve-pathname@^3.0.0: resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== -resolve@^1.1.6, resolve@^1.14.2: +resolve@^1.22.10: version "1.22.10" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39" integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w== @@ -7879,21 +7662,15 @@ sax@^1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.1.tgz#44cc8988377f126304d3b3fc1010c733b929ef0f" integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg== -scheduler@^0.23.2: - version "0.23.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" - integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== - dependencies: - loose-envify "^1.1.0" +scheduler@^0.26.0: + version "0.26.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.26.0.tgz#4ce8a8c2a2095f13ea11bf9a445be50c555d6337" + integrity sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA== -schema-utils@2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" - integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== - dependencies: - "@types/json-schema" "^7.0.4" - ajv "^6.12.2" - ajv-keywords "^3.4.1" +schema-dts@^1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/schema-dts/-/schema-dts-1.1.5.tgz#9237725d305bac3469f02b292a035107595dc324" + integrity sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg== schema-utils@^3.0.0: version "3.3.0" @@ -7904,10 +7681,10 @@ schema-utils@^3.0.0: ajv "^6.12.5" ajv-keywords "^3.5.2" -schema-utils@^4.0.0, schema-utils@^4.0.1, schema-utils@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.0.tgz#3b669f04f71ff2dfb5aba7ce2d5a9d79b35622c0" - integrity sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g== +schema-utils@^4.0.0, schema-utils@^4.0.1, schema-utils@^4.3.0, schema-utils@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.2.tgz#0c10878bf4a73fd2b1dfd14b9462b26788c806ae" + integrity sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ== dependencies: "@types/json-schema" "^7.0.9" ajv "^8.9.0" @@ -7947,10 +7724,10 @@ semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.5.4: - version "7.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f" - integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA== +semver@^7.3.5, semver@^7.3.7, semver@^7.5.4: + version "7.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" + integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== send@0.19.0: version "0.19.0" @@ -8060,19 +7837,10 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shell-quote@^1.7.3, shell-quote@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.2.tgz#d2d83e057959d53ec261311e9e9b8f51dcb2934a" - integrity sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA== - -shelljs@^0.8.5: - version "0.8.5" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" - integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" +shell-quote@^1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.3.tgz#55e40ef33cf5c689902353a3d8cd1a6725f08b4b" + integrity sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw== side-channel-list@^1.0.0: version "1.0.0" @@ -8201,9 +7969,9 @@ source-map@^0.6.0, source-map@~0.6.0: integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== source-map@^0.7.0: - version "0.7.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" - integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== + version "0.7.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.6.tgz#a3658ab87e5b6429c8a1f3ba0083d4c61ca3ef02" + integrity sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ== space-separated-tokens@^2.0.0: version "2.0.2" @@ -8254,9 +8022,9 @@ statuses@2.0.1: integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== std-env@^3.7.0: - version "3.8.1" - resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.8.1.tgz#2b81c631c62e3d0b964b87f099b8dcab6c9a5346" - integrity sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA== + version "3.9.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.9.0.tgz#1a6f7243b339dca4c9fd55e1c7504c77ef23e8f1" + integrity sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw== string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" @@ -8342,16 +8110,16 @@ strip-json-comments@~2.0.1: integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== style-to-js@^1.0.0: - version "1.1.16" - resolved "https://registry.yarnpkg.com/style-to-js/-/style-to-js-1.1.16.tgz#e6bd6cd29e250bcf8fa5e6591d07ced7575dbe7a" - integrity sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw== + version "1.1.17" + resolved "https://registry.yarnpkg.com/style-to-js/-/style-to-js-1.1.17.tgz#488b1558a8c1fd05352943f088cc3ce376813d83" + integrity sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA== dependencies: - style-to-object "1.0.8" + style-to-object "1.0.9" -style-to-object@1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-1.0.8.tgz#67a29bca47eaa587db18118d68f9d95955e81292" - integrity sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g== +style-to-object@1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-1.0.9.tgz#35c65b713f4a6dba22d3d0c61435f965423653f0" + integrity sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw== dependencies: inline-style-parser "0.2.4" @@ -8400,15 +8168,10 @@ svgo@^3.0.2, svgo@^3.2.0: csso "^5.0.5" picocolors "^1.0.0" -tapable@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" - integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== - tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + version "2.2.2" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.2.tgz#ab4984340d30cb9989a490032f086dbb8b56d872" + integrity sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg== terser-webpack-plugin@^5.3.11, terser-webpack-plugin@^5.3.9: version "5.3.14" @@ -8422,20 +8185,15 @@ terser-webpack-plugin@^5.3.11, terser-webpack-plugin@^5.3.9: terser "^5.31.1" terser@^5.10.0, terser@^5.15.1, terser@^5.31.1: - version "5.39.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.39.0.tgz#0e82033ed57b3ddf1f96708d123cca717d86ca3a" - integrity sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw== + version "5.43.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.43.1.tgz#88387f4f9794ff1a29e7ad61fb2932e25b4fdb6d" + integrity sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg== dependencies: "@jridgewell/source-map" "^0.3.3" - acorn "^8.8.2" + acorn "^8.14.0" commander "^2.20.0" source-map-support "~0.5.20" -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - thunky@^1.0.2: version "1.1.0" resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" @@ -8451,6 +8209,11 @@ tiny-warning@^1.0.0: resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== +tinypool@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-1.1.1.tgz#059f2d042bd37567fbc017d3d426bdd2a2612591" + integrity sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg== + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -8513,15 +8276,15 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@^5.4.5: - version "5.8.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.2.tgz#8170b3702f74b79db2e5a96207c15e65807999e4" - integrity sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ== +typescript@^5.9.2: + version "5.9.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.2.tgz#d93450cddec5154a2d5cabe3b8102b83316fb2a6" + integrity sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A== -undici-types@~6.20.0: - version "6.20.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433" - integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg== +undici-types@~7.10.0: + version "7.10.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.10.0.tgz#4ac2e058ce56b462b056e629cc6a02393d3ff350" + integrity sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag== unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.1" @@ -8626,7 +8389,7 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -update-browserslist-db@^1.1.1: +update-browserslist-db@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420" integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw== @@ -8714,9 +8477,9 @@ vfile-location@^5.0.0: vfile "^6.0.0" vfile-message@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-4.0.2.tgz#c883c9f677c72c166362fd635f21fc165a7d1181" - integrity sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw== + version "4.0.3" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-4.0.3.tgz#87b44dddd7b70f0641c2e3ed0864ba73e2ea8df4" + integrity sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw== dependencies: "@types/unist" "^3.0.0" unist-util-stringify-position "^4.0.0" @@ -8730,9 +8493,9 @@ vfile@^6.0.0, vfile@^6.0.1: vfile-message "^4.0.0" watchpack@^2.4.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.2.tgz#2feeaed67412e7c33184e5a79ca738fbd38564da" - integrity sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw== + version "2.4.4" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.4.tgz#473bda72f0850453da6425081ea46fc0d7602947" + integrity sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" @@ -8832,25 +8595,27 @@ webpack-merge@^6.0.1: flat "^5.0.2" wildcard "^2.0.1" -webpack-sources@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" - integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== +webpack-sources@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723" + integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg== webpack@^5.88.1, webpack@^5.95.0: - version "5.98.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.98.0.tgz#44ae19a8f2ba97537978246072fb89d10d1fbd17" - integrity sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA== + version "5.101.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.101.0.tgz#4b81407ffad9857f81ff03f872e3369b9198cc9d" + integrity sha512-B4t+nJqytPeuZlHuIKTbalhljIFXeNRqrUGAQgTGlfOl2lXXKXw+yZu6bicycP+PUlM44CxBjCFD6aciKFT3LQ== dependencies: "@types/eslint-scope" "^3.7.7" - "@types/estree" "^1.0.6" + "@types/estree" "^1.0.8" + "@types/json-schema" "^7.0.15" "@webassemblyjs/ast" "^1.14.1" "@webassemblyjs/wasm-edit" "^1.14.1" "@webassemblyjs/wasm-parser" "^1.14.1" - acorn "^8.14.0" + acorn "^8.15.0" + acorn-import-phases "^1.0.3" browserslist "^4.24.0" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.17.1" + enhanced-resolve "^5.17.2" es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" @@ -8860,11 +8625,11 @@ webpack@^5.88.1, webpack@^5.95.0: loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" - schema-utils "^4.3.0" + schema-utils "^4.3.2" tapable "^2.1.1" terser-webpack-plugin "^5.3.11" watchpack "^2.4.1" - webpack-sources "^3.2.3" + webpack-sources "^3.3.3" webpackbar@^6.0.1: version "6.0.1" @@ -8894,13 +8659,6 @@ websocket-extensions@>=0.1.1: resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== -which@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -8959,9 +8717,9 @@ ws@^7.3.1: integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== ws@^8.13.0: - version "8.18.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb" - integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w== + version "8.18.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.3.tgz#b56b88abffde62791c639170400c93dcb0c95472" + integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg== xdg-basedir@^5.0.1, xdg-basedir@^5.1.0: version "5.1.0" @@ -8980,16 +8738,6 @@ yallist@^3.0.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yaml@^1.7.2: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - yocto-queue@^1.0.0: version "1.2.1" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.2.1.tgz#36d7c4739f775b3cbc28e6136e21aa057adec418" diff --git a/example/alerter/Dockerfile b/example/alerter/Dockerfile index d8c88e32d..a264ee71e 100644 --- a/example/alerter/Dockerfile +++ b/example/alerter/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.87.0 as builder +FROM rust:1.89.0 as builder WORKDIR /builder COPY . . diff --git a/example/update_logger/Dockerfile b/example/update_logger/Dockerfile index af13660d0..ed5c4426c 100644 --- a/example/update_logger/Dockerfile +++ b/example/update_logger/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.87.0 as builder +FROM rust:1.89.0 as builder WORKDIR /builder COPY . . diff --git a/frontend/public/client/lib.d.ts b/frontend/public/client/lib.d.ts index 31b35a263..1c4847229 100644 --- a/frontend/public/client/lib.d.ts +++ b/frontend/public/client/lib.d.ts @@ -162,7 +162,7 @@ export declare function KomodoClient(url: string, options: InitOptions): { * and gives a callback to handle the output as it comes in. * * ```ts - * const stream = await komodo.execute_terminal( + * await komodo.execute_terminal( * { * server: "my-server", * terminal: "name", @@ -222,7 +222,7 @@ export declare function KomodoClient(url: string, options: InitOptions): { * and gives a callback to handle the output as it comes in. * * ```ts - * const stream = await komodo.execute_container_exec( + * await komodo.execute_container_exec( * { * server: "my-server", * container: "name", @@ -275,7 +275,7 @@ export declare function KomodoClient(url: string, options: InitOptions): { * and gives a callback to handle the output as it comes in. * * ```ts - * const stream = await komodo.execute_deployment_exec( + * await komodo.execute_deployment_exec( * { * deployment: "my-deployment", * shell: "bash", @@ -326,7 +326,7 @@ export declare function KomodoClient(url: string, options: InitOptions): { * and gives a callback to handle the output as it comes in. * * ```ts - * const stream = await komodo.execute_stack_exec( + * await komodo.execute_stack_exec( * { * stack: "my-stack", * service: "database" diff --git a/frontend/public/client/lib.js b/frontend/public/client/lib.js index d1681eb22..e1ff19d7e 100644 --- a/frontend/public/client/lib.js +++ b/frontend/public/client/lib.js @@ -279,7 +279,7 @@ export function KomodoClient(url, options) { * and gives a callback to handle the output as it comes in. * * ```ts - * const stream = await komodo.execute_terminal( + * await komodo.execute_terminal( * { * server: "my-server", * terminal: "name", @@ -335,7 +335,7 @@ export function KomodoClient(url, options) { * and gives a callback to handle the output as it comes in. * * ```ts - * const stream = await komodo.execute_container_exec( + * await komodo.execute_container_exec( * { * server: "my-server", * container: "name", @@ -386,7 +386,7 @@ export function KomodoClient(url, options) { * and gives a callback to handle the output as it comes in. * * ```ts - * const stream = await komodo.execute_deployment_exec( + * await komodo.execute_deployment_exec( * { * deployment: "my-deployment", * shell: "bash", @@ -435,7 +435,7 @@ export function KomodoClient(url, options) { * and gives a callback to handle the output as it comes in. * * ```ts - * const stream = await komodo.execute_stack_exec( + * await komodo.execute_stack_exec( * { * stack: "my-stack", * service: "database" diff --git a/frontend/public/client/responses.d.ts b/frontend/public/client/responses.d.ts index c667ffe97..5f9426fd0 100644 --- a/frontend/public/client/responses.d.ts +++ b/frontend/public/client/responses.d.ts @@ -1,7 +1,7 @@ import * as Types from "./types.js"; export type AuthResponses = { GetLoginOptions: Types.GetLoginOptionsResponse; - CreateLocalUser: Types.CreateLocalUserResponse; + SignUpLocalUser: Types.SignUpLocalUserResponse; LoginLocalUser: Types.LoginLocalUserResponse; ExchangeForJwt: Types.ExchangeForJwtResponse; GetUser: Types.GetUserResponse; @@ -134,9 +134,10 @@ export type ReadResponses = { ListDockerRegistryAccounts: Types.ListDockerRegistryAccountsResponse; }; export type WriteResponses = { - UpdateUserUsername: Types.UpdateUserUsername; - UpdateUserPassword: Types.UpdateUserPassword; - DeleteUser: Types.DeleteUser; + CreateLocalUser: Types.CreateLocalUserResponse; + UpdateUserUsername: Types.UpdateUserUsernameResponse; + UpdateUserPassword: Types.UpdateUserPasswordResponse; + DeleteUser: Types.DeleteUserResponse; CreateServiceUser: Types.CreateServiceUserResponse; UpdateServiceUserDescription: Types.UpdateServiceUserDescriptionResponse; CreateApiKeyForServiceUser: Types.CreateApiKeyForServiceUserResponse; @@ -308,4 +309,7 @@ export type ExecuteResponses = { UnpauseStackService: Types.Update; DestroyStackService: Types.Update; TestAlerter: Types.Update; + ClearRepoCache: Types.Update; + BackupCoreDatabase: Types.Update; + GlobalAutoUpdate: Types.Update; }; diff --git a/frontend/public/client/types.d.ts b/frontend/public/client/types.d.ts index 8214946ef..9f762c7f7 100644 --- a/frontend/public/client/types.d.ts +++ b/frontend/public/client/types.d.ts @@ -52,7 +52,15 @@ export declare enum ScheduleFormat { English = "English", Cron = "Cron" } +export declare enum FileFormat { + KeyValue = "key_value", + Toml = "toml", + Yaml = "yaml", + Json = "json" +} export interface ActionConfig { + /** Whether this action should run at startup. */ + run_at_startup: boolean; /** Choose whether to specify schedule as regular CRON, or using the english to CRON parser. */ schedule_format?: ScheduleFormat; /** @@ -105,6 +113,13 @@ export interface ActionConfig { * Supports variable / secret interpolation. */ file_contents?: string; + /** + * Specify the format in which the arguments are defined. + * Default: `key_value` (like environment) + */ + arguments_format?: FileFormat; + /** Default arguments to give to the Action for use in the script at `ARGS`. */ + arguments?: string; } /** Represents an empty json object: `{}` */ export interface NoData { @@ -437,6 +452,9 @@ export declare enum Operation { WriteSyncContents = "WriteSyncContents", CommitSync = "CommitSync", RunSync = "RunSync", + ClearRepoCache = "ClearRepoCache", + BackupCoreDatabase = "BackupCoreDatabase", + GlobalAutoUpdate = "GlobalAutoUpdate", CreateVariable = "CreateVariable", UpdateVariableValue = "UpdateVariableValue", DeleteVariable = "DeleteVariable", @@ -688,12 +706,12 @@ export interface BuildInfo { } export type Build = Resource; export declare enum BuildState { + /** Currently building */ + Building = "Building", /** Last build successful (or never built) */ Ok = "Ok", /** Last build failed */ Failed = "Failed", - /** Currently building */ - Building = "Building", /** Other case */ Unknown = "Unknown" } @@ -775,19 +793,25 @@ export type Execution = { type: "None"; params: NoData; -} | { +} +/** Run the target action. (alias: `action`, `ac`) */ + | { type: "RunAction"; params: RunAction; } | { type: "BatchRunAction"; params: BatchRunAction; -} | { +} +/** Run the target procedure. (alias: `procedure`, `pr`) */ + | { type: "RunProcedure"; params: RunProcedure; } | { type: "BatchRunProcedure"; params: BatchRunProcedure; -} | { +} +/** Run the target build. (alias: `build`, `bd`) */ + | { type: "RunBuild"; params: RunBuild; } | { @@ -796,7 +820,9 @@ export type Execution = } | { type: "CancelBuild"; params: CancelBuild; -} | { +} +/** Deploy the target deployment. (alias: `dp`) */ + | { type: "Deploy"; params: Deploy; } | { @@ -826,7 +852,9 @@ export type Execution = } | { type: "BatchDestroyDeployment"; params: BatchDestroyDeployment; -} | { +} +/** Clone the target repo */ + | { type: "CloneRepo"; params: CloneRepo; } | { @@ -910,13 +938,19 @@ export type Execution = } | { type: "PruneSystem"; params: PruneSystem; -} | { +} +/** Execute a Resource Sync. (alias: `sync`) */ + | { type: "RunSync"; params: RunSync; -} | { +} +/** Commit a Resource Sync. (alias: `commit`) */ + | { type: "CommitSync"; params: CommitSync; -} | { +} +/** Deploy the target stack. (alias: `stack`, `st`) */ + | { type: "DeployStack"; params: DeployStack; } | { @@ -958,6 +992,15 @@ export type Execution = } | { type: "TestAlerter"; params: TestAlerter; +} | { + type: "ClearRepoCache"; + params: ClearRepoCache; +} | { + type: "BackupCoreDatabase"; + params: BackupCoreDatabase; +} | { + type: "GlobalAutoUpdate"; + params: GlobalAutoUpdate; } | { type: "Sleep"; params: Sleep; @@ -1100,15 +1143,6 @@ export interface GitProviderAccount { token?: string; } export type CreateGitProviderAccountResponse = GitProviderAccount; -/** JSON containing an authentication token. */ -export interface JwtResponse { - /** A token the user can use to authenticate their requests. */ - jwt: string; -} -/** Response for [CreateLocalUser]. */ -export type CreateLocalUserResponse = JwtResponse; -export type CreateProcedureResponse = Procedure; -export type CreateRepoWebhookResponse = NoData; export type UserConfig = /** User that logs in with username / password */ { @@ -1177,6 +1211,9 @@ export interface User { all?: Record; updated_at?: I64; } +export type CreateLocalUserResponse = User; +export type CreateProcedureResponse = Procedure; +export type CreateRepoWebhookResponse = NoData; export type CreateServiceUserResponse = User; export type CreateStackWebhookResponse = NoData; export type CreateSyncWebhookResponse = NoData; @@ -1392,6 +1429,13 @@ export interface DeploymentQuerySpecifics { update_available?: boolean; } export type DeploymentQuery = ResourceQuery; +/** JSON containing an authentication token. */ +export interface JwtResponse { + /** User ID for signed in user. */ + user_id: string; + /** A token the user can use to authenticate their requests. */ + jwt: string; +} /** Response for [ExchangeForJwt]. */ export type ExchangeForJwtResponse = JwtResponse; /** Response containing pretty formatted toml contents. */ @@ -2031,6 +2075,11 @@ export interface ServerConfig { * Default: http://localhost:8120 */ address: string; + /** + * The address to use with links for containers on the server. + * If empty, will use the 'address' for links. + */ + external_address?: string; /** An optional region label */ region?: string; /** @@ -2515,9 +2564,9 @@ export interface Tag { */ _id?: MongoId; name: string; + owner?: string; /** Hex color code with alpha for UI display */ color?: TagColor; - owner?: string; } export type GetTagResponse = Tag; export type GetUpdateResponse = Update; @@ -2551,14 +2600,14 @@ export type GetUserGroupResponse = UserGroup; export type GetUserResponse = User; export type GetVariableResponse = Variable; export declare enum ContainerStateStatusEnum { - Empty = "", - Created = "created", Running = "running", + Created = "created", Paused = "paused", Restarting = "restarting", Exited = "exited", Removing = "removing", - Dead = "dead" + Dead = "dead", + Empty = "" } export declare enum HealthStatusEnum { Empty = "", @@ -3290,6 +3339,7 @@ export interface Volume { } export type InspectDockerVolumeResponse = Volume; export type InspectStackContainerResponse = Container; +export type JsonObject = any; export type JsonValue = any; export type ListActionsResponse = ActionListItem[]; export type ListAlertersResponse = AlerterListItem[]; @@ -3334,11 +3384,11 @@ export interface ContainerListItem { /** The network mode */ network_mode?: string; /** The network names attached to container */ - networks: string[]; + networks?: string[]; /** Port mappings for the container */ - ports: Port[]; + ports?: Port[]; /** The volume names attached to container */ - volumes: string[]; + volumes?: string[]; /** The container stats, if they can be retreived. */ stats?: ContainerStats; /** @@ -3508,12 +3558,12 @@ export interface Permission { } export type ListPermissionsResponse = Permission[]; export declare enum ProcedureState { + /** Currently running */ + Running = "Running", /** Last run successful */ Ok = "Ok", /** Last run failed */ Failed = "Failed", - /** Currently running */ - Running = "Running", /** Other case (never run) */ Unknown = "Unknown" } @@ -3582,14 +3632,14 @@ export interface RepoListItemInfo { export type RepoListItem = ResourceListItem; export type ListReposResponse = RepoListItem[]; export declare enum ResourceSyncState { - /** Last sync successful (or never synced). No Changes pending */ - Ok = "Ok", - /** Last sync failed */ - Failed = "Failed", /** Currently syncing */ Syncing = "Syncing", /** Updates pending */ Pending = "Pending", + /** Last sync successful (or never synced). No Changes pending */ + Ok = "Ok", + /** Last sync failed */ + Failed = "Failed", /** Other case */ Unknown = "Unknown" } @@ -3652,10 +3702,10 @@ export interface Schedule { export type ListSchedulesResponse = Schedule[]; export type ListSecretsResponse = string[]; export declare enum ServerState { - /** Server is unreachable. */ - NotOk = "NotOk", /** Server health check passing. */ Ok = "Ok", + /** Server is unreachable. */ + NotOk = "NotOk", /** Server is disabled. */ Disabled = "Disabled" } @@ -3666,6 +3716,11 @@ export interface ServerListItemInfo { region: string; /** Address of the server. */ address: string; + /** + * External address of the server (reachable by users). + * Used with links. + */ + external_address?: string; /** The Komodo Periphery version of the server. */ version: string; /** Whether server is configured to send unreachable alerts. */ @@ -3839,6 +3894,8 @@ export interface ServerQuerySpecifics { /** Server-specific query */ export type ServerQuery = ResourceQuery; export type SetLastSeenUpdateResponse = NoData; +/** Response for [SignUpLocalUser]. */ +export type SignUpLocalUserResponse = JwtResponse; export interface StackQuerySpecifics { /** * Query only for Stacks on these Servers. @@ -3942,6 +3999,18 @@ export interface AwsBuilderConfig { /** Which secrets are available on the AMI. */ secrets?: string[]; } +/** + * Backs up the Komodo Core database to compressed jsonl files. + * Admin only. Response: [Update] + * + * Mount a folder to `/backups`, and Core will use it to create + * timestamped database dumps, which can be restored using + * the Komodo CLI. + * + * TODO: Link to docs + */ +export interface BackupCoreDatabase { +} /** Builds multiple Repos in parallel that match pattern. Response: [BatchExecutionResponse]. */ export interface BatchBuildRepo { /** @@ -4178,6 +4247,12 @@ export interface CancelRepoBuild { /** Can be id or name */ repo: string; } +/** + * Clears all repos from the Core repo cache. Admin only. + * Response: [Update] + */ +export interface ClearRepoCache { +} /** * Clones the target repo. Response: [Update]. * @@ -4677,19 +4752,17 @@ export interface CreateGitProviderAccount { account: _PartialGitProviderAccount; } /** - * Create a new local user account. Will fail if a user with the - * given username already exists. - * Response: [CreateLocalUserResponse]. + * **Admin only.** Create a local user. + * Response: [User]. * - * Note. This method is only available if the core api has `local_auth` enabled. + * Note. Not to be confused with /auth/SignUpLocalUser. + * This method requires admin user credentials, and can + * bypass disabled user registration. */ export interface CreateLocalUser { - /** The username for the new user. */ + /** The username for the local user. */ username: string; - /** - * The password for the new user. - * This cannot be retreived later. - */ + /** A password for the local user. */ password: string; } /** @@ -4796,6 +4869,8 @@ export interface CreateSyncWebhook { export interface CreateTag { /** The name of the tag. */ name: string; + /** Tag color. Default: Slate. */ + color?: TagColor; } /** * Configures the behavior of [CreateTerminal] if the @@ -5353,7 +5428,7 @@ export interface FullContainerStats { precpu_stats?: ContainerCpuStats; memory_stats?: ContainerMemoryStats; /** Network statistics for the container per interface. This field is omitted if the container has no networking enabled. */ - networks?: ContainerNetworkStats; + networks?: Record; } /** Get a specific action. Response: [Action]. */ export interface GetAction { @@ -5529,6 +5604,8 @@ export interface GetCoreInfoResponse { github_webhook_owners: string[]; /** Whether to disable websocket automatic reconnect. */ disable_websocket_reconnect: boolean; + /** Whether to enable fancy toml highlighting. */ + enable_fancy_toml: boolean; /** TZ identifier Core is using, if manually set. */ timezone: string; } @@ -6061,6 +6138,16 @@ export interface GetVersionResponse { /** The version of the core api. */ version: string; } +/** + * Trigger a global poll for image updateson Stacks and Deployments + * with `poll_for_updates` or `auto_update` enabled. + * Admin only. Response: [Update] + * + * 1. `docker compose pull` any Stacks / Deployments with `poll_for_updates` or `auto_update` enabled. This will pick up any available updates. + * 2. Redeploy Stacks / Deployments that have updates found. + */ +export interface GlobalAutoUpdate { +} /** * Inspect the docker container associated with the Deployment. * Response: [Container]. @@ -7053,14 +7140,28 @@ export interface RestartStack { export interface RunAction { /** Id or name */ action: string; + /** + * Custom arguments which are merged on top of the default arguments. + * CLI Format: `"VAR1=val1&VAR2=val2"` + * + * Webhook-triggered actions use this to pass WEBHOOK_BRANCH and WEBHOOK_BODY. + */ + args?: JsonObject; } /** * Runs the target build. Response: [Update]. * * 1. Get a handle to the builder. If using AWS builder, this means starting a builder ec2 instance. + * * 2. Clone the repo on the builder. If an `on_clone` commmand is given, it will be executed. + * * 3. Execute `docker build {...params}`, where params are determined using the builds configuration. - * 4. If a dockerhub account is attached, the build will be pushed to that account. + * + * 4. If a docker registry is configured, the build will be pushed to the registry. + * + * 5. If using AWS builder, destroy the builder ec2 instance. + * + * 6. Deploy any Deployments with *Redeploy on Build* enabled. */ export interface RunBuild { /** Can be build id or name */ @@ -7211,6 +7312,23 @@ export interface SetUsersInUserGroup { /** The user ids or usernames to hard set as the group's users. */ users: string[]; } +/** + * Sign up a new local user account. Will fail if a user with the + * given username already exists. + * Response: [SignUpLocalUserResponse]. + * + * Note. This method is only available if the core api has `local_auth` enabled, + * and if user registration is not disabled (after the first user). + */ +export interface SignUpLocalUser { + /** The username for the new user. */ + username: string; + /** + * The password for the new user. + * This cannot be retreived later. + */ + password: string; +} /** Info for network interface usage. */ export interface SingleNetworkInterfaceUsage { /** The network interface name */ @@ -7225,6 +7343,7 @@ export interface SlackAlerterEndpoint { /** The Slack app webhook url */ url: string; } +/** Sleeps for the specified time. */ export interface Sleep { duration_ms?: I64; } @@ -7724,8 +7843,8 @@ export type AuthRequest = { type: "GetLoginOptions"; params: GetLoginOptions; } | { - type: "CreateLocalUser"; - params: CreateLocalUser; + type: "SignUpLocalUser"; + params: SignUpLocalUser; } | { type: "LoginLocalUser"; params: LoginLocalUser; @@ -7926,6 +8045,15 @@ export type ExecuteRequest = { } | { type: "RunSync"; params: RunSync; +} | { + type: "ClearRepoCache"; + params: ClearRepoCache; +} | { + type: "BackupCoreDatabase"; + params: BackupCoreDatabase; +} | { + type: "GlobalAutoUpdate"; + params: GlobalAutoUpdate; }; /** * One representative IANA zone for each distinct base UTC offset in the tz database. @@ -8434,6 +8562,9 @@ export type UserRequest = { params: DeleteApiKey; }; export type WriteRequest = { + type: "CreateLocalUser"; + params: CreateLocalUser; +} | { type: "UpdateUserUsername"; params: UpdateUserUsername; } | { diff --git a/frontend/public/client/types.js b/frontend/public/client/types.js index 491bd0aae..2df8d222a 100644 --- a/frontend/public/client/types.js +++ b/frontend/public/client/types.js @@ -1,5 +1,5 @@ /* - Generated by typeshare 1.13.2 + Generated by typeshare 1.13.3 */ /** The levels of permission that a User or UserGroup can have on a resource. */ export var PermissionLevel; @@ -18,6 +18,13 @@ export var ScheduleFormat; ScheduleFormat["English"] = "English"; ScheduleFormat["Cron"] = "Cron"; })(ScheduleFormat || (ScheduleFormat = {})); +export var FileFormat; +(function (FileFormat) { + FileFormat["KeyValue"] = "key_value"; + FileFormat["Toml"] = "toml"; + FileFormat["Yaml"] = "yaml"; + FileFormat["Json"] = "json"; +})(FileFormat || (FileFormat = {})); export var ActionState; (function (ActionState) { /** Unknown case */ @@ -159,6 +166,9 @@ export var Operation; Operation["WriteSyncContents"] = "WriteSyncContents"; Operation["CommitSync"] = "CommitSync"; Operation["RunSync"] = "RunSync"; + Operation["ClearRepoCache"] = "ClearRepoCache"; + Operation["BackupCoreDatabase"] = "BackupCoreDatabase"; + Operation["GlobalAutoUpdate"] = "GlobalAutoUpdate"; Operation["CreateVariable"] = "CreateVariable"; Operation["UpdateVariableValue"] = "UpdateVariableValue"; Operation["DeleteVariable"] = "DeleteVariable"; @@ -181,12 +191,12 @@ export var UpdateStatus; })(UpdateStatus || (UpdateStatus = {})); export var BuildState; (function (BuildState) { + /** Currently building */ + BuildState["Building"] = "Building"; /** Last build successful (or never built) */ BuildState["Ok"] = "Ok"; /** Last build failed */ BuildState["Failed"] = "Failed"; - /** Currently building */ - BuildState["Building"] = "Building"; /** Other case */ BuildState["Unknown"] = "Unknown"; })(BuildState || (BuildState = {})); @@ -349,14 +359,14 @@ export var TagColor; })(TagColor || (TagColor = {})); export var ContainerStateStatusEnum; (function (ContainerStateStatusEnum) { - ContainerStateStatusEnum["Empty"] = ""; - ContainerStateStatusEnum["Created"] = "created"; ContainerStateStatusEnum["Running"] = "running"; + ContainerStateStatusEnum["Created"] = "created"; ContainerStateStatusEnum["Paused"] = "paused"; ContainerStateStatusEnum["Restarting"] = "restarting"; ContainerStateStatusEnum["Exited"] = "exited"; ContainerStateStatusEnum["Removing"] = "removing"; ContainerStateStatusEnum["Dead"] = "dead"; + ContainerStateStatusEnum["Empty"] = ""; })(ContainerStateStatusEnum || (ContainerStateStatusEnum = {})); export var HealthStatusEnum; (function (HealthStatusEnum) { @@ -451,12 +461,12 @@ export var PortTypeEnum; })(PortTypeEnum || (PortTypeEnum = {})); export var ProcedureState; (function (ProcedureState) { + /** Currently running */ + ProcedureState["Running"] = "Running"; /** Last run successful */ ProcedureState["Ok"] = "Ok"; /** Last run failed */ ProcedureState["Failed"] = "Failed"; - /** Currently running */ - ProcedureState["Running"] = "Running"; /** Other case (never run) */ ProcedureState["Unknown"] = "Unknown"; })(ProcedureState || (ProcedureState = {})); @@ -477,23 +487,23 @@ export var RepoState; })(RepoState || (RepoState = {})); export var ResourceSyncState; (function (ResourceSyncState) { - /** Last sync successful (or never synced). No Changes pending */ - ResourceSyncState["Ok"] = "Ok"; - /** Last sync failed */ - ResourceSyncState["Failed"] = "Failed"; /** Currently syncing */ ResourceSyncState["Syncing"] = "Syncing"; /** Updates pending */ ResourceSyncState["Pending"] = "Pending"; + /** Last sync successful (or never synced). No Changes pending */ + ResourceSyncState["Ok"] = "Ok"; + /** Last sync failed */ + ResourceSyncState["Failed"] = "Failed"; /** Other case */ ResourceSyncState["Unknown"] = "Unknown"; })(ResourceSyncState || (ResourceSyncState = {})); export var ServerState; (function (ServerState) { - /** Server is unreachable. */ - ServerState["NotOk"] = "NotOk"; /** Server health check passing. */ ServerState["Ok"] = "Ok"; + /** Server is unreachable. */ + ServerState["NotOk"] = "NotOk"; /** Server is disabled. */ ServerState["Disabled"] = "Disabled"; })(ServerState || (ServerState = {})); diff --git a/frontend/public/index.d.ts b/frontend/public/index.d.ts index c8fd29dae..96d27960e 100644 --- a/frontend/public/index.d.ts +++ b/frontend/public/index.d.ts @@ -758,6 +758,11 @@ declare global { var KomodoClient: typeof Client; /** All Komodo Types */ export import Types = KomodoTypes; + /** The incoming arguments */ + var ARGS: { + WEBHOOK_BRANCH?: string; + WEBHOOK_BODY?: any; + } & Record; /** YAML parsing utilities */ var YAML: { /** diff --git a/frontend/runfile.toml b/frontend/runfile.toml new file mode 100644 index 000000000..8bf04d53d --- /dev/null +++ b/frontend/runfile.toml @@ -0,0 +1,10 @@ +[dev-frontend] +alias = "df" +description = "starts the frontend in dev mode" +cmd = "yarn dev" + +[build-frontend] +alias = "bf" +description = "generates fresh ts client and builds the frontend" +cmd = "yarn build" +after = "gen-client" \ No newline at end of file diff --git a/frontend/src/components/alert/topbar.tsx b/frontend/src/components/alert/topbar.tsx deleted file mode 100644 index 75afd4820..000000000 --- a/frontend/src/components/alert/topbar.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import { useRead } from "@lib/hooks"; -import { Button } from "@ui/button"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from "@ui/dropdown-menu"; -import { AlertTriangle } from "lucide-react"; -import { AlertLevel } from "."; -import { ResourceLink } from "@components/resources/common"; -import { UsableResource } from "@types"; -import { Dialog } from "@ui/dialog"; -import { Types } from "komodo_client"; -import { useState } from "react"; -import { AlertDetailsDialogContent } from "./details"; - -export const TopbarAlerts = () => { - const { data } = useRead( - "ListAlerts", - { query: { resolved: false } }, - { refetchInterval: 3_000 } - ); - const [open, setOpen] = useState(false); - - // If this is set, details will open. - const [alert, setAlert] = useState(); - - if (!data || data.alerts.length === 0) { - return null; - } - - return ( - <> - - - - - - {data?.alerts.map((alert) => ( - setAlert(alert)} - > -

- -
-
-
- setOpen(false)} - /> -
-
-

{alert.data.type}

- - ))} - - - setAlert(undefined)} /> - - ); -}; - -const AlertDetails = ({ - alert, - onClose, -}: { - alert: Types.Alert | undefined; - onClose: () => void; -}) => ( - <> - {alert && ( - !o && onClose()}> - - - )} - -); diff --git a/frontend/src/components/export.tsx b/frontend/src/components/export.tsx index 3bc4db22b..10deaa47c 100644 --- a/frontend/src/components/export.tsx +++ b/frontend/src/components/export.tsx @@ -92,7 +92,7 @@ const ExportPre = ({ return (
{loading && } - +
); diff --git a/frontend/src/components/layouts.tsx b/frontend/src/components/layouts.tsx index 64af30c01..7f6c06268 100644 --- a/frontend/src/components/layouts.tsx +++ b/frontend/src/components/layouts.tsx @@ -211,12 +211,14 @@ export const NewLayout = ({ enabled, onConfirm, onOpenChange, + configureLabel = "a unique name", }: { entityType: string; children: ReactNode; enabled: boolean; onConfirm: () => Promise; onOpenChange?: (open: boolean) => void; + configureLabel?: string; }) => { const [open, set] = useState(false); const [loading, setLoading] = useState(false); @@ -236,7 +238,9 @@ export const NewLayout = ({ New {entityType} - Enter a unique name for the new {entityType}. + + Enter {configureLabel} for the new {entityType}. +
{children}
diff --git a/frontend/src/components/log.tsx b/frontend/src/components/log.tsx index 3de220d22..5afa7d063 100644 --- a/frontend/src/components/log.tsx +++ b/frontend/src/components/log.tsx @@ -35,7 +35,8 @@ export const LogSection = ({ regular_logs: ( timestamps: boolean, stream: LogStream, - tail: number + tail: number, + poll: boolean ) => { Log: ReactNode; refetch: () => void; @@ -44,7 +45,8 @@ export const LogSection = ({ search_logs: ( timestamps: boolean, terms: string[], - invert: boolean + invert: boolean, + poll: boolean ) => { Log: ReactNode; refetch: () => void; stderr: boolean }; titleOther?: ReactNode; extraParams?: ReactNode; @@ -78,8 +80,8 @@ export const LogSection = ({ }; const { Log, refetch, stderr } = terms.length - ? search_logs(timestamps, terms, invert) - : regular_logs(timestamps, stream, Number(tail)); + ? search_logs(timestamps, terms, invert, poll) + : regular_logs(timestamps, stream, Number(tail), poll); return (
{ + const enable_fancy_toml = + useRead("GetCoreInfo", {}).data?.enable_fancy_toml ?? false; + const language = ( + _language === "fancy_toml" && !enable_fancy_toml ? "toml" : _language + ) as MonacoLanguage; const dimensions = useWindowDimensions(); const [editor, setEditor] = useState(null); @@ -153,7 +159,7 @@ export const MonacoDiffEditor = ({ original, modified, onModifiedValueChange, - language, + language: _language, readOnly, containerClassName, hideUnchangedRegions = true, @@ -166,6 +172,12 @@ export const MonacoDiffEditor = ({ containerClassName?: string; hideUnchangedRegions?: boolean; }) => { + const enable_fancy_toml = + useRead("GetCoreInfo", {}).data?.enable_fancy_toml ?? false; + const language = ( + _language === "fancy_toml" && !enable_fancy_toml ? "toml" : _language + ) as MonacoLanguage; + const [editor, setEditor] = useState(null); diff --git a/frontend/src/components/resources/action/config.tsx b/frontend/src/components/resources/action/config.tsx index 3397850a5..79c855f1c 100644 --- a/frontend/src/components/resources/action/config.tsx +++ b/frontend/src/components/resources/action/config.tsx @@ -29,6 +29,7 @@ import { SelectValue, } from "@ui/select"; import { TimezoneSelector } from "@components/util"; +import { snake_case_to_upper_space_case } from "@lib/formatting"; const ACTION_GIT_PROVIDER = "Action"; @@ -106,6 +107,59 @@ export const ActionConfig = ({ id }: { id: string }) => { }, }, }, + { + label: "Arguments", + description: "Manage the action file default arguments.", + components: { + arguments: (args, set) => { + const format = + update.arguments_format ?? + config.arguments_format ?? + Types.FileFormat.KeyValue; + return ( +
+
+ + +
+ set({ arguments: args })} + language={ + update.arguments_format ?? + config.arguments_format ?? + Types.FileFormat.KeyValue + } + readOnly={disabled} + /> +
+ ); + }, + }, + }, + { label: "Alert", labelHidden: true, @@ -211,6 +265,17 @@ export const ActionConfig = ({ id }: { id: string }) => { }, }, }, + { + label: "Startup", + labelHidden: true, + components: { + run_at_startup: { + label: "Run on Startup", + description: + "Run this action on completion of startup of Komodo Core", + }, + }, + }, { label: "Reload", labelHidden: true, @@ -278,3 +343,16 @@ export const ActionConfig = ({ id }: { id: string }) => { /> ); }; + +const default_arguments = (format: Types.FileFormat) => { + switch (format) { + case Types.FileFormat.KeyValue: + return "# ARG_NAME = value\n"; + case Types.FileFormat.Toml: + return '# ARG_NAME = "value"\n'; + case Types.FileFormat.Yaml: + return "# ARG_NAME: value\n"; + case Types.FileFormat.Json: + return "{}\n"; + } +}; diff --git a/frontend/src/components/resources/action/index.tsx b/frontend/src/components/resources/action/index.tsx index 6943c4665..240b3eb15 100644 --- a/frontend/src/components/resources/action/index.tsx +++ b/frontend/src/components/resources/action/index.tsx @@ -132,7 +132,7 @@ export const ActionComponents: RequiredResourceComponents = { name={action.name} title={running ? "Running" : "Run Action"} icon={} - onClick={() => mutate({ action: id })} + onClick={() => mutate({ action: id, args: {} })} disabled={running || isPending} loading={running} /> diff --git a/frontend/src/components/resources/action/table.tsx b/frontend/src/components/resources/action/table.tsx index ab7fec0dc..11e05d00e 100644 --- a/frontend/src/components/resources/action/table.tsx +++ b/frontend/src/components/resources/action/table.tsx @@ -37,6 +37,28 @@ export const ActionTable = ({ ), cell: ({ row }) => , }, + { + accessorKey: "info.next_scheduled_run", + header: ({ column }) => ( + + ), + sortingFn: (a, b) => { + const sa = a.original.info.next_scheduled_run; + const sb = b.original.info.next_scheduled_run; + + if (!sa && !sb) return 0; + if (!sa) return 1; + if (!sb) return -1; + + if (sa > sb) return 1; + else if (sa < sb) return -1; + else return 0; + }, + cell: ({ row }) => + row.original.info.next_scheduled_run + ? new Date(row.original.info.next_scheduled_run).toLocaleString() + : "Not Scheduled", + }, { header: "Tags", cell: ({ row }) => , diff --git a/frontend/src/components/resources/alerter/config/alert_types.tsx b/frontend/src/components/resources/alerter/config/alert_types.tsx index c1192303c..00b87b85a 100644 --- a/frontend/src/components/resources/alerter/config/alert_types.tsx +++ b/frontend/src/components/resources/alerter/config/alert_types.tsx @@ -19,10 +19,13 @@ const ALERT_TYPES: Types.AlertData["type"][] = [ "DeploymentImageUpdateAvailable", "DeploymentAutoUpdated", // Misc - "AwsBuilderTerminationFailed", - "ResourceSyncPendingUpdates", + "ScheduleRun", "BuildFailed", + "ResourceSyncPendingUpdates", "RepoBuildFailed", + "ActionFailed", + "ProcedureFailed", + "AwsBuilderTerminationFailed", ]; export const AlertTypeConfig = ({ diff --git a/frontend/src/components/resources/build/config.tsx b/frontend/src/components/resources/build/config.tsx index 4001fd656..169b8bfd0 100644 --- a/frontend/src/components/resources/build/config.tsx +++ b/frontend/src/components/resources/build/config.tsx @@ -371,7 +371,7 @@ export const BuildConfig = ({ /> )} { diff --git a/frontend/src/components/resources/common.tsx b/frontend/src/components/resources/common.tsx index b77dc0b6a..7522e2175 100644 --- a/frontend/src/components/resources/common.tsx +++ b/frontend/src/components/resources/common.tsx @@ -85,7 +85,7 @@ export const ResourcePageHeader = ({ const background = hex_color_by_intention(intent) + "15"; return (
diff --git a/frontend/src/components/resources/deployment/index.tsx b/frontend/src/components/resources/deployment/index.tsx index e3912ed3f..25d160e22 100644 --- a/frontend/src/components/resources/deployment/index.tsx +++ b/frontend/src/components/resources/deployment/index.tsx @@ -1,5 +1,5 @@ import { useLocalStorage, useRead } from "@lib/hooks"; -import { Types } from "komodo_client"; +import { ConnectExecQuery, Types } from "komodo_client"; import { RequiredResourceComponents } from "@types"; import { CircleArrowUp, HardDrive, Rocket, Server } from "lucide-react"; import { cn } from "@lib/utils"; @@ -38,6 +38,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "@ui/tooltip"; import { usePermissions } from "@lib/hooks"; import { ContainerTerminal } from "@components/terminal/container"; import { DeploymentInspect } from "./inspect"; +import { useMemo } from "react"; // const configOrLog = atomWithStorage("config-or-log-v1", "Config"); @@ -65,7 +66,7 @@ const ConfigTabsInner = ({ const [_view, setView] = useLocalStorage< "Config" | "Log" | "Inspect" | "Terminal" >("deployment-tabs-v1", "Config"); - const { specific } = usePermissions({ + const { specificLogs, specificInspect, specificTerminal } = usePermissions({ type: "Deployment", id: deployment.id, }); @@ -73,17 +74,17 @@ const ConfigTabsInner = ({ useServer(deployment.info.server_id)?.info.container_exec_disabled ?? true; const state = deployment.info.state; const logsDisabled = - !specific.includes(Types.SpecificPermission.Logs) || + !specificLogs || state === undefined || state === Types.DeploymentState.Unknown || state === Types.DeploymentState.NotDeployed; const inspectDisabled = - !specific.includes(Types.SpecificPermission.Inspect) || + !specificInspect || state === undefined || state === Types.DeploymentState.Unknown || state === Types.DeploymentState.NotDeployed; const terminalDisabled = - !specific.includes(Types.SpecificPermission.Terminal) || + !specificTerminal || container_exec_disabled || state !== Types.DeploymentState.Running; const view = @@ -93,38 +94,64 @@ const ConfigTabsInner = ({ ? "Config" : _view; - const tabs = ( - - - Config - - {specific.includes(Types.SpecificPermission.Logs) && ( - - Log + const tabs = useMemo( + () => ( + + + Config - )} - {specific.includes(Types.SpecificPermission.Inspect) && ( - - Inspect - - )} - {specific.includes(Types.SpecificPermission.Terminal) && ( - - Terminal - - )} - + {specificLogs && ( + + Log + + )} + {specificInspect && ( + + Inspect + + )} + {specificTerminal && ( + + Terminal + + )} + + ), + [ + specificLogs, + logsDisabled, + specificInspect, + inspectDisabled, + specificTerminal, + terminalDisabled, + ] + ); + const terminalQuery = useMemo( + () => + ({ + type: "deployment", + query: { + deployment: deployment.id, + // This is handled inside ContainerTerminal + shell: "", + }, + }) as ConnectExecQuery, + [deployment.id] ); return ( - + @@ -135,17 +162,7 @@ const ConfigTabsInner = ({ - + ); @@ -314,7 +331,7 @@ export const DeploymentComponents: RequiredResourceComponents = { if (!container) return null; return ( ); diff --git a/frontend/src/components/resources/deployment/log.tsx b/frontend/src/components/resources/deployment/log.tsx index 46f1cf14f..794a3864f 100644 --- a/frontend/src/components/resources/deployment/log.tsx +++ b/frontend/src/components/resources/deployment/log.tsx @@ -31,11 +31,11 @@ const DeploymentLogsInner = ({ }) => { return ( - NoSearchLogs(id, tail, timestamps, stream) + regular_logs={(timestamps, stream, tail, poll) => + NoSearchLogs(id, tail, timestamps, stream, poll) } - search_logs={(timestamps, terms, invert) => - SearchLogs(id, terms, invert, timestamps) + search_logs={(timestamps, terms, invert, poll) => + SearchLogs(id, terms, invert, timestamps, poll) } titleOther={titleOther} /> @@ -46,13 +46,18 @@ const NoSearchLogs = ( id: string, tail: number, timestamps: boolean, - stream: string + stream: string, + poll: boolean ) => { - const { data: log, refetch } = useRead("GetDeploymentLog", { - deployment: id, - tail, - timestamps, - }); + const { data: log, refetch } = useRead( + "GetDeploymentLog", + { + deployment: id, + tail, + timestamps, + }, + { refetchInterval: poll ? 3000 : false } + ); return { Log: (
@@ -68,15 +73,20 @@ const SearchLogs = ( id: string, terms: string[], invert: boolean, - timestamps: boolean + timestamps: boolean, + poll: boolean ) => { - const { data: log, refetch } = useRead("SearchDeploymentLog", { - deployment: id, - terms, - combinator: Types.SearchCombinator.And, - invert, - timestamps, - }); + const { data: log, refetch } = useRead( + "SearchDeploymentLog", + { + deployment: id, + terms, + combinator: Types.SearchCombinator.And, + invert, + timestamps, + }, + { refetchInterval: poll ? 10000 : false } + ); return { Log: (
diff --git a/frontend/src/components/resources/procedure/config.tsx b/frontend/src/components/resources/procedure/config.tsx index 519de11a4..fc622d54c 100644 --- a/frontend/src/components/resources/procedure/config.tsx +++ b/frontend/src/components/resources/procedure/config.tsx @@ -1412,6 +1412,19 @@ const TARGET_COMPONENTS: ExecutionConfigs = { ), }, + ClearRepoCache: { + params: {}, + Component: () => <>, + }, + BackupCoreDatabase: { + params: {}, + Component: () => <>, + }, + GlobalAutoUpdate: { + params: {}, + Component: () => <>, + }, + Sleep: { params: { duration_ms: 0 }, Component: ({ params, setParams, disabled }) => { diff --git a/frontend/src/components/resources/procedure/index.tsx b/frontend/src/components/resources/procedure/index.tsx index bde7ce5c8..44208a451 100644 --- a/frontend/src/components/resources/procedure/index.tsx +++ b/frontend/src/components/resources/procedure/index.tsx @@ -31,7 +31,7 @@ export const ProcedureComponents: RequiredResourceComponents = { list_item: (id) => useProcedure(id), resource_links: () => undefined, - Description: () => <>Compose Komodo actions together., + Description: () => <>Orchestrate multiple Komodo executions., Dashboard: () => { const summary = useRead("GetProceduresSummary", {}).data; diff --git a/frontend/src/components/resources/procedure/table.tsx b/frontend/src/components/resources/procedure/table.tsx index b0751c0a2..3ada17637 100644 --- a/frontend/src/components/resources/procedure/table.tsx +++ b/frontend/src/components/resources/procedure/table.tsx @@ -30,12 +30,6 @@ export const ProcedureTable = ({ ), }, - { - accessorKey: "info.stages", - header: ({ column }) => ( - - ), - }, { accessorKey: "info.state", header: ({ column }) => ( @@ -43,6 +37,28 @@ export const ProcedureTable = ({ ), cell: ({ row }) => , }, + { + accessorKey: "info.next_scheduled_run", + header: ({ column }) => ( + + ), + sortingFn: (a, b) => { + const sa = a.original.info.next_scheduled_run; + const sb = b.original.info.next_scheduled_run; + + if (!sa && !sb) return 0; + if (!sa) return 1; + if (!sb) return -1; + + if (sa > sb) return 1; + else if (sa < sb) return -1; + else return 0; + }, + cell: ({ row }) => + row.original.info.next_scheduled_run + ? new Date(row.original.info.next_scheduled_run).toLocaleString() + : "Not Scheduled", + }, { header: "Tags", cell: ({ row }) => , diff --git a/frontend/src/components/resources/resource-sync/config.tsx b/frontend/src/components/resources/resource-sync/config.tsx index d430fd903..da324bebf 100644 --- a/frontend/src/components/resources/resource-sync/config.tsx +++ b/frontend/src/components/resources/resource-sync/config.tsx @@ -192,11 +192,6 @@ export const ResourceSyncConfig = ({ description: "Enabled managed mode / the 'Commit' button. Commit is the 'reverse' of Execute, and will update the sync file with your configs updated in the UI.", }, - pending_alert: { - label: "Pending Alerts", - description: - "Send a message to your Alerters when the Sync has Pending Changes", - }, }, }; @@ -234,6 +229,17 @@ export const ResourceSyncConfig = ({ }, }; + const pending_alerts: ConfigComponent = { + label: "Alerts", + components: { + pending_alert: { + label: "Pending Alerts", + description: + "Send a message to your Alerters when the Sync has Pending Changes", + }, + }, + }; + if (mode === undefined) { components = { "": [choose_mode], @@ -259,80 +265,250 @@ export const ResourceSyncConfig = ({ ...general_common.components, }, }, - include_toggles, match_tags, + include_toggles, + pending_alerts, ], }; } else if (mode === "Git Repo") { const repo_linked = !!(update.linked_repo ?? config.linked_repo); + const source_config: ConfigComponent = { + label: "Source", + contentHidden: !show.git, + actions: ( + setShow({ ...show, git })} + /> + ), + components: { + linked_repo: (linked_repo, set) => ( + + ), + ...(!repo_linked + ? { + git_provider: (provider: string | undefined, set) => { + const https = update.git_https ?? config.git_https; + return ( + set({ git_provider })} + https={https} + onHttpsSwitch={() => set({ git_https: !https })} + /> + ); + }, + git_account: (value: string | undefined, set) => { + return ( + set({ git_account })} + disabled={disabled} + placeholder="None" + /> + ); + }, + repo: { + placeholder: "Enter repo", + description: + "The repo path on the provider. {namespace}/{repo_name}", + }, + branch: { + placeholder: "Enter branch", + description: "Select a custom branch, or default to 'main'.", + }, + commit: { + label: "Commit Hash", + placeholder: "Input commit hash", + description: + "Optional. Switch to a specific commit hash after cloning the branch.", + }, + } + : {}), + }, + }; + const webhooks_config: ConfigComponent = { + label: "Git Webhooks", + description: `Copy the webhook given here, and configure your ${webhook_integration}-style repo provider to send webhooks to Komodo`, + contentHidden: !show.webhooks, + actions: ( + setShow({ ...show, webhooks })} + /> + ), + components: { + ["Guard" as any]: () => { + if (update.branch ?? config.branch) { + return null; + } + return ( + +
Must configure Branch before webhooks will work.
+
+ ); + }, + ["Builder" as any]: () => ( + + ), + ["Refresh" as any]: () => ( + + + + ), + ["Sync" as any]: () => ( + + + + ), + webhook_enabled: webhooks !== undefined && !webhooks.managed, + webhook_secret: { + description: + "Provide a custom webhook secret for this resource, or use the global default.", + placeholder: "Input custom secret", + }, + ["managed" as any]: () => { + const inv = useInvalidate(); + const { toast } = useToast(); + const { mutate: createWebhook, isPending: createPending } = useWrite( + "CreateSyncWebhook", + { + onSuccess: () => { + toast({ title: "Webhook Created" }); + inv(["GetSyncWebhooksEnabled", { sync: id }]); + }, + } + ); + const { mutate: deleteWebhook, isPending: deletePending } = useWrite( + "DeleteSyncWebhook", + { + onSuccess: () => { + toast({ title: "Webhook Deleted" }); + inv(["GetSyncWebhooksEnabled", { sync: id }]); + }, + } + ); + if (!webhooks || !webhooks.managed) return; + return ( + + {webhooks.sync_enabled && ( +
+
+ Incoming webhook is{" "} +
+ ENABLED +
+ and will trigger +
+ SYNC EXECUTION +
+
+ } + variant="destructive" + onClick={() => + deleteWebhook({ + sync: id, + action: Types.SyncWebhookAction.Sync, + }) + } + loading={deletePending} + disabled={disabled || deletePending} + /> +
+ )} + {!webhooks.sync_enabled && webhooks.refresh_enabled && ( +
+
+ Incoming webhook is{" "} +
+ ENABLED +
+ and will trigger +
+ PENDING REFRESH +
+
+ } + variant="destructive" + onClick={() => + deleteWebhook({ + sync: id, + action: Types.SyncWebhookAction.Refresh, + }) + } + loading={deletePending} + disabled={disabled || deletePending} + /> +
+ )} + {!webhooks.sync_enabled && !webhooks.refresh_enabled && ( +
+
+ Incoming webhook is{" "} +
+ DISABLED +
+
+ } + onClick={() => + createWebhook({ + sync: id, + action: Types.SyncWebhookAction.Refresh, + }) + } + loading={createPending} + disabled={disabled || createPending} + /> + } + onClick={() => + createWebhook({ + sync: id, + action: Types.SyncWebhookAction.Sync, + }) + } + loading={createPending} + disabled={disabled || createPending} + /> +
+ )} +
+ ); + }, + }, + }; components = { "": [ - { - label: "Source", - contentHidden: !show.git, - actions: ( - setShow({ ...show, git })} - /> - ), - components: { - linked_repo: (linked_repo, set) => ( - - ), - ...(!repo_linked - ? { - git_provider: (provider: string | undefined, set) => { - const https = update.git_https ?? config.git_https; - return ( - set({ git_provider })} - https={https} - onHttpsSwitch={() => set({ git_https: !https })} - /> - ); - }, - git_account: (value: string | undefined, set) => { - return ( - set({ git_account })} - disabled={disabled} - placeholder="None" - /> - ); - }, - repo: { - placeholder: "Enter repo", - description: - "The repo path on the provider. {namespace}/{repo_name}", - }, - branch: { - placeholder: "Enter branch", - description: - "Select a custom branch, or default to 'main'.", - }, - commit: { - label: "Commit Hash", - placeholder: "Input commit hash", - description: - "Optional. Switch to a specific commit hash after cloning the branch.", - }, - } - : {}), - }, - }, + source_config, { label: "General", components: { @@ -351,179 +527,10 @@ export const ResourceSyncConfig = ({ ...general_common.components, }, }, - include_toggles, match_tags, - { - label: "Git Webhooks", - description: `Copy the webhook given here, and configure your ${webhook_integration}-style repo provider to send webhooks to Komodo`, - contentHidden: !show.webhooks, - actions: ( - setShow({ ...show, webhooks })} - /> - ), - components: { - ["Guard" as any]: () => { - if (update.branch ?? config.branch) { - return null; - } - return ( - -
Must configure Branch before webhooks will work.
-
- ); - }, - ["Builder" as any]: () => ( - - ), - ["Refresh" as any]: () => ( - - - - ), - ["Sync" as any]: () => ( - - - - ), - webhook_enabled: webhooks !== undefined && !webhooks.managed, - webhook_secret: { - description: - "Provide a custom webhook secret for this resource, or use the global default.", - placeholder: "Input custom secret", - }, - ["managed" as any]: () => { - const inv = useInvalidate(); - const { toast } = useToast(); - const { mutate: createWebhook, isPending: createPending } = - useWrite("CreateSyncWebhook", { - onSuccess: () => { - toast({ title: "Webhook Created" }); - inv(["GetSyncWebhooksEnabled", { sync: id }]); - }, - }); - const { mutate: deleteWebhook, isPending: deletePending } = - useWrite("DeleteSyncWebhook", { - onSuccess: () => { - toast({ title: "Webhook Deleted" }); - inv(["GetSyncWebhooksEnabled", { sync: id }]); - }, - }); - if (!webhooks || !webhooks.managed) return; - return ( - - {webhooks.sync_enabled && ( -
-
- Incoming webhook is{" "} -
- ENABLED -
- and will trigger -
- SYNC EXECUTION -
-
- } - variant="destructive" - onClick={() => - deleteWebhook({ - sync: id, - action: Types.SyncWebhookAction.Sync, - }) - } - loading={deletePending} - disabled={disabled || deletePending} - /> -
- )} - {!webhooks.sync_enabled && webhooks.refresh_enabled && ( -
-
- Incoming webhook is{" "} -
- ENABLED -
- and will trigger -
- PENDING REFRESH -
-
- } - variant="destructive" - onClick={() => - deleteWebhook({ - sync: id, - action: Types.SyncWebhookAction.Refresh, - }) - } - loading={deletePending} - disabled={disabled || deletePending} - /> -
- )} - {!webhooks.sync_enabled && !webhooks.refresh_enabled && ( -
-
- Incoming webhook is{" "} -
- DISABLED -
-
- } - onClick={() => - createWebhook({ - sync: id, - action: Types.SyncWebhookAction.Refresh, - }) - } - loading={createPending} - disabled={disabled || createPending} - /> - } - onClick={() => - createWebhook({ - sync: id, - action: Types.SyncWebhookAction.Sync, - }) - } - loading={createPending} - disabled={disabled || createPending} - /> -
- )} -
- ); - }, - }, - }, + include_toggles, + pending_alerts, + webhooks_config, ], }; } else if (mode === "UI Defined") { @@ -549,7 +556,7 @@ export const ResourceSyncConfig = ({ "# Initialize the sync to import your current resources.\n" } onValueChange={(file_contents) => set({ file_contents })} - language="toml" + language="fancy_toml" readOnly={disabled} /> ); @@ -557,8 +564,9 @@ export const ResourceSyncConfig = ({ }, }, general_common, - include_toggles, match_tags, + include_toggles, + pending_alerts, ], }; } @@ -574,7 +582,7 @@ export const ResourceSyncConfig = ({ await mutateAsync({ id, config: update }); }} components={components} - file_contents_language="toml" + file_contents_language="fancy_toml" /> ); }; diff --git a/frontend/src/components/resources/resource-sync/index.tsx b/frontend/src/components/resources/resource-sync/index.tsx index 1ba92e369..f8f1e07ec 100644 --- a/frontend/src/components/resources/resource-sync/index.tsx +++ b/frontend/src/components/resources/resource-sync/index.tsx @@ -105,7 +105,7 @@ const ConfigInfoPending = ({ id }: { id: string }) => { ); return ( - + diff --git a/frontend/src/components/resources/resource-sync/info.tsx b/frontend/src/components/resources/resource-sync/info.tsx index 78425d956..cf1b3d807 100644 --- a/frontend/src/components/resources/resource-sync/info.tsx +++ b/frontend/src/components/resources/resource-sync/info.tsx @@ -160,7 +160,7 @@ export const ResourceSyncInfo = ({ } }} disabled={!edits[keyPath]} - language="toml" + language="fancy_toml" loading={isPending} /> @@ -175,7 +175,7 @@ export const ResourceSyncInfo = ({ diff --git a/frontend/src/components/resources/resource-sync/pending.tsx b/frontend/src/components/resources/resource-sync/pending.tsx index b23280f5c..278bee1f1 100644 --- a/frontend/src/components/resources/resource-sync/pending.tsx +++ b/frontend/src/components/resources/resource-sync/pending.tsx @@ -162,7 +162,7 @@ export const ResourceSyncPending = ({ {update.data.type === "Create" && ( )} @@ -172,7 +172,7 @@ export const ResourceSyncPending = ({ )} @@ -180,7 +180,7 @@ export const ResourceSyncPending = ({ )} @@ -189,7 +189,7 @@ export const ResourceSyncPending = ({ {update.data.type === "Delete" && ( )} @@ -218,7 +218,7 @@ export const ResourceSyncPending = ({ {data.type === "Create" && ( )} @@ -228,7 +228,7 @@ export const ResourceSyncPending = ({ )} @@ -236,7 +236,7 @@ export const ResourceSyncPending = ({ )} @@ -245,7 +245,7 @@ export const ResourceSyncPending = ({ {data.type === "Delete" && ( )} @@ -274,7 +274,7 @@ export const ResourceSyncPending = ({ {data.type === "Create" && ( )} @@ -284,7 +284,7 @@ export const ResourceSyncPending = ({ )} @@ -292,7 +292,7 @@ export const ResourceSyncPending = ({ )} @@ -301,7 +301,7 @@ export const ResourceSyncPending = ({ {data.type === "Delete" && ( )} diff --git a/frontend/src/components/resources/server/config.tsx b/frontend/src/components/resources/server/config.tsx index d3c02496b..74a010646 100644 --- a/frontend/src/components/resources/server/config.tsx +++ b/frontend/src/components/resources/server/config.tsx @@ -49,16 +49,30 @@ export const ServerConfig = ({ }} components={{ "": [ + { + label: "Enabled", + labelHidden: true, + components: { + enabled: { + description: + "Whether to attempt to connect to this host / send alerts if offline. Disabling will also convert all attached resource's state to 'Unknown'.", + }, + }, + }, { label: "Address", labelHidden: true, components: { address: { - // boldLabel: true, description: "The http/s address of periphery in your network, eg. https://12.34.56.78:8120", placeholder: "https://12.34.56.78:8120", }, + external_address: { + description: + "Optional. The address of the server used in container links, if different than the Address.", + placeholder: "https://my.server.int", + }, region: { placeholder: "Region. Optional.", description: @@ -66,23 +80,11 @@ export const ServerConfig = ({ }, }, }, - { - label: "Enabled", - labelHidden: true, - components: { - enabled: { - // boldLabel: true, - description: - "Whether to attempt to connect to this host / send alerts if offline. Disabling will also convert all attached resource's state to 'Unknown'.", - }, - }, - }, { label: "Timeout", labelHidden: true, components: { timeout_seconds: { - // boldLabel: true, description: "The timeout used with the server health check, in seconds.", }, diff --git a/frontend/src/components/resources/server/index.tsx b/frontend/src/components/resources/server/index.tsx index 48b5cea82..d442befed 100644 --- a/frontend/src/components/resources/server/index.tsx +++ b/frontend/src/components/resources/server/index.tsx @@ -33,6 +33,7 @@ import { StackTable } from "../stack/table"; import { ResourceComponents } from ".."; import { ServerInfo } from "./info"; import { ServerStats } from "./stats"; +import { ServerStatsMini } from "./stats-mini"; import { GroupActions } from "@components/group-actions"; import { ServerTerminals } from "@components/terminal/server"; import { usePermissions } from "@lib/hooks"; @@ -124,7 +125,6 @@ const ConfigTabs = ({ id }: { id: string }) => { @@ -253,6 +253,8 @@ export const ServerVersion = ({ id }: { id: string }) => { ); }; +export { ServerStatsMini }; + export const ServerComponents: RequiredResourceComponents = { list_item: (id) => useServer(id), resource_links: (resource) => (resource.config as Types.ServerConfig).links, diff --git a/frontend/src/components/resources/server/stats-mini.tsx b/frontend/src/components/resources/server/stats-mini.tsx new file mode 100644 index 000000000..bb5538dcc --- /dev/null +++ b/frontend/src/components/resources/server/stats-mini.tsx @@ -0,0 +1,115 @@ +import { useRead } from "@lib/hooks"; +import { cn } from "@lib/utils"; +import { Progress } from "@ui/progress"; +import { ServerState } from "komodo_client/dist/types"; +import { Cpu, Database, MemoryStick, LucideIcon } from "lucide-react"; + +interface ServerStatsMiniProps { + id: string; + className?: string; +} + +interface StatItemProps { + icon: LucideIcon; + label: string; + percentage: number; + type: "cpu" | "memory" | "disk"; + isUnreachable: boolean; + getTextColor: (percentage: number, type: "cpu" | "memory" | "disk") => string; +} + +const StatItem = ({ icon: Icon, label, percentage, type, isUnreachable, getTextColor }: StatItemProps) => ( +
+
+); + +export const ServerStatsMini = ({ id, className }: ServerStatsMiniProps) => { + const calculatePercentage = (value: number) => + Number((value ?? 0).toFixed(2)); + + const server = useRead("ListServers", {}).data?.find((s) => s.id === id); + const serverDetails = useRead("GetServer", { server: id }).data; + + const cpuWarning = serverDetails?.config?.cpu_warning ?? 75; + const cpuCritical = serverDetails?.config?.cpu_critical ?? 90; + const memWarning = serverDetails?.config?.mem_warning ?? 75; + const memCritical = serverDetails?.config?.mem_critical ?? 90; + const diskWarning = serverDetails?.config?.disk_warning ?? 75; + const diskCritical = serverDetails?.config?.disk_critical ?? 90; + + const getTextColor = (percentage: number, type: "cpu" | "memory" | "disk") => { + const warning = type === "cpu" ? cpuWarning : type === "memory" ? memWarning : diskWarning; + const critical = type === "cpu" ? cpuCritical : type === "memory" ? memCritical : diskCritical; + + if (percentage >= critical) return "text-red-600"; + if (percentage >= warning) return "text-yellow-600"; + return "text-green-600"; + }; + const stats = useRead( + "GetSystemStats", + { server: id }, + { + enabled: server ? server.info.state !== "Disabled" : false, + refetchInterval: 10_000, + }, + ).data; + + if (!server || server.info.state === "Disabled") { + return null; + } + + const cpuPercentage = stats ? calculatePercentage(stats.cpu_perc) : 0; + const memoryPercentage = stats && stats.mem_total_gb > 0 ? calculatePercentage((stats.mem_used_gb / stats.mem_total_gb) * 100) : 0; + + const diskUsed = stats ? stats.disks.reduce((acc, disk) => acc + disk.used_gb, 0) : 0; + const diskTotal = stats ? stats.disks.reduce((acc, disk) => acc + disk.total_gb, 0) : 0; + const diskPercentage = diskTotal > 0? calculatePercentage((diskUsed / diskTotal) * 100) : 0; + + const isUnreachable = !stats || server.info.state === ServerState.NotOk; + const unreachableClass = isUnreachable ? "opacity-50" : ""; + + const statItems = [ + { icon: Cpu, label: "CPU", percentage: cpuPercentage, type: "cpu" as const }, + { icon: MemoryStick, label: "Memory", percentage: memoryPercentage, type: "memory" as const }, + { icon: Database, label: "Disk", percentage: diskPercentage, type: "disk" as const }, + ]; + + return ( +
+ {isUnreachable && ( +
+ Unreachable +
+ )} + {statItems.map((item) => ( + + ))} +
+ ); +}; diff --git a/frontend/src/components/resources/server/stats.tsx b/frontend/src/components/resources/server/stats.tsx index 7eebca84d..f81f7aa7c 100644 --- a/frontend/src/components/resources/server/stats.tsx +++ b/frontend/src/components/resources/server/stats.tsx @@ -1,8 +1,14 @@ import { Section } from "@components/layouts"; import { Card, CardContent, CardHeader, CardTitle } from "@ui/card"; import { Progress } from "@ui/progress"; -import { Cpu, Database, Loader2, MemoryStick } from "lucide-react"; -import { usePermissions, useRead } from "@lib/hooks"; +import { + Cpu, + Database, + Loader2, + MemoryStick, + Search, +} from "lucide-react"; +import { useLocalStorage, usePermissions, useRead } from "@lib/hooks"; import { Types } from "komodo_client"; import { DataTable, SortableHeader } from "@ui/data-table"; import { ReactNode, useMemo, useState } from "react"; @@ -17,6 +23,7 @@ import { SelectValue, } from "@ui/select"; import { DockerResourceLink, ShowHideButton } from "@components/util"; +import { filterBySplit } from "@lib/utils"; export const ServerStats = ({ id, @@ -40,7 +47,21 @@ export const ServerStats = ({ const containers = useRead("ListDockerContainers", { server: id, }).data?.filter((c) => c.stats); + const [showContainers, setShowContainers] = useLocalStorage( + "stats-show-container-table-v1", + true + ); + const [containerSearch, setContainerSearch] = useState(""); + const filteredContainers = filterBySplit( + containers, + containerSearch, + (container) => container.name + ); + const [showDisks, setShowDisks] = useLocalStorage( + "stats-show-disks-table-v1", + true + ); const disk_used = stats?.disks.reduce( (acc, curr) => (acc += curr.used_gb), 0 @@ -53,7 +74,7 @@ export const ServerStats = ({ return (
- {/* Stats */} + {/* System Info */}
+ {/* Current Overview */}
@@ -105,72 +127,175 @@ export const ServerStats = ({
-
- ( - - ), - cell: ({ row }) => ( - - ), - }, - { - accessorKey: "stats.cpu_perc", - size: 100, - header: ({ column }) => ( - - ), - }, - { - accessorKey: "stats.mem_perc", - size: 200, - header: ({ column }) => ( - - ), - cell: ({ row }) => ( -
- {row.original.stats?.mem_perc} -
- ({row.original.stats?.mem_usage}) + {/* Container Breakdown */} +
+
+ + setContainerSearch(e.target.value)} + placeholder="search..." + className="pl-8 w-[200px] lg:w-[300px]" + /> +
+ +
+ } + > + {showContainers && ( + ( + + ), + cell: ({ row }) => ( + + ), + }, + { + accessorKey: "stats.cpu_perc", + size: 100, + header: ({ column }) => ( + + ), + }, + { + accessorKey: "stats.mem_perc", + size: 200, + header: ({ column }) => ( + + ), + cell: ({ row }) => ( +
+ {row.original.stats?.mem_perc} +
+ ({row.original.stats?.mem_usage}) +
-
- ), - }, - { - accessorKey: "stats.net_io", - size: 150, - header: ({ column }) => ( - - ), - }, - { - accessorKey: "stats.block_io", - size: 150, - header: ({ column }) => ( - - ), - }, - { - accessorKey: "stats.pids", - size: 100, - header: ({ column }) => ( - - ), - }, - ]} - /> + ), + }, + { + accessorKey: "stats.net_io", + size: 150, + header: ({ column }) => ( + + ), + }, + { + accessorKey: "stats.block_io", + size: 150, + header: ({ column }) => ( + + ), + }, + { + accessorKey: "stats.pids", + size: 100, + header: ({ column }) => ( + + ), + }, + ]} + /> + )}
+ {/* Current Disk Breakdown */} +
+
+
Used:
+ {disk_used?.toFixed(2)} GB +
+
+
Total:
+ {disk_total?.toFixed(2)} GB +
+ +
+ } + > + {showDisks && ( + ({ + ...disk, + percentage: 100 * (disk.used_gb / disk.total_gb), + })) ?? [] + } + columns={[ + { + header: "Path", + cell: ({ row }) => ( +
+ {row.original.mount} +
+ ), + }, + { + accessorKey: "used_gb", + header: ({ column }) => ( + + ), + cell: ({ row }) => <>{row.original.used_gb.toFixed(2)} GB, + }, + { + accessorKey: "total_gb", + header: ({ column }) => ( + + ), + cell: ({ row }) => <>{row.original.total_gb.toFixed(2)} GB, + }, + { + accessorKey: "percentage", + header: ({ column }) => ( + + ), + cell: ({ row }) => ( + <>{row.original.percentage.toFixed(2)}% Full + ), + }, + ]} + /> + )} +
+ + {specific.includes(Types.SpecificPermission.Processes) && ( + + )} + + {/* Historical Charts */}
- -
-
-
Used:
- {disk_used?.toFixed(2)} GB -
-
-
Total:
- {disk_total?.toFixed(2)} GB -
- - } - > - ({ - ...disk, - percentage: 100 * (disk.used_gb / disk.total_gb), - })) ?? [] - } - columns={[ - { - header: "Path", - cell: ({ row }) => ( -
- {row.original.mount} -
- ), - }, - { - accessorKey: "used_gb", - header: ({ column }) => ( - - ), - cell: ({ row }) => <>{row.original.used_gb.toFixed(2)} GB, - }, - { - accessorKey: "total_gb", - header: ({ column }) => ( - - ), - cell: ({ row }) => <>{row.original.total_gb.toFixed(2)} GB, - }, - { - accessorKey: "percentage", - header: ({ column }) => ( - - ), - cell: ({ row }) => ( - <>{row.original.percentage.toFixed(2)}% Full - ), - }, - ]} - /> -
- - {specific.includes(Types.SpecificPermission.Processes) && ( - - )} ); @@ -313,14 +370,19 @@ const Processes = ({ id }: { id: string }) => { return (
} actions={ - setSearch(e.target.value)} - className="w-[300px]" - /> +
+
+ + setSearch(e.target.value)} + placeholder="search..." + className="pl-8 w-[200px] lg:w-[300px]" + /> +
+ +
} > {show && } diff --git a/frontend/src/components/resources/stack/index.tsx b/frontend/src/components/resources/stack/index.tsx index 15c863a43..0858a637a 100644 --- a/frontend/src/components/resources/stack/index.tsx +++ b/frontend/src/components/resources/stack/index.tsx @@ -115,7 +115,7 @@ const ConfigInfoServicesLog = ({ id }: { id: string }) => { ); return ( - + diff --git a/frontend/src/components/resources/stack/log.tsx b/frontend/src/components/resources/stack/log.tsx index 0f0bbb3a3..ec265ef13 100644 --- a/frontend/src/components/resources/stack/log.tsx +++ b/frontend/src/components/resources/stack/log.tsx @@ -57,22 +57,24 @@ const StackLogsInner = ({ const selected = services.filter((s) => s.selected); return ( + regular_logs={(timestamps, stream, tail, poll) => NoSearchLogs( id, services.filter((s) => s.selected).map((s) => s.service), tail, timestamps, - stream + stream, + poll ) } - search_logs={(timestamps, terms, invert) => + search_logs={(timestamps, terms, invert, poll) => SearchLogs( id, services.filter((s) => s.selected).map((s) => s.service), terms, invert, - timestamps + timestamps, + poll ) } titleOther={titleOther} @@ -120,14 +122,19 @@ const NoSearchLogs = ( services: string[], tail: number, timestamps: boolean, - stream: string + stream: string, + poll: boolean ) => { - const { data: log, refetch } = useRead("GetStackLog", { - stack: id, - services, - tail, - timestamps, - }); + const { data: log, refetch } = useRead( + "GetStackLog", + { + stack: id, + services, + tail, + timestamps, + }, + { refetchInterval: poll ? 3000 : false } + ); return { Log: (
@@ -144,16 +151,21 @@ const SearchLogs = ( services: string[], terms: string[], invert: boolean, - timestamps: boolean + timestamps: boolean, + poll: boolean ) => { - const { data: log, refetch } = useRead("SearchStackLog", { - stack: id, - services, - terms, - combinator: Types.SearchCombinator.And, - invert, - timestamps, - }); + const { data: log, refetch } = useRead( + "SearchStackLog", + { + stack: id, + services, + terms, + combinator: Types.SearchCombinator.And, + invert, + timestamps, + }, + { refetchInterval: poll ? 10000 : false } + ); return { Log: (
diff --git a/frontend/src/components/resources/stack/services.tsx b/frontend/src/components/resources/stack/services.tsx index c7a5a4127..3881c0b2e 100644 --- a/frontend/src/components/resources/stack/services.tsx +++ b/frontend/src/components/resources/stack/services.tsx @@ -114,10 +114,10 @@ export const StackServices = ({ ), cell: ({ row }) => - (row.original.container?.networks.length ?? 0) > 0 ? ( + (row.original.container?.networks?.length ?? 0) > 0 ? (
{server_id && - row.original.container?.networks.map((network, i) => ( + row.original.container?.networks?.map((network, i) => ( {i !== - row.original.container!.networks.length - 1 && ( + row.original.container!.networks!.length - 1 && (
|
)}
diff --git a/frontend/src/components/topbar.tsx b/frontend/src/components/topbar.tsx deleted file mode 100644 index 35d81c157..000000000 --- a/frontend/src/components/topbar.tsx +++ /dev/null @@ -1,308 +0,0 @@ -import { useRead, useResourceParamType, useShiftKeyListener } from "@lib/hooks"; -import { ResourceComponents } from "./resources"; -import { - AlertTriangle, - Bell, - Box, - Boxes, - CalendarDays, - FileQuestion, - FolderTree, - Keyboard, - LayoutDashboard, - Settings, - User, - Users, -} from "lucide-react"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuGroup, - DropdownMenuItem, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from "@ui/dropdown-menu"; -import { Button } from "@ui/button"; -import { Link } from "react-router-dom"; -import { RESOURCE_TARGETS, usableResourcePath } from "@lib/utils"; -import { OmniSearch, OmniDialog } from "./omnibar"; -import { WsStatusIndicator } from "@lib/socket"; -import { TopbarUpdates } from "./updates/topbar"; -import { Logout } from "./util"; -import { ThemeToggle } from "@ui/theme"; -import { useAtom } from "jotai"; -import { ReactNode, useState } from "react"; -import { HomeView, homeViewAtom } from "@main"; -import { - Dialog, - DialogContent, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@ui/dialog"; -import { Badge } from "@ui/badge"; -import { TopbarAlerts } from "./alert/topbar"; - -export const Topbar = () => { - const [omniOpen, setOmniOpen] = useState(false); - useShiftKeyListener("S", () => setOmniOpen(true)); - - return ( -
-
- {/* Logo */} - - -
KOMODO
- - - {/* Searchbar */} -
- -
- - {/* Shortcuts */} -
- - -
- - -
- - - - - - -
-
- -
- ); -}; - -const Docs = () => ( - - - -); - -const Version = () => { - const version = useRead("GetVersion", {}, { refetchInterval: 30_000 }).data - ?.version; - - if (!version) return null; - return ( - - - - ); -}; - -const MobileDropdown = () => { - const type = useResourceParamType(); - const Components = type && ResourceComponents[type]; - const [view, setView] = useAtom(homeViewAtom); - - const [icon, title] = Components - ? [, (type === "ResourceSync" ? "Sync" : type) + "s"] - : location.pathname === "/" && view === "Dashboard" - ? [, "Dashboard"] - : location.pathname === "/" && view === "Resources" - ? [, "Resources"] - : location.pathname === "/" && view === "Tree" - ? [, "Tree"] - : location.pathname === "/containers" - ? [, "Containers"] - : location.pathname === "/settings" - ? [, "Settings"] - : location.pathname === "/schedules" - ? [, "Schedules"] - : location.pathname === "/alerts" - ? [, "Alerts"] - : location.pathname === "/updates" - ? [, "Updates"] - : location.pathname.split("/")[1] === "user-groups" - ? [, "User Groups"] - : location.pathname.split("/")[1] === "users" - ? [, "Users"] - : [, "Unknown"]; - - return ( - - - - - - - } - to="/" - onClick={() => setView("Dashboard")} - /> - } - to="/" - onClick={() => setView("Resources")} - /> - } - to="/containers" - /> - - - - {RESOURCE_TARGETS.map((type) => { - const RTIcon = ResourceComponents[type].Icon; - const name = type === "ResourceSync" ? "Sync" : type; - return ( - } - to={`/${usableResourcePath(type)}`} - /> - ); - })} - - - - } - to="/alerts" - /> - - } - to="/updates" - /> - - - - } - to="/schedules" - /> - - } - to="/settings" - /> - - - - ); -}; - -const DropdownLinkItem = ({ - label, - icon, - to, - onClick, -}: { - label: string; - icon: ReactNode; - to: string; - onClick?: () => void; -}) => { - return ( - - - {icon} - {label} - - - ); -}; - -const KeyboardShortcuts = () => { - return ( - - - - - - - Keyboard Shortcuts - -
- - - - - - - - - - - - - -
-
-
- ); -}; - -const KeyboardShortcut = ({ - label, - keys, - divider = true, -}: { - label: string; - keys: string[]; - divider?: boolean; -}) => { - return ( - <> -
{label}
-
- {keys.map((key) => ( - - {key} - - ))} -
- - {divider && ( -
- )} - - ); -}; diff --git a/frontend/src/components/topbar/components.tsx b/frontend/src/components/topbar/components.tsx new file mode 100644 index 000000000..a4c46d08b --- /dev/null +++ b/frontend/src/components/topbar/components.tsx @@ -0,0 +1,614 @@ +import { + LOGIN_TOKENS, + useManageUser, + useRead, + useResourceParamType, + useUser, + useUserInvalidate, +} from "@lib/hooks"; +import { ResourceComponents } from "../resources"; +import { + AlertTriangle, + ArrowLeftRight, + Bell, + Box, + Boxes, + Calendar, + CalendarDays, + Check, + Circle, + FileQuestion, + FolderTree, + Keyboard, + LayoutDashboard, + Loader2, + LogOut, + Plus, + Settings, + User, + Users, + X, +} from "lucide-react"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@ui/dropdown-menu"; +import { Button } from "@ui/button"; +import { Link } from "react-router-dom"; +import { + cn, + RESOURCE_TARGETS, + usableResourcePath, + version_is_none, +} from "@lib/utils"; +import { useAtom } from "jotai"; +import { ReactNode, useState } from "react"; +import { HomeView, homeViewAtom } from "@main"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@ui/dialog"; +import { Badge } from "@ui/badge"; +import { ConfirmButton } from "../util"; +import { Types } from "komodo_client"; +import { UpdateDetails, UpdateUser } from "@components/updates/details"; +import { fmt_date, fmt_operation, fmt_version } from "@lib/formatting"; +import { ResourceLink, ResourceNameSimple } from "@components/resources/common"; +import { UsableResource } from "@types"; +import { AlertLevel } from "@components/alert"; +import { AlertDetailsDialogContent } from "@components/alert/details"; +import { Separator } from "@ui/separator"; + +export const MobileDropdown = () => { + const type = useResourceParamType(); + const Components = type && ResourceComponents[type]; + const [view, setView] = useAtom(homeViewAtom); + + const [icon, title] = Components + ? [, (type === "ResourceSync" ? "Sync" : type) + "s"] + : location.pathname === "/" && view === "Dashboard" + ? [, "Dashboard"] + : location.pathname === "/" && view === "Resources" + ? [, "Resources"] + : location.pathname === "/" && view === "Tree" + ? [, "Tree"] + : location.pathname === "/containers" + ? [, "Containers"] + : location.pathname === "/settings" + ? [, "Settings"] + : location.pathname === "/schedules" + ? [, "Schedules"] + : location.pathname === "/alerts" + ? [, "Alerts"] + : location.pathname === "/updates" + ? [, "Updates"] + : location.pathname.split("/")[1] === "user-groups" + ? [, "User Groups"] + : location.pathname.split("/")[1] === "users" + ? [, "Users"] + : [, "Unknown"]; + + return ( + + + + + + + } + to="/" + onClick={() => setView("Dashboard")} + /> + } + to="/" + onClick={() => setView("Resources")} + /> + } + to="/containers" + /> + + + + {RESOURCE_TARGETS.map((type) => { + const RTIcon = ResourceComponents[type].Icon; + const name = type === "ResourceSync" ? "Sync" : type; + return ( + } + to={`/${usableResourcePath(type)}`} + /> + ); + })} + + + + } + to="/alerts" + /> + + } + to="/updates" + /> + + + + } + to="/schedules" + /> + + } + to="/settings" + /> + + + + ); +}; + +const DropdownLinkItem = ({ + label, + icon, + to, + onClick, +}: { + label: string; + icon: ReactNode; + to: string; + onClick?: () => void; +}) => { + return ( + + + {icon} + {label} + + + ); +}; + +export const UserDropdown = () => { + const [_, setRerender] = useState(false); + const rerender = () => setRerender((r) => !r); + const [viewLogout, setViewLogout] = useState(false); + const [open, _setOpen] = useState(false); + const setOpen = (open: boolean) => { + _setOpen(open); + if (open) { + setViewLogout(false); + } + }; + const user = useUser().data; + const userInvalidate = useUserInvalidate(); + const accounts = LOGIN_TOKENS.accounts(); + return ( + + + + + +
+
+ + Switch accounts +
+ +
+ + {accounts.map((login) => { + const selected = login.user_id === user?._id?.$oid; + return ( +
+ + + {viewLogout && ( + + )} +
+ ); + })} + + + + + + + + {viewLogout && ( + } + variant="destructive" + className="flex gap-2 items-center justify-center w-full max-w-full" + onClick={() => { + LOGIN_TOKENS.remove_all(); + userInvalidate(); + }} + /> + )} +
+
+ ); +}; + +const Username = ({ user_id }: { user_id: string }) => { + const res = useRead("GetUsername", { user_id }).data; + return ; +}; + +const UsernameView = ({ + username, + avatar, + full, +}: { + username: string | undefined; + avatar: string | undefined; + full?: boolean; +}) => { + return ( + <> + {avatar ? : } +
+ {username} +
+ + ); +}; + +export const TopbarUpdates = () => { + const updates = useRead("ListUpdates", {}).data; + + const last_opened = useUser().data?.last_update_view; + const unseen_update = updates?.updates.some( + (u) => u.start_ts > (last_opened ?? Number.MAX_SAFE_INTEGER) + ); + + const userInvalidate = useUserInvalidate(); + const { mutate } = useManageUser("SetLastSeenUpdate", { + onSuccess: userInvalidate, + }); + + return ( + o && mutate({})}> + + + + + + {updates?.updates.map((update) => ( + + ))} + + + + ); +}; + +const SingleUpdate = ({ update }: { update: Types.UpdateListItem }) => { + const Components = + update.target.type !== "System" + ? ResourceComponents[update.target.type] + : null; + + const Icon = () => { + if (update.status === Types.UpdateStatus.Complete) { + if (update.success) return ; + else return ; + } else return ; + }; + + return ( + +
+
+
+
+ + {fmt_operation(update.operation)} +
+ {!version_is_none(update.version) && + fmt_version(update.version)} +
+
+
+ {Components && ( + <> + + + + )} + {!Components && ( + <> + + System + + )} +
+
+
+
+ +
+ {update.status === Types.UpdateStatus.InProgress + ? "ongoing" + : fmt_date(new Date(update.start_ts))} +
+
+ +
+
+
+
+ ); +}; + +export const TopbarAlerts = () => { + const { data } = useRead( + "ListAlerts", + { query: { resolved: false } }, + { refetchInterval: 3_000 } + ); + const [open, setOpen] = useState(false); + + // If this is set, details will open. + const [alert, setAlert] = useState(); + + if (!data || data.alerts.length === 0) { + return null; + } + + return ( + <> + + + + + + {data?.alerts.map((alert) => ( + setAlert(alert)} + > +
+ +
+
+
+ setOpen(false)} + /> +
+
+

{alert.data.type}

+
+ ))} +
+
+ setAlert(undefined)} /> + + ); +}; + +const AlertDetails = ({ + alert, + onClose, +}: { + alert: Types.Alert | undefined; + onClose: () => void; +}) => ( + <> + {alert && ( + !o && onClose()}> + + + )} + +); + +export const Docs = () => ( + + + +); + +export const Version = () => { + const version = useRead("GetVersion", {}, { refetchInterval: 30_000 }).data + ?.version; + + if (!version) return null; + return ( + + + + ); +}; + +export const KeyboardShortcuts = () => { + return ( + + + + + + + Keyboard Shortcuts + +
+ + + + + + + + + + + + + +
+
+
+ ); +}; + +const KeyboardShortcut = ({ + label, + keys, + divider = true, +}: { + label: string; + keys: string[]; + divider?: boolean; +}) => { + return ( + <> +
{label}
+
+ {keys.map((key) => ( + + {key} + + ))} +
+ + {divider && ( +
+ )} + + ); +}; diff --git a/frontend/src/components/topbar/index.tsx b/frontend/src/components/topbar/index.tsx new file mode 100644 index 000000000..4a463a5d4 --- /dev/null +++ b/frontend/src/components/topbar/index.tsx @@ -0,0 +1,57 @@ +import { useShiftKeyListener } from "@lib/hooks"; +import { Link } from "react-router-dom"; +import { OmniSearch, OmniDialog } from "../omnibar"; +import { WsStatusIndicator } from "@lib/socket"; +import { ThemeToggle } from "@ui/theme"; +import { useState } from "react"; +import { + Docs, + KeyboardShortcuts, + MobileDropdown, + TopbarAlerts, + TopbarUpdates, + UserDropdown, + Version, +} from "./components"; + +export const Topbar = () => { + const [omniOpen, setOmniOpen] = useState(false); + useShiftKeyListener("S", () => setOmniOpen(true)); + + return ( +
+
+ {/* Logo */} + + +
KOMODO
+ + + {/* Searchbar */} +
+ +
+ + {/* Shortcuts */} +
+ + +
+ + +
+ + + + + + +
+
+ +
+ ); +}; diff --git a/frontend/src/components/updates/details.tsx b/frontend/src/components/updates/details.tsx index 5f8da497d..9f8d10e5c 100644 --- a/frontend/src/components/updates/details.tsx +++ b/frontend/src/components/updates/details.tsx @@ -9,6 +9,7 @@ import { import { Calendar, Clock, + Link2, Loader2, Milestone, Settings, @@ -33,7 +34,7 @@ import { version_is_none, } from "@lib/utils"; import { UsableResource } from "@types"; -import { UserAvatar } from "@components/util"; +import { CopyButton, UserAvatar } from "@components/util"; import { ResourceNameSimple } from "@components/resources/common"; import { useWebsocketMessages } from "@lib/socket"; import { MonacoDiffEditor } from "@components/monaco"; @@ -97,9 +98,9 @@ export const UpdateDetailsInner = ({ setOpen, }: { id: string; - children?: ReactNode; open: boolean; setOpen: React.Dispatch>; + children?: ReactNode; }) => { return ( @@ -114,13 +115,13 @@ export const UpdateDetailsInner = ({ ); }; -const UpdateDetailsContent = ({ +export const UpdateDetailsContent = ({ id, open, setOpen, }: { id: string; - open: boolean; + open?: boolean; setOpen: React.Dispatch>; }) => { const { data: update, refetch } = useRead( @@ -166,7 +167,7 @@ const UpdateDetailsContent = ({ >
setOpen(false)} + onClick={() => setOpen?.(false)} > )}
-
+
{new Date(update.start_ts).toLocaleString()} @@ -200,6 +201,12 @@ const UpdateDetailsContent = ({ ? fmt_duration(update.start_ts, update.end_ts) : "ongoing"}
+ } + label={"shareable link"} + />
@@ -213,7 +220,7 @@ const UpdateDetailsContent = ({ diff --git a/frontend/src/components/updates/topbar.tsx b/frontend/src/components/updates/topbar.tsx deleted file mode 100644 index 6f4ab5eca..000000000 --- a/frontend/src/components/updates/topbar.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import { useManageUser, useRead, useUser, useUserInvalidate } from "@lib/hooks"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuGroup, - DropdownMenuTrigger, -} from "@ui/dropdown-menu"; -import { Bell, Check, Circle, Loader2, Settings, X } from "lucide-react"; -import { Button } from "@ui/button"; -import { Calendar } from "lucide-react"; -import { UpdateDetails, UpdateUser } from "./details"; -import { ResourceComponents } from "@components/resources"; -import { cn, version_is_none } from "@lib/utils"; -import { Types } from "komodo_client"; -import { fmt_date, fmt_operation, fmt_version } from "@lib/formatting"; -import { ResourceNameSimple } from "@components/resources/common"; -import { UsableResource } from "@types"; - -export const TopbarUpdates = () => { - const updates = useRead("ListUpdates", {}).data; - - const last_opened = useUser().data?.last_update_view; - const unseen_update = updates?.updates.some( - (u) => u.start_ts > (last_opened ?? Number.MAX_SAFE_INTEGER) - ); - - const userInvalidate = useUserInvalidate(); - const { mutate } = useManageUser("SetLastSeenUpdate", { - onSuccess: userInvalidate, - }); - - return ( - o && mutate({})}> - - - - - - {updates?.updates.map((update) => ( - - ))} - - - - ); -}; - -const SingleUpdate = ({ update }: { update: Types.UpdateListItem }) => { - const Components = - update.target.type !== "System" - ? ResourceComponents[update.target.type] - : null; - - const Icon = () => { - if (update.status === Types.UpdateStatus.Complete) { - if (update.success) return ; - else return ; - } else return ; - }; - - return ( - -
-
-
-
- - {fmt_operation(update.operation)} -
- {!version_is_none(update.version) && - fmt_version(update.version)} -
-
-
- {Components && ( - <> - - - - )} - {!Components && ( - <> - - System - - )} -
-
-
-
- -
- {update.status === Types.UpdateStatus.InProgress - ? "ongoing" - : fmt_date(new Date(update.start_ts))} -
-
- -
-
-
-
- ); -}; diff --git a/frontend/src/components/users/new.tsx b/frontend/src/components/users/new.tsx index c96c44597..c8177a011 100644 --- a/frontend/src/components/users/new.tsx +++ b/frontend/src/components/users/new.tsx @@ -61,3 +61,69 @@ export const NewServiceUser = () => { ); }; + +export const NewLocalUser = () => { + const { toast } = useToast(); + const inv = useInvalidate(); + const { mutateAsync } = useWrite("CreateLocalUser", { + onSuccess: () => { + inv(["ListUsers"]); + toast({ title: "Created Local User" }); + }, + }); + const [username, setUsername] = useState(""); + const [password, setPassword] = useState(""); + const [passwordConfirm, setPasswordConfirm] = useState(""); + return ( + { + if ( + username.length === 0 || + password.length === 0 || + password !== passwordConfirm + ) { + toast({ title: "Invalid user info", variant: "destructive" }); + } + return await mutateAsync({ username, password }); + }} + enabled={!!username && !!password && password === passwordConfirm} + onOpenChange={() => { + setUsername(""); + setPassword(""); + setPasswordConfirm(""); + }} + > +
+ Username + setUsername(e.target.value)} + /> + Password + setPassword(e.target.value)} + /> + Confirm Password + setPasswordConfirm(e.target.value)} + className={ + !password + ? undefined + : password === passwordConfirm + ? "border-green-500" + : "border-red-500" + } + /> +
+
+ ); +}; diff --git a/frontend/src/components/util.tsx b/frontend/src/components/util.tsx index a86ca56ca..710271986 100644 --- a/frontend/src/components/util.tsx +++ b/frontend/src/components/util.tsx @@ -25,7 +25,6 @@ import { HardDrive, LinkIcon, Loader2, - LogOut, Network, Search, SearchX, @@ -45,7 +44,6 @@ import { import { toast, useToast } from "@ui/use-toast"; import { cn, filterBySplit, usableResourcePath } from "@lib/utils"; import { Link, useNavigate } from "react-router-dom"; -import { AUTH_TOKEN_STORAGE_KEY } from "@main"; import { Textarea } from "@ui/textarea"; import { Card } from "@ui/card"; import { @@ -69,7 +67,6 @@ import { useContainerPortsMap, useRead, useTemplatesQueryBehavior, - useUser, } from "@lib/hooks"; import { Prune } from "./resources/server/actions"; import { MonacoEditor, MonacoLanguage } from "./monaco"; @@ -151,7 +148,10 @@ export const ActionButton = forwardRef< - ) - ); -}; - export const UserSettings = () => ( ); }; @@ -850,16 +833,16 @@ export const DockerContainersSection = ({ ), cell: ({ row }) => - row.original.networks.length > 0 ? ( + (row.original.networks?.length ?? 0) > 0 ? (
- {row.original.networks.map((network, i) => ( + {row.original.networks?.map((network, i) => ( - {i !== row.original.networks.length - 1 && ( + {i !== row.original.networks!.length - 1 && (
|
)}
@@ -883,7 +866,7 @@ export const DockerContainersSection = ({ ), cell: ({ row }) => ( ), @@ -1174,12 +1157,15 @@ export const ContainerPortLink = ({ ports: Types.Port[]; server_id: string | undefined; }) => { + const server = useServer(server_id); // Get the server address with periphery port removed - const server_address = useServer(server_id) - ?.info.address.split(":") - // take just protocol and dns (indexes 0 and 1) - .filter((_, i) => i < 2) - .join(":"); + const server_address = server?.info.external_address + ? server.info.external_address + : server?.info.address + .split(":") + // take just protocol and dns (indexes 0 and 1) + .filter((_, i) => i < 2) + .join(":"); const link = host_port === "443" ? server_address diff --git a/frontend/src/lib/dashboard-preferences.ts b/frontend/src/lib/dashboard-preferences.ts new file mode 100644 index 000000000..71a18fc8d --- /dev/null +++ b/frontend/src/lib/dashboard-preferences.ts @@ -0,0 +1,31 @@ +import { atomWithStorage } from "@lib/hooks"; +import { useAtom } from "jotai"; + +interface DashboardPreferences { + showServerStats: boolean; +} + +const DEFAULT_PREFERENCES: DashboardPreferences = { + showServerStats: false, +}; + +export const dashboardPreferencesAtom = atomWithStorage( + "komodo-dashboard-preferences", + DEFAULT_PREFERENCES +); + +export const useDashboardPreferences = () => { + const [preferences, setPreferences] = useAtom(dashboardPreferencesAtom); + + const updatePreference = ( + key: K, + value: DashboardPreferences[K] + ) => { + setPreferences({ ...preferences, [key]: value }); + }; + + return { + preferences, + updatePreference, + }; +}; diff --git a/frontend/src/lib/hooks.ts b/frontend/src/lib/hooks.ts index 65e84b900..7c993155f 100644 --- a/frontend/src/lib/hooks.ts +++ b/frontend/src/lib/hooks.ts @@ -1,4 +1,4 @@ -import { AUTH_TOKEN_STORAGE_KEY, KOMODO_BASE_URL } from "@main"; +import { KOMODO_BASE_URL } from "@main"; import { KomodoClient, Types } from "komodo_client"; import { AuthResponses, @@ -22,19 +22,109 @@ import { useEffect, useMemo, useState } from "react"; import { useParams } from "react-router-dom"; import { has_minimum_permissions, RESOURCE_TARGETS } from "./utils"; +export const atomWithStorage = (key: string, init: T) => { + const stored = localStorage.getItem(key); + const inner = atom(stored ? JSON.parse(stored) : init); + + return atom( + (get) => get(inner), + (_, set, newValue) => { + set(inner, newValue); + localStorage.setItem(key, JSON.stringify(newValue)); + } + ); +}; + +type LoginTokens = { + /** Current User ID */ + current: string | undefined; + /** Array of logged in user ids / tokens */ + tokens: Array; +}; + +const LOGIN_TOKENS_KEY = "komodo-auth-tokens-v1"; + +export const LOGIN_TOKENS = (() => { + const stored = localStorage.getItem(LOGIN_TOKENS_KEY); + + let tokens: LoginTokens = stored + ? JSON.parse(stored) + : { current: undefined, tokens: [] }; + + const update_local_storage = () => { + localStorage.setItem(LOGIN_TOKENS_KEY, JSON.stringify(tokens)); + }; + + const accounts = () => { + const current = tokens.tokens.find((t) => t.user_id === tokens.current); + const filtered = tokens.tokens.filter((t) => t.user_id !== tokens.current); + return current ? [current, ...filtered] : filtered; + }; + + const add_and_change = (user_id: string, jwt: string) => { + const filtered = tokens.tokens.filter((t) => t.user_id !== user_id); + filtered.push({ user_id, jwt }); + filtered.sort(); + tokens = { + current: user_id, + tokens: filtered, + }; + update_local_storage(); + }; + + const remove = (user_id: string) => { + const filtered = tokens.tokens.filter((t) => t.user_id !== user_id); + tokens = { + current: + tokens.current === user_id ? filtered[0]?.user_id : tokens.current, + tokens: filtered, + }; + update_local_storage(); + }; + + const remove_all = () => { + tokens = { + current: undefined, + tokens: [], + }; + update_local_storage(); + }; + + const change = (to_id: string) => { + tokens = { + current: to_id, + tokens: tokens.tokens, + }; + update_local_storage(); + }; + + return { + jwt: () => + tokens.current + ? (tokens.tokens.find((t) => t.user_id === tokens.current)?.jwt ?? "") + : "", + accounts, + add_and_change, + remove, + remove_all, + change, + }; +})(); + +export const komodo_client = () => + KomodoClient(KOMODO_BASE_URL, { + type: "jwt", + params: { jwt: LOGIN_TOKENS.jwt() }, + }); + // ============== RESOLVER ============== -const token = () => ({ - jwt: localStorage.getItem(AUTH_TOKEN_STORAGE_KEY) ?? "", -}); -export const komodo_client = () => - KomodoClient(KOMODO_BASE_URL, { type: "jwt", params: token() }); - -export const useLoginOptions = () => - useQuery({ +export const useLoginOptions = () => { + return useQuery({ queryKey: ["GetLoginOptions"], queryFn: () => komodo_client().auth("GetLoginOptions", {}), }); +}; export const useUser = () => { const userReset = useUserReset(); @@ -82,12 +172,13 @@ export const useRead = < type: T, params: P, config?: C -) => - useQuery({ +) => { + return useQuery({ queryKey: [type, params], queryFn: () => komodo_client().read(type, params), ...config, }); +}; export const useInvalidate = () => { const qc = useQueryClient(); @@ -347,19 +438,6 @@ export const useSetTitle = (more?: string) => { }, [title]); }; -export const atomWithStorage = (key: string, init: T) => { - const stored = localStorage.getItem(key); - const inner = atom(stored ? JSON.parse(stored) : init); - - return atom( - (get) => get(inner), - (_, set, newValue) => { - set(inner, newValue); - localStorage.setItem(key, JSON.stringify(newValue)); - } - ); -}; - const tagsAtom = atomWithStorage("tags-v0", []); export const useTags = () => { @@ -566,40 +644,44 @@ export const usePermissions = ({ type, id }: Types.ResourceTarget) => { Types.PermissionLevel.Execute ); - if (type === "Server") { - return { - canWrite, - canExecute, - canCreate: - user?.admin || - (!disable_non_admin_create && user?.create_server_permissions), - specific, - }; - } - if (type === "Build") { - return { - canWrite, - canExecute, - canCreate: - user?.admin || - (!disable_non_admin_create && user?.create_build_permissions), - specific, - }; - } - if (type === "Alerter" || type === "Builder") { - return { - canWrite, - canExecute, - canCreate: user?.admin, - specific, - }; - } + const [ + specificLogs, + specificInspect, + specificTerminal, + specificAttach, + specificProcesses, + ] = [ + specific.includes(Types.SpecificPermission.Logs), + specific.includes(Types.SpecificPermission.Inspect), + specific.includes(Types.SpecificPermission.Terminal), + specific.includes(Types.SpecificPermission.Attach), + specific.includes(Types.SpecificPermission.Processes), + ]; + + const canCreate = + type === "Server" + ? user?.admin || + (!disable_non_admin_create && user?.create_server_permissions) + : type === "Build" + ? user?.admin || + (!disable_non_admin_create && user?.create_build_permissions) + : type === "Alerter" || + type === "Builder" || + type === "Procedure" || + type === "Action" + ? user?.admin + : user?.admin || !disable_non_admin_create; return { canWrite, canExecute, - canCreate: user?.admin || !disable_non_admin_create, + canCreate, specific, + specificLogs, + specificInspect, + specificTerminal, + specificAttach, + specificProcesses, }; }; diff --git a/frontend/src/lib/socket.tsx b/frontend/src/lib/socket.tsx index 379b302df..cc05d0271 100644 --- a/frontend/src/lib/socket.tsx +++ b/frontend/src/lib/socket.tsx @@ -1,4 +1,4 @@ -import { komodo_client, useInvalidate, useRead, useUser } from "@lib/hooks"; +import { useInvalidate, komodo_client, useRead, useUser } from "@lib/hooks"; import { Types } from "komodo_client"; import { Button } from "@ui/button"; import { toast } from "@ui/use-toast"; diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index 1f41784d7..69b7fc5ae 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -10,14 +10,10 @@ import { atomWithStorage } from "@lib/hooks"; import "./monaco"; import { init_monaco } from "./monaco/init"; -export const AUTH_TOKEN_STORAGE_KEY = "komodo-auth-token"; - export const KOMODO_BASE_URL = import.meta.env.VITE_KOMODO_HOST ?? location.origin; - export const UPDATE_WS_URL = KOMODO_BASE_URL.replace("http", "ws") + "/ws/update"; - const query_client = new QueryClient({ defaultOptions: { queries: { retry: false } }, }); diff --git a/frontend/src/monaco/fancy_toml.ts b/frontend/src/monaco/fancy_toml.ts new file mode 100644 index 000000000..98d93c96c --- /dev/null +++ b/frontend/src/monaco/fancy_toml.ts @@ -0,0 +1,240 @@ +import * as monaco from "monaco-editor"; + +/// V2: Toml + Yaml + Env Vars +const fancy_toml_conf: monaco.languages.LanguageConfiguration = { + comments: { + lineComment: "#", + }, + brackets: [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ], + autoClosingPairs: [ + { open: "{", close: "}" }, + { open: "[", close: "]" }, + { open: "(", close: ")" }, + { open: '"', close: '"' }, + { open: "'", close: "'" }, + { open: '"""', close: '"""' }, + ], + surroundingPairs: [ + { open: "{", close: "}" }, + { open: "[", close: "]" }, + { open: "(", close: ")" }, + { open: '"', close: '"' }, + { open: "'", close: "'" }, + { open: '"""', close: '"""' }, + ], +}; + +const fancy_toml_language = { + defaultToken: "", + tokenPostfix: ".toml", + + escapes: /\\(?:[btnfr\"\'\\\/]|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/, + + tokenizer: { + root: [ + // Comments + [/\s*((#).*)$/, "comment"], + + // Table Definitions + [ + /^\s*(\[\[)([^[\]]+)(\]\])/, + [ + "punctuation.definition.array.table", + "entity.other.attribute-name.table.array", + "punctuation.definition.array.table", + ], + ], + [ + /^\s*(\[)([^[\]]+)(\])/, + [ + "punctuation.definition.table", + "entity.other.attribute-name.table", + "punctuation.definition.table", + ], + ], + + // Inline tables + [ + /\{/, + { + token: "punctuation.definition.table.inline", + next: "@inlineTable", + }, + ], + + // Entry (Key = Value) + [ + /\s*((?:(?:(?:[A-Za-z0-9_+-]+)|(?:\"[^\"]+\")|(?:'[^']+'))\s*\.?\s*)+)\s*(=)/, + ["", "delimiter"], + ], + + // Values (booleans, numbers, dates, strings, arrays) + { include: "@values" }, + ], + + // Inline Table + inlineTable: [ + [/\}/, { token: "punctuation.definition.table.inline", next: "@pop" }], + { include: "@comments" }, + [/,/, "punctuation.separator.table.inline"], + { include: "@values" }, + ], + + // Values (Strings, Numbers, Booleans, Dates, Arrays) + values: [ + // Triple quoted string (basic) + [/"""/, { token: "string", next: "@tripleStringWithYamlEnv" }], + + // Single quoted string + [/"/, { token: "string.quoted.single.basic.line", next: "@basicString" }], + + // Triple quoted literal string + [ + /'''/, + { + token: "string.quoted.triple.literal.block", + next: "@literalTripleStringWithYamlEnv", + }, + ], + + // Single quoted literal string + [ + /'/, + { + token: "string.quoted.single.literal.line", + next: "@literalStringSingle", + }, + ], + + // Dates and Times + [ + /\d{4}-\d{2}-\d{2}[Tt ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})/, + "constant.other.time.datetime.offset", + ], + [ + /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?/, + "constant.other.time.datetime.local", + ], + [/\d{4}-\d{2}-\d{2}/, "constant.other.time.date"], + [/\d{2}:\d{2}:\d{2}(?:\.\d+)?/, "constant.other.time.time"], + + // Booleans + [/\b(true|false)\b/, "constant.language.boolean"], + + // Numbers + [/[+-]?(0x[0-9A-Fa-f_]+|0o[0-7_]+|0b[01_]+)/, "number.hex"], + [ + /(?{ +/* ------------------------------------------------- + * Monarch tokenizer – TOML-only + * ------------------------------------------------- */ +const toml_language: monaco.languages.IMonarchLanguage = { defaultToken: "", tokenPostfix: ".toml", - escapes: /\\(?:[btnfr\"\'\\\/]|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/, + escapes: /\\(?:[btnfr"'\\\/]|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/, tokenizer: { + /* ---------- root ---------- */ root: [ - // Comments - [/\s*((#).*)$/, "comment"], + { include: "@comments" }, - // Table Definitions + /* Tables & array-tables */ [ /^\s*(\[\[)([^[\]]+)(\]\])/, [ @@ -57,66 +60,39 @@ const toml_language = { ], ], - // Inline tables + /* Inline tables */ [ /\{/, - { - token: "punctuation.definition.table.inline", - next: "@inlineTable", - }, + { token: "punctuation.definition.table.inline", next: "@inlineTable" }, ], - // Entry (Key = Value) + /* Key-value pair */ [ - /\s*((?:(?:(?:[A-Za-z0-9_+-]+)|(?:\"[^\"]+\")|(?:'[^']+'))\s*\.?\s*)+)\s*(=)/, + /\s*((?:(?:(?:[A-Za-z0-9_+\-]+)|(?:\"[^\"]+\")|(?:'[^']+'))\s*\.?\s*)+)\s*(=)/, ["", "delimiter"], ], - // Values (booleans, numbers, dates, strings, arrays) + /* Values */ { include: "@values" }, ], - // Inline Table + /* ---------- inline table ---------- */ inlineTable: [ - [ - /\}/, - { token: "punctuation.definition.table.inline", next: "@pop" }, - ], + [/\}/, { token: "punctuation.definition.table.inline", next: "@pop" }], { include: "@comments" }, [/,/, "punctuation.separator.table.inline"], { include: "@values" }, ], - // Values (Strings, Numbers, Booleans, Dates, Arrays) + /* ---------- values ---------- */ values: [ - // Triple quoted string (basic) - [/"""/, { token: "string", next: "@tripleStringWithYamlEnv" }], + /* Strings ---------------------------------------------------- */ + [/"""/, { token: "string", next: "@tripleBasicString" }], + [/"/, { token: "string", next: "@basicString" }], + [/'''/, { token: "string", next: "@tripleLiteralString" }], + [/'/, { token: "string", next: "@literalStringSingle" }], - // Single quoted string - [ - /"/, - { token: "string.quoted.single.basic.line", next: "@basicString" }, - ], - - // Triple quoted literal string - [ - /'''/, - { - token: "string.quoted.triple.literal.block", - next: "@literalTripleStringWithYamlEnv", - }, - ], - - // Single quoted literal string - [ - /'/, - { - token: "string.quoted.single.literal.line", - next: "@literalStringSingle", - }, - ], - - // Dates and Times + /* Dates, times, booleans ------------------------------------ */ [ /\d{4}-\d{2}-\d{2}[Tt ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})/, "constant.other.time.datetime.offset", @@ -127,537 +103,60 @@ const toml_language = { ], [/\d{4}-\d{2}-\d{2}/, "constant.other.time.date"], [/\d{2}:\d{2}:\d{2}(?:\.\d+)?/, "constant.other.time.time"], - - // Booleans [/\b(true|false)\b/, "constant.language.boolean"], - // Numbers + /* Numbers ---------------------------------------------------- */ [/[+-]?(0x[0-9A-Fa-f_]+|0o[0-7_]+|0b[01_]+)/, "number.hex"], [ - /(?{ -// defaultToken: "", -// tokenPostfix: ".toml", - -// escapes: -// /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/, - -// tokenizer: { -// root: [ -// { include: "@comments" }, -// { include: "@tables" }, -// { include: "@keys" }, -// { include: "@whitespace" }, -// { include: "@dateTimeWithTz" }, -// { include: "@dateTime" }, -// { include: "@date" }, -// { include: "@float" }, -// { include: "@integer" }, -// { include: "@boolean" }, -// { include: "@string" }, -// ], - -// comments: [ -// [ -// /\s*((#).*)$/, -// { -// cases: { -// $1: "comment.line.number-sign.toml", -// $2: "punctuation.definition.comment.toml", -// }, -// }, -// ], -// ], - -// dateTimeWithTz: [ -// [ -// /(?{ -// defaultToken: "", -// tokenPostfix: ".toml", - -// escapes: -// /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/, - -// tokenizer: { -// root: [ -// { include: "@comments" }, -// { include: "@tables" }, -// { include: "@keys" }, -// { include: "@whitespace" }, -// { include: "@dateTimeWithTz" }, -// { include: "@dateTime" }, -// { include: "@date" }, -// { include: "@float" }, -// { include: "@integer" }, -// { include: "@boolean" }, -// { include: "@string" }, -// ], - -// comments: [ -// [ -// /\s*((#).*)$/, -// { -// cases: { -// $1: "comment.line.number-sign.toml", -// $2: "punctuation.definition.comment.toml", -// }, -// }, -// ], -// ], - -// dateTimeWithTz: [ -// [ -// /(? ), cell: ({ row }) => - row.original.networks.length > 0 ? ( + (row.original.networks?.length ?? 0) > 0 ? (
- {row.original.networks.map((network, i) => ( + {row.original.networks?.map((network, i) => ( - {i !== row.original.networks.length - 1 && ( + {i !== row.original.networks!.length - 1 && (
|
)}
@@ -167,7 +167,7 @@ export default function ContainersPage() { ), cell: ({ row }) => ( ), diff --git a/frontend/src/pages/home/dashboard.tsx b/frontend/src/pages/home/dashboard.tsx index 97f1df77d..5c6749c83 100644 --- a/frontend/src/pages/home/dashboard.tsx +++ b/frontend/src/pages/home/dashboard.tsx @@ -2,8 +2,12 @@ import { ExportButton } from "@components/export"; import { Page, Section } from "@components/layouts"; import { ResourceComponents } from "@components/resources"; import { ResourceLink, ResourceNameSimple } from "@components/resources/common"; +import { ServerStatsMini } from "@components/resources/server"; import { TagsWithBadge } from "@components/tags"; import { StatusBadge, TemplateMarker } from "@components/util"; +import { useDashboardPreferences } from "@lib/dashboard-preferences"; +import { Button } from "@ui/button"; +import { Eye, EyeOff } from "lucide-react"; import { action_state_intention, build_state_intention, @@ -27,13 +31,42 @@ import { UpdateAvailable as DeploymentUpdateAvailable } from "@components/resour export default function Dashboard() { const noResources = useNoResources(); const user = useUser().data!; + const { preferences, updatePreference } = useDashboardPreferences(); + return ( <> } - actions={} + actions={ +
+ + +
+ } >
{noResources && ( @@ -65,7 +98,7 @@ const ResourceRow = ({ type }: { type: UsableResource }) => { const _recents = useUser().data?.recents?.[type]?.slice(0, 6); const _resources = useRead(`List${type}s`, {}).data; const recents = _recents?.filter( - (recent) => !_resources?.every((resource) => resource.id !== recent) + (recent) => !_resources?.every((resource) => resource.id !== recent), ); const resources = _resources ?.filter((r) => !recents?.includes(r.id)) @@ -81,7 +114,7 @@ const ResourceRow = ({ type }: { type: UsableResource }) => {
@@ -94,7 +127,7 @@ const ResourceRow = ({ type }: { type: UsableResource }) => { Recently Viewed

-
+
{ids.map((id, i) => ( { const Components = ResourceComponents[type]; const resource = Components.list_item(id); + const { preferences } = useDashboardPreferences(); if (!resource) return null; const tags = resource?.tags; + const showServerStats = type === "Server" && preferences.showServerStats; return (
@@ -148,8 +184,17 @@ const RecentCard = ({ {type === "Deployment" && } {type === "Stack" && }
-
- + +
+ {showServerStats && } +
+ +
); diff --git a/frontend/src/pages/login.tsx b/frontend/src/pages/login.tsx index 19628b3e0..1e9528f5b 100644 --- a/frontend/src/pages/login.tsx +++ b/frontend/src/pages/login.tsx @@ -9,70 +9,55 @@ import { } from "@ui/card"; import { Input } from "@ui/input"; import { Label } from "@ui/label"; -import { useAuth, useLoginOptions, useUserInvalidate } from "@lib/hooks"; +import { + LOGIN_TOKENS, + useAuth, + useLoginOptions, + useUserInvalidate, +} from "@lib/hooks"; import { useState } from "react"; import { ThemeToggle } from "@ui/theme"; -import { AUTH_TOKEN_STORAGE_KEY, KOMODO_BASE_URL } from "@main"; -import { KeyRound, Loader2, X } from "lucide-react"; +import { KOMODO_BASE_URL } from "@main"; +import { KeyRound, X } from "lucide-react"; import { cn } from "@lib/utils"; import { useToast } from "@ui/use-toast"; +import { Types } from "komodo_client"; type OauthProvider = "Github" | "Google" | "OIDC"; const login_with_oauth = (provider: OauthProvider) => { - const redirect = encodeURIComponent(location.href); + const _redirect = location.pathname.startsWith("/login") + ? location.origin + + (new URLSearchParams(location.search).get("backto") ?? "") + : location.href; + const redirect = encodeURIComponent(_redirect); location.replace( `${KOMODO_BASE_URL}/auth/${provider.toLowerCase()}/login?redirect=${redirect}` ); }; -const sanitize_query = (search: URLSearchParams) => { - search.delete("token"); - const query = search.toString(); - location.replace( - `${location.origin}${location.pathname}${query.length ? "?" + query : ""}` - ); -}; - -let exchange_token_sent = false; - -/// returns whether to show login / loading screen depending on state of exchange token loop -const useExchangeToken = () => { - const search = new URLSearchParams(location.search); - const exchange_token = search.get("token"); - const { mutate } = useAuth("ExchangeForJwt", { - onSuccess: ({ jwt }) => { - localStorage.setItem(AUTH_TOKEN_STORAGE_KEY, jwt); - sanitize_query(search); - }, - }); - - // In this case, failed to get user (jwt unset / invalid) - // and the exchange token is not in url. - // Just show the login. - if (!exchange_token) return false; - - // guard against multiple reqs sent - // maybe isPending would do this but not sure about with render loop, this for sure will. - if (!exchange_token_sent) { - mutate({ token: exchange_token }); - exchange_token_sent = true; - } - - return true; -}; - export default function Login() { const options = useLoginOptions().data; const [creds, set] = useState({ username: "", password: "" }); const userInvalidate = useUserInvalidate(); const { toast } = useToast(); - const onSuccess = ({ jwt }: { jwt: string }) => { - localStorage.setItem(AUTH_TOKEN_STORAGE_KEY, jwt); + + // If signing in another user, need to redirect away from /login manually + const maybeNavigate = location.pathname.startsWith("/login") + ? () => + location.replace( + new URLSearchParams(location.search).get("backto") ?? "/" + ) + : undefined; + + const onSuccess = ({ user_id, jwt }: Types.JwtResponse) => { + LOGIN_TOKENS.add_and_change(user_id, jwt); userInvalidate(); + maybeNavigate?.(); }; + const { mutate: signup, isPending: signupPending } = useAuth( - "CreateLocalUser", + "SignUpLocalUser", { onSuccess, onError: (e: any) => { @@ -113,15 +98,7 @@ export default function Login() { }, }); - // Handle exchange token loop to avoid showing login flash - const exchangeTokenPending = useExchangeToken(); - if (exchangeTokenPending) { - return ( -
- -
- ); - } + const no_auth_configured = options !== undefined && diff --git a/frontend/src/pages/server-info/container/index.tsx b/frontend/src/pages/server-info/container/index.tsx index 5f1ed8ab8..ada25e3c7 100644 --- a/frontend/src/pages/server-info/container/index.tsx +++ b/frontend/src/pages/server-info/container/index.tsx @@ -27,7 +27,7 @@ import { import { Link, useNavigate, useParams } from "react-router-dom"; import { ContainerLogs } from "./log"; import { Actions } from "./actions"; -import { Types } from "komodo_client"; +import { ConnectExecQuery, Types } from "komodo_client"; import { container_state_intention } from "@lib/color"; import { UsableResource } from "@types"; import { Fragment } from "react/jsx-runtime"; @@ -36,6 +36,7 @@ import { ResourceNotifications } from "@pages/resource-notifications"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@ui/tabs"; import { ContainerTerminal } from "@components/terminal/container"; import { ContainerInspect } from "./inspect"; +import { useMemo } from "react"; export default function ContainerPage() { const { type, id, container } = useParams() as { @@ -121,7 +122,7 @@ const ContainerPageInner = ({ /> )} - {list_container?.networks.map((network) => ( + {list_container?.networks?.map((network) => ( | ))} - {list_container?.volumes.map((volume) => ( + {list_container?.volumes?.map((volume) => ( | - - Log - - {specific.includes(Types.SpecificPermission.Inspect) && ( - - Inspect + const tabs = useMemo(() => { + return ( + + + Log - )} - {specific.includes(Types.SpecificPermission.Terminal) && ( - - Terminal - - )} - + {specificInspect && ( + + Inspect + + )} + {specificTerminal && ( + + Terminal + + )} + + ); + }, [ + logDisabled, + specificInspect, + inspectDisabled, + specificTerminal, + terminalDisabled, + ]); + const terminalQuery = useMemo( + () => + ({ + type: "container", + query: { + server, + container, + // This is handled inside ContainerTerminal + shell: "", + }, + }) as ConnectExecQuery, + [server, container] ); return ( - + - + ); diff --git a/frontend/src/pages/server-info/container/log.tsx b/frontend/src/pages/server-info/container/log.tsx index 004366205..9673cf698 100644 --- a/frontend/src/pages/server-info/container/log.tsx +++ b/frontend/src/pages/server-info/container/log.tsx @@ -25,11 +25,11 @@ export const ContainerLogs = ({ return ( - NoSearchLogs(id, container_name, tail, timestamps, stream) + regular_logs={(timestamps, stream, tail, poll) => + NoSearchLogs(id, container_name, tail, timestamps, stream, poll) } - search_logs={(timestamps, terms, invert) => - SearchLogs(id, container_name, terms, invert, timestamps) + search_logs={(timestamps, terms, invert, poll) => + SearchLogs(id, container_name, terms, invert, timestamps, poll) } /> ); @@ -40,14 +40,19 @@ const NoSearchLogs = ( container: string, tail: number, timestamps: boolean, - stream: string + stream: string, + poll: boolean ) => { - const { data: log, refetch } = useRead("GetContainerLog", { - server: id, - container, - tail: Number(tail), - timestamps, - }); + const { data: log, refetch } = useRead( + "GetContainerLog", + { + server: id, + container, + tail: Number(tail), + timestamps, + }, + { refetchInterval: poll ? 3000 : false } + ); return { Log: (
@@ -64,16 +69,21 @@ const SearchLogs = ( container: string, terms: string[], invert: boolean, - timestamps: boolean + timestamps: boolean, + poll: boolean ) => { - const { data: log, refetch } = useRead("SearchContainerLog", { - server: id, - container, - terms, - combinator: Types.SearchCombinator.And, - invert, - timestamps, - }); + const { data: log, refetch } = useRead( + "SearchContainerLog", + { + server: id, + container, + terms, + combinator: Types.SearchCombinator.And, + invert, + timestamps, + }, + { refetchInterval: poll ? 10000 : false } + ); return { Log: (
diff --git a/frontend/src/pages/settings/users.tsx b/frontend/src/pages/settings/users.tsx index 1a1abb5f7..1e3352de0 100644 --- a/frontend/src/pages/settings/users.tsx +++ b/frontend/src/pages/settings/users.tsx @@ -1,37 +1,49 @@ import { ExportButton } from "@components/export"; import { Section } from "@components/layouts"; import { DeleteUserGroup } from "@components/users/delete-user-group"; -import { NewServiceUser, NewUserGroup } from "@components/users/new"; +import { + NewLocalUser, + NewServiceUser, + NewUserGroup, +} from "@components/users/new"; import { UserTable } from "@components/users/table"; import { useInvalidate, + useLoginOptions, useRead, useSetTitle, useUser, useWrite, } from "@lib/hooks"; +import { filterBySplit } from "@lib/utils"; import { DataTable } from "@ui/data-table"; import { Input } from "@ui/input"; import { useToast } from "@ui/use-toast"; import { Search, User, Users } from "lucide-react"; -import { useState } from "react"; +import React, { useState } from "react"; import { useNavigate } from "react-router-dom"; export const UsersPage = ({ goToProfile }: { goToProfile: () => void }) => { useSetTitle("Users"); + const [search, setSearch] = useState(""); return (
- - + +
); }; -const UserGroupsSection = () => { +const UserGroupsSection = ({ + search, + setSearch, +}: { + search: string; + setSearch: React.Dispatch>; +}) => { const nav = useNavigate(); const groups = useRead("ListUserGroups", {}).data; - const [search, setSearch] = useState(""); - const searchSplit = search.split(" "); + const filtered = filterBySplit(groups, search, (group) => group.name); return (
}>
@@ -59,11 +71,7 @@ const UserGroupsSection = () => {
- searchSplit.every((term) => group.name.includes(term)) - ) ?? [] - } + data={filtered} columns={[ { header: "Name", accessorKey: "name" }, { @@ -84,10 +92,17 @@ const UserGroupsSection = () => { ); }; -const UsersSection = ({ goToProfile }: { goToProfile: () => void }) => { +const UsersSection = ({ + goToProfile, + search, +}: { + goToProfile: () => void; + search: string; +}) => { const user = useUser().data; const inv = useInvalidate(); const { toast } = useToast(); + const local_login_enabled = useLoginOptions().data?.local; const { mutate: deleteUser } = useWrite("DeleteUser", { onSuccess: () => { toast({ title: "User deleted." }); @@ -95,28 +110,15 @@ const UsersSection = ({ goToProfile }: { goToProfile: () => void }) => { }, }); const users = useRead("ListUsers", {}).data; - const [search, setSearch] = useState(""); - const searchSplit = search.split(" "); + const filtered = filterBySplit(users, search, (user) => user.username); return (
}> -
+
+ {local_login_enabled && } -
- - setSearch(e.target.value)} - className="pl-8 w-[200px] lg:w-[300px]" - /> -
- searchSplit.every((term) => user.username.includes(term)) - ) ?? [] - } + users={filtered} onUserDelete={ user?.admin ? (user_id) => deleteUser({ user: user_id }) : undefined } diff --git a/frontend/src/pages/stack-service/index.tsx b/frontend/src/pages/stack-service/index.tsx index 0d3766017..c3edb48d5 100644 --- a/frontend/src/pages/stack-service/index.tsx +++ b/frontend/src/pages/stack-service/index.tsx @@ -25,7 +25,7 @@ import { useContainerPortsMap, } from "@lib/hooks"; import { cn } from "@lib/utils"; -import { Types } from "komodo_client"; +import { ConnectExecQuery, Types } from "komodo_client"; import { ChevronLeft, Clapperboard, Layers2 } from "lucide-react"; import { Link, useParams } from "react-router-dom"; import { StackServiceLogs } from "./log"; @@ -38,6 +38,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@ui/tabs"; import { ContainerTerminal } from "@components/terminal/container"; import { useServer } from "@components/resources/server"; import { StackServiceInspect } from "./inspect"; +import { useMemo } from "react"; type IdServiceComponent = React.FC<{ id: string; service?: string }>; @@ -143,7 +144,7 @@ const StackServicePageInner = ({ )} {stack?.info.server_id && - container?.networks.map((network) => ( + container?.networks?.map((network) => ( | ( + container.volumes?.map((volume) => ( | - - Log - - {specific.includes(Types.SpecificPermission.Inspect) && ( - - Inspect + const tabs = useMemo( + () => ( + + + Log - )} - {specific.includes(Types.SpecificPermission.Terminal) && ( - - Terminal - - )} - + {specificInspect && ( + + Inspect + + )} + {specificTerminal && ( + + Terminal + + )} + + ), + [ + logDisabled, + specificInspect, + inspectDisabled, + specificTerminal, + terminalDisabled, + ] + ); + const terminalQuery = useMemo( + () => + ({ + type: "stack", + query: { + stack: stack.id, + service, + // This is handled inside ContainerTerminal + shell: "", + }, + }) as ConnectExecQuery, + [stack.id, service] ); return ( - + - + ); diff --git a/frontend/src/pages/stack-service/log.tsx b/frontend/src/pages/stack-service/log.tsx index 162c48267..5c6d7ce92 100644 --- a/frontend/src/pages/stack-service/log.tsx +++ b/frontend/src/pages/stack-service/log.tsx @@ -49,11 +49,11 @@ const StackLogsInner = ({ return ( - NoSearchLogs(id, service, tail, timestamps, stream) + regular_logs={(timestamps, stream, tail, poll) => + NoSearchLogs(id, service, tail, timestamps, stream, poll) } - search_logs={(timestamps, terms, invert) => - SearchLogs(id, service, terms, invert, timestamps) + search_logs={(timestamps, terms, invert, poll) => + SearchLogs(id, service, terms, invert, timestamps, poll) } /> ); @@ -64,14 +64,19 @@ const NoSearchLogs = ( service: string, tail: number, timestamps: boolean, - stream: string + stream: string, + poll: boolean ) => { - const { data: log, refetch } = useRead("GetStackLog", { - stack: id, - services: [service], - tail, - timestamps, - }); + const { data: log, refetch } = useRead( + "GetStackLog", + { + stack: id, + services: [service], + tail, + timestamps, + }, + { refetchInterval: poll ? 3000 : false } + ); return { Log: (
@@ -88,16 +93,21 @@ const SearchLogs = ( service: string, terms: string[], invert: boolean, - timestamps: boolean + timestamps: boolean, + poll: boolean ) => { - const { data: log, refetch } = useRead("SearchStackLog", { - stack: id, - services: [service], - terms, - combinator: Types.SearchCombinator.And, - invert, - timestamps, - }); + const { data: log, refetch } = useRead( + "SearchStackLog", + { + stack: id, + services: [service], + terms, + combinator: Types.SearchCombinator.And, + invert, + timestamps, + }, + { refetchInterval: poll ? 10000 : false } + ); return { Log: (
diff --git a/frontend/src/pages/update.tsx b/frontend/src/pages/update.tsx new file mode 100644 index 000000000..aa3ffc8b6 --- /dev/null +++ b/frontend/src/pages/update.tsx @@ -0,0 +1,16 @@ +import { UpdateDetailsInner } from "@components/updates/details"; +import { useRead, useSetTitle } from "@lib/hooks"; +import { To, useLocation, useNavigate, useParams } from "react-router-dom"; + +export default function UpdatePage() { + useSetTitle("Update"); + // https://github.com/remix-run/react-router/discussions/9788#discussioncomment-4604278 + const navTo = (useLocation().key === "default" ? "/" : -1) as To; + const navigate = useNavigate(); + const id = useParams().id as string; + const update = useRead("GetUpdate", { id }).data; + + if (!update) return null; + + return navigate(navTo)} />; +} diff --git a/frontend/src/pages/updates.tsx b/frontend/src/pages/updates.tsx index a619fab1a..25ecbce0e 100644 --- a/frontend/src/pages/updates.tsx +++ b/frontend/src/pages/updates.tsx @@ -1,7 +1,7 @@ import { Page } from "@components/layouts"; import { ResourceComponents } from "@components/resources"; import { UpdatesTable } from "@components/updates/table"; -import { useRead, useResourceParamType, useSetTitle } from "@lib/hooks"; +import { useRead, useSetTitle } from "@lib/hooks"; import { filterBySplit, RESOURCE_TARGETS } from "@lib/utils"; import { Types } from "komodo_client"; import { CaretSortIcon } from "@radix-ui/react-icons"; @@ -25,7 +25,7 @@ import { SearchX, } from "lucide-react"; import { useState } from "react"; -import { useParams, useSearchParams } from "react-router-dom"; +import { useSearchParams } from "react-router-dom"; import { Select, SelectContent, @@ -37,6 +37,7 @@ import { import { ResourceSelector } from "@components/resources/common"; export default function UpdatesPage() { + useSetTitle("Updates"); const [page, setPage] = useState(0); const [params, setParams] = useSearchParams(); @@ -170,110 +171,6 @@ export default function UpdatesPage() { ); } -export const Updates = () => { - const type = useResourceParamType()!; - const id = useParams().id as string; - if (type && id) { - return ; - } else { - return ; - } -}; - -const AllUpdates = () => { - useSetTitle("Updates"); - const [operation, setOperation] = useState(); - const [page, setPage] = useState(0); - const updates = useRead("ListUpdates", { query: { operation }, page }).data; - return ( - } - actions={ - - } - > -
- -
- - Page: {page + 1} - -
-
-
- ); -}; - -const ResourceUpdates = ({ - type, - id, -}: { - type: UsableResource; - id: string; -}) => { - const name = useRead(`List${type}s`, {}).data?.find((r) => r.id === id)?.name; - useSetTitle(name && `${name} | Updates`); - const [operation, setOperation] = useState(); - const [page, setPage] = useState(0); - const updates = useRead("ListUpdates", { - query: { - "target.type": type, - "target.id": id, - operation, - }, - page, - }).data; - const Components = ResourceComponents[type]; - return ( - Updates} - icon={} - actions={ - - } - > -
- -
- - Page: {page + 1} - -
-
-
- ); -}; - const OPERATIONS_BY_RESOURCE: { [key: string]: Types.Operation[] } = { Server: [ Types.Operation.CreateServer, diff --git a/frontend/src/pages/user_disabled.tsx b/frontend/src/pages/user_disabled.tsx index 4eb979e76..a448723ea 100644 --- a/frontend/src/pages/user_disabled.tsx +++ b/frontend/src/pages/user_disabled.tsx @@ -1,8 +1,9 @@ -import { AUTH_TOKEN_STORAGE_KEY } from "@main"; +import { LOGIN_TOKENS, useUser } from "@lib/hooks"; import { Button } from "@ui/button"; import { UserX } from "lucide-react"; export default function UserDisabled() { + const user_id = useUser().data?._id?.$oid; return (
@@ -11,7 +12,7 @@ export default function UserDisabled() {