diff --git a/.github/workflows/startos-iso.yaml b/.github/workflows/startos-iso.yaml index 30b2bec0f..c51eafc5c 100644 --- a/.github/workflows/startos-iso.yaml +++ b/.github/workflows/startos-iso.yaml @@ -71,27 +71,27 @@ jobs: sudo mount -t tmpfs tmpfs . if: ${{ github.event.inputs.runner == 'fast' }} - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: ${{ env.NODEJS_VERSION }} - name: Set up docker QEMU - uses: docker/setup-qemu-action@v2 + uses: docker/setup-qemu-action@v3 - name: Set up system dependencies run: sudo apt-get update && sudo apt-get install -y qemu-user-static systemd-container - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Make run: make ARCH=${{ matrix.arch }} compiled-${{ matrix.arch }}.tar - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: compiled-${{ matrix.arch }}.tar path: compiled-${{ matrix.arch }}.tar @@ -144,7 +144,7 @@ jobs: run: rm -rf /opt/hostedtoolcache* if: ${{ github.event.inputs.runner != 'fast' }} - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive @@ -166,7 +166,7 @@ jobs: if: ${{ github.event.inputs.runner == 'fast' && (matrix.platform == 'x86_64' || matrix.platform == 'x86_64-nonfree') }} - name: Download compiled artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: compiled-${{ env.ARCH }}.tar @@ -190,18 +190,18 @@ jobs: run: PLATFORM=${{ matrix.platform }} make img if: ${{ matrix.platform == 'raspberrypi' }} - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: ${{ matrix.platform }}.squashfs path: results/*.squashfs - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: ${{ matrix.platform }}.iso path: results/*.iso if: ${{ matrix.platform != 'raspberrypi' }} - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: ${{ matrix.platform }}.img path: results/*.img diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index c6082ac25..0a5eb38e9 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -19,11 +19,11 @@ jobs: name: Run Automated Tests runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: ${{ env.NODEJS_VERSION }} diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 000000000..cb9385f41 --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,133 @@ +# Setting up your development environment on Debian/Ubuntu + +A step-by-step guide + +> This is the only officially supported build environment. +> MacOS has limited build capabilities and Windows requires [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install) + +## Installing dependencies + +Run the following commands one at a time + +```sh +sudo apt update +sudo apt install -y ca-certificates curl gpg build-essential +curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg +echo "deb [arch=$(dpkg-architecture -q DEB_HOST_ARCH) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bookworm stable" | sudo tee /etc/apt/sources.list.d/docker.list +sudo apt update +sudo apt install -y sed grep gawk jq gzip brotli containerd.io docker-ce docker-ce-cli docker-compose-plugin qemu-user-static binfmt-support squashfs-tools git debspawn rsync b3sum +sudo mkdir -p /etc/debspawn/ +echo "AllowUnsafePermissions=true" | sudo tee /etc/debspawn/global.toml +sudo usermod -aG docker $USER +sudo su $USER +docker run --privileged --rm tonistiigi/binfmt --install all +docker buildx create --use +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # proceed with default installation +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash +source ~/.bashrc +nvm install 20 +nvm use 20 +``` + +## Cloning the repository + +```sh +git clone --recursive https://github.com/Start9Labs/start-os.git --branch next/minor +cd start-os +``` + +## Building an ISO + +```sh +PLATFORM=$(uname -m) ENVIRONMENT=dev make iso +``` + +This will build an ISO for your current architecture. If you are building to run on an architecture other than the one you are currently on, replace `$(uname -m)` with the correct platform for the device (one of `aarch64`, `aarch64-nonfree`, `x86_64`, `x86_64-nonfree`, `raspberrypi`) + +## Creating a VM + +### Install virt-manager + +```sh +sudo apt update +sudo apt install -y virt-manager +sudo usermod -aG libvirt $USER +sudo su $USER +``` + +### Launch virt-manager + +```sh +virt-manager +``` + +### Create new virtual machine + +![Select "Create a new virtual machine"](assets/create-vm/step-1.png) +![Click "Forward"](assets/create-vm/step-2.png) +![Click "Browse"](assets/create-vm/step-3.png) +![Click "+"](assets/create-vm/step-4.png) + +#### make sure to set "Target Path" to the path to your results directory in start-os + +![Create storage pool](assets/create-vm/step-5.png) +![Select storage pool](assets/create-vm/step-6.png) +![Select ISO](assets/create-vm/step-7.png) +![Select "Generic or unknown OS" and click "Forward"](assets/create-vm/step-8.png) +![Set Memory and CPUs](assets/create-vm/step-9.png) +![Create disk](assets/create-vm/step-10.png) +![Name VM](assets/create-vm/step-11.png) +![Create network](assets/create-vm/step-12.png) + +## Updating a VM + +The fastest way to update a VM to your latest code depends on what you changed: + +### UI or startd: + +```sh +PLATFORM=$(uname -m) ENVIRONMENT=dev make update-startbox REMOTE=start9@ +``` + +### Container runtime or debian dependencies: + +```sh +PLATFORM=$(uname -m) ENVIRONMENT=dev make update-deb REMOTE=start9@ +``` + +### Image recipe: + +```sh +PLATFORM=$(uname -m) ENVIRONMENT=dev make update-squashfs REMOTE=start9@ +``` + +--- + +If the device you are building for is not available via ssh, it is also possible to use `magic-wormhole` to send the relevant files. + +### Prerequisites: + +```sh +sudo apt update +sudo apt install -y magic-wormhole +``` + +As before, the fastest way to update a VM to your latest code depends on what you changed. Each of the following commands will return a command to paste into the shell of the device you would like to upgrade. + +### UI or startd: + +```sh +PLATFORM=$(uname -m) ENVIRONMENT=dev make wormhole +``` + +### Container runtime or debian dependencies: + +```sh +PLATFORM=$(uname -m) ENVIRONMENT=dev make wormhole-deb +``` + +### Image recipe: + +```sh +PLATFORM=$(uname -m) ENVIRONMENT=dev make wormhole-squashfs +``` diff --git a/Makefile b/Makefile index 4915101e3..9a9a001b7 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ COMPAT_SRC := $(shell git ls-files system-images/compat/) UTILS_SRC := $(shell git ls-files system-images/utils/) BINFMT_SRC := $(shell git ls-files system-images/binfmt/) CORE_SRC := $(shell git ls-files core) $(shell git ls-files --recurse-submodules patch-db) web/dist/static web/patchdb-ui-seed.json $(GIT_HASH_FILE) -WEB_SHARED_SRC := $(shell git ls-files web/projects/shared) $(shell ls -p web/ | grep -v / | sed 's/^/web\//g') web/node_modules/.package-lock.json web/config.json patch-db/client/dist web/patchdb-ui-seed.json +WEB_SHARED_SRC := $(shell git ls-files web/projects/shared) $(shell ls -p web/ | grep -v / | sed 's/^/web\//g') web/node_modules/.package-lock.json web/config.json patch-db/client/dist web/patchdb-ui-seed.json sdk/dist WEB_UI_SRC := $(shell git ls-files web/projects/ui) WEB_SETUP_WIZARD_SRC := $(shell git ls-files web/projects/setup-wizard) WEB_INSTALL_WIZARD_SRC := $(shell git ls-files web/projects/install-wizard) @@ -152,16 +152,21 @@ update-overlay: $(ALL_TARGETS) $(call ssh,"sudo systemctl start startd") wormhole: core/target/$(ARCH)-unknown-linux-musl/release/startbox - @echo "Paste the following command into the shell of your start-os server:" + @echo "Paste the following command into the shell of your StartOS server:" + @echo @wormhole send core/target/$(ARCH)-unknown-linux-musl/release/startbox 2>&1 | awk -Winteractive '/wormhole receive/ { printf "sudo /usr/lib/startos/scripts/chroot-and-upgrade \"cd /usr/bin && rm startbox && wormhole receive --accept-file %s && chmod +x startbox\"\n", $$3 }' wormhole-deb: results/$(BASENAME).deb - @echo "Paste the following command into the shell of your start-os server:" + @echo "Paste the following command into the shell of your StartOS server:" + @echo @wormhole send results/$(BASENAME).deb 2>&1 | awk -Winteractive '/wormhole receive/ { printf "sudo /usr/lib/startos/scripts/chroot-and-upgrade '"'"'cd $$(mktemp -d) && wormhole receive --accept-file %s && apt-get install -y --reinstall ./$(BASENAME).deb'"'"'\n", $$3 }' -wormhole-cli: core/target/$(ARCH)-unknown-linux-musl/release/start-cli - @echo "Paste the following command into the shell of your start-os server:" - @wormhole send results/$(BASENAME).deb 2>&1 | awk -Winteractive '/wormhole receive/ { printf "sudo /usr/lib/startos/scripts/chroot-and-upgrade '"'"'cd $$(mktemp -d) && wormhole receive --accept-file %s && apt-get install -y --reinstall ./$(BASENAME).deb'"'"'\n", $$3 }' +wormhole-squashfs: results/$(BASENAME).squashfs + $(eval SQFS_SUM := $(shell b3sum results/$(BASENAME).squashfs | head -c 32)) + $(eval SQFS_SIZE := $(shell du -s --bytes results/$(BASENAME).squashfs | awk '{print $$1}')) + @echo "Paste the following command into the shell of your StartOS server:" + @echo + @wormhole send results/$(BASENAME).squashfs 2>&1 | awk -Winteractive '/wormhole receive/ { printf "sudo sh -c '"'"'/usr/lib/startos/scripts/prune-images $(SQFS_SIZE) && cd /media/startos/images && wormhole receive --accept-file %s && mv $(BASENAME).squashfs $(SQFS_SUM).rootfs && ln -rsf ./$(SQFS_SUM).rootfs ../config/current.rootfs && sync && reboot'"'"'\n", $$3 }' update: $(ALL_TARGETS) @if [ -z "$(REMOTE)" ]; then >&2 echo "Must specify REMOTE" && false; fi @@ -169,6 +174,28 @@ update: $(ALL_TARGETS) $(MAKE) install REMOTE=$(REMOTE) SSHPASS=$(SSHPASS) DESTDIR=/media/startos/next PLATFORM=$(PLATFORM) $(call ssh,'sudo /media/startos/next/usr/lib/startos/scripts/chroot-and-upgrade --no-sync "apt-get install -y $(shell cat ./build/lib/depends)"') +update-startbox: core/target/$(ARCH)-unknown-linux-musl/release/startbox # only update binary (faster than full update) + @if [ -z "$(REMOTE)" ]; then >&2 echo "Must specify REMOTE" && false; fi + $(call ssh,'sudo /usr/lib/startos/scripts/chroot-and-upgrade --create') + $(call cp,core/target/$(ARCH)-unknown-linux-musl/release/startbox,/media/startos/next/usr/bin/startbox) + $(call ssh,'sudo /media/startos/next/usr/lib/startos/scripts/chroot-and-upgrade --no-sync true') + +update-deb: results/$(BASENAME).deb # better than update, but only available from debian + @if [ -z "$(REMOTE)" ]; then >&2 echo "Must specify REMOTE" && false; fi + $(call ssh,'sudo /usr/lib/startos/scripts/chroot-and-upgrade --create') + $(call mkdir,/media/startos/next/tmp/startos-deb) + $(call cp,results/$(BASENAME).deb,/media/startos/next/tmp/startos-deb/$(BASENAME).deb) + $(call ssh,'sudo /media/startos/next/usr/lib/startos/scripts/chroot-and-upgrade --no-sync "apt-get install -y --reinstall /tmp/startos-deb/$(BASENAME).deb"') + +update-squashfs: results/$(BASENAME).squashfs + @if [ -z "$(REMOTE)" ]; then >&2 echo "Must specify REMOTE" && false; fi + $(eval SQFS_SUM := $(shell b3sum results/$(BASENAME).squashfs)) + $(eval SQFS_SIZE := $(shell du -s --bytes results/$(BASENAME).squashfs | awk '{print $$1}')) + $(call ssh,'/usr/lib/startos/scripts/prune-images $(SQFS_SIZE)') + $(call cp,results/$(BASENAME).squashfs,/media/startos/images/$(SQFS_SUM).rootfs) + $(call ssh,'sudo ln -rsf /media/startos/images/$(SQFS_SUM).rootfs /media/startos/config/current.rootfs') + $(call ssh,'sudo reboot') + emulate-reflash: $(ALL_TARGETS) @if [ -z "$(REMOTE)" ]; then >&2 echo "Must specify REMOTE" && false; fi $(call ssh,'sudo /usr/lib/startos/scripts/chroot-and-upgrade --create') @@ -228,22 +255,26 @@ system-images/binfmt/docker-images/$(ARCH).tar: $(BINFMT_SRC) cd system-images/binfmt && make docker-images/$(ARCH).tar && touch docker-images/$(ARCH).tar $(BINS): $(CORE_SRC) $(ENVIRONMENT_FILE) - cd core && ARCH=$(ARCH) ./build-prod.sh + cd core && ARCH=$(ARCH) ./build-startos-bins.sh touch $(BINS) web/node_modules/.package-lock.json: web/package.json sdk/dist npm --prefix web ci touch web/node_modules/.package-lock.json -web/dist/raw/ui: $(WEB_UI_SRC) $(WEB_SHARED_SRC) +web/.angular: patch-db/client/dist sdk/dist web/node_modules/.package-lock.json + rm -rf web/.angular + mkdir -p web/.angular + +web/dist/raw/ui: $(WEB_UI_SRC) $(WEB_SHARED_SRC) web/.angular npm --prefix web run build:ui touch web/dist/raw/ui -web/dist/raw/setup-wizard: $(WEB_SETUP_WIZARD_SRC) $(WEB_SHARED_SRC) +web/dist/raw/setup-wizard: $(WEB_SETUP_WIZARD_SRC) $(WEB_SHARED_SRC) web/.angular npm --prefix web run build:setup touch web/dist/raw/setup-wizard -web/dist/raw/install-wizard: $(WEB_INSTALL_WIZARD_SRC) $(WEB_SHARED_SRC) +web/dist/raw/install-wizard: $(WEB_INSTALL_WIZARD_SRC) $(WEB_SHARED_SRC) web/.angular npm --prefix web run build:install-wiz touch web/dist/raw/install-wizard diff --git a/assets/create-vm/step-1.png b/assets/create-vm/step-1.png new file mode 100644 index 000000000..2dfafc25f Binary files /dev/null and b/assets/create-vm/step-1.png differ diff --git a/assets/create-vm/step-10.png b/assets/create-vm/step-10.png new file mode 100644 index 000000000..bc1985394 Binary files /dev/null and b/assets/create-vm/step-10.png differ diff --git a/assets/create-vm/step-11.png b/assets/create-vm/step-11.png new file mode 100644 index 000000000..322dd5394 Binary files /dev/null and b/assets/create-vm/step-11.png differ diff --git a/assets/create-vm/step-12.png b/assets/create-vm/step-12.png new file mode 100644 index 000000000..52f14f56e Binary files /dev/null and b/assets/create-vm/step-12.png differ diff --git a/assets/create-vm/step-2.png b/assets/create-vm/step-2.png new file mode 100644 index 000000000..020f3d7d1 Binary files /dev/null and b/assets/create-vm/step-2.png differ diff --git a/assets/create-vm/step-3.png b/assets/create-vm/step-3.png new file mode 100644 index 000000000..0295ba6bc Binary files /dev/null and b/assets/create-vm/step-3.png differ diff --git a/assets/create-vm/step-4.png b/assets/create-vm/step-4.png new file mode 100644 index 000000000..85832d260 Binary files /dev/null and b/assets/create-vm/step-4.png differ diff --git a/assets/create-vm/step-5.png b/assets/create-vm/step-5.png new file mode 100644 index 000000000..d34cb16a7 Binary files /dev/null and b/assets/create-vm/step-5.png differ diff --git a/assets/create-vm/step-6.png b/assets/create-vm/step-6.png new file mode 100644 index 000000000..92f2c2f1f Binary files /dev/null and b/assets/create-vm/step-6.png differ diff --git a/assets/create-vm/step-7.png b/assets/create-vm/step-7.png new file mode 100644 index 000000000..ad8eb9b81 Binary files /dev/null and b/assets/create-vm/step-7.png differ diff --git a/assets/create-vm/step-8.png b/assets/create-vm/step-8.png new file mode 100644 index 000000000..ce5443c76 Binary files /dev/null and b/assets/create-vm/step-8.png differ diff --git a/assets/create-vm/step-9.png b/assets/create-vm/step-9.png new file mode 100644 index 000000000..042735490 Binary files /dev/null and b/assets/create-vm/step-9.png differ diff --git a/build/lib/scripts/chroot-and-upgrade b/build/lib/scripts/chroot-and-upgrade index 7adaaaccb..59581fbc6 100755 --- a/build/lib/scripts/chroot-and-upgrade +++ b/build/lib/scripts/chroot-and-upgrade @@ -1,5 +1,7 @@ #!/bin/bash +SOURCE_DIR="$(dirname "${BASH_SOURCE[0]}")" + if [ "$UID" -ne 0 ]; then >&2 echo 'Must be run as root' exit 1 @@ -77,20 +79,7 @@ umount /media/startos/next/boot if [ "$CHROOT_RES" -eq 0 ]; then if [ -h /media/startos/config/current.rootfs ] && [ -e /media/startos/config/current.rootfs ]; then - echo 'Pruning...' - current="$(readlink -f /media/startos/config/current.rootfs)" - needed=$(du -s --bytes /media/startos/next | awk '{print $1}') - while [[ "$(df -B1 --output=avail --sync /media/startos/images | tail -n1)" -lt "$needed" ]]; do - to_prune="$(ls -t1 /media/startos/images/*.rootfs | grep -v "$current" | tail -n1)" - if [ -e "$to_prune" ]; then - echo " Pruning $to_prune" - rm -rf "$to_prune" - else - >&2 echo "Not enough space and nothing to prune!" - exit 1 - fi - done - echo 'done.' + ${SOURCE_DIR}/prune-images $(du -s --bytes /media/startos/next | awk '{print $1}') fi echo 'Upgrading...' diff --git a/build/lib/scripts/prune-images b/build/lib/scripts/prune-images new file mode 100755 index 000000000..21861467f --- /dev/null +++ b/build/lib/scripts/prune-images @@ -0,0 +1,49 @@ +#!/bin/bash + +if [ "$UID" -ne 0 ]; then + >&2 echo 'Must be run as root' + exit 1 +fi + +POSITIONAL_ARGS=() + +while [[ $# -gt 0 ]]; do + case $1 in + -*|--*) + echo "Unknown option $1" + exit 1 + ;; + *) + POSITIONAL_ARGS+=("$1") # save positional arg + shift # past argument + ;; + esac +done + +set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters + +needed=$1 + +if [ -z "$needed" ]; then + >&2 echo "usage: $0 " + exit 1 +fi + +if [ -h /media/startos/config/current.rootfs ] && [ -e /media/startos/config/current.rootfs ]; then + echo 'Pruning...' + current="$(readlink -f /media/startos/config/current.rootfs)" + while [[ "$(df -B1 --output=avail --sync /media/startos/images | tail -n1)" -lt "$needed" ]]; do + to_prune="$(ls -t1 /media/startos/images/*.rootfs | grep -v "$current" | tail -n1)" + if [ -e "$to_prune" ]; then + echo " Pruning $to_prune" + rm -rf "$to_prune" + else + >&2 echo "Not enough space and nothing to prune!" + exit 1 + fi + done + echo 'done.' +else + >&2 echo 'No current.rootfs, not safe to prune' + exit 1 +fi \ No newline at end of file diff --git a/container-runtime/package-lock.json b/container-runtime/package-lock.json index 9b211c077..e63bec6a1 100644 --- a/container-runtime/package-lock.json +++ b/container-runtime/package-lock.json @@ -9,11 +9,13 @@ "version": "0.0.0", "dependencies": { "@iarna/toml": "^2.2.5", + "@noble/curves": "^1.4.0", + "@noble/hashes": "^1.4.0", "@start9labs/start-sdk": "file:../sdk/dist", "esbuild-plugin-resolve": "^2.0.0", "filebrowser": "^1.0.0", "isomorphic-fetch": "^3.0.0", - "lodash": "^4.17.21", + "lodash.merge": "^4.6.2", "node-fetch": "^3.1.0", "ts-matches": "^5.5.1", "tslib": "^2.5.3", @@ -30,24 +32,27 @@ }, "../sdk/dist": { "name": "@start9labs/start-sdk", - "version": "0.3.6-alpha1", + "version": "0.3.6-alpha5", "license": "MIT", "dependencies": { + "@iarna/toml": "^2.2.5", + "@noble/curves": "^1.4.0", + "@noble/hashes": "^1.4.0", "isomorphic-fetch": "^3.0.0", - "lodash": "^4.17.21", - "ts-matches": "^5.4.1" + "lodash.merge": "^4.6.2", + "mime": "^4.0.3", + "ts-matches": "^5.5.1", + "yaml": "^2.2.2" }, "devDependencies": { - "@iarna/toml": "^2.2.5", "@types/jest": "^29.4.0", - "@types/lodash": "^4.17.5", + "@types/lodash.merge": "^4.6.2", "jest": "^29.4.3", "prettier": "^3.2.5", "ts-jest": "^29.0.5", "ts-node": "^10.9.1", "tsx": "^4.7.1", - "typescript": "^5.0.4", - "yaml": "^2.2.2" + "typescript": "^5.0.4" } }, "node_modules/@iarna/toml": { @@ -72,6 +77,28 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, + "node_modules/@noble/curves": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", + "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "dev": true, @@ -1316,10 +1343,10 @@ "json-buffer": "3.0.1" } }, - "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.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "node_modules/lowercase-keys": { "version": "2.0.0", @@ -2233,6 +2260,19 @@ "os-filter-obj": "^2.0.0" } }, + "@noble/curves": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", + "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", + "requires": { + "@noble/hashes": "1.4.0" + } + }, + "@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==" + }, "@nodelib/fs.scandir": { "version": "2.1.5", "dev": true, @@ -2261,14 +2301,17 @@ "version": "file:../sdk/dist", "requires": { "@iarna/toml": "^2.2.5", + "@noble/curves": "^1.4.0", + "@noble/hashes": "^1.4.0", "@types/jest": "^29.4.0", - "@types/lodash": "^4.17.5", + "@types/lodash.merge": "^4.6.2", "isomorphic-fetch": "^3.0.0", "jest": "^29.4.3", - "lodash": "^4.17.21", + "lodash.merge": "^4.6.2", + "mime": "^4.0.3", "prettier": "^3.2.5", "ts-jest": "^29.0.5", - "ts-matches": "^5.4.1", + "ts-matches": "^5.5.1", "ts-node": "^10.9.1", "tsx": "^4.7.1", "typescript": "^5.0.4", @@ -2988,10 +3031,10 @@ "json-buffer": "3.0.1" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "lowercase-keys": { "version": "2.0.0", diff --git a/container-runtime/package.json b/container-runtime/package.json index 357c606fc..515f50ee7 100644 --- a/container-runtime/package.json +++ b/container-runtime/package.json @@ -18,10 +18,12 @@ "dependencies": { "@iarna/toml": "^2.2.5", "@start9labs/start-sdk": "file:../sdk/dist", + "@noble/hashes": "^1.4.0", + "@noble/curves": "^1.4.0", "esbuild-plugin-resolve": "^2.0.0", "filebrowser": "^1.0.0", "isomorphic-fetch": "^3.0.0", - "lodash": "^4.17.21", + "lodash.merge": "^4.6.2", "node-fetch": "^3.1.0", "ts-matches": "^5.5.1", "tslib": "^2.5.3", diff --git a/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts b/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts index 127fb0e09..3a8d4f4b2 100644 --- a/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts +++ b/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts @@ -42,6 +42,12 @@ import { } from "@start9labs/start-sdk/cjs/lib/interfaces/Host" import { ServiceInterfaceBuilder } from "@start9labs/start-sdk/cjs/lib/interfaces/ServiceInterfaceBuilder" import { Effects } from "../../../Models/Effects" +import { + OldConfigSpec, + matchOldConfigSpec, + transformConfigSpec, + transformOldConfigToNew, +} from "./transformConfigSpec" type Optional = A | undefined | null function todo(): never { @@ -533,7 +539,9 @@ export class SystemForEmbassy implements System { effects: Effects, timeoutMs: number | null, ): Promise { - return this.getConfigUncleaned(effects, timeoutMs).then(removePointers) + return this.getConfigUncleaned(effects, timeoutMs) + .then(removePointers) + .then(convertToNewConfig) } private async getConfigUncleaned( effects: Effects, @@ -1054,3 +1062,10 @@ function extractServiceInterfaceId(manifest: Manifest, specInterface: string) { const serviceInterfaceId = `${specInterface}-${internalPort}` return serviceInterfaceId } +async function convertToNewConfig(value: T.ConfigRes): Promise { + const valueSpec: OldConfigSpec = matchOldConfigSpec.unsafeCast(value.spec) + const spec = transformConfigSpec(valueSpec) + if (!value.config) return { spec, config: null } + const config = transformOldConfigToNew(valueSpec, value.config) + return { spec, config } +} diff --git a/container-runtime/src/Adapters/Systems/SystemForEmbassy/transformConfigSpec.ts b/container-runtime/src/Adapters/Systems/SystemForEmbassy/transformConfigSpec.ts new file mode 100644 index 000000000..cb7809903 --- /dev/null +++ b/container-runtime/src/Adapters/Systems/SystemForEmbassy/transformConfigSpec.ts @@ -0,0 +1,550 @@ +import { CT } from "@start9labs/start-sdk" +import { + dictionary, + object, + anyOf, + string, + literals, + array, + number, + boolean, + Parser, + deferred, + every, + nill, +} from "ts-matches" + +export function transformConfigSpec(oldSpec: OldConfigSpec): CT.InputSpec { + return Object.entries(oldSpec).reduce((inputSpec, [key, oldVal]) => { + let newVal: CT.ValueSpec + + if (oldVal.type === "boolean") { + newVal = { + type: "toggle", + name: oldVal.name, + default: oldVal.default, + description: oldVal.description || null, + warning: oldVal.warning || null, + disabled: false, + immutable: false, + } + } else if (oldVal.type === "enum") { + newVal = { + type: "select", + name: oldVal.name, + description: oldVal.description || null, + warning: oldVal.warning || null, + default: oldVal.default, + values: oldVal.values.reduce( + (obj, curr) => ({ + ...obj, + [curr]: oldVal["value-names"][curr], + }), + {}, + ), + required: false, + disabled: false, + immutable: false, + } + } else if (oldVal.type === "list") { + newVal = getListSpec(oldVal) + } else if (oldVal.type === "number") { + const range = Range.from(oldVal.range) + + newVal = { + type: "number", + name: oldVal.name, + default: oldVal.default || null, + description: oldVal.description || null, + warning: oldVal.warning || null, + disabled: false, + immutable: false, + required: !oldVal.nullable, + min: range.min + ? range.minInclusive + ? range.min + : range.min + 1 + : null, + max: range.max + ? range.maxInclusive + ? range.max + : range.max - 1 + : null, + integer: oldVal.integral, + step: null, + units: oldVal.units || null, + placeholder: oldVal.placeholder || null, + } + } else if (oldVal.type === "object") { + newVal = { + type: "object", + name: oldVal.name, + description: oldVal.description || null, + warning: oldVal.warning || null, + spec: transformConfigSpec(matchOldConfigSpec.unsafeCast(oldVal.spec)), + } + } else if (oldVal.type === "string") { + newVal = { + type: "text", + name: oldVal.name, + default: oldVal.default || null, + description: oldVal.description || null, + warning: oldVal.warning || null, + disabled: false, + immutable: false, + required: !oldVal.nullable, + patterns: + oldVal.pattern && oldVal["pattern-description"] + ? [ + { + regex: oldVal.pattern, + description: oldVal["pattern-description"], + }, + ] + : [], + minLength: null, + maxLength: null, + masked: oldVal.masked, + generate: null, + inputmode: "text", + placeholder: oldVal.placeholder || null, + } + } else { + newVal = { + type: "union", + name: oldVal.tag.name, + description: oldVal.tag.description || null, + warning: oldVal.tag.warning || null, + variants: Object.entries(oldVal.variants).reduce( + (obj, [id, spec]) => ({ + ...obj, + [id]: { + name: oldVal.tag["variant-names"][id], + spec: transformConfigSpec(matchOldConfigSpec.unsafeCast(spec)), + }, + }), + {} as Record, + ), + disabled: false, + required: true, + default: oldVal.default, + immutable: false, + } + } + + return { + ...inputSpec, + [key]: newVal, + } + }, {} as CT.InputSpec) +} + +export function transformOldConfigToNew( + spec: OldConfigSpec, + config: Record, +): Record { + return Object.entries(spec).reduce((obj, [key, val]) => { + let newVal = config[key] + + if (isObject(val)) { + newVal = transformOldConfigToNew( + matchOldConfigSpec.unsafeCast(val.spec), + config[key], + ) + } + + if (isUnion(val)) { + const selection = config[key][val.tag.id] + delete config[key][val.tag.id] + + newVal = { + selection, + value: transformOldConfigToNew( + matchOldConfigSpec.unsafeCast(val.variants[selection]), + config[key], + ), + } + } + + if (isList(val) && isObjectList(val)) { + newVal = (config[key] as object[]).map((obj) => + transformOldConfigToNew( + matchOldConfigSpec.unsafeCast(val.spec.spec), + obj, + ), + ) + } + + return { + ...obj, + [key]: newVal, + } + }, {}) +} + +export function transformNewConfigToOld( + spec: OldConfigSpec, + config: Record, +): Record { + return Object.entries(spec).reduce((obj, [key, val]) => { + let newVal = config[key] + + if (isObject(val)) { + newVal = transformNewConfigToOld( + matchOldConfigSpec.unsafeCast(val.spec), + config[key], + ) + } + + if (isUnion(val)) { + newVal = { + [val.tag.id]: config[key].selection, + ...transformNewConfigToOld( + matchOldConfigSpec.unsafeCast(val.variants[config[key].selection]), + config[key].unionSelectValue, + ), + } + } + + if (isList(val) && isObjectList(val)) { + newVal = (config[key] as object[]).map((obj) => + transformNewConfigToOld( + matchOldConfigSpec.unsafeCast(val.spec.spec), + obj, + ), + ) + } + + return { + ...obj, + [key]: newVal, + } + }, {}) +} + +function getListSpec( + oldVal: OldValueSpecList, +): CT.ValueSpecMultiselect | CT.ValueSpecList { + const range = Range.from(oldVal.range) + + let partial: Omit = { + name: oldVal.name, + description: oldVal.description || null, + warning: oldVal.warning || null, + minLength: range.min + ? range.minInclusive + ? range.min + : range.min + 1 + : null, + maxLength: range.max + ? range.maxInclusive + ? range.max + : range.max - 1 + : null, + disabled: false, + } + + if (isEnumList(oldVal)) { + return { + ...partial, + type: "multiselect", + default: oldVal.default as string[], + immutable: false, + values: oldVal.spec.values.reduce( + (obj, curr) => ({ + ...obj, + [curr]: oldVal.spec["value-names"][curr], + }), + {}, + ), + } + } else if (isStringList(oldVal)) { + return { + ...partial, + type: "list", + default: oldVal.default as string[], + spec: { + type: "text", + patterns: + oldVal.spec.pattern && oldVal.spec["pattern-description"] + ? [ + { + regex: oldVal.spec.pattern, + description: oldVal.spec["pattern-description"], + }, + ] + : [], + minLength: null, + maxLength: null, + masked: oldVal.spec.masked, + generate: null, + inputmode: "text", + placeholder: oldVal.spec.placeholder || null, + }, + } + } else if (isObjectList(oldVal)) { + return { + ...partial, + type: "list", + default: oldVal.default as Record[], + spec: { + type: "object", + spec: transformConfigSpec( + matchOldConfigSpec.unsafeCast(oldVal.spec.spec), + ), + uniqueBy: oldVal.spec["unique-by"], + displayAs: oldVal.spec["display-as"] || null, + }, + } + } else { + throw new Error("Invalid list subtype. enum, string, and object permitted.") + } +} + +function isObject(val: OldValueSpec): val is OldValueSpecObject { + return val.type === "object" +} + +function isUnion(val: OldValueSpec): val is OldValueSpecUnion { + return val.type === "union" +} + +function isList(val: OldValueSpec): val is OldValueSpecList { + return val.type === "list" +} + +function isEnumList( + val: OldValueSpecList, +): val is OldValueSpecList & { subtype: "enum" } { + return val.subtype === "enum" +} + +function isStringList( + val: OldValueSpecList, +): val is OldValueSpecList & { subtype: "string" } { + return val.subtype === "string" +} + +function isObjectList( + val: OldValueSpecList, +): val is OldValueSpecList & { subtype: "object" } { + if (["number", "union"].includes(val.subtype)) { + throw new Error("Invalid list subtype. enum, string, and object permitted.") + } + return val.subtype === "object" +} +export type OldConfigSpec = Record +const [_matchOldConfigSpec, setMatchOldConfigSpec] = deferred() +export const matchOldConfigSpec = _matchOldConfigSpec as Parser< + unknown, + OldConfigSpec +> +export const matchOldDefaultString = anyOf( + string, + object({ charset: string, len: number }), +) +type OldDefaultString = typeof matchOldDefaultString._TYPE + +export const matchOldValueSpecString = object( + { + masked: boolean, + copyable: boolean, + type: literals("string"), + nullable: boolean, + name: string, + placeholder: string, + pattern: string, + "pattern-description": string, + default: matchOldDefaultString, + textarea: boolean, + description: string, + warning: string, + }, + [ + "placeholder", + "pattern", + "pattern-description", + "default", + "textarea", + "description", + "warning", + ], +) + +export const matchOldValueSpecNumber = object( + { + type: literals("number"), + nullable: boolean, + name: string, + range: string, + integral: boolean, + default: number, + description: string, + warning: string, + units: string, + placeholder: string, + }, + ["default", "description", "warning", "units", "placeholder"], +) +type OldValueSpecNumber = typeof matchOldValueSpecNumber._TYPE + +export const matchOldValueSpecBoolean = object( + { + type: literals("boolean"), + default: boolean, + name: string, + description: string, + warning: string, + }, + ["description", "warning"], +) +type OldValueSpecBoolean = typeof matchOldValueSpecBoolean._TYPE + +const matchOldValueSpecObject = object( + { + type: literals("object"), + spec: _matchOldConfigSpec, + name: string, + description: string, + warning: string, + }, + ["description", "warning"], +) +type OldValueSpecObject = typeof matchOldValueSpecObject._TYPE + +const matchOldValueSpecEnum = object( + { + values: array(string), + "value-names": dictionary([string, string]), + type: literals("enum"), + default: string, + name: string, + description: string, + warning: string, + }, + ["description", "warning"], +) +type OldValueSpecEnum = typeof matchOldValueSpecEnum._TYPE + +const matchOldUnionTagSpec = object( + { + id: string, // The name of the field containing one of the union variants + "variant-names": dictionary([string, string]), // The name of each variant + name: string, + description: string, + warning: string, + }, + ["description", "warning"], +) +const matchOldValueSpecUnion = object({ + type: literals("union"), + tag: matchOldUnionTagSpec, + variants: dictionary([string, _matchOldConfigSpec]), + default: string, +}) +type OldValueSpecUnion = typeof matchOldValueSpecUnion._TYPE + +const [matchOldUniqueBy, setOldUniqueBy] = deferred() +type OldUniqueBy = + | null + | string + | { any: OldUniqueBy[] } + | { all: OldUniqueBy[] } + +setOldUniqueBy( + anyOf( + nill, + string, + object({ any: array(matchOldUniqueBy) }), + object({ all: array(matchOldUniqueBy) }), + ), +) + +const matchOldListValueSpecObject = object( + { + spec: _matchOldConfigSpec, // this is a mapped type of the config object at this level, replacing the object's values with specs on those values + "unique-by": matchOldUniqueBy, // indicates whether duplicates can be permitted in the list + "display-as": string, // this should be a handlebars template which can make use of the entire config which corresponds to 'spec' + }, + ["display-as"], +) +const matchOldListValueSpecString = object( + { + masked: boolean, + copyable: boolean, + pattern: string, + "pattern-description": string, + placeholder: string, + }, + ["pattern", "pattern-description", "placeholder"], +) + +const matchOldListValueSpecEnum = object({ + values: array(string), + "value-names": dictionary([string, string]), +}) + +// represents a spec for a list +const matchOldValueSpecList = every( + object( + { + type: literals("list"), + range: string, // '[0,1]' (inclusive) OR '[0,*)' (right unbounded), normal math rules + default: anyOf( + array(string), + array(number), + array(matchOldDefaultString), + array(object), + ), + name: string, + description: string, + warning: string, + }, + ["description", "warning"], + ), + anyOf( + object({ + subtype: literals("string"), + spec: matchOldListValueSpecString, + }), + object({ + subtype: literals("enum"), + spec: matchOldListValueSpecEnum, + }), + object({ + subtype: literals("object"), + spec: matchOldListValueSpecObject, + }), + ), +) +type OldValueSpecList = typeof matchOldValueSpecList._TYPE + +export const matchOldValueSpec = anyOf( + matchOldValueSpecString, + matchOldValueSpecNumber, + matchOldValueSpecBoolean, + matchOldValueSpecObject, + matchOldValueSpecEnum, + matchOldValueSpecList, + matchOldValueSpecUnion, +) +type OldValueSpec = typeof matchOldValueSpec._TYPE + +setMatchOldConfigSpec(dictionary([string, matchOldValueSpec])) + +export class Range { + min?: number + max?: number + minInclusive!: boolean + maxInclusive!: boolean + + static from(s: string = "(*,*)"): Range { + const r = new Range() + r.minInclusive = s.startsWith("[") + r.maxInclusive = s.endsWith("]") + const [minStr, maxStr] = s.split(",").map((a) => a.trim()) + r.min = minStr === "(*" ? undefined : Number(minStr.slice(1)) + r.max = maxStr === "*)" ? undefined : Number(maxStr.slice(0, -1)) + return r + } +} diff --git a/core/Cargo.lock b/core/Cargo.lock index 031ec41ab..80c2dcc0e 100644 --- a/core/Cargo.lock +++ b/core/Cargo.lock @@ -166,6 +166,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + [[package]] name = "arrayvec" version = "0.7.4" @@ -225,7 +231,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -236,7 +242,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -432,7 +438,7 @@ checksum = "be5951c75bdabb58753d140dd5802f12ff3a483cb2e16fb5276e111b94b19e87" dependencies = [ "concurrent-queue 1.2.4", "event-listener", - "spin 0.9.8", + "spin", ] [[package]] @@ -508,9 +514,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" dependencies = [ "serde", ] @@ -521,16 +527,28 @@ version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d084b0137aaa901caf9f1e8b21daa6aa24d41cd806e111335541eff9683bd6" +[[package]] +name = "bitvec" +version = "0.19.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55f93d0ef3363c364d5976646a38f04cf67cfe1d4c8d160cdea02cab2c116b33" +dependencies = [ + "funty 1.1.0", + "radium 0.5.3", + "tap", + "wyz 0.2.0", +] + [[package]] name = "bitvec" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ - "funty", - "radium", + "funty 2.0.0", + "radium 0.7.0", "tap", - "wyz", + "wyz 0.5.1", ] [[package]] @@ -540,7 +558,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" dependencies = [ "arrayref", - "arrayvec", + "arrayvec 0.7.4", "constant_time_eq", ] @@ -551,7 +569,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52" dependencies = [ "arrayref", - "arrayvec", + "arrayvec 0.7.4", "cc", "cfg-if", "constant_time_eq", @@ -624,9 +642,9 @@ checksum = "981520c98f422fcc584dc1a95c334e6953900b9106bc47a9839b81790009eb21" [[package]] name = "cc" -version = "1.0.99" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" +checksum = "ac367972e516d45567c7eafc73d24e1c193dcf200a8d94e9db7b3d38b349572d" dependencies = [ "jobserver", "libc", @@ -740,7 +758,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -914,6 +932,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" dependencies = [ + "percent-encoding", "time", "version_check", ] @@ -935,6 +954,23 @@ dependencies = [ "url", ] +[[package]] +name = "cookie_store" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4934e6b7e8419148b6ef56950d277af8561060b56afd59e2aadf98b59fce6baa" +dependencies = [ + "cookie 0.18.1", + "idna 0.5.0", + "log", + "publicsuffix", + "serde", + "serde_derive", + "serde_json", + "time", + "url", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -1033,7 +1069,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "crossterm_winapi", "futures-core", "libc", @@ -1126,16 +1162,15 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.2" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", - "platforms", "rustc_version", "subtle", "zeroize", @@ -1149,7 +1184,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -1173,7 +1208,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -1184,7 +1219,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -1199,7 +1234,7 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "709ade444d53896e60f6265660eb50480dd08b77bfc822e5dcc233b88b0b2fba" dependencies = [ - "bitvec", + "bitvec 1.0.1", "deku_derive", "no_std_io", "rustversion", @@ -1215,7 +1250,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -1238,7 +1273,7 @@ checksum = "5fe87ce4529967e0ba1dcf8450bab64d97dfd5010a6256187ffe2e43e6f0e049" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -1253,15 +1288,15 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case 0.4.0", "proc-macro2", "quote", "rustc_version", - "syn 1.0.109", + "syn 2.0.68", ] [[package]] @@ -1306,17 +1341,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "displaydoc" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - [[package]] name = "divrem" version = "1.0.0" @@ -1398,7 +1422,7 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ - "curve25519-dalek 4.1.2", + "curve25519-dalek 4.1.3", "ed25519 2.2.3", "rand_core 0.6.4", "serde", @@ -1410,9 +1434,9 @@ dependencies = [ [[package]] name = "either" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" dependencies = [ "serde", ] @@ -1439,12 +1463,13 @@ dependencies = [ [[package]] name = "emver" -version = "0.1.7" -source = "git+https://github.com/Start9Labs/emver-rs.git#61cf0bc96711b4d6f3f30df8efef025e0cc02bad" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed260c4d7efaec031b9c4f6c4d3cf136e3df2bbfe50925800236f5e847f28704" dependencies = [ "either", "fp-core", - "nom", + "nom 6.1.2", "serde", ] @@ -1487,7 +1512,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -1523,6 +1548,24 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "exver" +version = "0.2.0" +source = "git+https://github.com/Start9Labs/exver-rs.git#29f52c1be18a0fe187670beac92822994b0d1949" +dependencies = [ + "either", + "emver", + "fp-core", + "getrandom 0.2.15", + "itertools 0.13.0", + "memchr", + "pest", + "pest_derive", + "serde", + "smallvec", + "yasi", +] + [[package]] name = "eyre" version = "0.6.12" @@ -1600,7 +1643,7 @@ checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" dependencies = [ "futures-core", "futures-sink", - "spin 0.9.8", + "spin", ] [[package]] @@ -1642,6 +1685,12 @@ dependencies = [ "itertools 0.8.2", ] +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + [[package]] name = "funty" version = "2.0.0" @@ -1715,7 +1764,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -1793,7 +1842,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8283e7331b8c93b9756e0cfdbcfb90312852f953c6faf9bf741e684cc3b6ad69" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "crc", "log", "uuid", @@ -1907,7 +1956,7 @@ dependencies = [ "base64 0.21.7", "byteorder", "flate2", - "nom", + "nom 7.1.3", "num-traits", ] @@ -2055,9 +2104,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.9.3" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0e7a4dd27b9476dc40cb050d3632d3bba3a70ddbff012285f7f8559a1e7e545" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -2116,6 +2165,23 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +dependencies = [ + "futures-util", + "http 1.1.0", + "hyper 1.3.1", + "hyper-util", + "rustls 0.23.10", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.0", + "tower-service", +] + [[package]] name = "hyper-timeout" version = "0.4.1" @@ -2187,124 +2253,6 @@ dependencies = [ "cc", ] -[[package]] -name = "icu_collections" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locid" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" - -[[package]] -name = "icu_normalizer" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "utf16_iter", - "utf8_iter", - "write16", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" - -[[package]] -name = "icu_properties" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f8ac670d7422d7f76b32e17a5db556510825b29ec9154f235977c9caba61036" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locid_transform", - "icu_properties_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" - -[[package]] -name = "icu_provider" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_provider_macros", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "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.66", -] - [[package]] name = "id-pool" version = "0.2.2" @@ -2342,14 +2290,12 @@ dependencies = [ [[package]] name = "idna" -version = "1.0.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4716a3a0933a1d01c2f72450e89596eb51dd34ef3c211ccd875acdf1f8fe47ed" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ - "icu_normalizer", - "icu_properties", - "smallvec", - "utf8_iter", + "unicode-bidi", + "unicode-normalization", ] [[package]] @@ -2389,18 +2335,18 @@ dependencies = [ [[package]] name = "include_dir" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" +checksum = "923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd" dependencies = [ "include_dir_macros", ] [[package]] name = "include_dir_macros" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" +checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75" dependencies = [ "proc-macro2", "quote", @@ -2558,6 +2504,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -2727,11 +2682,24 @@ checksum = "e479e99b287d578ed5f6cd4c92cdf48db219088adb9c5b14f7c155b71dfba792" [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin 0.5.2", + "spin", +] + +[[package]] +name = "lexical-core" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" +dependencies = [ + "arrayvec 0.5.2", + "bitflags 1.3.2", + "cfg-if", + "ryu", + "static_assertions", ] [[package]] @@ -2752,7 +2720,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", ] @@ -2779,12 +2747,6 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" -[[package]] -name = "litemap" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" - [[package]] name = "lock_api" version = "0.4.12" @@ -2834,7 +2796,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c487024623ae38584610237dd1be8932bb2b324474b23c37a25f9fbe6bf5e9e" dependencies = [ "bincode", - "bitvec", + "bitvec 1.0.1", "serde", "serde-big-array", "thiserror", @@ -2852,9 +2814,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" @@ -2897,9 +2859,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] @@ -2924,7 +2886,7 @@ dependencies = [ "base64 0.21.7", "color-eyre", "ed25519-dalek 2.1.1", - "emver", + "exver", "ipnet", "lazy_static", "mbrman", @@ -3011,7 +2973,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cfg-if", "libc", ] @@ -3025,6 +2987,19 @@ dependencies = [ "memchr", ] +[[package]] +name = "nom" +version = "6.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2" +dependencies = [ + "bitvec 0.19.6", + "funty 1.1.0", + "lexical-core", + "memchr", + "version_check", +] + [[package]] name = "nom" version = "7.1.3" @@ -3061,9 +3036,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", @@ -3170,7 +3145,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -3219,7 +3194,7 @@ version = "0.10.64" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cfg-if", "foreign-types", "libc", @@ -3236,7 +3211,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -3335,7 +3310,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.1", + "redox_syscall 0.5.2", "smallvec", "windows-targets 0.52.5", ] @@ -3412,6 +3387,51 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pest" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "pest_meta" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.8", +] + [[package]] name = "petgraph" version = "0.6.5" @@ -3454,7 +3474,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -3496,12 +3516,6 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" -[[package]] -name = "platforms" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" - [[package]] name = "portable-atomic" version = "1.6.0" @@ -3560,22 +3574,22 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "proptest" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.5.0", + "bitflags 2.6.0", "lazy_static", "num-traits", "rand 0.8.5", @@ -3618,7 +3632,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -3661,6 +3675,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" + [[package]] name = "radium" version = "0.7.0" @@ -3802,11 +3822,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] @@ -3866,14 +3886,14 @@ checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "reqwest" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" +checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" dependencies = [ "base64 0.22.1", "bytes", - "cookie 0.17.0", - "cookie_store", + "cookie 0.18.1", + "cookie_store 0.21.0", "encoding_rs", "futures-core", "futures-util", @@ -3882,6 +3902,7 @@ dependencies = [ "http-body 1.0.0", "http-body-util", "hyper 1.3.1", + "hyper-rustls", "hyper-tls", "hyper-util", "ipnet", @@ -3896,7 +3917,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 0.1.2", + "sync_wrapper 1.0.1", "system-configuration", "tokio", "tokio-native-tls", @@ -3918,7 +3939,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93ea5c6f30c19d766efe8d823c88f9abd1c56516648a0d4264ab2dc04cc19472" dependencies = [ "bytes", - "cookie_store", + "cookie_store 0.20.0", "reqwest", "url", ] @@ -3943,7 +3964,7 @@ dependencies = [ "cfg-if", "getrandom 0.2.15", "libc", - "spin 0.9.8", + "spin", "untrusted", "windows-sys 0.52.0", ] @@ -3962,7 +3983,7 @@ dependencies = [ [[package]] name = "rpc-toolkit" version = "0.2.3" -source = "git+https://github.com/Start9Labs/rpc-toolkit.git?branch=refactor/no-dyn-ctx#5a24903031e72ac75fd23889215361edc7b20842" +source = "git+https://github.com/Start9Labs/rpc-toolkit.git?branch=refactor/no-dyn-ctx#f608480034942f1f521ab95949ab33fbc51d99a9" dependencies = [ "async-stream", "async-trait", @@ -4056,7 +4077,7 @@ version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -4088,6 +4109,19 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls" +version = "0.23.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki 0.102.4", + "subtle", + "zeroize", +] + [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -4228,7 +4262,7 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -4288,14 +4322,14 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4" dependencies = [ "indexmap 2.2.6", "itoa", @@ -4361,7 +4395,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -4529,12 +4563,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spin" version = "0.9.8" @@ -4560,7 +4588,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f895e3734318cc55f1fe66258926c9b910c124d47520339efecbb6c59cec7c1f" dependencies = [ - "nom", + "nom 7.1.3", "unicode_categories", ] @@ -4667,7 +4695,7 @@ checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418" dependencies = [ "atoi", "base64 0.21.7", - "bitflags 2.5.0", + "bitflags 2.6.0", "byteorder", "bytes", "chrono", @@ -4710,7 +4738,7 @@ checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e" dependencies = [ "atoi", "base64 0.21.7", - "bitflags 2.5.0", + "bitflags 2.6.0", "byteorder", "chrono", "crc", @@ -4788,7 +4816,7 @@ dependencies = [ "quote", "regex-syntax 0.6.29", "strsim 0.10.0", - "syn 2.0.66", + "syn 2.0.68", "unicode-width", ] @@ -4834,12 +4862,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - [[package]] name = "start-os" version = "0.3.5-rev.2" @@ -4865,14 +4887,14 @@ dependencies = [ "console", "console-subscriber", "cookie 0.18.1", - "cookie_store", + "cookie_store 0.20.0", "der", "digest 0.10.7", "divrem", "ed25519 2.2.3", "ed25519-dalek 1.0.1", "ed25519-dalek 2.1.1", - "emver", + "exver", "fd-lock-rs", "futures", "gpt", @@ -4881,6 +4903,7 @@ dependencies = [ "hmac", "http 1.1.0", "http-body-util", + "hyper-util", "id-pool", "imbl", "imbl-value", @@ -4905,7 +4928,7 @@ dependencies = [ "models", "new_mime_guess", "nix 0.27.1", - "nom", + "nom 7.1.3", "num", "num_enum", "once_cell", @@ -4936,6 +4959,7 @@ dependencies = [ "sha2 0.10.8", "shell-words", "simple-logging", + "socket2", "sqlx", "sscanf", "ssh-key", @@ -4943,7 +4967,7 @@ dependencies = [ "tar", "thiserror", "tokio", - "tokio-rustls", + "tokio-rustls 0.25.0", "tokio-socks", "tokio-stream", "tokio-tar", @@ -4966,6 +4990,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "stderrlog" version = "0.5.4" @@ -5017,9 +5047,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -5034,9 +5064,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" dependencies = [ "proc-macro2", "quote", @@ -5055,17 +5085,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" -[[package]] -name = "synstructure" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - [[package]] name = "system-configuration" version = "0.5.1" @@ -5163,7 +5182,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -5227,21 +5246,11 @@ dependencies = [ "crunchy", ] -[[package]] -name = "tinystr" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" -dependencies = [ - "displaydoc", - "zerovec", -] - [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82" dependencies = [ "tinyvec_macros", ] @@ -5290,7 +5299,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -5314,6 +5323,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls 0.23.10", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-socks" version = "0.5.1" @@ -5547,7 +5567,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -5699,7 +5719,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", "termcolor", ] @@ -5740,7 +5760,7 @@ checksum = "1f718dfaf347dcb5b983bfc87608144b0bad87970aebcbea5ce44d2a30c08e63" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -5749,6 +5769,12 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + [[package]] name = "unarray" version = "0.1.4" @@ -5823,12 +5849,12 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c25da092f0a868cdf09e8674cd3b7ef3a7d92a24253e663a2fb85e2496de56" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", - "idna 1.0.0", + "idna 0.5.0", "percent-encoding", "serde", ] @@ -5845,18 +5871,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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - [[package]] name = "utf8parse" version = "0.2.2" @@ -5865,9 +5879,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.8.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" dependencies = [ "getrandom 0.2.15", ] @@ -5957,7 +5971,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", "wasm-bindgen-shared", ] @@ -5991,7 +6005,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6249,16 +6263,10 @@ dependencies = [ ] [[package]] -name = "write16" -version = "1.0.0" +name = "wyz" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - -[[package]] -name = "writeable" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" [[package]] name = "wyz" @@ -6322,30 +6330,6 @@ dependencies = [ "serde", ] -[[package]] -name = "yoke" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", - "synstructure", -] - [[package]] name = "zerocopy" version = "0.7.34" @@ -6363,28 +6347,7 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", -] - -[[package]] -name = "zerofrom" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", - "synstructure", + "syn 2.0.68", ] [[package]] @@ -6404,29 +6367,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", -] - -[[package]] -name = "zerovec" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2cc8827d6c0994478a15c53f374f46fbd41bea663d809b14744bc42e6b109c" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -6449,9 +6390,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.10+zstd.1.5.6" +version = "2.0.11+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +checksum = "75652c55c0b6f3e6f12eb786fe1bc960396bf05a1eb3bf1f3691c3610ac2e6d4" dependencies = [ "cc", "pkg-config", diff --git a/core/build-reg.sh b/core/build-registrybox.sh similarity index 100% rename from core/build-reg.sh rename to core/build-registrybox.sh diff --git a/core/build-prod.sh b/core/build-startos-bins.sh similarity index 100% rename from core/build-prod.sh rename to core/build-startos-bins.sh diff --git a/core/models/Cargo.toml b/core/models/Cargo.toml index 76c66b4f2..44295745d 100644 --- a/core/models/Cargo.toml +++ b/core/models/Cargo.toml @@ -12,7 +12,7 @@ color-eyre = "0.6.2" ed25519-dalek = { version = "2.0.0", features = ["serde"] } lazy_static = "1.4" mbrman = "0.5.2" -emver = { version = "0.1", git = "https://github.com/Start9Labs/emver-rs.git", features = [ +exver = { version = "0.2.0", git = "https://github.com/Start9Labs/exver-rs.git", features = [ "serde", ] } ipnet = "2.8.0" diff --git a/core/models/src/errors.rs b/core/models/src/errors.rs index 95416ec80..8bbc705ee 100644 --- a/core/models/src/errors.rs +++ b/core/models/src/errors.rs @@ -242,8 +242,8 @@ impl From for Error { Error::new(e, ErrorKind::Utf8) } } -impl From for Error { - fn from(e: emver::ParseError) -> Self { +impl From for Error { + fn from(e: exver::ParseError) -> Self { Error::new(e, ErrorKind::ParseVersion) } } diff --git a/core/models/src/version.rs b/core/models/src/version.rs index 48871e3a1..f0c7b19ae 100644 --- a/core/models/src/version.rs +++ b/core/models/src/version.rs @@ -8,14 +8,14 @@ use ts_rs::TS; #[derive(Debug, Clone, TS)] #[ts(type = "string", rename = "Version")] pub struct VersionString { - version: emver::Version, + version: exver::ExtendedVersion, string: String, } impl VersionString { pub fn as_str(&self) -> &str { self.string.as_str() } - pub fn into_version(self) -> emver::Version { + pub fn into_version(self) -> exver::ExtendedVersion { self.version } } @@ -25,7 +25,7 @@ impl std::fmt::Display for VersionString { } } impl std::str::FromStr for VersionString { - type Err = ::Err; + type Err = ::Err; fn from_str(s: &str) -> Result { Ok(VersionString { string: s.to_owned(), @@ -33,32 +33,32 @@ impl std::str::FromStr for VersionString { }) } } -impl From for VersionString { - fn from(v: emver::Version) -> Self { +impl From for VersionString { + fn from(v: exver::ExtendedVersion) -> Self { VersionString { string: v.to_string(), version: v, } } } -impl From for emver::Version { +impl From for exver::ExtendedVersion { fn from(v: VersionString) -> Self { v.version } } impl Default for VersionString { fn default() -> Self { - Self::from(emver::Version::default()) + Self::from(exver::ExtendedVersion::default()) } } impl Deref for VersionString { - type Target = emver::Version; + type Target = exver::ExtendedVersion; fn deref(&self) -> &Self::Target { &self.version } } -impl AsRef for VersionString { - fn as_ref(&self) -> &emver::Version { +impl AsRef for VersionString { + fn as_ref(&self) -> &exver::ExtendedVersion { &self.version } } @@ -80,7 +80,13 @@ impl PartialOrd for VersionString { } impl Ord for VersionString { fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.version.cmp(&other.version) + self.version.partial_cmp(&other.version).unwrap_or_else(|| { + match (self.version.flavor(), other.version.flavor()) { + (None, Some(_)) => std::cmp::Ordering::Greater, + (Some(_), None) => std::cmp::Ordering::Less, + (a, b) => a.cmp(&b), + } + }) } } impl Hash for VersionString { @@ -94,7 +100,8 @@ impl<'de> Deserialize<'de> for VersionString { D: Deserializer<'de>, { let string = String::deserialize(deserializer)?; - let version = emver::Version::from_str(&string).map_err(::serde::de::Error::custom)?; + let version = + exver::ExtendedVersion::from_str(&string).map_err(::serde::de::Error::custom)?; Ok(Self { string, version }) } } diff --git a/core/startos/.sqlx/query-1ce5254f27de971fd87f5ab66d300f2b22433c86617a0dbf796bf2170186dd2e.json b/core/startos/.sqlx/query-1ce5254f27de971fd87f5ab66d300f2b22433c86617a0dbf796bf2170186dd2e.json deleted file mode 100644 index d36100fef..000000000 --- a/core/startos/.sqlx/query-1ce5254f27de971fd87f5ab66d300f2b22433c86617a0dbf796bf2170186dd2e.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO network_keys (package, interface, key) VALUES ($1, $2, $3) ON CONFLICT (package, interface) DO NOTHING", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Text", - "Text", - "Bytea" - ] - }, - "nullable": [] - }, - "hash": "1ce5254f27de971fd87f5ab66d300f2b22433c86617a0dbf796bf2170186dd2e" -} diff --git a/core/startos/.sqlx/query-21471490cdc3adb206274cc68e1ea745ffa5da4479478c1fd2158a45324b1930.json b/core/startos/.sqlx/query-21471490cdc3adb206274cc68e1ea745ffa5da4479478c1fd2158a45324b1930.json deleted file mode 100644 index e0b1d7cf2..000000000 --- a/core/startos/.sqlx/query-21471490cdc3adb206274cc68e1ea745ffa5da4479478c1fd2158a45324b1930.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "DELETE FROM ssh_keys WHERE fingerprint = $1", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [] - }, - "hash": "21471490cdc3adb206274cc68e1ea745ffa5da4479478c1fd2158a45324b1930" -} diff --git a/core/startos/.sqlx/query-28ea34bbde836e0618c5fc9bb7c36e463c20c841a7d6a0eb15be0f24f4a928ec.json b/core/startos/.sqlx/query-28ea34bbde836e0618c5fc9bb7c36e463c20c841a7d6a0eb15be0f24f4a928ec.json deleted file mode 100644 index e234a72a9..000000000 --- a/core/startos/.sqlx/query-28ea34bbde836e0618c5fc9bb7c36e463c20c841a7d6a0eb15be0f24f4a928ec.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT hostname, path, username, password FROM cifs_shares WHERE id = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "hostname", - "type_info": "Text" - }, - { - "ordinal": 1, - "name": "path", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "username", - "type_info": "Text" - }, - { - "ordinal": 3, - "name": "password", - "type_info": "Text" - } - ], - "parameters": { - "Left": [ - "Int4" - ] - }, - "nullable": [ - false, - false, - false, - true - ] - }, - "hash": "28ea34bbde836e0618c5fc9bb7c36e463c20c841a7d6a0eb15be0f24f4a928ec" -} diff --git a/core/startos/.sqlx/query-350ab82048fb4a049042e4fdbe1b8c606ca400e43e31b9a05d2937217e0f6962.json b/core/startos/.sqlx/query-350ab82048fb4a049042e4fdbe1b8c606ca400e43e31b9a05d2937217e0f6962.json deleted file mode 100644 index c451ce9f3..000000000 --- a/core/startos/.sqlx/query-350ab82048fb4a049042e4fdbe1b8c606ca400e43e31b9a05d2937217e0f6962.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "DELETE FROM tor WHERE package = $1 AND interface = $2", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Text", - "Text" - ] - }, - "nullable": [] - }, - "hash": "350ab82048fb4a049042e4fdbe1b8c606ca400e43e31b9a05d2937217e0f6962" -} diff --git a/core/startos/.sqlx/query-4099028a5c0de578255bf54a67cef6cb0f1e9a4e158260700f1639dd4b438997.json b/core/startos/.sqlx/query-4099028a5c0de578255bf54a67cef6cb0f1e9a4e158260700f1639dd4b438997.json deleted file mode 100644 index 761af064b..000000000 --- a/core/startos/.sqlx/query-4099028a5c0de578255bf54a67cef6cb0f1e9a4e158260700f1639dd4b438997.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT * FROM ssh_keys WHERE fingerprint = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "fingerprint", - "type_info": "Text" - }, - { - "ordinal": 1, - "name": "openssh_pubkey", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "created_at", - "type_info": "Text" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - false, - false, - false - ] - }, - "hash": "4099028a5c0de578255bf54a67cef6cb0f1e9a4e158260700f1639dd4b438997" -} diff --git a/core/startos/.sqlx/query-4691e3a2ce80b59009ac17124f54f925f61dc5ea371903e62cdffa5d7b67ca96.json b/core/startos/.sqlx/query-4691e3a2ce80b59009ac17124f54f925f61dc5ea371903e62cdffa5d7b67ca96.json deleted file mode 100644 index 1f7edd1ce..000000000 --- a/core/startos/.sqlx/query-4691e3a2ce80b59009ac17124f54f925f61dc5ea371903e62cdffa5d7b67ca96.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT * FROM session WHERE logged_out IS NULL OR logged_out > CURRENT_TIMESTAMP", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Text" - }, - { - "ordinal": 1, - "name": "logged_in", - "type_info": "Timestamp" - }, - { - "ordinal": 2, - "name": "logged_out", - "type_info": "Timestamp" - }, - { - "ordinal": 3, - "name": "last_active", - "type_info": "Timestamp" - }, - { - "ordinal": 4, - "name": "user_agent", - "type_info": "Text" - }, - { - "ordinal": 5, - "name": "metadata", - "type_info": "Text" - } - ], - "parameters": { - "Left": [] - }, - "nullable": [ - false, - false, - true, - false, - true, - false - ] - }, - "hash": "4691e3a2ce80b59009ac17124f54f925f61dc5ea371903e62cdffa5d7b67ca96" -} diff --git a/core/startos/.sqlx/query-4bcfbefb1eb3181343871a1cd7fc3afb81c2be5c681cfa8b4be0ce70610e9c3a.json b/core/startos/.sqlx/query-4bcfbefb1eb3181343871a1cd7fc3afb81c2be5c681cfa8b4be0ce70610e9c3a.json deleted file mode 100644 index 2157198e5..000000000 --- a/core/startos/.sqlx/query-4bcfbefb1eb3181343871a1cd7fc3afb81c2be5c681cfa8b4be0ce70610e9c3a.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "UPDATE session SET logged_out = CURRENT_TIMESTAMP WHERE id = $1", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [] - }, - "hash": "4bcfbefb1eb3181343871a1cd7fc3afb81c2be5c681cfa8b4be0ce70610e9c3a" -} diff --git a/core/startos/.sqlx/query-629be61c3c341c131ddbbff0293a83dbc6afd07cae69d246987f62cf0cc35c2a.json b/core/startos/.sqlx/query-629be61c3c341c131ddbbff0293a83dbc6afd07cae69d246987f62cf0cc35c2a.json deleted file mode 100644 index 764cff84a..000000000 --- a/core/startos/.sqlx/query-629be61c3c341c131ddbbff0293a83dbc6afd07cae69d246987f62cf0cc35c2a.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT password FROM account", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "password", - "type_info": "Text" - } - ], - "parameters": { - "Left": [] - }, - "nullable": [ - false - ] - }, - "hash": "629be61c3c341c131ddbbff0293a83dbc6afd07cae69d246987f62cf0cc35c2a" -} diff --git a/core/startos/.sqlx/query-687688055e63d27123cdc89a5bbbd8361776290a9411d527eaf1fdb40bef399d.json b/core/startos/.sqlx/query-687688055e63d27123cdc89a5bbbd8361776290a9411d527eaf1fdb40bef399d.json deleted file mode 100644 index 2e8a9ee0e..000000000 --- a/core/startos/.sqlx/query-687688055e63d27123cdc89a5bbbd8361776290a9411d527eaf1fdb40bef399d.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT key FROM tor WHERE package = $1 AND interface = $2", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "key", - "type_info": "Bytea" - } - ], - "parameters": { - "Left": [ - "Text", - "Text" - ] - }, - "nullable": [ - false - ] - }, - "hash": "687688055e63d27123cdc89a5bbbd8361776290a9411d527eaf1fdb40bef399d" -} diff --git a/core/startos/.sqlx/query-6d35ccf780fb2bb62586dd1d3df9c1550a41ee580dad3f49d35cb843ebef10ca.json b/core/startos/.sqlx/query-6d35ccf780fb2bb62586dd1d3df9c1550a41ee580dad3f49d35cb843ebef10ca.json deleted file mode 100644 index 3f859bd10..000000000 --- a/core/startos/.sqlx/query-6d35ccf780fb2bb62586dd1d3df9c1550a41ee580dad3f49d35cb843ebef10ca.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "UPDATE session SET last_active = CURRENT_TIMESTAMP WHERE id = $1 AND logged_out IS NULL OR logged_out > CURRENT_TIMESTAMP", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [] - }, - "hash": "6d35ccf780fb2bb62586dd1d3df9c1550a41ee580dad3f49d35cb843ebef10ca" -} diff --git a/core/startos/.sqlx/query-770c1017734720453dc87b58c385b987c5af5807151ff71a59000014586752e0.json b/core/startos/.sqlx/query-770c1017734720453dc87b58c385b987c5af5807151ff71a59000014586752e0.json deleted file mode 100644 index cf3591e01..000000000 --- a/core/startos/.sqlx/query-770c1017734720453dc87b58c385b987c5af5807151ff71a59000014586752e0.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO network_keys (package, interface, key) VALUES ($1, $2, $3) ON CONFLICT (package, interface) DO UPDATE SET package = EXCLUDED.package RETURNING key", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "key", - "type_info": "Bytea" - } - ], - "parameters": { - "Left": [ - "Text", - "Text", - "Bytea" - ] - }, - "nullable": [ - false - ] - }, - "hash": "770c1017734720453dc87b58c385b987c5af5807151ff71a59000014586752e0" -} diff --git a/core/startos/.sqlx/query-7b64f032d507e8ffe37c41f4c7ad514a66c421a11ab04c26d89a7aa8f6b67210.json b/core/startos/.sqlx/query-7b64f032d507e8ffe37c41f4c7ad514a66c421a11ab04c26d89a7aa8f6b67210.json deleted file mode 100644 index 53fc6f066..000000000 --- a/core/startos/.sqlx/query-7b64f032d507e8ffe37c41f4c7ad514a66c421a11ab04c26d89a7aa8f6b67210.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT id, package_id, created_at, code, level, title, message, data FROM notifications WHERE id < $1 ORDER BY id DESC LIMIT $2", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Int4" - }, - { - "ordinal": 1, - "name": "package_id", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "created_at", - "type_info": "Timestamp" - }, - { - "ordinal": 3, - "name": "code", - "type_info": "Int4" - }, - { - "ordinal": 4, - "name": "level", - "type_info": "Text" - }, - { - "ordinal": 5, - "name": "title", - "type_info": "Text" - }, - { - "ordinal": 6, - "name": "message", - "type_info": "Text" - }, - { - "ordinal": 7, - "name": "data", - "type_info": "Text" - } - ], - "parameters": { - "Left": [ - "Int4", - "Int8" - ] - }, - "nullable": [ - false, - true, - false, - false, - false, - false, - false, - true - ] - }, - "hash": "7b64f032d507e8ffe37c41f4c7ad514a66c421a11ab04c26d89a7aa8f6b67210" -} diff --git a/core/startos/.sqlx/query-7c7a3549c997eb75bf964ea65fbb98a73045adf618696cd838d79203ef5383fb.json b/core/startos/.sqlx/query-7c7a3549c997eb75bf964ea65fbb98a73045adf618696cd838d79203ef5383fb.json deleted file mode 100644 index 245a838d8..000000000 --- a/core/startos/.sqlx/query-7c7a3549c997eb75bf964ea65fbb98a73045adf618696cd838d79203ef5383fb.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n INSERT INTO account (\n id,\n server_id,\n hostname,\n password,\n network_key,\n root_ca_key_pem,\n root_ca_cert_pem\n ) VALUES (\n 0, $1, $2, $3, $4, $5, $6\n ) ON CONFLICT (id) DO UPDATE SET\n server_id = EXCLUDED.server_id,\n hostname = EXCLUDED.hostname,\n password = EXCLUDED.password,\n network_key = EXCLUDED.network_key,\n root_ca_key_pem = EXCLUDED.root_ca_key_pem,\n root_ca_cert_pem = EXCLUDED.root_ca_cert_pem\n ", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Text", - "Text", - "Text", - "Bytea", - "Text", - "Text" - ] - }, - "nullable": [] - }, - "hash": "7c7a3549c997eb75bf964ea65fbb98a73045adf618696cd838d79203ef5383fb" -} diff --git a/core/startos/.sqlx/query-7e0649d839927e57fa03ee51a2c9f96a8bdb0fc97ee8a3c6df1069e1e2b98576.json b/core/startos/.sqlx/query-7e0649d839927e57fa03ee51a2c9f96a8bdb0fc97ee8a3c6df1069e1e2b98576.json deleted file mode 100644 index e3ce7957d..000000000 --- a/core/startos/.sqlx/query-7e0649d839927e57fa03ee51a2c9f96a8bdb0fc97ee8a3c6df1069e1e2b98576.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "DELETE FROM tor WHERE package = $1", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [] - }, - "hash": "7e0649d839927e57fa03ee51a2c9f96a8bdb0fc97ee8a3c6df1069e1e2b98576" -} diff --git a/core/startos/.sqlx/query-8951b9126fbf60dbb5997241e11e3526b70bccf3e407327917294a993bc17ed5.json b/core/startos/.sqlx/query-8951b9126fbf60dbb5997241e11e3526b70bccf3e407327917294a993bc17ed5.json deleted file mode 100644 index e39aebf69..000000000 --- a/core/startos/.sqlx/query-8951b9126fbf60dbb5997241e11e3526b70bccf3e407327917294a993bc17ed5.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO tor (package, interface, key) VALUES ($1, $2, $3) ON CONFLICT (package, interface) DO NOTHING", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Text", - "Text", - "Bytea" - ] - }, - "nullable": [] - }, - "hash": "8951b9126fbf60dbb5997241e11e3526b70bccf3e407327917294a993bc17ed5" -} diff --git a/core/startos/.sqlx/query-94d471bb374b4965c6cbedf8c17bbf6bea226d38efaf6559923c79a36d5ca08c.json b/core/startos/.sqlx/query-94d471bb374b4965c6cbedf8c17bbf6bea226d38efaf6559923c79a36d5ca08c.json deleted file mode 100644 index e7fe8d38c..000000000 --- a/core/startos/.sqlx/query-94d471bb374b4965c6cbedf8c17bbf6bea226d38efaf6559923c79a36d5ca08c.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT id, package_id, created_at, code, level, title, message, data FROM notifications ORDER BY id DESC LIMIT $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Int4" - }, - { - "ordinal": 1, - "name": "package_id", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "created_at", - "type_info": "Timestamp" - }, - { - "ordinal": 3, - "name": "code", - "type_info": "Int4" - }, - { - "ordinal": 4, - "name": "level", - "type_info": "Text" - }, - { - "ordinal": 5, - "name": "title", - "type_info": "Text" - }, - { - "ordinal": 6, - "name": "message", - "type_info": "Text" - }, - { - "ordinal": 7, - "name": "data", - "type_info": "Text" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - false, - true, - false, - false, - false, - false, - false, - true - ] - }, - "hash": "94d471bb374b4965c6cbedf8c17bbf6bea226d38efaf6559923c79a36d5ca08c" -} diff --git a/core/startos/.sqlx/query-95c4ab4c645f3302568c6ff13d85ab58252362694cf0f56999bf60194d20583a.json b/core/startos/.sqlx/query-95c4ab4c645f3302568c6ff13d85ab58252362694cf0f56999bf60194d20583a.json deleted file mode 100644 index aadc0fc3a..000000000 --- a/core/startos/.sqlx/query-95c4ab4c645f3302568c6ff13d85ab58252362694cf0f56999bf60194d20583a.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT id, hostname, path, username, password FROM cifs_shares", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Int4" - }, - { - "ordinal": 1, - "name": "hostname", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "path", - "type_info": "Text" - }, - { - "ordinal": 3, - "name": "username", - "type_info": "Text" - }, - { - "ordinal": 4, - "name": "password", - "type_info": "Text" - } - ], - "parameters": { - "Left": [] - }, - "nullable": [ - false, - false, - false, - false, - true - ] - }, - "hash": "95c4ab4c645f3302568c6ff13d85ab58252362694cf0f56999bf60194d20583a" -} diff --git a/core/startos/.sqlx/query-a60d6e66719325b08dc4ecfacaf337527233c84eee758ac9be967906e5841d27.json b/core/startos/.sqlx/query-a60d6e66719325b08dc4ecfacaf337527233c84eee758ac9be967906e5841d27.json deleted file mode 100644 index c56a9ebd1..000000000 --- a/core/startos/.sqlx/query-a60d6e66719325b08dc4ecfacaf337527233c84eee758ac9be967906e5841d27.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "DELETE FROM cifs_shares WHERE id = $1", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4" - ] - }, - "nullable": [] - }, - "hash": "a60d6e66719325b08dc4ecfacaf337527233c84eee758ac9be967906e5841d27" -} diff --git a/core/startos/.sqlx/query-a6b0c8909a3a5d6d9156aebfb359424e6b5a1d1402e028219e21726f1ebd282e.json b/core/startos/.sqlx/query-a6b0c8909a3a5d6d9156aebfb359424e6b5a1d1402e028219e21726f1ebd282e.json deleted file mode 100644 index 86bd9250e..000000000 --- a/core/startos/.sqlx/query-a6b0c8909a3a5d6d9156aebfb359424e6b5a1d1402e028219e21726f1ebd282e.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT fingerprint, openssh_pubkey, created_at FROM ssh_keys", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "fingerprint", - "type_info": "Text" - }, - { - "ordinal": 1, - "name": "openssh_pubkey", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "created_at", - "type_info": "Text" - } - ], - "parameters": { - "Left": [] - }, - "nullable": [ - false, - false, - false - ] - }, - "hash": "a6b0c8909a3a5d6d9156aebfb359424e6b5a1d1402e028219e21726f1ebd282e" -} diff --git a/core/startos/.sqlx/query-b1147beaaabbed89f2ab8c1e13ec4393a9a8fde2833cf096af766a979d94dee6.json b/core/startos/.sqlx/query-b1147beaaabbed89f2ab8c1e13ec4393a9a8fde2833cf096af766a979d94dee6.json deleted file mode 100644 index c8ff84277..000000000 --- a/core/startos/.sqlx/query-b1147beaaabbed89f2ab8c1e13ec4393a9a8fde2833cf096af766a979d94dee6.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "UPDATE cifs_shares SET hostname = $1, path = $2, username = $3, password = $4 WHERE id = $5", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Text", - "Text", - "Text", - "Text", - "Int4" - ] - }, - "nullable": [] - }, - "hash": "b1147beaaabbed89f2ab8c1e13ec4393a9a8fde2833cf096af766a979d94dee6" -} diff --git a/core/startos/.sqlx/query-b203820ee1c553a4b246eac74b79bd10d5717b2a0ddecf22330b7d531aac7c5d.json b/core/startos/.sqlx/query-b203820ee1c553a4b246eac74b79bd10d5717b2a0ddecf22330b7d531aac7c5d.json deleted file mode 100644 index b76542db8..000000000 --- a/core/startos/.sqlx/query-b203820ee1c553a4b246eac74b79bd10d5717b2a0ddecf22330b7d531aac7c5d.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "DELETE FROM network_keys WHERE package = $1", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [] - }, - "hash": "b203820ee1c553a4b246eac74b79bd10d5717b2a0ddecf22330b7d531aac7c5d" -} diff --git a/core/startos/.sqlx/query-b81592b3a74940ab56d41537484090d45cfa4c85168a587b1a41dc5393cccea1.json b/core/startos/.sqlx/query-b81592b3a74940ab56d41537484090d45cfa4c85168a587b1a41dc5393cccea1.json deleted file mode 100644 index e2e8a1620..000000000 --- a/core/startos/.sqlx/query-b81592b3a74940ab56d41537484090d45cfa4c85168a587b1a41dc5393cccea1.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "UPDATE account SET tor_key = NULL, network_key = gen_random_bytes(32)", - "describe": { - "columns": [], - "parameters": { - "Left": [] - }, - "nullable": [] - }, - "hash": "b81592b3a74940ab56d41537484090d45cfa4c85168a587b1a41dc5393cccea1" -} diff --git a/core/startos/.sqlx/query-bc9382d34bf93f468c64d0d02613452e7a69768da179e78479cd35ee42b493ae.json b/core/startos/.sqlx/query-bc9382d34bf93f468c64d0d02613452e7a69768da179e78479cd35ee42b493ae.json new file mode 100644 index 000000000..d5fae12b7 --- /dev/null +++ b/core/startos/.sqlx/query-bc9382d34bf93f468c64d0d02613452e7a69768da179e78479cd35ee42b493ae.json @@ -0,0 +1,16 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO user_activity (created_at, server_id, arch) VALUES ($1, $2, $3)", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Timestamptz", + "Varchar", + "Varchar" + ] + }, + "nullable": [] + }, + "hash": "bc9382d34bf93f468c64d0d02613452e7a69768da179e78479cd35ee42b493ae" +} diff --git a/core/startos/.sqlx/query-d5117054072476377f3c4f040ea429d4c9b2cf534e76f35c80a2bf60e8599cca.json b/core/startos/.sqlx/query-d5117054072476377f3c4f040ea429d4c9b2cf534e76f35c80a2bf60e8599cca.json deleted file mode 100644 index b77ba7ce9..000000000 --- a/core/startos/.sqlx/query-d5117054072476377f3c4f040ea429d4c9b2cf534e76f35c80a2bf60e8599cca.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT openssh_pubkey FROM ssh_keys", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "openssh_pubkey", - "type_info": "Text" - } - ], - "parameters": { - "Left": [] - }, - "nullable": [ - false - ] - }, - "hash": "d5117054072476377f3c4f040ea429d4c9b2cf534e76f35c80a2bf60e8599cca" -} diff --git a/core/startos/.sqlx/query-da71f94b29798d1738d2b10b9a721ea72db8cfb362e7181c8226d9297507c62b.json b/core/startos/.sqlx/query-da71f94b29798d1738d2b10b9a721ea72db8cfb362e7181c8226d9297507c62b.json deleted file mode 100644 index 5c5c89c27..000000000 --- a/core/startos/.sqlx/query-da71f94b29798d1738d2b10b9a721ea72db8cfb362e7181c8226d9297507c62b.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO notifications (package_id, code, level, title, message, data) VALUES ($1, $2, $3, $4, $5, $6)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Text", - "Int4", - "Text", - "Text", - "Text", - "Text" - ] - }, - "nullable": [] - }, - "hash": "da71f94b29798d1738d2b10b9a721ea72db8cfb362e7181c8226d9297507c62b" -} diff --git a/core/startos/.sqlx/query-dfc23b7e966c3853284753a7e934351ba0cae3825988b3e0ecd3b6781bcff524.json b/core/startos/.sqlx/query-dfc23b7e966c3853284753a7e934351ba0cae3825988b3e0ecd3b6781bcff524.json deleted file mode 100644 index 2fc8ad1ba..000000000 --- a/core/startos/.sqlx/query-dfc23b7e966c3853284753a7e934351ba0cae3825988b3e0ecd3b6781bcff524.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "DELETE FROM network_keys WHERE package = $1 AND interface = $2", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Text", - "Text" - ] - }, - "nullable": [] - }, - "hash": "dfc23b7e966c3853284753a7e934351ba0cae3825988b3e0ecd3b6781bcff524" -} diff --git a/core/startos/.sqlx/query-e185203cf84e43b801dfb23b4159e34aeaef1154dcd3d6811ab504915497ccf7.json b/core/startos/.sqlx/query-e185203cf84e43b801dfb23b4159e34aeaef1154dcd3d6811ab504915497ccf7.json deleted file mode 100644 index a4dc187cd..000000000 --- a/core/startos/.sqlx/query-e185203cf84e43b801dfb23b4159e34aeaef1154dcd3d6811ab504915497ccf7.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "DELETE FROM notifications WHERE id = $1", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4" - ] - }, - "nullable": [] - }, - "hash": "e185203cf84e43b801dfb23b4159e34aeaef1154dcd3d6811ab504915497ccf7" -} diff --git a/core/startos/.sqlx/query-e545696735f202f9d13cf22a561f3ff3f9aed7f90027a9ba97634bcb47d772f0.json b/core/startos/.sqlx/query-e545696735f202f9d13cf22a561f3ff3f9aed7f90027a9ba97634bcb47d772f0.json deleted file mode 100644 index 97a4ec95a..000000000 --- a/core/startos/.sqlx/query-e545696735f202f9d13cf22a561f3ff3f9aed7f90027a9ba97634bcb47d772f0.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT tor_key FROM account WHERE id = 0", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "tor_key", - "type_info": "Bytea" - } - ], - "parameters": { - "Left": [] - }, - "nullable": [ - true - ] - }, - "hash": "e545696735f202f9d13cf22a561f3ff3f9aed7f90027a9ba97634bcb47d772f0" -} diff --git a/core/startos/.sqlx/query-e5843c5b0e7819b29aa1abf2266799bd4f82e761837b526a0972c3d4439a264d.json b/core/startos/.sqlx/query-e5843c5b0e7819b29aa1abf2266799bd4f82e761837b526a0972c3d4439a264d.json deleted file mode 100644 index b2aa04370..000000000 --- a/core/startos/.sqlx/query-e5843c5b0e7819b29aa1abf2266799bd4f82e761837b526a0972c3d4439a264d.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO session (id, user_agent, metadata) VALUES ($1, $2, $3)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Text", - "Text", - "Text" - ] - }, - "nullable": [] - }, - "hash": "e5843c5b0e7819b29aa1abf2266799bd4f82e761837b526a0972c3d4439a264d" -} diff --git a/core/startos/.sqlx/query-e95322a8e2ae3b93f1e974b24c0b81803f1e9ec9e8ebbf15cafddfc1c5a028ed.json b/core/startos/.sqlx/query-e95322a8e2ae3b93f1e974b24c0b81803f1e9ec9e8ebbf15cafddfc1c5a028ed.json deleted file mode 100644 index fd5a467ec..000000000 --- a/core/startos/.sqlx/query-e95322a8e2ae3b93f1e974b24c0b81803f1e9ec9e8ebbf15cafddfc1c5a028ed.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT\n network_keys.package,\n network_keys.interface,\n network_keys.key,\n tor.key AS \"tor_key?\"\n FROM\n network_keys\n LEFT JOIN\n tor\n ON\n network_keys.package = tor.package\n AND\n network_keys.interface = tor.interface\n WHERE\n network_keys.package = $1\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "package", - "type_info": "Text" - }, - { - "ordinal": 1, - "name": "interface", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "key", - "type_info": "Bytea" - }, - { - "ordinal": 3, - "name": "tor_key?", - "type_info": "Bytea" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - false, - false, - false, - false - ] - }, - "hash": "e95322a8e2ae3b93f1e974b24c0b81803f1e9ec9e8ebbf15cafddfc1c5a028ed" -} diff --git a/core/startos/.sqlx/query-eb750adaa305bdbf3c5b70aaf59139c7b7569602adb58f2d6b3a94da4f167b0a.json b/core/startos/.sqlx/query-eb750adaa305bdbf3c5b70aaf59139c7b7569602adb58f2d6b3a94da4f167b0a.json deleted file mode 100644 index fb8a7c1e5..000000000 --- a/core/startos/.sqlx/query-eb750adaa305bdbf3c5b70aaf59139c7b7569602adb58f2d6b3a94da4f167b0a.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "DELETE FROM notifications WHERE id < $1", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int4" - ] - }, - "nullable": [] - }, - "hash": "eb750adaa305bdbf3c5b70aaf59139c7b7569602adb58f2d6b3a94da4f167b0a" -} diff --git a/core/startos/.sqlx/query-ecc765d8205c0876956f95f76944ac6a5f34dd820c4073b7728c7067aab9fded.json b/core/startos/.sqlx/query-ecc765d8205c0876956f95f76944ac6a5f34dd820c4073b7728c7067aab9fded.json deleted file mode 100644 index 27c9752b2..000000000 --- a/core/startos/.sqlx/query-ecc765d8205c0876956f95f76944ac6a5f34dd820c4073b7728c7067aab9fded.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO cifs_shares (hostname, path, username, password) VALUES ($1, $2, $3, $4) RETURNING id", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Int4" - } - ], - "parameters": { - "Left": [ - "Text", - "Text", - "Text", - "Text" - ] - }, - "nullable": [ - false - ] - }, - "hash": "ecc765d8205c0876956f95f76944ac6a5f34dd820c4073b7728c7067aab9fded" -} diff --git a/core/startos/.sqlx/query-f6d1c5ef0f9d9577bea8382318967b9deb46da75788c7fe6082b43821c22d556.json b/core/startos/.sqlx/query-f6d1c5ef0f9d9577bea8382318967b9deb46da75788c7fe6082b43821c22d556.json deleted file mode 100644 index 6ed9898f6..000000000 --- a/core/startos/.sqlx/query-f6d1c5ef0f9d9577bea8382318967b9deb46da75788c7fe6082b43821c22d556.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "INSERT INTO ssh_keys (fingerprint, openssh_pubkey, created_at) VALUES ($1, $2, $3)", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Text", - "Text", - "Text" - ] - }, - "nullable": [] - }, - "hash": "f6d1c5ef0f9d9577bea8382318967b9deb46da75788c7fe6082b43821c22d556" -} diff --git a/core/startos/.sqlx/query-f7d2dae84613bcef330f7403352cc96547f3f6dbec11bf2eadfaf53ad8ab51b5.json b/core/startos/.sqlx/query-f7d2dae84613bcef330f7403352cc96547f3f6dbec11bf2eadfaf53ad8ab51b5.json deleted file mode 100644 index f48ccb074..000000000 --- a/core/startos/.sqlx/query-f7d2dae84613bcef330f7403352cc96547f3f6dbec11bf2eadfaf53ad8ab51b5.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT network_key FROM account WHERE id = 0", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "network_key", - "type_info": "Bytea" - } - ], - "parameters": { - "Left": [] - }, - "nullable": [ - false - ] - }, - "hash": "f7d2dae84613bcef330f7403352cc96547f3f6dbec11bf2eadfaf53ad8ab51b5" -} diff --git a/core/startos/.sqlx/query-fe6e4f09f3028e5b6b6259e86cbad285680ce157aae9d7837ac020c8b2945e7f.json b/core/startos/.sqlx/query-fe6e4f09f3028e5b6b6259e86cbad285680ce157aae9d7837ac020c8b2945e7f.json deleted file mode 100644 index 6ef1d5023..000000000 --- a/core/startos/.sqlx/query-fe6e4f09f3028e5b6b6259e86cbad285680ce157aae9d7837ac020c8b2945e7f.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT * FROM account WHERE id = 0", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Int4" - }, - { - "ordinal": 1, - "name": "password", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "tor_key", - "type_info": "Bytea" - }, - { - "ordinal": 3, - "name": "server_id", - "type_info": "Text" - }, - { - "ordinal": 4, - "name": "hostname", - "type_info": "Text" - }, - { - "ordinal": 5, - "name": "network_key", - "type_info": "Bytea" - }, - { - "ordinal": 6, - "name": "root_ca_key_pem", - "type_info": "Text" - }, - { - "ordinal": 7, - "name": "root_ca_cert_pem", - "type_info": "Text" - } - ], - "parameters": { - "Left": [] - }, - "nullable": [ - false, - false, - true, - true, - true, - false, - false, - false - ] - }, - "hash": "fe6e4f09f3028e5b6b6259e86cbad285680ce157aae9d7837ac020c8b2945e7f" -} diff --git a/core/startos/Cargo.toml b/core/startos/Cargo.toml index a8707bf65..d2304fedb 100644 --- a/core/startos/Cargo.toml +++ b/core/startos/Cargo.toml @@ -42,7 +42,7 @@ cli = [] container-runtime = [] daemon = [] registry = [] -default = ["cli", "daemon", "registry"] +default = ["cli", "daemon"] dev = [] unstable = ["console-subscriber", "tokio/tracing"] docker = [] @@ -86,7 +86,7 @@ ed25519-dalek = { version = "2.1.1", features = [ "pkcs8", ] } ed25519-dalek-v1 = { package = "ed25519-dalek", version = "1" } -emver = { version = "0.1.7", git = "https://github.com/Start9Labs/emver-rs.git", features = [ +exver = { version = "0.2.0", git = "https://github.com/Start9Labs/exver-rs.git", features = [ "serde", ] } fd-lock-rs = "0.1.4" @@ -97,6 +97,7 @@ hex = "0.4.3" hmac = "0.12.1" http = "1.0.0" http-body-util = "0.1" +hyper-util = { version = "0.1.5", features = ["tokio", "service"] } id-pool = { version = "0.2.2", default-features = false, features = [ "serde", "u16", @@ -159,6 +160,7 @@ serde_yaml = { package = "serde_yml", version = "0.0.10" } sha2 = "0.10.2" shell-words = "1" simple-logging = "2.0.2" +socket2 = "0.5.7" sqlx = { version = "0.7.2", features = [ "chrono", "runtime-tokio-rustls", diff --git a/core/startos/src/account.rs b/core/startos/src/account.rs index e074d301d..9e755342f 100644 --- a/core/startos/src/account.rs +++ b/core/startos/src/account.rs @@ -28,6 +28,7 @@ pub struct AccountInfo { pub root_ca_key: PKey, pub root_ca_cert: X509, pub ssh_key: ssh_key::PrivateKey, + pub compat_s9pk_key: ed25519_dalek::SigningKey, } impl AccountInfo { pub fn new(password: &str, start_time: SystemTime) -> Result { @@ -39,6 +40,7 @@ impl AccountInfo { let ssh_key = ssh_key::PrivateKey::from(ssh_key::private::Ed25519Keypair::random( &mut rand::thread_rng(), )); + let compat_s9pk_key = ed25519_dalek::SigningKey::generate(&mut rand::thread_rng()); Ok(Self { server_id, hostname, @@ -47,6 +49,7 @@ impl AccountInfo { root_ca_key, root_ca_cert, ssh_key, + compat_s9pk_key, }) } @@ -61,6 +64,7 @@ impl AccountInfo { let root_ca_key = cert_store.as_root_key().de()?.0; let root_ca_cert = cert_store.as_root_cert().de()?.0; let ssh_key = db.as_private().as_ssh_privkey().de()?.0; + let compat_s9pk_key = db.as_private().as_compat_s9pk_key().de()?.0; Ok(Self { server_id, @@ -70,6 +74,7 @@ impl AccountInfo { root_ca_key, root_ca_cert, ssh_key, + compat_s9pk_key, }) } @@ -92,6 +97,9 @@ impl AccountInfo { db.as_private_mut() .as_ssh_privkey_mut() .ser(Pem::new_ref(&self.ssh_key))?; + db.as_private_mut() + .as_compat_s9pk_key_mut() + .ser(Pem::new_ref(&self.compat_s9pk_key))?; let key_store = db.as_private_mut().as_key_store_mut(); key_store.as_onion_mut().insert_key(&self.tor_key)?; let cert_store = key_store.as_local_certs_mut(); diff --git a/core/startos/src/backup/os.rs b/core/startos/src/backup/os.rs index 6848473a7..7c8119e79 100644 --- a/core/startos/src/backup/os.rs +++ b/core/startos/src/backup/os.rs @@ -85,6 +85,7 @@ impl OsBackupV0 { ssh_key::Algorithm::Ed25519, )?, tor_key: TorSecretKeyV3::from(self.tor_key.0), + compat_s9pk_key: ed25519_dalek::SigningKey::generate(&mut rand::thread_rng()), }, ui: self.ui, }) @@ -113,6 +114,7 @@ impl OsBackupV1 { root_ca_cert: self.root_ca_cert.0, ssh_key: ssh_key::PrivateKey::from(Ed25519Keypair::from_seed(&self.net_key.0)), tor_key: TorSecretKeyV3::from(ed25519_expand_key(&self.net_key.0)), + compat_s9pk_key: ed25519_dalek::SigningKey::from_bytes(&self.net_key), }, ui: self.ui, } @@ -124,13 +126,14 @@ impl OsBackupV1 { #[serde(rename = "kebab-case")] struct OsBackupV2 { - server_id: String, // uuidv4 - hostname: String, // - - root_ca_key: Pem>, // PEM Encoded OpenSSL Key - root_ca_cert: Pem, // PEM Encoded OpenSSL X509 Certificate - ssh_key: Pem, // PEM Encoded OpenSSH Key - tor_key: TorSecretKeyV3, // Base64 Encoded Ed25519 Expanded Secret Key - ui: Value, // JSON Value + server_id: String, // uuidv4 + hostname: String, // - + root_ca_key: Pem>, // PEM Encoded OpenSSL Key + root_ca_cert: Pem, // PEM Encoded OpenSSL X509 Certificate + ssh_key: Pem, // PEM Encoded OpenSSH Key + tor_key: TorSecretKeyV3, // Base64 Encoded Ed25519 Expanded Secret Key + compat_s9pk_key: Pem, // PEM Encoded ED25519 Key + ui: Value, // JSON Value } impl OsBackupV2 { fn project(self) -> OsBackup { @@ -143,6 +146,7 @@ impl OsBackupV2 { root_ca_cert: self.root_ca_cert.0, ssh_key: self.ssh_key.0, tor_key: self.tor_key, + compat_s9pk_key: self.compat_s9pk_key.0, }, ui: self.ui, } @@ -155,6 +159,7 @@ impl OsBackupV2 { root_ca_cert: Pem(backup.account.root_ca_cert.clone()), ssh_key: Pem(backup.account.ssh_key.clone()), tor_key: backup.account.tor_key.clone(), + compat_s9pk_key: Pem(backup.account.compat_s9pk_key.clone()), ui: backup.ui.clone(), } } diff --git a/core/startos/src/backup/restore.rs b/core/startos/src/backup/restore.rs index 556f750ec..3f0aacbe8 100644 --- a/core/startos/src/backup/restore.rs +++ b/core/startos/src/backup/restore.rs @@ -156,16 +156,14 @@ async fn restore_packages( let mut tasks = BTreeMap::new(); for id in ids { let backup_dir = backup_guard.clone().package_backup(&id); + let s9pk_path = backup_dir.path().join(&id).with_extension("s9pk"); let task = ctx .services .install( ctx.clone(), - S9pk::open( - backup_dir.path().join(&id).with_extension("s9pk"), - Some(&id), - ) - .await?, + || S9pk::open(s9pk_path, Some(&id)), Some(backup_dir), + None, ) .await?; tasks.insert(id, task); diff --git a/core/startos/src/backup/target/mod.rs b/core/startos/src/backup/target/mod.rs index 2c7a28d94..f1273aa6a 100644 --- a/core/startos/src/backup/target/mod.rs +++ b/core/startos/src/backup/target/mod.rs @@ -7,6 +7,7 @@ use clap::Parser; use color_eyre::eyre::eyre; use digest::generic_array::GenericArray; use digest::OutputSizeUser; +use exver::Version; use models::PackageId; use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler}; use serde::{Deserialize, Serialize}; @@ -194,7 +195,7 @@ pub async fn list(ctx: RpcContext) -> Result>, pub package_backups: BTreeMap, } @@ -204,7 +205,7 @@ pub struct BackupInfo { pub struct PackageBackupInfo { pub title: String, pub version: VersionString, - pub os_version: VersionString, + pub os_version: Version, pub timestamp: DateTime, } @@ -223,9 +224,9 @@ fn display_backup_info(params: WithIoFormat, info: BackupInfo) { "TIMESTAMP", ]); table.add_row(row![ - "EMBASSY OS", - info.version.as_str(), - info.version.as_str(), + "StartOS", + &info.version.to_string(), + &info.version.to_string(), &if let Some(ts) = &info.timestamp { ts.to_string() } else { @@ -236,7 +237,7 @@ fn display_backup_info(params: WithIoFormat, info: BackupInfo) { let row = row![ &*id, info.version.as_str(), - info.os_version.as_str(), + &info.os_version.to_string(), &info.timestamp.to_string(), ]; table.add_row(row); diff --git a/core/startos/src/context/cli.rs b/core/startos/src/context/cli.rs index 22084bbe1..0eca1d2c2 100644 --- a/core/startos/src/context/cli.rs +++ b/core/startos/src/context/cli.rs @@ -25,7 +25,7 @@ use crate::rpc_continuations::Guid; #[derive(Debug)] pub struct CliContextSeed { - pub runtime: OnceCell, + pub runtime: OnceCell>, pub base_url: Url, pub rpc_url: Url, pub registry_url: Option, @@ -43,7 +43,9 @@ impl Drop for CliContextSeed { std::fs::create_dir_all(&parent_dir).unwrap(); } let mut writer = fd_lock_rs::FdLock::lock( - File::create(&tmp).unwrap(), + File::create(&tmp) + .with_ctx(|_| (ErrorKind::Filesystem, &tmp)) + .unwrap(), fd_lock_rs::LockType::Exclusive, true, ) @@ -80,9 +82,12 @@ impl CliContext { }); let cookie_store = Arc::new(CookieStoreMutex::new({ let mut store = if cookie_path.exists() { - CookieStore::load_json(BufReader::new(File::open(&cookie_path)?)) - .map_err(|e| eyre!("{}", e)) - .with_kind(crate::ErrorKind::Deserialization)? + CookieStore::load_json(BufReader::new( + File::open(&cookie_path) + .with_ctx(|_| (ErrorKind::Filesystem, cookie_path.display()))?, + )) + .map_err(|e| eyre!("{}", e)) + .with_kind(crate::ErrorKind::Deserialization)? } else { CookieStore::default() }; @@ -249,16 +254,19 @@ impl std::ops::Deref for CliContext { } } impl Context for CliContext { - fn runtime(&self) -> tokio::runtime::Handle { - self.runtime - .get_or_init(|| { - tokio::runtime::Builder::new_multi_thread() - .enable_all() - .build() - .unwrap() - }) - .handle() - .clone() + fn runtime(&self) -> Option> { + Some( + self.runtime + .get_or_init(|| { + Arc::new( + tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap(), + ) + }) + .clone(), + ) } } impl CallRemote for CliContext { @@ -290,7 +298,7 @@ impl CallRemote for CliContext { #[test] fn test() { let ctx = CliContext::init(ClientConfig::default()).unwrap(); - ctx.runtime().block_on(async { + ctx.runtime().unwrap().block_on(async { reqwest::Client::new() .get("http://example.com") .send() diff --git a/core/startos/src/context/config.rs b/core/startos/src/context/config.rs index 7b4865301..e02648919 100644 --- a/core/startos/src/context/config.rs +++ b/core/startos/src/context/config.rs @@ -37,7 +37,10 @@ pub trait ContextConfig: DeserializeOwned + Default { .map(|f| f.parse()) .transpose()? .unwrap_or_default(); - format.from_reader(File::open(path)?) + format.from_reader( + File::open(path.as_ref()) + .with_ctx(|_| (ErrorKind::Filesystem, path.as_ref().display()))?, + ) } fn load_path_rec(&mut self, path: Option>) -> Result<(), Error> { if let Some(path) = path.filter(|p| p.as_ref().exists()) { diff --git a/core/startos/src/context/rpc.rs b/core/startos/src/context/rpc.rs index 3dd3354aa..4920a6223 100644 --- a/core/startos/src/context/rpc.rs +++ b/core/startos/src/context/rpc.rs @@ -57,6 +57,7 @@ pub struct RpcContextSeed { pub client: Client, pub hardware: Hardware, pub start_time: Instant, + #[cfg(feature = "dev")] pub dev: Dev, } @@ -249,6 +250,7 @@ impl RpcContext { .with_kind(crate::ErrorKind::ParseUrl)?, hardware: Hardware { devices, ram }, start_time: Instant::now(), + #[cfg(feature = "dev")] dev: Dev { lxc: Mutex::new(BTreeMap::new()), }, diff --git a/core/startos/src/db/model/mod.rs b/core/startos/src/db/model/mod.rs index cae1bfe51..678f7e5fb 100644 --- a/core/startos/src/db/model/mod.rs +++ b/core/startos/src/db/model/mod.rs @@ -40,6 +40,7 @@ impl Database { notifications: Notifications::new(), cifs: CifsTargets::new(), package_stores: BTreeMap::new(), + compat_s9pk_key: Pem(account.compat_s9pk_key.clone()), }, // TODO }) } diff --git a/core/startos/src/db/model/package.rs b/core/startos/src/db/model/package.rs index 8bb5a9517..22d6440bb 100644 --- a/core/startos/src/db/model/package.rs +++ b/core/startos/src/db/model/package.rs @@ -1,7 +1,7 @@ use std::collections::{BTreeMap, BTreeSet}; use chrono::{DateTime, Utc}; -use emver::VersionRange; +use exver::VersionRange; use imbl_value::InternedString; use models::{ActionId, DataUrl, HealthCheckId, HostId, PackageId, ServiceInterfaceId}; use patch_db::json_ptr::JsonPointer; diff --git a/core/startos/src/db/model/private.rs b/core/startos/src/db/model/private.rs index 2b8c55dbd..c57364fc3 100644 --- a/core/startos/src/db/model/private.rs +++ b/core/startos/src/db/model/private.rs @@ -19,6 +19,8 @@ use crate::util::serde::Pem; pub struct Private { pub key_store: KeyStore, pub password: String, // argon2 hash + #[serde(default = "generate_compat_key")] + pub compat_s9pk_key: Pem, pub ssh_privkey: Pem, pub ssh_pubkeys: SshKeys, pub available_ports: AvailablePorts, @@ -28,3 +30,7 @@ pub struct Private { #[serde(default)] pub package_stores: BTreeMap, } + +fn generate_compat_key() -> Pem { + Pem(ed25519_dalek::SigningKey::generate(&mut rand::thread_rng())) +} diff --git a/core/startos/src/db/model/public.rs b/core/startos/src/db/model/public.rs index e5257f2a4..5f8dc029a 100644 --- a/core/startos/src/db/model/public.rs +++ b/core/startos/src/db/model/public.rs @@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet}; use std::net::{Ipv4Addr, Ipv6Addr}; use chrono::{DateTime, Utc}; -use emver::VersionRange; +use exver::{Version, VersionRange}; use imbl_value::InternedString; use ipnet::{Ipv4Net, Ipv6Net}; use isocountry::CountryCode; @@ -21,7 +21,6 @@ use crate::net::utils::{get_iface_ipv4_addr, get_iface_ipv6_addr}; use crate::prelude::*; use crate::progress::FullProgress; use crate::util::cpupower::Governor; -use crate::util::VersionString; use crate::version::{Current, VersionT}; use crate::{ARCH, PLATFORM}; @@ -43,7 +42,7 @@ impl Public { arch: get_arch(), platform: get_platform(), id: account.server_id.clone(), - version: Current::new().semver().into(), + version: Current::new().semver(), hostname: account.hostname.no_dot_host_name(), last_backup: None, eos_version_compat: Current::new().compat().clone(), @@ -109,7 +108,8 @@ pub struct ServerInfo { pub platform: InternedString, pub id: String, pub hostname: String, - pub version: VersionString, + #[ts(type = "string")] + pub version: Version, #[ts(type = "string | null")] pub last_backup: Option>, #[ts(type = "string")] diff --git a/core/startos/src/developer/mod.rs b/core/startos/src/developer/mod.rs index 79a875dfc..4a2a4c3df 100644 --- a/core/startos/src/developer/mod.rs +++ b/core/startos/src/developer/mod.rs @@ -8,8 +8,8 @@ use ed25519_dalek::{SigningKey, VerifyingKey}; use tracing::instrument; use crate::context::CliContext; +use crate::prelude::*; use crate::util::serde::Pem; -use crate::{Error, ResultExt}; #[instrument(skip_all)] pub fn init(ctx: CliContext) -> Result<(), Error> { @@ -26,7 +26,8 @@ pub fn init(ctx: CliContext) -> Result<(), Error> { secret_key: secret.to_bytes(), public_key: Some(PublicKeyBytes(VerifyingKey::from(&secret).to_bytes())), }; - let mut dev_key_file = File::create(&ctx.developer_key_path)?; + let mut dev_key_file = File::create(&ctx.developer_key_path) + .with_ctx(|_| (ErrorKind::Filesystem, ctx.developer_key_path.display()))?; dev_key_file.write_all( keypair_bytes .to_pkcs8_pem(base64ct::LineEnding::default()) diff --git a/core/startos/src/disk/mod.rs b/core/startos/src/disk/mod.rs index 705a34f98..d7ce5f766 100644 --- a/core/startos/src/disk/mod.rs +++ b/core/startos/src/disk/mod.rs @@ -102,10 +102,10 @@ fn display_disk_info(params: WithIoFormat, args: Vec) { } else { "N/A" }, - if let Some(eos) = part.start_os.as_ref() { - eos.version.as_str() + &if let Some(eos) = part.start_os.as_ref() { + eos.version.to_string() } else { - "N/A" + "N/A".to_owned() }, ]; table.add_row(row); diff --git a/core/startos/src/disk/util.rs b/core/startos/src/disk/util.rs index a98c52418..d3f2a8d27 100644 --- a/core/startos/src/disk/util.rs +++ b/core/startos/src/disk/util.rs @@ -20,7 +20,7 @@ use super::mount::guard::TmpMountGuard; use crate::disk::mount::guard::GenericMountGuard; use crate::disk::OsPartitionInfo; use crate::util::serde::IoFormat; -use crate::util::{Invoke, VersionString}; +use crate::util::Invoke; use crate::{Error, ResultExt as _}; #[derive(Clone, Copy, Debug, Deserialize, Serialize)] @@ -56,7 +56,7 @@ pub struct PartitionInfo { #[derive(Clone, Debug, Default, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct EmbassyOsRecoveryInfo { - pub version: VersionString, + pub version: exver::Version, pub full: bool, pub password_hash: Option, pub wrapped_key: Option, diff --git a/core/startos/src/firmware.rs b/core/startos/src/firmware.rs index a9d5ced79..7e7b9d70f 100644 --- a/core/startos/src/firmware.rs +++ b/core/startos/src/firmware.rs @@ -3,13 +3,12 @@ use std::path::Path; use async_compression::tokio::bufread::GzipDecoder; use serde::{Deserialize, Serialize}; -use tokio::fs::File; use tokio::io::BufReader; use tokio::process::Command; use crate::disk::fsck::RequiresReboot; use crate::prelude::*; -use crate::progress::PhaseProgressTrackerHandle; +use crate::util::io::open_file; use crate::util::Invoke; use crate::PLATFORM; @@ -134,7 +133,7 @@ pub async fn update_firmware(firmware: Firmware) -> Result<(), Error> { .invoke(ErrorKind::Filesystem) .await?; let mut rdr = if tokio::fs::metadata(&firmware_path).await.is_ok() { - GzipDecoder::new(BufReader::new(File::open(&firmware_path).await?)) + GzipDecoder::new(BufReader::new(open_file(&firmware_path).await?)) } else { return Err(Error::new( eyre!("Firmware {id}.rom.gz not found in {firmware_dir:?}"), diff --git a/core/startos/src/init.rs b/core/startos/src/init.rs index cdc444c32..fdc38b60d 100644 --- a/core/startos/src/init.rs +++ b/core/startos/src/init.rs @@ -5,7 +5,7 @@ use std::os::unix::fs::PermissionsExt; use std::path::Path; use std::time::{Duration, SystemTime}; -use axum::extract::ws::{self, CloseFrame}; +use axum::extract::ws::{self}; use color_eyre::eyre::eyre; use futures::{StreamExt, TryStreamExt}; use itertools::Itertools; @@ -31,7 +31,7 @@ use crate::progress::{ }; use crate::rpc_continuations::{Guid, RpcContinuation}; use crate::ssh::SSH_AUTHORIZED_KEYS_FILE; -use crate::util::io::IOHook; +use crate::util::io::{create_file, IOHook}; use crate::util::net::WebSocketExt; use crate::util::{cpupower, Invoke}; use crate::Error; @@ -138,10 +138,7 @@ pub async fn init_postgres(datadir: impl AsRef) -> Result<(), Error> { old_version -= 1; let old_datadir = db_dir.join(old_version.to_string()); if tokio::fs::metadata(&old_datadir).await.is_ok() { - tokio::fs::File::create(&incomplete_path) - .await? - .sync_all() - .await?; + create_file(&incomplete_path).await?.sync_all().await?; Command::new("pg_upgradecluster") .arg(old_version.to_string()) .arg("main") diff --git a/core/startos/src/install/mod.rs b/core/startos/src/install/mod.rs index 5d50da27d..18591dc8d 100644 --- a/core/startos/src/install/mod.rs +++ b/core/startos/src/install/mod.rs @@ -1,21 +1,21 @@ +use std::ops::Deref; use std::path::PathBuf; -use std::sync::Arc; use std::time::Duration; use clap::builder::ValueParserFactory; use clap::{value_parser, CommandFactory, FromArgMatches, Parser}; use color_eyre::eyre::eyre; -use emver::VersionRange; -use futures::StreamExt; -use imbl_value::InternedString; +use exver::VersionRange; +use futures::{AsyncWriteExt, StreamExt}; +use imbl_value::{json, InternedString}; use itertools::Itertools; -use patch_db::json_ptr::JsonPointer; +use models::VersionString; use reqwest::header::{HeaderMap, CONTENT_LENGTH}; use reqwest::Url; use rpc_toolkit::yajrc::RpcError; use rpc_toolkit::HandlerArgs; +use rustyline_async::ReadlineEvent; use serde::{Deserialize, Serialize}; -use serde_json::{json, Value}; use tokio::sync::oneshot; use tracing::instrument; use ts_rs::TS; @@ -23,13 +23,14 @@ use ts_rs::TS; use crate::context::{CliContext, RpcContext}; use crate::db::model::package::{ManifestPreference, PackageState, PackageStateMatchModelRef}; use crate::prelude::*; -use crate::progress::{FullProgress, PhasedProgressBar}; +use crate::progress::{FullProgress, FullProgressTracker, PhasedProgressBar}; +use crate::registry::context::{RegistryContext, RegistryUrlParams}; +use crate::registry::package::get::GetPackageResponse; use crate::rpc_continuations::{Guid, RpcContinuation}; use crate::s9pk::manifest::PackageId; -use crate::s9pk::merkle_archive::source::http::HttpSource; -use crate::s9pk::S9pk; use crate::upload::upload; use crate::util::clap::FromStrParser; +use crate::util::io::open_file; use crate::util::net::WebSocketExt; use crate::util::Never; @@ -38,32 +39,33 @@ pub const PKG_PUBLIC_DIR: &str = "package-data/public"; pub const PKG_WASM_DIR: &str = "package-data/wasm"; // #[command(display(display_serializable))] -pub async fn list(ctx: RpcContext) -> Result { - Ok(ctx.db.peek().await.as_public().as_package_data().as_entries()? +pub async fn list(ctx: RpcContext) -> Result, Error> { + Ok(ctx + .db + .peek() + .await + .as_public() + .as_package_data() + .as_entries()? .iter() .filter_map(|(id, pde)| { let status = match pde.as_state_info().as_match() { - PackageStateMatchModelRef::Installed(_) => { - "installed" - } - PackageStateMatchModelRef::Installing(_) => { - "installing" - } - PackageStateMatchModelRef::Updating(_) => { - "updating" - } - PackageStateMatchModelRef::Restoring(_) => { - "restoring" - } - PackageStateMatchModelRef::Removing(_) => { - "removing" - } - PackageStateMatchModelRef::Error(_) => { - "error" - } + PackageStateMatchModelRef::Installed(_) => "installed", + PackageStateMatchModelRef::Installing(_) => "installing", + PackageStateMatchModelRef::Updating(_) => "updating", + PackageStateMatchModelRef::Restoring(_) => "restoring", + PackageStateMatchModelRef::Removing(_) => "removing", + PackageStateMatchModelRef::Error(_) => "error", }; - serde_json::to_value(json!({ "status": status, "id": id.clone(), "version": pde.as_state_info().as_manifest(ManifestPreference::Old).as_version().de().ok()?})) - .ok() + Some(json!({ + "status": status, + "id": id.clone(), + "version": pde.as_state_info() + .as_manifest(ManifestPreference::Old) + .as_version() + .de() + .ok()? + })) }) .collect()) } @@ -107,65 +109,57 @@ impl std::fmt::Display for MinMax { } } -#[derive(Deserialize, Serialize, Parser, TS)] +#[derive(Deserialize, Serialize, TS)] #[serde(rename_all = "camelCase")] -#[command(rename_all = "kebab-case")] pub struct InstallParams { + #[ts(type = "string")] + registry: Url, id: PackageId, - #[arg(short = 'm', long = "marketplace-url")] - #[ts(type = "string | null")] - registry: Option, - #[arg(short = 'v', long = "version-spec")] - version_spec: Option, - #[arg(long = "version-priority")] - version_priority: Option, + version: VersionString, } -// #[command( -// custom_cli(cli_install(async, context(CliContext))), -// )] #[instrument(skip_all)] pub async fn install( ctx: RpcContext, InstallParams { - id, registry, - version_spec, - version_priority, + id, + version, }: InstallParams, ) -> Result<(), Error> { - let version_str = match &version_spec { - None => "*", - Some(v) => &*v, - }; - let version: VersionRange = version_str.parse()?; - let registry = registry.unwrap_or_else(|| crate::DEFAULT_MARKETPLACE.parse().unwrap()); - let version_priority = version_priority.unwrap_or_default(); - let s9pk = S9pk::deserialize( - &Arc::new( - HttpSource::new( - ctx.client.clone(), - format!( - "{}/package/v0/{}.s9pk?spec={}&version-priority={}", - registry, id, version, version_priority, - ) - .parse()?, - ) - .await?, - ), - None, // TODO - ) - .await?; + let package: GetPackageResponse = from_value( + ctx.call_remote_with::( + "package.get", + json!({ + "id": id, + "version": VersionRange::exactly(version.deref().clone()), + }), + RegistryUrlParams { + registry: registry.clone(), + }, + ) + .await?, + )?; - ensure_code!( - &s9pk.as_manifest().id == &id, - ErrorKind::ValidateS9pk, - "manifest.id does not match expected" - ); + let asset = &package + .best + .get(&version) + .ok_or_else(|| { + Error::new( + eyre!("{id}@{version} not found on {registry}"), + ErrorKind::NotFound, + ) + })? + .s9pk; let download = ctx .services - .install(ctx.clone(), s9pk, None::) + .install( + ctx.clone(), + || asset.deserialize_s9pk(ctx.client.clone()), + None::, + None, + ) .await?; tokio::spawn(async move { download.await?.await }); @@ -193,113 +187,74 @@ pub async fn sideload( SideloadParams { session }: SideloadParams, ) -> Result { let (upload, file) = upload(&ctx, session.clone()).await?; - let (id_send, id_recv) = oneshot::channel(); let (err_send, err_recv) = oneshot::channel(); let progress = Guid::new(); - let db = ctx.db.clone(); - let mut sub = db - .subscribe( - "/package-data/{id}/install-progress" - .parse::() - .with_kind(ErrorKind::Database)?, - ) - .await; - ctx.rpc_continuations.add( - progress.clone(), - RpcContinuation::ws_authed(&ctx, session, - |mut ws| { - use axum::extract::ws::Message; - async move { - if let Err(e) = async { - let id = match id_recv.await.map_err(|_| { - Error::new( - eyre!("Could not get id to watch progress"), - ErrorKind::Cancelled, - ) - }).and_then(|a|a) { - Ok(a) => a, - Err(e) =>{ ws.send(Message::Text( - serde_json::to_string(&Err::<(), _>(RpcError::from(e.clone_output()))) - .with_kind(ErrorKind::Serialization)?, - )) - .await - .with_kind(ErrorKind::Network)?; - return Err(e); - } - }; - tokio::select! { - res = async { - while let Some(_) = sub.recv().await { - ws.send(Message::Text( - serde_json::to_string(&if let Some(p) = db - .peek() - .await - .as_public() - .as_package_data() - .as_idx(&id) - .and_then(|e| e.as_state_info().as_installing_info()).map(|i| i.as_progress()) - { - Ok::<_, ()>(p.de()?) - } else { - let mut p = FullProgress::new(); - p.overall.complete(); - Ok(p) - }) - .with_kind(ErrorKind::Serialization)?, - )) - .await - .with_kind(ErrorKind::Network)?; - } - Ok::<_, Error>(()) - } => res?, - err = err_recv => { - if let Ok(e) = err { - ws.send(Message::Text( - serde_json::to_string(&Err::<(), _>(e)) - .with_kind(ErrorKind::Serialization)?, - )) - .await - .with_kind(ErrorKind::Network)?; + let progress_tracker = FullProgressTracker::new(); + let mut progress_listener = progress_tracker.stream(Some(Duration::from_millis(200))); + ctx.rpc_continuations + .add( + progress.clone(), + RpcContinuation::ws_authed( + &ctx, + session, + |mut ws| { + use axum::extract::ws::Message; + async move { + if let Err(e) = async { + tokio::select! { + res = async { + while let Some(progress) = progress_listener.next().await { + ws.send(Message::Text( + serde_json::to_string(&Ok::<_, ()>(progress)) + .with_kind(ErrorKind::Serialization)?, + )) + .await + .with_kind(ErrorKind::Network)?; + } + Ok::<_, Error>(()) + } => res?, + err = err_recv => { + if let Ok(e) = err { + ws.send(Message::Text( + serde_json::to_string(&Err::<(), _>(e)) + .with_kind(ErrorKind::Serialization)?, + )) + .await + .with_kind(ErrorKind::Network)?; + } } } + + ws.normal_close("complete").await?; + + Ok::<_, Error>(()) + } + .await + { + tracing::error!("Error tracking sideload progress: {e}"); + tracing::debug!("{e:?}"); } - - ws.normal_close("complete").await?; - - Ok::<_, Error>(()) } - .await - { - tracing::error!("Error tracking sideload progress: {e}"); - tracing::debug!("{e:?}"); - } - } - }, - Duration::from_secs(600), - ), - ) - .await; + }, + Duration::from_secs(600), + ), + ) + .await; tokio::spawn(async move { if let Err(e) = async { - match S9pk::deserialize( - &file, None, // TODO - ) - .await - { - Ok(s9pk) => { - let _ = id_send.send(Ok(s9pk.as_manifest().id.clone())); - ctx.services - .install(ctx.clone(), s9pk, None::) - .await? - .await? - .await?; - file.delete().await - } - Err(e) => { - let _ = id_send.send(Err(e.clone_output())); - return Err(e); - } - } + let key = ctx.db.peek().await.into_private().into_compat_s9pk_key(); + + ctx.services + .install( + ctx.clone(), + || crate::s9pk::load(file.clone(), || Ok(key.de()?.0), Some(&progress_tracker)), + None::, + Some(progress_tracker.clone()), + ) + .await? + .await? + .await?; + file.delete().await } .await { @@ -311,10 +266,16 @@ pub async fn sideload( Ok(SideloadResponse { upload, progress }) } +#[derive(Deserialize, Serialize, Parser)] +pub struct QueryPackageParams { + id: PackageId, + version: Option, +} + #[derive(Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub enum CliInstallParams { - Marketplace(InstallParams), + Marketplace(QueryPackageParams), Sideload(PathBuf), } impl CommandFactory for CliInstallParams { @@ -328,14 +289,19 @@ impl CommandFactory for CliInstallParams { .required_unless_present("id") .value_parser(value_parser!(PathBuf)), ) - .args(InstallParams::command().get_arguments().cloned().map(|a| { - if a.get_id() == "id" { - a.required(false).required_unless_present("sideload") - } else { - a - } - .conflicts_with("sideload") - })) + .args( + QueryPackageParams::command() + .get_arguments() + .cloned() + .map(|a| { + if a.get_id() == "id" { + a.required(false).required_unless_present("sideload") + } else { + a + } + .conflicts_with("sideload") + }), + ) } fn command_for_update() -> clap::Command { Self::command() @@ -346,7 +312,9 @@ impl FromArgMatches for CliInstallParams { if let Some(sideload) = matches.get_one::("sideload") { Ok(Self::Sideload(sideload.clone())) } else { - Ok(Self::Marketplace(InstallParams::from_arg_matches(matches)?)) + Ok(Self::Marketplace(QueryPackageParams::from_arg_matches( + matches, + )?)) } } fn update_from_arg_matches(&mut self, matches: &clap::ArgMatches) -> Result<(), clap::Error> { @@ -355,6 +323,35 @@ impl FromArgMatches for CliInstallParams { } } +#[derive(Deserialize, Serialize, Parser, TS)] +#[ts(export)] +pub struct InstalledVersionParams { + id: PackageId, +} + +pub async fn installed_version( + ctx: RpcContext, + InstalledVersionParams { id }: InstalledVersionParams, +) -> Result, Error> { + if let Some(pde) = ctx + .db + .peek() + .await + .into_public() + .into_package_data() + .into_idx(&id) + { + Ok(Some( + pde.into_state_info() + .as_manifest(ManifestPreference::Old) + .as_version() + .de()?, + )) + } else { + Ok(None) + } +} + #[instrument(skip_all)] pub async fn cli_install( HandlerArgs { @@ -368,7 +365,7 @@ pub async fn cli_install( let method = parent_method.into_iter().chain(method).collect_vec(); match params { CliInstallParams::Sideload(path) => { - let file = crate::s9pk::load(&ctx, path).await?; + let file = open_file(path).await?; // rpc call remote sideload let SideloadResponse { upload, progress } = from_value::( @@ -435,9 +432,70 @@ pub async fn cli_install( progress?; upload?; } - CliInstallParams::Marketplace(params) => { - ctx.call_remote::(&method.join("."), to_value(¶ms)?) - .await?; + CliInstallParams::Marketplace(QueryPackageParams { id, version }) => { + let source_version: Option = from_value( + ctx.call_remote::("package.installed-version", json!({ "id": &id })) + .await?, + )?; + let mut packages: GetPackageResponse = from_value( + ctx.call_remote::( + "package.get", + json!({ "id": &id, "version": version, "sourceVersion": source_version }), + ) + .await?, + )?; + let version = if packages.best.len() == 1 { + packages.best.pop_first().map(|(k, _)| k).unwrap() + } else { + println!("Multiple flavors of {id} found. Please select one of the following versions to install:"); + let version; + loop { + let (mut read, mut output) = rustyline_async::Readline::new("> ".into()) + .with_kind(ErrorKind::Filesystem)?; + for (idx, version) in packages.best.keys().enumerate() { + output + .write_all(format!(" {}) {}\n", idx + 1, version).as_bytes()) + .await?; + read.add_history_entry(version.to_string()); + } + if let ReadlineEvent::Line(line) = read.readline().await? { + let trimmed = line.trim(); + match trimmed.parse() { + Ok(v) => { + if let Some((k, _)) = packages.best.remove_entry(&v) { + version = k; + break; + } + } + Err(_) => match trimmed.parse::() { + Ok(i) if (1..=packages.best.len()).contains(&i) => { + version = packages.best.keys().nth(i - 1).unwrap().clone(); + break; + } + _ => (), + }, + } + eprintln!("invalid selection: {trimmed}"); + println!("Please select one of the following versions to install:"); + } else { + return Err(Error::new( + eyre!("Could not determine precise version to install"), + ErrorKind::InvalidRequest, + ) + .into()); + } + } + version + }; + ctx.call_remote::( + &method.join("."), + to_value(&InstallParams { + id, + registry: ctx.registry_url.clone().or_not_found("--registry")?, + version, + })?, + ) + .await?; } } Ok(()) diff --git a/core/startos/src/lib.rs b/core/startos/src/lib.rs index 6e7cc8f8b..4882d998e 100644 --- a/core/startos/src/lib.rs +++ b/core/startos/src/lib.rs @@ -1,4 +1,4 @@ -pub const DEFAULT_MARKETPLACE: &str = "https://registry.start9.com"; +pub const DEFAULT_REGISTRY: &str = "https://registry.start9.com"; // pub const COMMUNITY_MARKETPLACE: &str = "https://community-registry.start9.com"; pub const HOST_IP: [u8; 4] = [172, 18, 0, 1]; pub use std::env::consts::ARCH; @@ -115,7 +115,7 @@ impl std::fmt::Display for ApiState { } pub fn main_api() -> ParentHandler { - ParentHandler::new() + let api = ParentHandler::new() .subcommand::("git-info", from_fn(version::git_info)) .subcommand( "echo", @@ -146,9 +146,11 @@ pub fn main_api() -> ParentHandler { ) .no_cli(), ) - .subcommand("lxc", lxc::lxc::()) .subcommand("s9pk", s9pk::rpc::s9pk()) - .subcommand("util", util::rpc::util::()) + .subcommand("util", util::rpc::util::()); + #[cfg(feature = "dev")] + let api = api.subcommand("lxc", lxc::dev::lxc::()); + api } pub fn server() -> ParentHandler { @@ -261,6 +263,12 @@ pub fn package() -> ParentHandler { .with_display_serializable() .with_call_remote::(), ) + .subcommand( + "installed-version", + from_fn_async(install::installed_version) + .with_display_serializable() + .with_call_remote::(), + ) .subcommand("config", config::config::()) .subcommand( "start", diff --git a/core/startos/src/lxc/dev.rs b/core/startos/src/lxc/dev.rs new file mode 100644 index 000000000..61dd8e598 --- /dev/null +++ b/core/startos/src/lxc/dev.rs @@ -0,0 +1,112 @@ +use std::ops::Deref; + +use clap::Parser; +use rpc_toolkit::{ + from_fn_async, CallRemoteHandler, Context, Empty, HandlerArgs, HandlerExt, HandlerFor, + ParentHandler, +}; +use serde::{Deserialize, Serialize}; +use ts_rs::TS; + +use crate::context::{CliContext, RpcContext}; +use crate::lxc::{ContainerId, LxcConfig}; +use crate::prelude::*; +use crate::rpc_continuations::Guid; + +pub fn lxc() -> ParentHandler { + ParentHandler::new() + .subcommand( + "create", + from_fn_async(create).with_call_remote::(), + ) + .subcommand( + "list", + from_fn_async(list) + .with_custom_display_fn(|_, res| { + use prettytable::*; + let mut table = table!([bc => "GUID"]); + for guid in res { + table.add_row(row![&*guid]); + } + table.printstd(); + Ok(()) + }) + .with_call_remote::(), + ) + .subcommand( + "remove", + from_fn_async(remove) + .no_display() + .with_call_remote::(), + ) + .subcommand("connect", from_fn_async(connect_rpc).no_cli()) + .subcommand("connect", from_fn_async(connect_rpc_cli).no_display()) +} + +pub async fn create(ctx: RpcContext) -> Result { + let container = ctx.lxc_manager.create(None, LxcConfig::default()).await?; + let guid = container.guid.deref().clone(); + ctx.dev.lxc.lock().await.insert(guid.clone(), container); + Ok(guid) +} + +pub async fn list(ctx: RpcContext) -> Result, Error> { + Ok(ctx.dev.lxc.lock().await.keys().cloned().collect()) +} + +#[derive(Deserialize, Serialize, Parser, TS)] +pub struct RemoveParams { + #[ts(type = "string")] + pub guid: ContainerId, +} + +pub async fn remove(ctx: RpcContext, RemoveParams { guid }: RemoveParams) -> Result<(), Error> { + if let Some(container) = ctx.dev.lxc.lock().await.remove(&guid) { + container.exit().await?; + } + Ok(()) +} + +#[derive(Deserialize, Serialize, Parser, TS)] +pub struct ConnectParams { + #[ts(type = "string")] + pub guid: ContainerId, +} + +pub async fn connect_rpc( + ctx: RpcContext, + ConnectParams { guid }: ConnectParams, +) -> Result { + super::connect( + &ctx, + ctx.dev.lxc.lock().await.get(&guid).ok_or_else(|| { + Error::new(eyre!("No container with guid: {guid}"), ErrorKind::NotFound) + })?, + ) + .await +} + +pub async fn connect_rpc_cli( + HandlerArgs { + context, + parent_method, + method, + params, + inherited_params, + raw_params, + }: HandlerArgs, +) -> Result<(), Error> { + let ctx = context.clone(); + let guid = CallRemoteHandler::::new(from_fn_async(connect_rpc)) + .handle_async(HandlerArgs { + context, + parent_method, + method, + params: rpc_toolkit::util::Flat(params, Empty {}), + inherited_params, + raw_params, + }) + .await?; + + super::connect_cli(&ctx, guid).await +} diff --git a/core/startos/src/lxc/mod.rs b/core/startos/src/lxc/mod.rs index 1f1424338..99f019d5a 100644 --- a/core/startos/src/lxc/mod.rs +++ b/core/startos/src/lxc/mod.rs @@ -1,23 +1,17 @@ use std::collections::BTreeSet; use std::net::Ipv4Addr; -use std::ops::Deref; use std::path::Path; use std::sync::{Arc, Weak}; use std::time::Duration; use clap::builder::ValueParserFactory; -use clap::Parser; use futures::{AsyncWriteExt, StreamExt}; use imbl_value::{InOMap, InternedString}; use models::InvalidId; -use rpc_toolkit::yajrc::{RpcError, RpcResponse}; -use rpc_toolkit::{ - from_fn_async, CallRemoteHandler, Context, Empty, GenericRpcMethod, HandlerArgs, HandlerExt, - HandlerFor, ParentHandler, RpcRequest, -}; +use rpc_toolkit::yajrc::RpcError; +use rpc_toolkit::{GenericRpcMethod, RpcRequest, RpcResponse}; use rustyline_async::{ReadlineEvent, SharedWriter}; use serde::{Deserialize, Serialize}; -use tokio::fs::File; use tokio::io::{AsyncBufReadExt, BufReader}; use tokio::process::Command; use tokio::sync::Mutex; @@ -35,9 +29,13 @@ use crate::disk::mount::util::unmount; use crate::prelude::*; use crate::rpc_continuations::{Guid, RpcContinuation}; use crate::util::clap::FromStrParser; +use crate::util::io::open_file; use crate::util::rpc_client::UnixRpcClient; use crate::util::{new_guid, Invoke}; +#[cfg(feature = "dev")] +pub mod dev; + const LXC_CONTAINER_DIR: &str = "/var/lib/lxc"; const RPC_DIR: &str = "media/startos/rpc"; // must not be absolute path pub const CONTAINER_RPC_SERVER_SOCKET: &str = "service.sock"; // must not be absolute path @@ -344,7 +342,7 @@ impl Drop for LxcContainer { if let Err(e) = async { let err_path = rootfs.path().join("var/log/containerRuntime.err"); if tokio::fs::metadata(&err_path).await.is_ok() { - let mut lines = BufReader::new(File::open(&err_path).await?).lines(); + let mut lines = BufReader::new(open_file(&err_path).await?).lines(); while let Some(line) = lines.next_line().await? { let container = &**guid; tracing::error!(container, "{}", line); @@ -373,80 +371,6 @@ impl Drop for LxcContainer { #[derive(Default, Serialize)] pub struct LxcConfig {} - -pub fn lxc() -> ParentHandler { - ParentHandler::new() - .subcommand( - "create", - from_fn_async(create).with_call_remote::(), - ) - .subcommand( - "list", - from_fn_async(list) - .with_custom_display_fn(|_, res| { - use prettytable::*; - let mut table = table!([bc => "GUID"]); - for guid in res { - table.add_row(row![&*guid]); - } - table.printstd(); - Ok(()) - }) - .with_call_remote::(), - ) - .subcommand( - "remove", - from_fn_async(remove) - .no_display() - .with_call_remote::(), - ) - .subcommand("connect", from_fn_async(connect_rpc).no_cli()) - .subcommand("connect", from_fn_async(connect_rpc_cli).no_display()) -} - -pub async fn create(ctx: RpcContext) -> Result { - let container = ctx.lxc_manager.create(None, LxcConfig::default()).await?; - let guid = container.guid.deref().clone(); - ctx.dev.lxc.lock().await.insert(guid.clone(), container); - Ok(guid) -} - -pub async fn list(ctx: RpcContext) -> Result, Error> { - Ok(ctx.dev.lxc.lock().await.keys().cloned().collect()) -} - -#[derive(Deserialize, Serialize, Parser, TS)] -pub struct RemoveParams { - #[ts(type = "string")] - pub guid: ContainerId, -} - -pub async fn remove(ctx: RpcContext, RemoveParams { guid }: RemoveParams) -> Result<(), Error> { - if let Some(container) = ctx.dev.lxc.lock().await.remove(&guid) { - container.exit().await?; - } - Ok(()) -} - -#[derive(Deserialize, Serialize, Parser, TS)] -pub struct ConnectParams { - #[ts(type = "string")] - pub guid: ContainerId, -} - -pub async fn connect_rpc( - ctx: RpcContext, - ConnectParams { guid }: ConnectParams, -) -> Result { - connect( - &ctx, - ctx.dev.lxc.lock().await.get(&guid).ok_or_else(|| { - Error::new(eyre!("No container with guid: {guid}"), ErrorKind::NotFound) - })?, - ) - .await -} - pub async fn connect(ctx: &RpcContext, container: &LxcContainer) -> Result { use axum::extract::ws::Message; @@ -476,11 +400,8 @@ pub async fn connect(ctx: &RpcContext, container: &LxcContainer) -> Result { - id, - result, - }) - .with_kind(ErrorKind::Serialization)?, + serde_json::to_string(&RpcResponse { id, result }) + .with_kind(ErrorKind::Serialization)?, )) .await .with_kind(ErrorKind::Network)?; @@ -614,28 +535,3 @@ pub async fn connect_cli(ctx: &CliContext, guid: Guid) -> Result<(), Error> { Ok(()) } - -pub async fn connect_rpc_cli( - HandlerArgs { - context, - parent_method, - method, - params, - inherited_params, - raw_params, - }: HandlerArgs, -) -> Result<(), Error> { - let ctx = context.clone(); - let guid = CallRemoteHandler::::new(from_fn_async(connect_rpc)) - .handle_async(HandlerArgs { - context, - parent_method, - method, - params: rpc_toolkit::util::Flat(params, Empty {}), - inherited_params, - raw_params, - }) - .await?; - - connect_cli(&ctx, guid).await -} diff --git a/core/startos/src/net/service_interface.rs b/core/startos/src/net/service_interface.rs index e905be545..dbe228ef2 100644 --- a/core/startos/src/net/service_interface.rs +++ b/core/startos/src/net/service_interface.rs @@ -5,8 +5,6 @@ use models::{HostId, ServiceInterfaceId}; use serde::{Deserialize, Serialize}; use ts_rs::TS; -use crate::net::host::address::HostAddress; - #[derive(Clone, Debug, Deserialize, Serialize, TS)] #[ts(export)] #[serde(rename_all = "camelCase")] diff --git a/core/startos/src/net/static_server.rs b/core/startos/src/net/static_server.rs index 7e8034d99..79adad504 100644 --- a/core/startos/src/net/static_server.rs +++ b/core/startos/src/net/static_server.rs @@ -19,7 +19,6 @@ use new_mime_guess::MimeGuess; use openssl::hash::MessageDigest; use openssl::x509::X509; use rpc_toolkit::{Context, HttpServer, Server}; -use tokio::fs::File; use tokio::io::BufReader; use tokio_util::io::ReaderStream; @@ -29,6 +28,7 @@ use crate::middleware::auth::{Auth, HasValidSession}; use crate::middleware::cors::Cors; use crate::middleware::db::SyncDb; use crate::rpc_continuations::{Guid, RpcContinuations}; +use crate::util::io::open_file; use crate::{ diagnostic_api, init_api, install_api, main_api, setup_api, Error, ErrorKind, ResultExt, }; @@ -44,8 +44,6 @@ const EMBEDDED_UIS: Dir<'_> = #[cfg(not(all(feature = "daemon", not(feature = "test"))))] const EMBEDDED_UIS: Dir<'_> = Dir::new("", &[]); -const PROXY_STRIP_HEADERS: &[&str] = &["cookie", "host", "origin", "referer", "user-agent"]; - #[derive(Clone)] pub enum UiMode { Setup, @@ -340,9 +338,8 @@ impl FileData { .any(|e| e == "gzip") .then_some("gzip"); - let file = File::open(path) - .await - .with_ctx(|_| (ErrorKind::Filesystem, path.display().to_string()))?; + let file = open_file(path) + .await?; let metadata = file .metadata() .await diff --git a/core/startos/src/net/utils.rs b/core/startos/src/net/utils.rs index 6de319a5e..9cba8a0cd 100644 --- a/core/startos/src/net/utils.rs +++ b/core/startos/src/net/utils.rs @@ -112,24 +112,6 @@ pub async fn find_eth_iface() -> Result { )) } -#[pin_project::pin_project] -pub struct SingleAccept(Option); -impl SingleAccept { - pub fn new(conn: T) -> Self { - Self(Some(conn)) - } -} -// impl axum_server::accept::Accept for SingleAccept { -// type Conn = T; -// type Error = Infallible; -// fn poll_accept( -// self: std::pin::Pin<&mut Self>, -// _cx: &mut std::task::Context<'_>, -// ) -> std::task::Poll>> { -// std::task::Poll::Ready(self.project().0.take().map(Ok)) -// } -// } - pub struct TcpListeners { listeners: Vec, } diff --git a/core/startos/src/net/vhost.rs b/core/startos/src/net/vhost.rs index b4f5715ae..e6a9d5b21 100644 --- a/core/startos/src/net/vhost.rs +++ b/core/startos/src/net/vhost.rs @@ -1,10 +1,15 @@ use std::collections::BTreeMap; use std::net::{IpAddr, Ipv6Addr, SocketAddr}; +use std::str::FromStr; use std::sync::{Arc, Weak}; use std::time::Duration; +use axum::body::Body; +use axum::extract::Request; +use axum::response::Response; use color_eyre::eyre::eyre; use helpers::NonDetachingJoinHandle; +use http::Uri; use imbl_value::InternedString; use models::ResultExt; use serde::{Deserialize, Serialize}; @@ -20,8 +25,9 @@ use tracing::instrument; use ts_rs::TS; use crate::db::model::Database; +use crate::net::static_server::server_error; use crate::prelude::*; -use crate::util::io::{BackTrackingReader, TimeoutStream}; +use crate::util::io::BackTrackingReader; use crate::util::serde::MaybeUtf8String; // not allowed: <=1024, >=32768, 5355, 5432, 9050, 6010, 9051, 5353 @@ -113,8 +119,16 @@ impl VHostServer { loop { match listener.accept().await { Ok((stream, _)) => { - let stream = - Box::pin(TimeoutStream::new(stream, Duration::from_secs(300))); + if let Err(e) = socket2::SockRef::from(&stream).set_tcp_keepalive( + &socket2::TcpKeepalive::new() + .with_time(Duration::from_secs(900)) + .with_interval(Duration::from_secs(60)) + .with_retries(5), + ) { + tracing::error!("Failed to set tcp keepalive: {e}"); + tracing::debug!("{e:?}"); + } + let mut stream = BackTrackingReader::new(stream); stream.start_buffering(); let mapping = mapping.clone(); @@ -129,38 +143,39 @@ impl VHostServer { { Ok(a) => a, Err(_) => { - // stream.rewind(); - // return hyper::server::Server::builder( - // SingleAccept::new(stream), - // ) - // .serve(make_service_fn(|_| async { - // Ok::<_, Infallible>(service_fn(|req| async move { - // let host = req - // .headers() - // .get(http::header::HOST) - // .and_then(|host| host.to_str().ok()); - // let uri = Uri::from_parts({ - // let mut parts = - // req.uri().to_owned().into_parts(); - // parts.authority = host - // .map(FromStr::from_str) - // .transpose()?; - // parts - // })?; - // Response::builder() - // .status( - // http::StatusCode::TEMPORARY_REDIRECT, - // ) - // .header( - // http::header::LOCATION, - // uri.to_string(), - // ) - // .body(Body::default()) - // })) - // })) - // .await - // .with_kind(crate::ErrorKind::Network); - todo!() + stream.rewind(); + return hyper_util::server::conn::auto::Builder::new(hyper_util::rt::TokioExecutor::new()) + .serve_connection( + hyper_util::rt::TokioIo::new(stream), + hyper_util::service::TowerToHyperService::new(axum::Router::new().fallback( + axum::routing::method_routing::any(move |req: Request| async move { + match async move { + let host = req + .headers() + .get(http::header::HOST) + .and_then(|host| host.to_str().ok()); + let uri = Uri::from_parts({ + let mut parts = req.uri().to_owned().into_parts(); + parts.authority = host.map(FromStr::from_str).transpose()?; + parts + })?; + Response::builder() + .status(http::StatusCode::TEMPORARY_REDIRECT) + .header(http::header::LOCATION, uri.to_string()) + .body(Body::default()) + }.await { + Ok(a) => a, + Err(e) => { + tracing::warn!("Error redirecting http request on ssl port: {e}"); + tracing::error!("{e:?}"); + server_error(Error::new(e, ErrorKind::Network)) + } + } + }), + )), + ) + .await + .map_err(|e| Error::new(color_eyre::eyre::Report::msg(e), ErrorKind::Network)); } }; let target_name = diff --git a/core/startos/src/notifications.rs b/core/startos/src/notifications.rs index fde3d5e80..c99ffb356 100644 --- a/core/startos/src/notifications.rs +++ b/core/startos/src/notifications.rs @@ -74,6 +74,7 @@ pub async fn list( .as_notifications() .as_entries()? .into_iter() + .rev() .take(limit); let notifs = records .into_iter() @@ -97,6 +98,7 @@ pub async fn list( .as_entries()? .into_iter() .filter(|(id, _)| *id < before) + .rev() .take(limit); records .into_iter() diff --git a/core/startos/src/os_install/mod.rs b/core/startos/src/os_install/mod.rs index 4e5c7ed15..28fd2a3be 100644 --- a/core/startos/src/os_install/mod.rs +++ b/core/startos/src/os_install/mod.rs @@ -21,7 +21,7 @@ use crate::disk::OsPartitionInfo; use crate::net::utils::find_eth_iface; use crate::prelude::*; use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile; -use crate::util::io::TmpDir; +use crate::util::io::{open_file, TmpDir}; use crate::util::serde::IoFormat; use crate::util::Invoke; use crate::ARCH; @@ -241,12 +241,10 @@ pub async fn execute( tokio::fs::create_dir_all(&images_path).await?; let image_path = images_path .join(hex::encode( - &MultiCursorFile::from( - tokio::fs::File::open("/run/live/medium/live/filesystem.squashfs").await?, - ) - .blake3_mmap() - .await? - .as_bytes()[..16], + &MultiCursorFile::from(open_file("/run/live/medium/live/filesystem.squashfs").await?) + .blake3_mmap() + .await? + .as_bytes()[..16], )) .with_extension("rootfs"); tokio::fs::copy("/run/live/medium/live/filesystem.squashfs", &image_path).await?; diff --git a/core/startos/src/registry/asset.rs b/core/startos/src/registry/asset.rs index ea37b2309..ab251d2aa 100644 --- a/core/startos/src/registry/asset.rs +++ b/core/startos/src/registry/asset.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::sync::Arc; use reqwest::Client; use serde::{Deserialize, Serialize}; @@ -7,10 +8,13 @@ use ts_rs::TS; use url::Url; use crate::prelude::*; +use crate::registry::signer::commitment::merkle_archive::MerkleArchiveCommitment; use crate::registry::signer::commitment::{Commitment, Digestable}; use crate::registry::signer::sign::{AnySignature, AnyVerifyingKey}; use crate::registry::signer::AcceptSigners; use crate::s9pk::merkle_archive::source::http::HttpSource; +use crate::s9pk::merkle_archive::source::Section; +use crate::s9pk::S9pk; #[derive(Debug, Deserialize, Serialize, TS)] #[serde(rename_all = "camelCase")] @@ -52,3 +56,15 @@ impl Commitment<&'a HttpSource>> RegistryAsset { .await } } +impl RegistryAsset { + pub async fn deserialize_s9pk( + &self, + client: Client, + ) -> Result>>, Error> { + S9pk::deserialize( + &Arc::new(HttpSource::new(client, self.url.clone()).await?), + Some(&self.commitment), + ) + .await + } +} diff --git a/core/startos/src/registry/context.rs b/core/startos/src/registry/context.rs index e5beabca7..64a157073 100644 --- a/core/startos/src/registry/context.rs +++ b/core/startos/src/registry/context.rs @@ -10,6 +10,7 @@ use reqwest::{Client, Proxy}; use rpc_toolkit::yajrc::RpcError; use rpc_toolkit::{CallRemote, Context, Empty}; use serde::{Deserialize, Serialize}; +use sqlx::PgPool; use tokio::sync::broadcast::Sender; use tracing::instrument; use url::Url; @@ -32,17 +33,22 @@ pub struct RegistryConfig { #[arg(short = 'l', long = "listen")] pub listen: Option, #[arg(short = 'h', long = "hostname")] - pub hostname: InternedString, - #[arg(short = 'p', long = "proxy")] + pub hostname: Option, + #[arg(short = 'p', long = "tor-proxy")] pub tor_proxy: Option, #[arg(short = 'd', long = "datadir")] pub datadir: Option, + #[arg(short = 'u', long = "pg-connection-url")] + pub pg_connection_url: Option, } impl ContextConfig for RegistryConfig { fn next(&mut self) -> Option { self.config.take() } fn merge_with(&mut self, other: Self) { + self.listen = self.listen.take().or(other.listen); + self.hostname = self.hostname.take().or(other.hostname); + self.tor_proxy = self.tor_proxy.take().or(other.tor_proxy); self.datadir = self.datadir.take().or(other.datadir); } } @@ -64,6 +70,7 @@ pub struct RegistryContextSeed { pub rpc_continuations: RpcContinuations, pub client: Client, pub shutdown: Sender<()>, + pub pool: Option, } #[derive(Clone)] @@ -91,8 +98,24 @@ impl RegistryContext { .clone() .map(Ok) .unwrap_or_else(|| "socks5h://localhost:9050".parse())?; + let pool: Option = match &config.pg_connection_url { + Some(url) => match PgPool::connect(url.as_str()).await { + Ok(pool) => Some(pool), + Err(_) => None, + }, + None => None, + }; Ok(Self(Arc::new(RegistryContextSeed { - hostname: config.hostname.clone(), + hostname: config + .hostname + .as_ref() + .ok_or_else(|| { + Error::new( + eyre!("missing required configuration: hostname"), + ErrorKind::NotFound, + ) + })? + .clone(), listen: config .listen .unwrap_or(SocketAddr::new(Ipv4Addr::LOCALHOST.into(), 5959)), @@ -110,6 +133,7 @@ impl RegistryContext { .build() .with_kind(crate::ErrorKind::ParseUrl)?, shutdown, + pool, }))) } } diff --git a/core/startos/src/registry/device_info.rs b/core/startos/src/registry/device_info.rs index 51d6ac46b..9a357358a 100644 --- a/core/startos/src/registry/device_info.rs +++ b/core/startos/src/registry/device_info.rs @@ -4,7 +4,7 @@ use std::ops::Deref; use axum::extract::Request; use axum::response::Response; -use emver::{Version, VersionRange}; +use exver::{Version, VersionRange}; use http::HeaderValue; use imbl_value::InternedString; use rpc_toolkit::{Middleware, RpcRequest, RpcResponse}; diff --git a/core/startos/src/registry/metrics-db/registry-sqlx-data.sh b/core/startos/src/registry/metrics-db/registry-sqlx-data.sh new file mode 100755 index 000000000..2b24873a4 --- /dev/null +++ b/core/startos/src/registry/metrics-db/registry-sqlx-data.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +cd "$(dirname "${BASH_SOURCE[0]}")" +TMP_DIR=$(mktemp -d) +mkdir $TMP_DIR/pgdata +docker run -d --rm --name=tmp_postgres -e POSTGRES_PASSWORD=password -v $TMP_DIR/pgdata:/var/lib/postgresql/data postgres + +( + set -e + ctr=0 + until docker exec tmp_postgres psql -U postgres 2> /dev/null || [ $ctr -ge 5 ]; do + ctr=$[ctr + 1] + sleep 5; + done + + PG_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' tmp_postgres) + + cat "./registry_schema.sql" | docker exec -i tmp_postgres psql -U postgres -d postgres -f- + cd ../../.. + DATABASE_URL=postgres://postgres:password@$PG_IP/postgres PLATFORM=$(uname -m) cargo sqlx prepare -- --lib --profile=test --workspace + echo "Subscript Complete" +) + +docker stop tmp_postgres +sudo rm -rf $TMP_DIR diff --git a/core/startos/src/registry/metrics-db/registry_schema.sql b/core/startos/src/registry/metrics-db/registry_schema.sql new file mode 100644 index 000000000..abd9f4ea6 --- /dev/null +++ b/core/startos/src/registry/metrics-db/registry_schema.sql @@ -0,0 +1,828 @@ +-- +-- PostgreSQL database dump +-- + +-- Dumped from database version 14.12 (Ubuntu 14.12-0ubuntu0.22.04.1) +-- Dumped by pg_dump version 14.12 (Ubuntu 14.12-0ubuntu0.22.04.1) + +SET statement_timeout = 0; +SET lock_timeout = 0; +SET idle_in_transaction_session_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET xmloption = content; +SET client_min_messages = warning; +SET row_security = off; + +SET default_tablespace = ''; + +SET default_table_access_method = heap; + +-- +-- Name: admin; Type: TABLE; Schema: public; Owner: alpha_admin +-- + +CREATE TABLE public.admin ( + id character varying NOT NULL, + created_at timestamp with time zone NOT NULL, + pass_hash character varying NOT NULL, + deleted_at timestamp with time zone +); + + +ALTER TABLE public.admin OWNER TO alpha_admin; + +-- +-- Name: admin_pkgs; Type: TABLE; Schema: public; Owner: alpha_admin +-- + +CREATE TABLE public.admin_pkgs ( + id bigint NOT NULL, + admin character varying NOT NULL, + pkg_id character varying NOT NULL +); + + +ALTER TABLE public.admin_pkgs OWNER TO alpha_admin; + +-- +-- Name: admin_pkgs_id_seq; Type: SEQUENCE; Schema: public; Owner: alpha_admin +-- + +CREATE SEQUENCE public.admin_pkgs_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.admin_pkgs_id_seq OWNER TO alpha_admin; + +-- +-- Name: admin_pkgs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: alpha_admin +-- + +ALTER SEQUENCE public.admin_pkgs_id_seq OWNED BY public.admin_pkgs.id; + + +-- +-- Name: category; Type: TABLE; Schema: public; Owner: alpha_admin +-- + +CREATE TABLE public.category ( + id bigint NOT NULL, + created_at timestamp with time zone NOT NULL, + name character varying NOT NULL, + description character varying NOT NULL, + priority bigint DEFAULT 0 NOT NULL +); + + +ALTER TABLE public.category OWNER TO alpha_admin; + +-- +-- Name: category_id_seq; Type: SEQUENCE; Schema: public; Owner: alpha_admin +-- + +CREATE SEQUENCE public.category_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.category_id_seq OWNER TO alpha_admin; + +-- +-- Name: category_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: alpha_admin +-- + +ALTER SEQUENCE public.category_id_seq OWNED BY public.category.id; + + +-- +-- Name: eos_hash; Type: TABLE; Schema: public; Owner: alpha_admin +-- + +CREATE TABLE public.eos_hash ( + id bigint NOT NULL, + version character varying NOT NULL, + hash character varying NOT NULL +); + + +ALTER TABLE public.eos_hash OWNER TO alpha_admin; + +-- +-- Name: eos_hash_id_seq; Type: SEQUENCE; Schema: public; Owner: alpha_admin +-- + +CREATE SEQUENCE public.eos_hash_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.eos_hash_id_seq OWNER TO alpha_admin; + +-- +-- Name: eos_hash_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: alpha_admin +-- + +ALTER SEQUENCE public.eos_hash_id_seq OWNED BY public.eos_hash.id; + + +-- +-- Name: error_log_record; Type: TABLE; Schema: public; Owner: alpha_admin +-- + +CREATE TABLE public.error_log_record ( + id bigint NOT NULL, + created_at timestamp with time zone NOT NULL, + epoch character varying NOT NULL, + commit_hash character varying NOT NULL, + source_file character varying NOT NULL, + line bigint NOT NULL, + target character varying NOT NULL, + level character varying NOT NULL, + message character varying NOT NULL, + incidents bigint NOT NULL +); + + +ALTER TABLE public.error_log_record OWNER TO alpha_admin; + +-- +-- Name: error_log_record_id_seq; Type: SEQUENCE; Schema: public; Owner: alpha_admin +-- + +CREATE SEQUENCE public.error_log_record_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.error_log_record_id_seq OWNER TO alpha_admin; + +-- +-- Name: error_log_record_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: alpha_admin +-- + +ALTER SEQUENCE public.error_log_record_id_seq OWNED BY public.error_log_record.id; + + +-- +-- Name: metric; Type: TABLE; Schema: public; Owner: alpha_admin +-- + +CREATE TABLE public.metric ( + id bigint NOT NULL, + created_at timestamp with time zone NOT NULL, + version character varying NOT NULL, + pkg_id character varying NOT NULL +); + + +ALTER TABLE public.metric OWNER TO alpha_admin; + +-- +-- Name: metric_id_seq; Type: SEQUENCE; Schema: public; Owner: alpha_admin +-- + +CREATE SEQUENCE public.metric_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.metric_id_seq OWNER TO alpha_admin; + +-- +-- Name: metric_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: alpha_admin +-- + +ALTER SEQUENCE public.metric_id_seq OWNED BY public.metric.id; + + +-- +-- Name: os_version; Type: TABLE; Schema: public; Owner: alpha_admin +-- + +CREATE TABLE public.os_version ( + id bigint NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL, + number character varying NOT NULL, + headline character varying NOT NULL, + release_notes character varying NOT NULL, + arch character varying +); + + +ALTER TABLE public.os_version OWNER TO alpha_admin; + +-- +-- Name: os_version_id_seq; Type: SEQUENCE; Schema: public; Owner: alpha_admin +-- + +CREATE SEQUENCE public.os_version_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.os_version_id_seq OWNER TO alpha_admin; + +-- +-- Name: os_version_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: alpha_admin +-- + +ALTER SEQUENCE public.os_version_id_seq OWNED BY public.os_version.id; + + +-- +-- Name: persistent_migration; Type: TABLE; Schema: public; Owner: alpha_admin +-- + +CREATE TABLE public.persistent_migration ( + id integer NOT NULL, + version integer NOT NULL, + label character varying, + "timestamp" timestamp with time zone NOT NULL +); + + +ALTER TABLE public.persistent_migration OWNER TO alpha_admin; + +-- +-- Name: persistent_migration_id_seq; Type: SEQUENCE; Schema: public; Owner: alpha_admin +-- + +CREATE SEQUENCE public.persistent_migration_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.persistent_migration_id_seq OWNER TO alpha_admin; + +-- +-- Name: persistent_migration_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: alpha_admin +-- + +ALTER SEQUENCE public.persistent_migration_id_seq OWNED BY public.persistent_migration.id; + + +-- +-- Name: pkg_category; Type: TABLE; Schema: public; Owner: alpha_admin +-- + +CREATE TABLE public.pkg_category ( + id bigint NOT NULL, + created_at timestamp with time zone NOT NULL, + category_id bigint NOT NULL, + pkg_id character varying NOT NULL +); + + +ALTER TABLE public.pkg_category OWNER TO alpha_admin; + +-- +-- Name: pkg_dependency; Type: TABLE; Schema: public; Owner: alpha_admin +-- + +CREATE TABLE public.pkg_dependency ( + id bigint NOT NULL, + created_at timestamp with time zone NOT NULL, + pkg_id character varying NOT NULL, + pkg_version character varying NOT NULL, + dep_id character varying NOT NULL, + dep_version_range character varying NOT NULL +); + + +ALTER TABLE public.pkg_dependency OWNER TO alpha_admin; + +-- +-- Name: pkg_dependency_id_seq; Type: SEQUENCE; Schema: public; Owner: alpha_admin +-- + +CREATE SEQUENCE public.pkg_dependency_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.pkg_dependency_id_seq OWNER TO alpha_admin; + +-- +-- Name: pkg_dependency_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: alpha_admin +-- + +ALTER SEQUENCE public.pkg_dependency_id_seq OWNED BY public.pkg_dependency.id; + + +-- +-- Name: pkg_record; Type: TABLE; Schema: public; Owner: alpha_admin +-- + +CREATE TABLE public.pkg_record ( + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone, + pkg_id character varying NOT NULL, + hidden boolean DEFAULT false NOT NULL +); + + +ALTER TABLE public.pkg_record OWNER TO alpha_admin; + +-- +-- Name: service_category_id_seq; Type: SEQUENCE; Schema: public; Owner: alpha_admin +-- + +CREATE SEQUENCE public.service_category_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.service_category_id_seq OWNER TO alpha_admin; + +-- +-- Name: service_category_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: alpha_admin +-- + +ALTER SEQUENCE public.service_category_id_seq OWNED BY public.pkg_category.id; + + +-- +-- Name: upload; Type: TABLE; Schema: public; Owner: alpha_admin +-- + +CREATE TABLE public.upload ( + id bigint NOT NULL, + uploader character varying NOT NULL, + pkg_id character varying NOT NULL, + pkg_version character varying NOT NULL, + created_at timestamp with time zone NOT NULL +); + + +ALTER TABLE public.upload OWNER TO alpha_admin; + +-- +-- Name: upload_id_seq; Type: SEQUENCE; Schema: public; Owner: alpha_admin +-- + +CREATE SEQUENCE public.upload_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.upload_id_seq OWNER TO alpha_admin; + +-- +-- Name: upload_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: alpha_admin +-- + +ALTER SEQUENCE public.upload_id_seq OWNED BY public.upload.id; + + +-- +-- Name: user_activity; Type: TABLE; Schema: public; Owner: alpha_admin +-- + +CREATE TABLE public.user_activity ( + id bigint NOT NULL, + created_at timestamp with time zone NOT NULL, + server_id character varying NOT NULL, + os_version character varying, + arch character varying +); + + +ALTER TABLE public.user_activity OWNER TO alpha_admin; + +-- +-- Name: user_activity_id_seq; Type: SEQUENCE; Schema: public; Owner: alpha_admin +-- + +CREATE SEQUENCE public.user_activity_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER TABLE public.user_activity_id_seq OWNER TO alpha_admin; + +-- +-- Name: user_activity_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: alpha_admin +-- + +ALTER SEQUENCE public.user_activity_id_seq OWNED BY public.user_activity.id; + + +-- +-- Name: version; Type: TABLE; Schema: public; Owner: alpha_admin +-- + +CREATE TABLE public.version ( + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone, + number character varying NOT NULL, + release_notes character varying NOT NULL, + os_version character varying NOT NULL, + pkg_id character varying NOT NULL, + title character varying NOT NULL, + desc_short character varying NOT NULL, + desc_long character varying NOT NULL, + icon_type character varying NOT NULL, + deprecated_at timestamp with time zone +); + + +ALTER TABLE public.version OWNER TO alpha_admin; + +-- +-- Name: version_platform; Type: TABLE; Schema: public; Owner: alpha_admin +-- + +CREATE TABLE public.version_platform ( + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone, + pkg_id character varying NOT NULL, + version_number character varying NOT NULL, + arch character varying NOT NULL, + ram bigint, + device jsonb +); + + +ALTER TABLE public.version_platform OWNER TO alpha_admin; + +-- +-- Name: admin_pkgs id; Type: DEFAULT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.admin_pkgs ALTER COLUMN id SET DEFAULT nextval('public.admin_pkgs_id_seq'::regclass); + + +-- +-- Name: category id; Type: DEFAULT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.category ALTER COLUMN id SET DEFAULT nextval('public.category_id_seq'::regclass); + + +-- +-- Name: eos_hash id; Type: DEFAULT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.eos_hash ALTER COLUMN id SET DEFAULT nextval('public.eos_hash_id_seq'::regclass); + + +-- +-- Name: error_log_record id; Type: DEFAULT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.error_log_record ALTER COLUMN id SET DEFAULT nextval('public.error_log_record_id_seq'::regclass); + + +-- +-- Name: metric id; Type: DEFAULT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.metric ALTER COLUMN id SET DEFAULT nextval('public.metric_id_seq'::regclass); + + +-- +-- Name: os_version id; Type: DEFAULT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.os_version ALTER COLUMN id SET DEFAULT nextval('public.os_version_id_seq'::regclass); + + +-- +-- Name: persistent_migration id; Type: DEFAULT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.persistent_migration ALTER COLUMN id SET DEFAULT nextval('public.persistent_migration_id_seq'::regclass); + + +-- +-- Name: pkg_category id; Type: DEFAULT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.pkg_category ALTER COLUMN id SET DEFAULT nextval('public.service_category_id_seq'::regclass); + + +-- +-- Name: pkg_dependency id; Type: DEFAULT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.pkg_dependency ALTER COLUMN id SET DEFAULT nextval('public.pkg_dependency_id_seq'::regclass); + + +-- +-- Name: upload id; Type: DEFAULT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.upload ALTER COLUMN id SET DEFAULT nextval('public.upload_id_seq'::regclass); + + +-- +-- Name: user_activity id; Type: DEFAULT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.user_activity ALTER COLUMN id SET DEFAULT nextval('public.user_activity_id_seq'::regclass); + + +-- +-- Name: admin admin_pkey; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.admin + ADD CONSTRAINT admin_pkey PRIMARY KEY (id); + + +-- +-- Name: admin_pkgs admin_pkgs_pkey; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.admin_pkgs + ADD CONSTRAINT admin_pkgs_pkey PRIMARY KEY (id); + + +-- +-- Name: category category_pkey; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.category + ADD CONSTRAINT category_pkey PRIMARY KEY (id); + + +-- +-- Name: eos_hash eos_hash_pkey; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.eos_hash + ADD CONSTRAINT eos_hash_pkey PRIMARY KEY (id); + + +-- +-- Name: error_log_record error_log_record_pkey; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.error_log_record + ADD CONSTRAINT error_log_record_pkey PRIMARY KEY (id); + + +-- +-- Name: metric metric_pkey; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.metric + ADD CONSTRAINT metric_pkey PRIMARY KEY (id); + + +-- +-- Name: os_version os_version_pkey; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.os_version + ADD CONSTRAINT os_version_pkey PRIMARY KEY (id); + + +-- +-- Name: persistent_migration persistent_migration_pkey; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.persistent_migration + ADD CONSTRAINT persistent_migration_pkey PRIMARY KEY (id); + + +-- +-- Name: pkg_category pkg_category_pkey; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.pkg_category + ADD CONSTRAINT pkg_category_pkey PRIMARY KEY (id); + + +-- +-- Name: pkg_dependency pkg_dependency_pkey; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.pkg_dependency + ADD CONSTRAINT pkg_dependency_pkey PRIMARY KEY (id); + + +-- +-- Name: admin_pkgs unique_admin_pkg; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.admin_pkgs + ADD CONSTRAINT unique_admin_pkg UNIQUE (pkg_id, admin); + + +-- +-- Name: error_log_record unique_log_record; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.error_log_record + ADD CONSTRAINT unique_log_record UNIQUE (epoch, commit_hash, source_file, line, target, level, message); + + +-- +-- Name: category unique_name; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.category + ADD CONSTRAINT unique_name UNIQUE (name); + + +-- +-- Name: pkg_category unique_pkg_category; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.pkg_category + ADD CONSTRAINT unique_pkg_category UNIQUE (pkg_id, category_id); + + +-- +-- Name: pkg_dependency unique_pkg_dep_version; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.pkg_dependency + ADD CONSTRAINT unique_pkg_dep_version UNIQUE (pkg_id, pkg_version, dep_id); + + +-- +-- Name: eos_hash unique_version; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.eos_hash + ADD CONSTRAINT unique_version UNIQUE (version); + + +-- +-- Name: upload upload_pkey; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.upload + ADD CONSTRAINT upload_pkey PRIMARY KEY (id); + + +-- +-- Name: user_activity user_activity_pkey; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.user_activity + ADD CONSTRAINT user_activity_pkey PRIMARY KEY (id); + + +-- +-- Name: version version_pkey; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.version + ADD CONSTRAINT version_pkey PRIMARY KEY (pkg_id, number); + + +-- +-- Name: version_platform version_platform_pkey; Type: CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.version_platform + ADD CONSTRAINT version_platform_pkey PRIMARY KEY (pkg_id, version_number, arch); + + +-- +-- Name: category_name_idx; Type: INDEX; Schema: public; Owner: alpha_admin +-- + +CREATE UNIQUE INDEX category_name_idx ON public.category USING btree (name); + + +-- +-- Name: pkg_record_pkg_id_idx; Type: INDEX; Schema: public; Owner: alpha_admin +-- + +CREATE UNIQUE INDEX pkg_record_pkg_id_idx ON public.pkg_record USING btree (pkg_id); + + +-- +-- Name: version_number_idx; Type: INDEX; Schema: public; Owner: alpha_admin +-- + +CREATE INDEX version_number_idx ON public.version USING btree (number); + + +-- +-- Name: admin_pkgs admin_pkgs_admin_fkey; Type: FK CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.admin_pkgs + ADD CONSTRAINT admin_pkgs_admin_fkey FOREIGN KEY (admin) REFERENCES public.admin(id) ON UPDATE RESTRICT ON DELETE RESTRICT; + + +-- +-- Name: metric metric_pkg_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.metric + ADD CONSTRAINT metric_pkg_id_fkey FOREIGN KEY (pkg_id) REFERENCES public.pkg_record(pkg_id) ON UPDATE RESTRICT ON DELETE RESTRICT; + + +-- +-- Name: pkg_category pkg_category_category_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.pkg_category + ADD CONSTRAINT pkg_category_category_id_fkey FOREIGN KEY (category_id) REFERENCES public.category(id) ON UPDATE RESTRICT ON DELETE RESTRICT; + + +-- +-- Name: pkg_category pkg_category_pkg_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.pkg_category + ADD CONSTRAINT pkg_category_pkg_id_fkey FOREIGN KEY (pkg_id) REFERENCES public.pkg_record(pkg_id) ON UPDATE RESTRICT ON DELETE RESTRICT; + + +-- +-- Name: pkg_dependency pkg_dependency_dep_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.pkg_dependency + ADD CONSTRAINT pkg_dependency_dep_id_fkey FOREIGN KEY (dep_id) REFERENCES public.pkg_record(pkg_id) ON UPDATE RESTRICT ON DELETE RESTRICT; + + +-- +-- Name: pkg_dependency pkg_dependency_pkg_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.pkg_dependency + ADD CONSTRAINT pkg_dependency_pkg_id_fkey FOREIGN KEY (pkg_id) REFERENCES public.pkg_record(pkg_id) ON UPDATE RESTRICT ON DELETE RESTRICT; + + +-- +-- Name: upload upload_pkg_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.upload + ADD CONSTRAINT upload_pkg_id_fkey FOREIGN KEY (pkg_id) REFERENCES public.pkg_record(pkg_id) ON UPDATE RESTRICT ON DELETE RESTRICT; + + +-- +-- Name: upload upload_uploader_fkey; Type: FK CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.upload + ADD CONSTRAINT upload_uploader_fkey FOREIGN KEY (uploader) REFERENCES public.admin(id) ON UPDATE RESTRICT ON DELETE RESTRICT; + + +-- +-- Name: version version_pkg_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.version + ADD CONSTRAINT version_pkg_id_fkey FOREIGN KEY (pkg_id) REFERENCES public.pkg_record(pkg_id) ON UPDATE RESTRICT ON DELETE RESTRICT; + + +-- +-- Name: version_platform version_platform_pkg_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: alpha_admin +-- + +ALTER TABLE ONLY public.version_platform + ADD CONSTRAINT version_platform_pkg_id_fkey FOREIGN KEY (pkg_id) REFERENCES public.pkg_record(pkg_id) ON UPDATE RESTRICT ON DELETE RESTRICT; + + +-- +-- PostgreSQL database dump complete +-- + diff --git a/core/startos/src/registry/mod.rs b/core/startos/src/registry/mod.rs index 9a53d6338..1039264df 100644 --- a/core/startos/src/registry/mod.rs +++ b/core/startos/src/registry/mod.rs @@ -1,5 +1,4 @@ use std::collections::{BTreeMap, BTreeSet}; -use std::net::SocketAddr; use axum::Router; use futures::future::ready; diff --git a/core/startos/src/registry/os/asset/add.rs b/core/startos/src/registry/os/asset/add.rs index 33f5ef90f..6108dd5bc 100644 --- a/core/startos/src/registry/os/asset/add.rs +++ b/core/startos/src/registry/os/asset/add.rs @@ -3,7 +3,6 @@ use std::panic::UnwindSafe; use std::path::PathBuf; use clap::Parser; -use helpers::NonDetachingJoinHandle; use imbl_value::InternedString; use itertools::Itertools; use rpc_toolkit::{from_fn_async, Context, HandlerArgs, HandlerExt, ParentHandler}; @@ -13,7 +12,7 @@ use url::Url; use crate::context::CliContext; use crate::prelude::*; -use crate::progress::{FullProgressTracker, PhasedProgressBar}; +use crate::progress::{FullProgressTracker}; use crate::registry::asset::RegistryAsset; use crate::registry::context::RegistryContext; use crate::registry::os::index::OsVersionInfo; @@ -25,6 +24,7 @@ use crate::s9pk::merkle_archive::hash::VerifyingWriter; use crate::s9pk::merkle_archive::source::http::HttpSource; use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile; use crate::s9pk::merkle_archive::source::ArchiveSource; +use crate::util::io::open_file; use crate::util::serde::Base64; use crate::util::VersionString; @@ -184,7 +184,7 @@ pub async fn cli_add_asset( } }; - let file = MultiCursorFile::from(tokio::fs::File::open(&path).await?); + let file = MultiCursorFile::from(open_file(&path).await?); let progress = FullProgressTracker::new(); let mut sign_phase = progress.add_phase(InternedString::intern("Signing File"), Some(10)); diff --git a/core/startos/src/registry/os/asset/get.rs b/core/startos/src/registry/os/asset/get.rs index 29ff24da6..b185cf6a4 100644 --- a/core/startos/src/registry/os/asset/get.rs +++ b/core/startos/src/registry/os/asset/get.rs @@ -20,6 +20,7 @@ use crate::registry::os::SIG_CONTEXT; use crate::registry::signer::commitment::blake3::Blake3Commitment; use crate::registry::signer::commitment::Commitment; use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile; +use crate::util::io::open_file; use crate::util::VersionString; pub fn get_api() -> ParentHandler { @@ -158,9 +159,7 @@ async fn cli_get_os_asset( if let Some(mut reverify_phase) = reverify_phase { reverify_phase.start(); res.commitment - .check(&MultiCursorFile::from( - tokio::fs::File::open(download).await?, - )) + .check(&MultiCursorFile::from(open_file(download).await?)) .await?; reverify_phase.complete(); } diff --git a/core/startos/src/registry/os/asset/sign.rs b/core/startos/src/registry/os/asset/sign.rs index 50c583593..8bf1cfeb5 100644 --- a/core/startos/src/registry/os/asset/sign.rs +++ b/core/startos/src/registry/os/asset/sign.rs @@ -21,6 +21,7 @@ use crate::registry::signer::sign::ed25519::Ed25519; use crate::registry::signer::sign::{AnySignature, AnyVerifyingKey, SignatureScheme}; use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile; use crate::s9pk::merkle_archive::source::ArchiveSource; +use crate::util::io::open_file; use crate::util::serde::Base64; use crate::util::VersionString; @@ -166,7 +167,7 @@ pub async fn cli_sign_asset( } }; - let file = MultiCursorFile::from(tokio::fs::File::open(&path).await?); + let file = MultiCursorFile::from(open_file(&path).await?); let progress = FullProgressTracker::new(); let mut sign_phase = progress.add_phase(InternedString::intern("Signing File"), Some(10)); diff --git a/core/startos/src/registry/os/index.rs b/core/startos/src/registry/os/index.rs index 3ee75bc6a..0b1ca5b89 100644 --- a/core/startos/src/registry/os/index.rs +++ b/core/startos/src/registry/os/index.rs @@ -1,6 +1,6 @@ use std::collections::{BTreeMap, BTreeSet}; -use emver::VersionRange; +use exver::VersionRange; use imbl_value::InternedString; use serde::{Deserialize, Serialize}; use ts_rs::TS; diff --git a/core/startos/src/registry/os/version/mod.rs b/core/startos/src/registry/os/version/mod.rs index 5bf926e5e..9ebe8a696 100644 --- a/core/startos/src/registry/os/version/mod.rs +++ b/core/startos/src/registry/os/version/mod.rs @@ -1,10 +1,12 @@ use std::collections::BTreeMap; +use chrono::Utc; use clap::Parser; -use emver::VersionRange; +use exver::VersionRange; use itertools::Itertools; use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler}; use serde::{Deserialize, Serialize}; +use sqlx::query; use ts_rs::TS; use crate::context::CliContext; @@ -126,12 +128,35 @@ pub struct GetVersionParams { #[ts(type = "string | null")] #[arg(long = "target")] pub target: Option, + #[ts(type = "string | null")] + #[arg(long = "id")] + server_id: Option, + #[ts(type = "string | null")] + #[arg(long = "arch")] + arch: Option, } pub async fn get_version( ctx: RegistryContext, - GetVersionParams { source, target }: GetVersionParams, + GetVersionParams { + source, + target, + server_id, + arch, + }: GetVersionParams, ) -> Result, Error> { + if let (Some(pool), Some(server_id), Some(arch)) = (&ctx.pool, server_id, arch) { + let created_at = Utc::now(); + + query!( + "INSERT INTO user_activity (created_at, server_id, arch) VALUES ($1, $2, $3)", + created_at, + server_id, + arch + ) + .execute(pool) + .await?; + } let target = target.unwrap_or(VersionRange::Any); ctx.db .peek() diff --git a/core/startos/src/registry/package/get.rs b/core/startos/src/registry/package/get.rs index 835192361..fb63be1bc 100644 --- a/core/startos/src/registry/package/get.rs +++ b/core/startos/src/registry/package/get.rs @@ -1,7 +1,7 @@ use std::collections::{BTreeMap, BTreeSet}; use clap::{Parser, ValueEnum}; -use emver::{Version, VersionRange}; +use exver::{ExtendedVersion, VersionRange}; use imbl_value::InternedString; use itertools::Itertools; use models::PackageId; @@ -45,8 +45,7 @@ pub struct GetPackageParams { pub id: Option, #[ts(type = "string | null")] pub version: Option, - #[ts(type = "string | null")] - pub source_version: Option, + pub source_version: Option, #[ts(skip)] #[arg(skip)] #[serde(rename = "__device_info")] @@ -132,7 +131,7 @@ fn get_matching_models<'a>( device_info, .. }: &GetPackageParams, -) -> Result)>, Error> { +) -> Result)>, Error> { if let Some(id) = id { if let Some(pkg) = db.as_packages().as_idx(id) { vec![(id.clone(), pkg)] @@ -166,7 +165,7 @@ fn get_matching_models<'a>( .as_ref() .map_or(Ok(true), |device_info| info.works_for_device(device_info))? { - Some((k.clone(), Version::from(v), info)) + Some((k.clone(), ExtendedVersion::from(v), info)) } else { None }, diff --git a/core/startos/src/registry/package/index.rs b/core/startos/src/registry/package/index.rs index 0e6969fa5..80055f06d 100644 --- a/core/startos/src/registry/package/index.rs +++ b/core/startos/src/registry/package/index.rs @@ -1,6 +1,6 @@ use std::collections::{BTreeMap, BTreeSet}; -use emver::{Version, VersionRange}; +use exver::{Version, VersionRange}; use imbl_value::InternedString; use models::{DataUrl, PackageId, VersionString}; use serde::{Deserialize, Serialize}; @@ -70,7 +70,8 @@ pub struct PackageVersionInfo { pub support_site: Url, #[ts(type = "string")] pub marketing_site: Url, - pub os_version: VersionString, + #[ts(type = "string")] + pub os_version: Version, pub hardware_requirements: HardwareRequirements, #[ts(type = "string | null")] pub source_version: Option, diff --git a/core/startos/src/registry/signer/sign/mod.rs b/core/startos/src/registry/signer/sign/mod.rs index 50576a198..a29109864 100644 --- a/core/startos/src/registry/signer/sign/mod.rs +++ b/core/startos/src/registry/signer/sign/mod.rs @@ -4,7 +4,6 @@ use std::str::FromStr; use ::ed25519::pkcs8::BitStringRef; use clap::builder::ValueParserFactory; use der::referenced::OwnedToRef; -use der::{Decode, Encode}; use pkcs8::der::AnyRef; use pkcs8::{PrivateKeyInfo, SubjectPublicKeyInfo}; use serde::{Deserialize, Serialize}; diff --git a/core/startos/src/s9pk/merkle_archive/directory_contents.rs b/core/startos/src/s9pk/merkle_archive/directory_contents.rs index c5e5c4a7d..b39789222 100644 --- a/core/startos/src/s9pk/merkle_archive/directory_contents.rs +++ b/core/startos/src/s9pk/merkle_archive/directory_contents.rs @@ -274,6 +274,21 @@ impl DirectoryContents { ((_, a), (_, b), _) if !a.as_contents().is_dir() && b.as_contents().is_dir() => { std::cmp::Ordering::Greater } + ((_, a), (_, b), _) + if a.as_contents().is_missing() && !b.as_contents().is_missing() => + { + std::cmp::Ordering::Greater + } + ((_, a), (_, b), _) + if !a.as_contents().is_missing() && b.as_contents().is_missing() => + { + std::cmp::Ordering::Less + } + ((n_a, a), (n_b, b), _) + if a.as_contents().is_missing() && b.as_contents().is_missing() => + { + n_a.cmp(n_b) + } ((a, _), (b, _), Some(sort_by)) => sort_by(&***a, &***b), _ => std::cmp::Ordering::Equal, }) { diff --git a/core/startos/src/s9pk/merkle_archive/mod.rs b/core/startos/src/s9pk/merkle_archive/mod.rs index 00ead65c5..977e5ebb2 100644 --- a/core/startos/src/s9pk/merkle_archive/mod.rs +++ b/core/startos/src/s9pk/merkle_archive/mod.rs @@ -121,14 +121,14 @@ impl MerkleArchive> { } if max_size > *root_maxsize { return Err(Error::new( - eyre!("merkle root directory max size too large"), + eyre!("root directory max size too large"), ErrorKind::InvalidSignature, )); } } else { if max_size > CAP_1_MiB as u64 { return Err(Error::new( - eyre!("merkle root directory max size over 1MiB, cancelling download in case of DOS attack"), + eyre!("root directory max size over 1MiB, cancelling download in case of DOS attack"), ErrorKind::InvalidSignature, )); } @@ -377,6 +377,9 @@ impl EntryContents { pub fn is_dir(&self) -> bool { matches!(self, &EntryContents::Directory(_)) } + pub fn is_missing(&self) -> bool { + matches!(self, &EntryContents::Missing) + } } impl EntryContents> { #[instrument(skip_all)] diff --git a/core/startos/src/s9pk/merkle_archive/source/http.rs b/core/startos/src/s9pk/merkle_archive/source/http.rs index fda9d32ed..e58208277 100644 --- a/core/startos/src/s9pk/merkle_archive/source/http.rs +++ b/core/startos/src/s9pk/merkle_archive/source/http.rs @@ -4,7 +4,7 @@ use std::sync::{Arc, Mutex}; use std::task::Poll; use bytes::Bytes; -use futures::{Stream, StreamExt, TryStreamExt}; +use futures::{Stream, TryStreamExt}; use reqwest::header::{ACCEPT_RANGES, CONTENT_LENGTH, RANGE}; use reqwest::{Client, Url}; use tokio::io::{AsyncRead, AsyncReadExt, ReadBuf, Take}; @@ -54,11 +54,12 @@ impl HttpSource { } } impl ArchiveSource for HttpSource { - type Reader = HttpReader; + type FetchReader = HttpReader; + type FetchAllReader = StreamReader>, Bytes>; async fn size(&self) -> Option { self.size } - async fn fetch_all(&self) -> Result { + async fn fetch_all(&self) -> Result { Ok(StreamReader::new( self.client .get(self.url.clone()) @@ -72,7 +73,7 @@ impl ArchiveSource for HttpSource { .apply(boxed), )) } - async fn fetch(&self, position: u64, size: u64) -> Result { + async fn fetch(&self, position: u64, size: u64) -> Result { match &self.range_support { Ok(_) => Ok(HttpReader::Range( StreamReader::new(if size > 0 { diff --git a/core/startos/src/s9pk/merkle_archive/source/mod.rs b/core/startos/src/s9pk/merkle_archive/source/mod.rs index 0a00b18dd..6b7459787 100644 --- a/core/startos/src/s9pk/merkle_archive/source/mod.rs +++ b/core/startos/src/s9pk/merkle_archive/source/mod.rs @@ -10,6 +10,7 @@ use tokio::io::{AsyncRead, AsyncWrite}; use crate::prelude::*; use crate::s9pk::merkle_archive::hash::VerifyingWriter; +use crate::util::io::{open_file, TmpDir}; pub mod http; pub mod multi_cursor_file; @@ -159,7 +160,7 @@ impl FileSource for PathBuf { Ok(tokio::fs::metadata(self).await?.len()) } async fn reader(&self) -> Result { - Ok(File::open(self).await?) + Ok(open_file(self).await?) } } @@ -180,18 +181,17 @@ impl FileSource for Arc<[u8]> { } pub trait ArchiveSource: Send + Sync + Sized + 'static { - type Reader: AsyncRead + Unpin + Send; + type FetchReader: AsyncRead + Unpin + Send; + type FetchAllReader: AsyncRead + Unpin + Send; fn size(&self) -> impl Future> + Send { async { None } } - fn fetch_all( - &self, - ) -> impl Future> + Send; + fn fetch_all(&self) -> impl Future> + Send; fn fetch( &self, position: u64, size: u64, - ) -> impl Future> + Send; + ) -> impl Future> + Send; fn copy_all_to( &self, w: &mut W, @@ -222,14 +222,15 @@ pub trait ArchiveSource: Send + Sync + Sized + 'static { } impl ArchiveSource for Arc { - type Reader = T::Reader; + type FetchReader = T::FetchReader; + type FetchAllReader = T::FetchAllReader; async fn size(&self) -> Option { self.deref().size().await } - async fn fetch_all(&self) -> Result { + async fn fetch_all(&self) -> Result { self.deref().fetch_all().await } - async fn fetch(&self, position: u64, size: u64) -> Result { + async fn fetch(&self, position: u64, size: u64) -> Result { self.deref().fetch(position, size).await } async fn copy_all_to( @@ -249,11 +250,12 @@ impl ArchiveSource for Arc { } impl ArchiveSource for Arc<[u8]> { - type Reader = tokio::io::Take>; - async fn fetch_all(&self) -> Result { + type FetchReader = tokio::io::Take>; + type FetchAllReader = std::io::Cursor; + async fn fetch_all(&self) -> Result { Ok(std::io::Cursor::new(self.clone())) } - async fn fetch(&self, position: u64, size: u64) -> Result { + async fn fetch(&self, position: u64, size: u64) -> Result { use tokio::io::AsyncReadExt; let mut cur = std::io::Cursor::new(self.clone()); @@ -269,7 +271,7 @@ pub struct Section { size: u64, } impl FileSource for Section { - type Reader = S::Reader; + type Reader = S::FetchReader; async fn size(&self) -> Result { Ok(self.size) } @@ -285,3 +287,81 @@ pub type DynRead = Box; pub fn into_dyn_read(r: R) -> DynRead { Box::new(r) } + +#[derive(Clone)] +pub struct TmpSource { + tmp_dir: Arc, + source: S, +} +impl TmpSource { + pub fn new(tmp_dir: Arc, source: S) -> Self { + Self { tmp_dir, source } + } + pub async fn gc(self) -> Result<(), Error> { + self.tmp_dir.gc().await + } +} +impl std::ops::Deref for TmpSource { + type Target = S; + fn deref(&self) -> &Self::Target { + &self.source + } +} +impl ArchiveSource for TmpSource { + type FetchReader = ::FetchReader; + type FetchAllReader = ::FetchAllReader; + async fn size(&self) -> Option { + self.source.size().await + } + async fn fetch_all(&self) -> Result { + self.source.fetch_all().await + } + async fn fetch(&self, position: u64, size: u64) -> Result { + self.source.fetch(position, size).await + } + async fn copy_all_to( + &self, + w: &mut W, + ) -> Result<(), Error> { + self.source.copy_all_to(w).await + } + async fn copy_to( + &self, + position: u64, + size: u64, + w: &mut W, + ) -> Result<(), Error> { + self.source.copy_to(position, size, w).await + } +} +impl From> for DynFileSource { + fn from(value: TmpSource) -> Self { + DynFileSource::new(value) + } +} + +impl FileSource for TmpSource { + type Reader = ::Reader; + async fn size(&self) -> Result { + self.source.size().await + } + async fn reader(&self) -> Result { + self.source.reader().await + } + async fn copy( + &self, + mut w: &mut W, + ) -> Result<(), Error> { + self.source.copy(&mut w).await + } + async fn copy_verify( + &self, + mut w: &mut W, + verify: Option<(Hash, u64)>, + ) -> Result<(), Error> { + self.source.copy_verify(&mut w, verify).await + } + async fn to_vec(&self, verify: Option<(Hash, u64)>) -> Result, Error> { + self.source.to_vec(verify).await + } +} diff --git a/core/startos/src/s9pk/merkle_archive/source/multi_cursor_file.rs b/core/startos/src/s9pk/merkle_archive/source/multi_cursor_file.rs index 4b7d5736d..658f3f923 100644 --- a/core/startos/src/s9pk/merkle_archive/source/multi_cursor_file.rs +++ b/core/startos/src/s9pk/merkle_archive/source/multi_cursor_file.rs @@ -6,12 +6,13 @@ use std::sync::Arc; use std::task::Poll; use tokio::fs::File; -use tokio::io::{AsyncRead, AsyncReadExt, ReadBuf, Take}; +use tokio::io::{AsyncRead, AsyncReadExt, AsyncSeek, ReadBuf, Take}; use tokio::sync::{Mutex, OwnedMutexGuard}; use crate::disk::mount::filesystem::loop_dev::LoopDev; use crate::prelude::*; use crate::s9pk::merkle_archive::source::{ArchiveSource, Section}; +use crate::util::io::open_file; fn path_from_fd(fd: RawFd) -> Result { #[cfg(target_os = "linux")] @@ -42,7 +43,7 @@ impl MultiCursorFile { path_from_fd(self.fd) } pub async fn open(fd: &impl AsRawFd) -> Result { - let f = File::open(path_from_fd(fd.as_raw_fd())?).await?; + let f = open_file(path_from_fd(fd.as_raw_fd())?).await?; Ok(Self::from(f)) } pub async fn cursor(&self) -> Result { @@ -50,7 +51,7 @@ impl MultiCursorFile { if let Ok(file) = self.file.clone().try_lock_owned() { file } else { - Arc::new(Mutex::new(File::open(self.path()?).await?)) + Arc::new(Mutex::new(open_file(self.path()?).await?)) .try_lock_owned() .expect("freshly created") }, @@ -88,24 +89,48 @@ impl AsyncRead for FileCursor { Pin::new(&mut (&mut **this.0.get_mut())).poll_read(cx, buf) } } +impl AsyncSeek for FileCursor { + fn start_seek(self: Pin<&mut Self>, position: SeekFrom) -> std::io::Result<()> { + let this = self.project(); + Pin::new(&mut (&mut **this.0.get_mut())).start_seek(position) + } + fn poll_complete( + self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + let this = self.project(); + Pin::new(&mut (&mut **this.0.get_mut())).poll_complete(cx) + } +} +impl std::ops::Deref for FileCursor { + type Target = File; + fn deref(&self) -> &Self::Target { + &*self.0 + } +} +impl std::ops::DerefMut for FileCursor { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut *self.0 + } +} impl ArchiveSource for MultiCursorFile { - type Reader = Take; + type FetchReader = Take; + type FetchAllReader = FileCursor; async fn size(&self) -> Option { tokio::fs::metadata(self.path().ok()?) .await .ok() .map(|m| m.len()) } - #[allow(refining_impl_trait)] - async fn fetch_all(&self) -> Result { + async fn fetch_all(&self) -> Result { use tokio::io::AsyncSeekExt; let mut file = self.cursor().await?; file.0.seek(SeekFrom::Start(0)).await?; Ok(file) } - async fn fetch(&self, position: u64, size: u64) -> Result { + async fn fetch(&self, position: u64, size: u64) -> Result { use tokio::io::AsyncSeekExt; let mut file = self.cursor().await?; diff --git a/core/startos/src/s9pk/merkle_archive/varint.rs b/core/startos/src/s9pk/merkle_archive/varint.rs index 479b488e6..f4f18d140 100644 --- a/core/startos/src/s9pk/merkle_archive/varint.rs +++ b/core/startos/src/s9pk/merkle_archive/varint.rs @@ -3,7 +3,7 @@ use tokio::io::{AsyncRead, AsyncWrite}; use crate::prelude::*; -/// Most-significant byte, == 0x80 +/// Most-significant bit, == 0x80 pub const MSB: u8 = 0b1000_0000; const MAX_STR_LEN: u64 = 1024 * 1024; // 1 MiB @@ -39,22 +39,20 @@ pub async fn serialize_varstring( Ok(()) } +const MAX_SIZE: usize = (std::mem::size_of::() * 8 + 7) / 7; + #[derive(Default)] struct VarIntProcessor { - buf: [u8; 10], - maxsize: usize, + buf: [u8; MAX_SIZE], i: usize, } impl VarIntProcessor { fn new() -> VarIntProcessor { - VarIntProcessor { - maxsize: (std::mem::size_of::() * 8 + 7) / 7, - ..VarIntProcessor::default() - } + Self::default() } fn push(&mut self, b: u8) -> Result<(), Error> { - if self.i >= self.maxsize { + if self.i >= MAX_SIZE { return Err(Error::new( eyre!("Unterminated varint"), ErrorKind::ParseS9pk, diff --git a/core/startos/src/s9pk/mod.rs b/core/startos/src/s9pk/mod.rs index fcf9379a0..a06218d40 100644 --- a/core/startos/src/s9pk/mod.rs +++ b/core/startos/src/s9pk/mod.rs @@ -4,37 +4,57 @@ pub mod rpc; pub mod v1; pub mod v2; -use std::io::SeekFrom; -use std::path::Path; +use std::sync::Arc; -use tokio::fs::File; -use tokio::io::{AsyncReadExt, AsyncSeekExt}; +use tokio::io::{AsyncReadExt, AsyncSeek}; pub use v2::{manifest, S9pk}; -use crate::context::CliContext; use crate::prelude::*; +use crate::progress::FullProgressTracker; +use crate::s9pk::merkle_archive::source::{ArchiveSource, DynFileSource}; use crate::s9pk::v1::reader::S9pkReader; use crate::s9pk::v2::compat::MAGIC_AND_VERSION; +use crate::util::io::TmpDir; -pub async fn load(ctx: &CliContext, path: impl AsRef) -> Result { +pub async fn load( + source: S, + key: K, + progress: Option<&FullProgressTracker>, +) -> Result, Error> +where + S: ArchiveSource, + S::FetchAllReader: AsyncSeek + Sync, + K: FnOnce() -> Result, +{ // TODO: return s9pk const MAGIC_LEN: usize = MAGIC_AND_VERSION.len(); let mut magic = [0_u8; MAGIC_LEN]; - let mut file = tokio::fs::File::open(&path).await?; - file.read_exact(&mut magic).await?; - file.seek(SeekFrom::Start(0)).await?; + source.fetch(0, 3).await?.read_exact(&mut magic).await?; if magic == v2::compat::MAGIC_AND_VERSION { + let phase = if let Some(progress) = progress { + let mut phase = progress.add_phase( + "Converting Package to V2".into(), + Some(source.size().await.unwrap_or(60)), + ); + phase.start(); + Some(phase) + } else { + None + }; tracing::info!("Converting package to v2 s9pk"); - let new_path = path.as_ref().with_extension("compat.s9pk"); - S9pk::from_v1( - S9pkReader::from_reader(file, true).await?, - &new_path, - ctx.developer_key()?.clone(), + let tmp_dir = TmpDir::new().await?; + let s9pk = S9pk::from_v1( + S9pkReader::from_reader(source.fetch_all().await?, true).await?, + Arc::new(tmp_dir), + key()?, ) .await?; - tokio::fs::rename(&new_path, &path).await?; - file = tokio::fs::File::open(&path).await?; tracing::info!("Converted s9pk successfully"); + if let Some(mut phase) = phase { + phase.complete(); + } + Ok(s9pk.into_dyn()) + } else { + Ok(S9pk::deserialize(&Arc::new(source), None).await?.into_dyn()) } - Ok(file) } diff --git a/core/startos/src/s9pk/rpc.rs b/core/startos/src/s9pk/rpc.rs index fac9e6724..83b78dad7 100644 --- a/core/startos/src/s9pk/rpc.rs +++ b/core/startos/src/s9pk/rpc.rs @@ -1,19 +1,19 @@ use std::path::PathBuf; +use std::sync::Arc; use clap::Parser; use models::ImageId; use rpc_toolkit::{from_fn_async, Empty, HandlerExt, ParentHandler}; use serde::{Deserialize, Serialize}; -use tokio::fs::File; use ts_rs::TS; use crate::context::CliContext; use crate::prelude::*; use crate::s9pk::manifest::Manifest; +use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile; use crate::s9pk::v2::pack::ImageConfig; use crate::s9pk::v2::SIG_CONTEXT; -use crate::s9pk::S9pk; -use crate::util::io::TmpDir; +use crate::util::io::{create_file, open_file, TmpDir}; use crate::util::serde::{apply_expr, HandlerExtSerde}; pub const SKIP_ENV: &[&str] = &["TERM", "container", "HOME", "HOSTNAME"]; @@ -79,19 +79,25 @@ async fn add_image( AddImageParams { id, config }: AddImageParams, S9pkPath { s9pk: s9pk_path }: S9pkPath, ) -> Result<(), Error> { - let mut s9pk = S9pk::from_file(super::load(&ctx, &s9pk_path).await?) - .await? - .into_dyn(); + let mut s9pk = super::load( + MultiCursorFile::from(open_file(&s9pk_path).await?), + || ctx.developer_key().cloned(), + None, + ) + .await?; s9pk.as_manifest_mut().images.insert(id, config); - let tmpdir = TmpDir::new().await?; - s9pk.load_images(&tmpdir).await?; + let tmp_dir = Arc::new(TmpDir::new().await?); + s9pk.load_images(tmp_dir.clone()).await?; s9pk.validate_and_filter(None)?; let tmp_path = s9pk_path.with_extension("s9pk.tmp"); - let mut tmp_file = File::create(&tmp_path).await?; + let mut tmp_file = create_file(&tmp_path).await?; s9pk.serialize(&mut tmp_file, true).await?; + drop(s9pk); tmp_file.sync_all().await?; tokio::fs::rename(&tmp_path, &s9pk_path).await?; + tmp_dir.gc().await?; + Ok(()) } @@ -104,13 +110,18 @@ async fn edit_manifest( EditManifestParams { expression }: EditManifestParams, S9pkPath { s9pk: s9pk_path }: S9pkPath, ) -> Result { - let mut s9pk = S9pk::from_file(super::load(&ctx, &s9pk_path).await?).await?; + let mut s9pk = super::load( + MultiCursorFile::from(open_file(&s9pk_path).await?), + || ctx.developer_key().cloned(), + None, + ) + .await?; let old = serde_json::to_value(s9pk.as_manifest()).with_kind(ErrorKind::Serialization)?; *s9pk.as_manifest_mut() = serde_json::from_value(apply_expr(old.into(), &expression)?.into()) .with_kind(ErrorKind::Serialization)?; let manifest = s9pk.as_manifest().clone(); let tmp_path = s9pk_path.with_extension("s9pk.tmp"); - let mut tmp_file = File::create(&tmp_path).await?; + let mut tmp_file = create_file(&tmp_path).await?; s9pk.as_archive_mut() .set_signer(ctx.developer_key()?.clone(), SIG_CONTEXT); s9pk.serialize(&mut tmp_file, true).await?; @@ -123,9 +134,14 @@ async fn edit_manifest( async fn file_tree( ctx: CliContext, _: Empty, - S9pkPath { s9pk }: S9pkPath, + S9pkPath { s9pk: s9pk_path }: S9pkPath, ) -> Result, Error> { - let s9pk = S9pk::from_file(super::load(&ctx, &s9pk).await?).await?; + let s9pk = super::load( + MultiCursorFile::from(open_file(&s9pk_path).await?), + || ctx.developer_key().cloned(), + None, + ) + .await?; Ok(s9pk.as_archive().contents().file_paths("")) } @@ -138,11 +154,16 @@ struct CatParams { async fn cat( ctx: CliContext, CatParams { file_path }: CatParams, - S9pkPath { s9pk }: S9pkPath, + S9pkPath { s9pk: s9pk_path }: S9pkPath, ) -> Result<(), Error> { use crate::s9pk::merkle_archive::source::FileSource; - let s9pk = S9pk::from_file(super::load(&ctx, &s9pk).await?).await?; + let s9pk = super::load( + MultiCursorFile::from(open_file(&s9pk_path).await?), + || ctx.developer_key().cloned(), + None, + ) + .await?; tokio::io::copy( &mut s9pk .as_archive() @@ -162,8 +183,13 @@ async fn cat( async fn inspect_manifest( ctx: CliContext, _: Empty, - S9pkPath { s9pk }: S9pkPath, + S9pkPath { s9pk: s9pk_path }: S9pkPath, ) -> Result { - let s9pk = S9pk::from_file(super::load(&ctx, &s9pk).await?).await?; + let s9pk = super::load( + MultiCursorFile::from(open_file(&s9pk_path).await?), + || ctx.developer_key().cloned(), + None, + ) + .await?; Ok(s9pk.as_manifest().clone()) } diff --git a/core/startos/src/s9pk/v1/manifest.rs b/core/startos/src/s9pk/v1/manifest.rs index 845d8f773..4a9956f9f 100644 --- a/core/startos/src/s9pk/v1/manifest.rs +++ b/core/startos/src/s9pk/v1/manifest.rs @@ -1,8 +1,7 @@ use std::collections::BTreeMap; use std::path::{Path, PathBuf}; -use emver::VersionRange; -use imbl_value::InOMap; +use exver::{Version, VersionRange}; use indexmap::IndexMap; pub use models::PackageId; use models::{ActionId, HealthCheckId, ImageId, VolumeId}; @@ -13,23 +12,16 @@ use crate::prelude::*; use crate::s9pk::git_hash::GitHash; use crate::s9pk::manifest::{Alerts, Description, HardwareRequirements}; use crate::util::serde::{Duration, IoFormat}; -use crate::util::VersionString; -use crate::version::{Current, VersionT}; - -fn current_version() -> VersionString { - Current::new().semver().into() -} #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "kebab-case")] pub struct Manifest { - #[serde(default = "current_version")] - pub eos_version: VersionString, + pub eos_version: Version, pub id: PackageId, #[serde(default)] pub git_hash: Option, pub title: String, - pub version: VersionString, + pub version: exver::emver::Version, pub description: Description, #[serde(default)] pub assets: Assets, diff --git a/core/startos/src/s9pk/v1/reader.rs b/core/startos/src/s9pk/v1/reader.rs index 7437fdaa9..f2bbf578e 100644 --- a/core/startos/src/s9pk/v1/reader.rs +++ b/core/startos/src/s9pk/v1/reader.rs @@ -20,6 +20,7 @@ use super::header::{FileSection, Header, TableOfContents}; use super::SIG_CONTEXT; use crate::prelude::*; use crate::s9pk::v1::docker::DockerReader; +use crate::util::io::open_file; use crate::util::VersionString; #[pin_project::pin_project] @@ -150,9 +151,7 @@ pub struct S9pkReader>(path: P, check_sig: bool) -> Result { let p = path.as_ref(); - let rdr = File::open(p) - .await - .with_ctx(|_| (crate::error::ErrorKind::Filesystem, p.display().to_string()))?; + let rdr = open_file(p).await?; Self::from_reader(BufReader::new(rdr), check_sig).await } diff --git a/core/startos/src/s9pk/v2/compat.rs b/core/startos/src/s9pk/v2/compat.rs index ec5b586ea..914d2e5aa 100644 --- a/core/startos/src/s9pk/v2/compat.rs +++ b/core/startos/src/s9pk/v2/compat.rs @@ -2,9 +2,8 @@ use std::collections::BTreeMap; use std::path::Path; use std::sync::Arc; -use itertools::Itertools; +use exver::ExtendedVersion; use models::ImageId; -use tokio::fs::File; use tokio::io::{AsyncRead, AsyncSeek, AsyncWriteExt}; use tokio::process::Command; @@ -12,29 +11,35 @@ use crate::dependencies::{DepInfo, Dependencies}; use crate::prelude::*; use crate::s9pk::manifest::Manifest; use crate::s9pk::merkle_archive::directory_contents::DirectoryContents; -use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile; -use crate::s9pk::merkle_archive::source::Section; +use crate::s9pk::merkle_archive::source::TmpSource; use crate::s9pk::merkle_archive::{Entry, MerkleArchive}; -use crate::s9pk::rpc::SKIP_ENV; use crate::s9pk::v1::manifest::{Manifest as ManifestV1, PackageProcedure}; use crate::s9pk::v1::reader::S9pkReader; -use crate::s9pk::v2::pack::{PackSource, CONTAINER_TOOL}; +use crate::s9pk::v2::pack::{ImageSource, PackSource, CONTAINER_TOOL}; use crate::s9pk::v2::{S9pk, SIG_CONTEXT}; -use crate::util::io::TmpDir; +use crate::util::io::{create_file, TmpDir}; use crate::util::Invoke; pub const MAGIC_AND_VERSION: &[u8] = &[0x3b, 0x3b, 0x01]; -impl S9pk> { +impl S9pk> { #[instrument(skip_all)] pub async fn from_v1( mut reader: S9pkReader, - destination: impl AsRef, + tmp_dir: Arc, signer: ed25519_dalek::SigningKey, ) -> Result { - let scratch_dir = TmpDir::new().await?; + Command::new(CONTAINER_TOOL) + .arg("run") + .arg("--rm") + .arg("--privileged") + .arg("tonistiigi/binfmt") + .arg("--install") + .arg("all") + .invoke(ErrorKind::Docker) + .await?; - let mut archive = DirectoryContents::::new(); + let mut archive = DirectoryContents::>::new(); // manifest.json let manifest_raw = reader.manifest().await?; @@ -56,33 +61,35 @@ impl S9pk> { let license: Arc<[u8]> = reader.license().await?.to_vec().await?.into(); archive.insert_path( "LICENSE.md", - Entry::file(PackSource::Buffered(license.into())), + Entry::file(TmpSource::new( + tmp_dir.clone(), + PackSource::Buffered(license.into()), + )), )?; // instructions.md let instructions: Arc<[u8]> = reader.instructions().await?.to_vec().await?.into(); archive.insert_path( "instructions.md", - Entry::file(PackSource::Buffered(instructions.into())), + Entry::file(TmpSource::new( + tmp_dir.clone(), + PackSource::Buffered(instructions.into()), + )), )?; // icon.md let icon: Arc<[u8]> = reader.icon().await?.to_vec().await?.into(); archive.insert_path( format!("icon.{}", manifest.assets.icon_type()), - Entry::file(PackSource::Buffered(icon.into())), + Entry::file(TmpSource::new( + tmp_dir.clone(), + PackSource::Buffered(icon.into()), + )), )?; // images for arch in reader.docker_arches().await? { - let images_dir = scratch_dir.join("images").join(&arch); - let docker_platform = if arch == "x86_64" { - "--platform=linux/amd64".to_owned() - } else if arch == "aarch64" { - "--platform=linux/arm64".to_owned() - } else { - format!("--platform=linux/{arch}") - }; + let images_dir = tmp_dir.join("images").join(&arch); tokio::fs::create_dir_all(&images_dir).await?; Command::new(CONTAINER_TOOL) .arg("load") @@ -93,97 +100,24 @@ impl S9pk> { let mut image_config = new_manifest.images.remove(image).unwrap_or_default(); image_config.arch.insert(arch.as_str().into()); new_manifest.images.insert(image.clone(), image_config); - let sqfs_path = images_dir.join(image).with_extension("squashfs"); let image_name = if *system { format!("start9/{}:latest", image) } else { format!("start9/{}/{}:{}", manifest.id, image, manifest.version) }; - let id = String::from_utf8( - Command::new(CONTAINER_TOOL) - .arg("create") - .arg(&docker_platform) - .arg(&image_name) - .invoke(ErrorKind::Docker) - .await?, - )?; - let env = String::from_utf8( - Command::new(CONTAINER_TOOL) - .arg("run") - .arg("--rm") - .arg(&docker_platform) - .arg("--entrypoint") - .arg("env") - .arg(&image_name) - .invoke(ErrorKind::Docker) - .await?, - )? - .lines() - .filter(|l| { - l.trim() - .split_once("=") - .map_or(false, |(v, _)| !SKIP_ENV.contains(&v)) - }) - .join("\n") - + "\n"; - let workdir = Path::new( - String::from_utf8( - Command::new(CONTAINER_TOOL) - .arg("run") - .arg("--rm") - .arg(&docker_platform) - .arg("--entrypoint") - .arg("pwd") - .arg(&image_name) - .invoke(ErrorKind::Docker) - .await?, - )? - .trim(), - ) - .to_owned(); - Command::new("bash") - .arg("-c") - .arg(format!( - "{CONTAINER_TOOL} export {id} | mksquashfs - {sqfs} -tar", - id = id.trim(), - sqfs = sqfs_path.display() - )) - .invoke(ErrorKind::Docker) + ImageSource::DockerTag(image_name.clone()) + .load( + tmp_dir.clone(), + &new_manifest.id, + &new_manifest.version, + image, + &arch, + &mut archive, + ) .await?; - Command::new(CONTAINER_TOOL) - .arg("rm") - .arg(id.trim()) - .invoke(ErrorKind::Docker) - .await?; - archive.insert_path( - Path::new("images") - .join(&arch) - .join(&image) - .with_extension("squashfs"), - Entry::file(PackSource::File(sqfs_path)), - )?; - archive.insert_path( - Path::new("images") - .join(&arch) - .join(&image) - .with_extension("env"), - Entry::file(PackSource::Buffered(Vec::from(env).into())), - )?; - archive.insert_path( - Path::new("images") - .join(&arch) - .join(&image) - .with_extension("json"), - Entry::file(PackSource::Buffered( - serde_json::to_vec(&serde_json::json!({ - "workdir": workdir - })) - .with_kind(ErrorKind::Serialization)? - .into(), - )), - )?; Command::new(CONTAINER_TOOL) .arg("rmi") + .arg("-f") .arg(&image_name) .invoke(ErrorKind::Docker) .await?; @@ -191,7 +125,7 @@ impl S9pk> { } // assets - let asset_dir = scratch_dir.join("assets"); + let asset_dir = tmp_dir.join("assets"); tokio::fs::create_dir_all(&asset_dir).await?; tokio_tar::Archive::new(reader.assets().await?) .unpack(&asset_dir) @@ -212,21 +146,21 @@ impl S9pk> { Path::new("assets") .join(&asset_id) .with_extension("squashfs"), - Entry::file(PackSource::File(sqfs_path)), + Entry::file(TmpSource::new(tmp_dir.clone(), PackSource::File(sqfs_path))), )?; } // javascript - let js_dir = scratch_dir.join("javascript"); + let js_dir = tmp_dir.join("javascript"); let sqfs_path = js_dir.with_extension("squashfs"); tokio::fs::create_dir_all(&js_dir).await?; if let Some(mut scripts) = reader.scripts().await? { - let mut js_file = File::create(js_dir.join("embassy.js")).await?; + let mut js_file = create_file(js_dir.join("embassy.js")).await?; tokio::io::copy(&mut scripts, &mut js_file).await?; js_file.sync_all().await?; } { - let mut js_file = File::create(js_dir.join("embassyManifest.json")).await?; + let mut js_file = create_file(js_dir.join("embassyManifest.json")).await?; js_file .write_all(&serde_json::to_vec(&manifest_raw).with_kind(ErrorKind::Serialization)?) .await?; @@ -239,30 +173,24 @@ impl S9pk> { .await?; archive.insert_path( Path::new("javascript.squashfs"), - Entry::file(PackSource::File(sqfs_path)), + Entry::file(TmpSource::new(tmp_dir.clone(), PackSource::File(sqfs_path))), )?; archive.insert_path( "manifest.json", - Entry::file(PackSource::Buffered( - serde_json::to_vec::(&new_manifest) - .with_kind(ErrorKind::Serialization)? - .into(), + Entry::file(TmpSource::new( + tmp_dir.clone(), + PackSource::Buffered( + serde_json::to_vec::(&new_manifest) + .with_kind(ErrorKind::Serialization)? + .into(), + ), )), )?; - let mut s9pk = S9pk::new(MerkleArchive::new(archive, signer, SIG_CONTEXT), None).await?; - let mut dest_file = File::create(destination.as_ref()).await?; - s9pk.serialize(&mut dest_file, false).await?; - dest_file.sync_all().await?; - - scratch_dir.delete().await?; - - Ok(S9pk::deserialize( - &MultiCursorFile::from(File::open(destination.as_ref()).await?), - None, - ) - .await?) + let mut res = S9pk::new(MerkleArchive::new(archive, signer, SIG_CONTEXT), None).await?; + res.as_archive_mut().update_hashes(true).await?; + Ok(res) } } @@ -272,7 +200,7 @@ impl From for Manifest { Self { id: value.id, title: value.title, - version: value.version, + version: ExtendedVersion::from(value.version).into(), release_notes: value.release_notes, license: value.license.into(), wrapper_repo: value.wrapper_repo, diff --git a/core/startos/src/s9pk/v2/manifest.rs b/core/startos/src/s9pk/v2/manifest.rs index 77e48c126..9607bb654 100644 --- a/core/startos/src/s9pk/v2/manifest.rs +++ b/core/startos/src/s9pk/v2/manifest.rs @@ -2,6 +2,7 @@ use std::collections::{BTreeMap, BTreeSet}; use std::path::Path; use color_eyre::eyre::eyre; +use exver::Version; use helpers::const_true; use imbl_value::InternedString; pub use models::PackageId; @@ -20,8 +21,8 @@ use crate::util::serde::Regex; use crate::util::VersionString; use crate::version::{Current, VersionT}; -fn current_version() -> VersionString { - Current::new().semver().into() +fn current_version() -> Version { + Current::new().semver() } #[derive(Clone, Debug, Deserialize, Serialize, HasModel, TS)] @@ -59,7 +60,8 @@ pub struct Manifest { #[ts(type = "string | null")] pub git_hash: Option, #[serde(default = "current_version")] - pub os_version: VersionString, + #[ts(type = "string")] + pub os_version: Version, #[serde(default = "const_true")] pub has_config: bool, } @@ -146,7 +148,7 @@ impl Manifest { #[ts(export)] pub struct HardwareRequirements { #[serde(default)] - #[ts(type = "{ [key: string]: string }")] + #[ts(type = "{ [key: string]: string }")] // TODO more specific key pub device: BTreeMap, #[ts(type = "number | null")] pub ram: Option, diff --git a/core/startos/src/s9pk/v2/mod.rs b/core/startos/src/s9pk/v2/mod.rs index a1183efa8..2477e63a0 100644 --- a/core/startos/src/s9pk/v2/mod.rs +++ b/core/startos/src/s9pk/v2/mod.rs @@ -12,10 +12,12 @@ use crate::s9pk::manifest::Manifest; use crate::s9pk::merkle_archive::file_contents::FileContents; use crate::s9pk::merkle_archive::sink::Sink; use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile; -use crate::s9pk::merkle_archive::source::{ArchiveSource, DynFileSource, FileSource, Section}; +use crate::s9pk::merkle_archive::source::{ + ArchiveSource, DynFileSource, FileSource, Section, TmpSource, +}; use crate::s9pk::merkle_archive::{Entry, MerkleArchive}; use crate::s9pk::v2::pack::{ImageSource, PackSource}; -use crate::util::io::TmpDir; +use crate::util::io::{open_file, TmpDir}; const MAGIC_AND_VERSION: &[u8] = &[0x3b, 0x3b, 0x02]; @@ -165,8 +167,8 @@ impl S9pk { } } -impl + FileSource + Clone> S9pk { - pub async fn load_images(&mut self, tmpdir: &TmpDir) -> Result<(), Error> { +impl> + FileSource + Clone> S9pk { + pub async fn load_images(&mut self, tmp_dir: Arc) -> Result<(), Error> { let id = &self.manifest.id; let version = &self.manifest.version; for (image_id, image_config) in &mut self.manifest.images { @@ -175,7 +177,7 @@ impl + FileSource + Clone> S9pk { image_config .source .load( - tmpdir, + tmp_dir.clone(), id, version, image_id, @@ -206,7 +208,7 @@ impl S9pk> { ) .await?; - let mut magic_version = [0u8; 3]; + let mut magic_version = [0u8; MAGIC_AND_VERSION.len()]; header.read_exact(&mut magic_version).await?; ensure_code!( &magic_version == MAGIC_AND_VERSION, @@ -232,7 +234,7 @@ impl S9pk { Self::deserialize(&MultiCursorFile::from(file), None).await } pub async fn open(path: impl AsRef, id: Option<&PackageId>) -> Result { - let res = Self::from_file(tokio::fs::File::open(path).await?).await?; + let res = Self::from_file(open_file(path).await?).await?; if let Some(id) = id { ensure_code!( &res.as_manifest().id == id, diff --git a/core/startos/src/s9pk/v2/pack.rs b/core/startos/src/s9pk/v2/pack.rs index 18fe0472b..fb271e785 100644 --- a/core/startos/src/s9pk/v2/pack.rs +++ b/core/startos/src/s9pk/v2/pack.rs @@ -10,7 +10,6 @@ use futures::{FutureExt, TryStreamExt}; use imbl_value::InternedString; use models::{ImageId, PackageId, VersionString}; use serde::{Deserialize, Serialize}; -use tokio::fs::File; use tokio::io::AsyncRead; use tokio::process::Command; use tokio::sync::OnceCell; @@ -23,12 +22,12 @@ use crate::rpc_continuations::Guid; use crate::s9pk::merkle_archive::directory_contents::DirectoryContents; use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile; use crate::s9pk::merkle_archive::source::{ - into_dyn_read, ArchiveSource, DynFileSource, FileSource, + into_dyn_read, ArchiveSource, DynFileSource, FileSource, TmpSource, }; use crate::s9pk::merkle_archive::{Entry, MerkleArchive}; use crate::s9pk::v2::SIG_CONTEXT; use crate::s9pk::S9pk; -use crate::util::io::TmpDir; +use crate::util::io::{create_file, open_file, TmpDir}; use crate::util::Invoke; #[cfg(not(feature = "docker"))] @@ -64,7 +63,7 @@ impl SqfsDir { .invoke(ErrorKind::Filesystem) .await?; Ok(MultiCursorFile::from( - File::open(&path) + open_file(&path) .await .with_ctx(|_| (ErrorKind::Filesystem, path.display()))?, )) @@ -100,11 +99,7 @@ impl FileSource for PackSource { async fn reader(&self) -> Result { match self { Self::Buffered(a) => Ok(into_dyn_read(Cursor::new(a.clone()))), - Self::File(f) => Ok(into_dyn_read( - File::open(f) - .await - .with_ctx(|_| (ErrorKind::Filesystem, f.display()))?, - )), + Self::File(f) => Ok(into_dyn_read(open_file(f).await?)), Self::Squashfs(dir) => dir.file().await?.fetch_all().await.map(into_dyn_read), } } @@ -284,9 +279,9 @@ pub enum ImageSource { } impl ImageSource { #[instrument(skip_all)] - pub fn load<'a, S: From + FileSource + Clone>( + pub fn load<'a, S: From> + FileSource + Clone>( &'a self, - tmpdir: &'a TmpDir, + tmp_dir: Arc, id: &'a PackageId, version: &'a VersionString, image_id: &'a ImageId, @@ -331,12 +326,13 @@ impl ImageSource { .arg(&tag) .arg(&docker_platform) .arg("-o") - .arg("type=image") + .arg("type=docker,dest=-") .capture(false) + .pipe(Command::new(CONTAINER_TOOL).arg("load")) .invoke(ErrorKind::Docker) .await?; ImageSource::DockerTag(tag.clone()) - .load(tmpdir, id, version, image_id, arch, into) + .load(tmp_dir, id, version, image_id, arch, into) .await?; Command::new(CONTAINER_TOOL) .arg("rmi") @@ -390,21 +386,24 @@ impl ImageSource { into.insert_path( base_path.with_extension("json"), Entry::file( - PackSource::Buffered( - serde_json::to_vec(&ImageMetadata { - workdir: if config.working_dir == Path::new("") { - "/".into() - } else { - config.working_dir - }, - user: if config.user.is_empty() { - "root".into() - } else { - config.user.into() - }, - }) - .with_kind(ErrorKind::Serialization)? - .into(), + TmpSource::new( + tmp_dir.clone(), + PackSource::Buffered( + serde_json::to_vec(&ImageMetadata { + workdir: if config.working_dir == Path::new("") { + "/".into() + } else { + config.working_dir + }, + user: if config.user.is_empty() { + "root".into() + } else { + config.user.into() + }, + }) + .with_kind(ErrorKind::Serialization)? + .into(), + ), ) .into(), ), @@ -412,10 +411,16 @@ impl ImageSource { into.insert_path( base_path.with_extension("env"), Entry::file( - PackSource::Buffered(config.env.join("\n").into_bytes().into()).into(), + TmpSource::new( + tmp_dir.clone(), + PackSource::Buffered(config.env.join("\n").into_bytes().into()), + ) + .into(), ), )?; - let dest = tmpdir.join(Guid::new().as_ref()).with_extension("squashfs"); + let dest = tmp_dir + .join(Guid::new().as_ref()) + .with_extension("squashfs"); let container = String::from_utf8( Command::new(CONTAINER_TOOL) .arg("create") @@ -438,7 +443,7 @@ impl ImageSource { .await?; into.insert_path( base_path.with_extension("squashfs"), - Entry::file(PackSource::File(dest).into()), + Entry::file(TmpSource::new(tmp_dir.clone(), PackSource::File(dest)).into()), )?; Ok(()) @@ -460,8 +465,8 @@ pub struct ImageMetadata { #[instrument(skip_all)] pub async fn pack(ctx: CliContext, params: PackParams) -> Result<(), Error> { - let tmpdir = Arc::new(TmpDir::new().await?); - let mut files = DirectoryContents::::new(); + let tmp_dir = Arc::new(TmpDir::new().await?); + let mut files = DirectoryContents::>::new(); let js_dir = params.javascript(); let manifest: Arc<[u8]> = Command::new("node") .arg("-e") @@ -474,7 +479,10 @@ pub async fn pack(ctx: CliContext, params: PackParams) -> Result<(), Error> { .into(); files.insert( "manifest.json".into(), - Entry::file(PackSource::Buffered(manifest.clone())), + Entry::file(TmpSource::new( + tmp_dir.clone(), + PackSource::Buffered(manifest.clone()), + )), ); let icon = params.icon().await?; let icon_ext = icon @@ -483,22 +491,28 @@ pub async fn pack(ctx: CliContext, params: PackParams) -> Result<(), Error> { .to_string_lossy(); files.insert( InternedString::from_display(&lazy_format!("icon.{}", icon_ext)), - Entry::file(PackSource::File(icon)), + Entry::file(TmpSource::new(tmp_dir.clone(), PackSource::File(icon))), ); files.insert( "LICENSE.md".into(), - Entry::file(PackSource::File(params.license())), + Entry::file(TmpSource::new( + tmp_dir.clone(), + PackSource::File(params.license()), + )), ); files.insert( "instructions.md".into(), - Entry::file(PackSource::File(params.instructions())), + Entry::file(TmpSource::new( + tmp_dir.clone(), + PackSource::File(params.instructions()), + )), ); files.insert( "javascript.squashfs".into(), - Entry::file(PackSource::Squashfs(Arc::new(SqfsDir::new( - js_dir, - tmpdir.clone(), - )))), + Entry::file(TmpSource::new( + tmp_dir.clone(), + PackSource::Squashfs(Arc::new(SqfsDir::new(js_dir, tmp_dir.clone()))), + )), ); let mut s9pk = S9pk::new( @@ -511,26 +525,29 @@ pub async fn pack(ctx: CliContext, params: PackParams) -> Result<(), Error> { for assets in s9pk.as_manifest().assets.clone() { s9pk.as_archive_mut().contents_mut().insert_path( Path::new("assets").join(&assets).with_extension("squashfs"), - Entry::file(PackSource::Squashfs(Arc::new(SqfsDir::new( - assets_dir.join(&assets), - tmpdir.clone(), - )))), + Entry::file(TmpSource::new( + tmp_dir.clone(), + PackSource::Squashfs(Arc::new(SqfsDir::new( + assets_dir.join(&assets), + tmp_dir.clone(), + ))), + )), )?; } - s9pk.load_images(&*tmpdir).await?; + s9pk.load_images(tmp_dir.clone()).await?; s9pk.validate_and_filter(None)?; s9pk.serialize( - &mut File::create(params.output(&s9pk.as_manifest().id)).await?, + &mut create_file(params.output(&s9pk.as_manifest().id)).await?, false, ) .await?; drop(s9pk); - tmpdir.gc().await?; + tmp_dir.gc().await?; Ok(()) } diff --git a/core/startos/src/service/cli.rs b/core/startos/src/service/cli.rs index 87491932b..f5e04999c 100644 --- a/core/startos/src/service/cli.rs +++ b/core/startos/src/service/cli.rs @@ -19,7 +19,7 @@ pub struct ContainerClientConfig { pub struct ContainerCliSeed { socket: PathBuf, - runtime: OnceCell, + runtime: OnceCell>, } #[derive(Clone)] @@ -35,17 +35,20 @@ impl ContainerCliContext { } } impl Context for ContainerCliContext { - fn runtime(&self) -> tokio::runtime::Handle { - self.0 - .runtime - .get_or_init(|| { - tokio::runtime::Builder::new_current_thread() - .enable_all() - .build() - .unwrap() - }) - .handle() - .clone() + fn runtime(&self) -> Option> { + Some( + self.0 + .runtime + .get_or_init(|| { + Arc::new( + tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap(), + ) + }) + .clone(), + ) } } diff --git a/core/startos/src/service/mod.rs b/core/startos/src/service/mod.rs index 92564b8e4..b85bd8d6d 100644 --- a/core/startos/src/service/mod.rs +++ b/core/startos/src/service/mod.rs @@ -11,7 +11,6 @@ use persistent_container::PersistentContainer; use rpc_toolkit::{from_fn_async, CallRemoteHandler, Empty, HandlerArgs, HandlerFor}; use serde::{Deserialize, Serialize}; use start_stop::StartStop; -use tokio::fs::File; use tokio::sync::Notify; use ts_rs::TS; @@ -33,6 +32,7 @@ use crate::status::MainStatus; use crate::util::actor::background::BackgroundJobQueue; use crate::util::actor::concurrent::ConcurrentActor; use crate::util::actor::Actor; +use crate::util::io::create_file; use crate::util::serde::Pem; use crate::volume::data_dir; @@ -403,7 +403,7 @@ impl Service { #[instrument(skip_all)] pub async fn backup(&self, guard: impl GenericMountGuard) -> Result<(), Error> { let id = &self.seed.id; - let mut file = File::create(guard.path().join(id).with_extension("s9pk")).await?; + let mut file = create_file(guard.path().join(id).with_extension("s9pk")).await?; self.seed .persistent_container .s9pk diff --git a/core/startos/src/service/persistent_container.rs b/core/startos/src/service/persistent_container.rs index d9d08e5d3..e0b31ea97 100644 --- a/core/startos/src/service/persistent_container.rs +++ b/core/startos/src/service/persistent_container.rs @@ -9,14 +9,12 @@ use helpers::NonDetachingJoinHandle; use models::{ImageId, ProcedureName, VolumeId}; use rpc_toolkit::{Empty, Server, ShutdownHandle}; use serde::de::DeserializeOwned; -use tokio::fs::File; use tokio::process::Command; use tokio::sync::{oneshot, watch, Mutex, OnceCell}; use tracing::instrument; use super::service_effect_handler::{service_effect_handler, EffectContext}; use super::transition::{TransitionKind, TransitionState}; -use super::ServiceActorSeed; use crate::context::RpcContext; use crate::disk::mount::filesystem::bind::Bind; use crate::disk::mount::filesystem::idmapped::IdMapped; @@ -32,6 +30,7 @@ use crate::s9pk::merkle_archive::source::FileSource; use crate::s9pk::S9pk; use crate::service::start_stop::StartStop; use crate::service::{rpc, RunningStatus, Service}; +use crate::util::io::create_file; use crate::util::rpc_client::UnixRpcClient; use crate::util::Invoke; use crate::volume::{asset_dir, data_dir}; @@ -237,7 +236,7 @@ impl PersistentContainer { .get_path(Path::new("images").join(arch).join(&env_filename)) .and_then(|e| e.as_file()) { - env.copy(&mut File::create(image_path.join(&env_filename)).await?) + env.copy(&mut create_file(image_path.join(&env_filename)).await?) .await?; } let json_filename = Path::new(image.as_ref()).with_extension("json"); @@ -247,7 +246,7 @@ impl PersistentContainer { .get_path(Path::new("images").join(arch).join(&json_filename)) .and_then(|e| e.as_file()) { - json.copy(&mut File::create(image_path.join(&json_filename)).await?) + json.copy(&mut create_file(image_path.join(&json_filename)).await?) .await?; } } diff --git a/core/startos/src/service/service_effect_handler.rs b/core/startos/src/service/service_effect_handler.rs index bcd6da7d1..7547584e0 100644 --- a/core/startos/src/service/service_effect_handler.rs +++ b/core/startos/src/service/service_effect_handler.rs @@ -7,8 +7,8 @@ use std::str::FromStr; use std::sync::{Arc, Weak}; use clap::builder::ValueParserFactory; -use clap::{CommandFactory, FromArgMatches, Parser}; -use emver::VersionRange; +use clap::Parser; +use exver::VersionRange; use imbl_value::json; use itertools::Itertools; use models::{ @@ -64,56 +64,6 @@ impl EffectContext { } } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct WithProcedureId { - #[serde(default)] - procedure_id: Guid, - #[serde(flatten)] - rest: T, -} -impl FromArgMatches for WithProcedureId { - fn from_arg_matches(matches: &clap::ArgMatches) -> Result { - let rest = T::from_arg_matches(matches)?; - Ok(Self { - procedure_id: matches.get_one("procedure-id").cloned().unwrap_or_default(), - rest, - }) - } - fn from_arg_matches_mut(matches: &mut clap::ArgMatches) -> Result { - let rest = T::from_arg_matches_mut(matches)?; - Ok(Self { - procedure_id: matches.get_one("procedure-id").cloned().unwrap_or_default(), - rest, - }) - } - fn update_from_arg_matches(&mut self, matches: &clap::ArgMatches) -> Result<(), clap::Error> { - self.rest.update_from_arg_matches(matches)?; - self.procedure_id = matches.get_one("procedure-id").cloned().unwrap_or_default(); - Ok(()) - } - fn update_from_arg_matches_mut( - &mut self, - matches: &mut clap::ArgMatches, - ) -> Result<(), clap::Error> { - self.rest.update_from_arg_matches_mut(matches)?; - self.procedure_id = matches.get_one("procedure-id").cloned().unwrap_or_default(); - Ok(()) - } -} -impl CommandFactory for WithProcedureId { - fn command() -> clap::Command { - T::command_for_update().arg( - clap::Arg::new("procedure-id") - .action(clap::ArgAction::Set) - .value_parser(clap::value_parser!(Guid)), - ) - } - fn command_for_update() -> clap::Command { - Self::command() - } -} - pub fn service_effect_handler() -> ParentHandler { ParentHandler::new() .subcommand("gitInfo", from_fn(|_: C| crate::version::git_info())) @@ -877,6 +827,8 @@ async fn exists(context: EffectContext, params: ParamsPackageId) -> Result, #[ts(type = "string")] @@ -886,15 +838,12 @@ struct ExecuteAction { } async fn execute_action( context: EffectContext, - WithProcedureId { + ExecuteAction { procedure_id, - rest: - ExecuteAction { - service_id, - action_id, - input, - }, - }: WithProcedureId, + service_id, + action_id, + input, + }: ExecuteAction, ) -> Result { let context = context.deref()?; let package_id = service_id @@ -950,9 +899,18 @@ async fn running(context: EffectContext, params: ParamsPackageId) -> Result, + ProcedureId { procedure_id }: ProcedureId, ) -> Result<(), Error> { let context = context.deref()?; context.restart(procedure_id).await?; @@ -961,7 +919,7 @@ async fn restart( async fn shutdown( context: EffectContext, - WithProcedureId { procedure_id, .. }: WithProcedureId, + ProcedureId { procedure_id }: ProcedureId, ) -> Result<(), Error> { let context = context.deref()?; context.stop(procedure_id).await?; @@ -1001,7 +959,6 @@ async fn set_configured(context: EffectContext, params: SetConfigured) -> Result enum SetMainStatusStatus { Running, Stopped, - Starting, } impl FromStr for SetMainStatusStatus { type Err = color_eyre::eyre::Report; @@ -1009,7 +966,6 @@ impl FromStr for SetMainStatusStatus { match s { "running" => Ok(Self::Running), "stopped" => Ok(Self::Stopped), - "starting" => Ok(Self::Starting), _ => Err(eyre!("unknown status {s}")), } } @@ -1033,7 +989,6 @@ async fn set_main_status(context: EffectContext, params: SetMainStatus) -> Resul match params.status { SetMainStatusStatus::Running => context.seed.started(), SetMainStatusStatus::Stopped => context.seed.stopped(), - SetMainStatusStatus::Starting => context.seed.started(), } Ok(Value::Null) } @@ -1262,15 +1217,17 @@ impl ValueParserFactory for DependencyRequirement { #[command(rename_all = "camelCase")] #[ts(export)] struct SetDependenciesParams { + #[serde(default)] + procedure_id: Guid, dependencies: Vec, } async fn set_dependencies( context: EffectContext, - WithProcedureId { + SetDependenciesParams { procedure_id, - rest: SetDependenciesParams { dependencies }, - }: WithProcedureId, + dependencies, + }: SetDependenciesParams, ) -> Result<(), Error> { let context = context.deref()?; let id = &context.seed.id; @@ -1426,7 +1383,7 @@ struct CheckDependenciesResult { is_running: bool, health_checks: Vec, #[ts(type = "string | null")] - version: Option, + version: Option, } async fn check_dependencies( diff --git a/core/startos/src/service/service_map.rs b/core/startos/src/service/service_map.rs index f8874d21a..02244169c 100644 --- a/core/startos/src/service/service_map.rs +++ b/core/startos/src/service/service_map.rs @@ -94,12 +94,19 @@ impl ServiceMap { } #[instrument(skip_all)] - pub async fn install( + pub async fn install( &self, ctx: RpcContext, - mut s9pk: S9pk, + s9pk: F, recovery_source: Option, - ) -> Result { + progress: Option, + ) -> Result + where + F: FnOnce() -> Fut, + Fut: Future, Error>>, + S: FileSource + Clone, + { + let mut s9pk = s9pk().await?; s9pk.validate_and_filter(ctx.s9pk_arch)?; let manifest = s9pk.as_manifest().clone(); let id = manifest.id.clone(); @@ -118,7 +125,7 @@ impl ServiceMap { }; let size = s9pk.size(); - let progress = FullProgressTracker::new(); + let progress = progress.unwrap_or_else(|| FullProgressTracker::new()); let download_progress_contribution = size.unwrap_or(60); let mut download_progress = progress.add_phase( InternedString::intern("Download"), diff --git a/core/startos/src/setup.rs b/core/startos/src/setup.rs index 2b701c01f..8fb7cf7c1 100644 --- a/core/startos/src/setup.rs +++ b/core/startos/src/setup.rs @@ -8,7 +8,6 @@ use patch_db::json_ptr::ROOT; use rpc_toolkit::yajrc::RpcError; use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler}; use serde::{Deserialize, Serialize}; -use tokio::fs::File; use tokio::io::AsyncWriteExt; use tokio::try_join; use tracing::instrument; @@ -35,7 +34,7 @@ use crate::prelude::*; use crate::progress::{FullProgress, PhaseProgressTrackerHandle}; use crate::rpc_continuations::Guid; use crate::util::crypto::EncryptedWire; -use crate::util::io::{dir_copy, dir_size, Counter}; +use crate::util::io::{create_file, dir_copy, dir_size, Counter}; use crate::{Error, ErrorKind, ResultExt}; pub fn setup() -> ParentHandler { @@ -324,7 +323,7 @@ pub async fn execute( pub async fn complete(ctx: SetupContext) -> Result { match ctx.result.get() { Some(Ok((res, ctx))) => { - let mut guid_file = File::create("/media/startos/config/disk.guid").await?; + let mut guid_file = create_file("/media/startos/config/disk.guid").await?; guid_file.write_all(ctx.disk_guid.as_bytes()).await?; guid_file.sync_all().await?; Ok(res.clone()) diff --git a/core/startos/src/ssh.rs b/core/startos/src/ssh.rs index 82d06be4c..b97fba3e4 100644 --- a/core/startos/src/ssh.rs +++ b/core/startos/src/ssh.rs @@ -13,6 +13,7 @@ use ts_rs::TS; use crate::context::{CliContext, RpcContext}; use crate::prelude::*; use crate::util::clap::FromStrParser; +use crate::util::io::create_file; use crate::util::serde::{display_serializable, HandlerExtSerde, WithIoFormat}; pub const SSH_AUTHORIZED_KEYS_FILE: &str = "/home/start9/.ssh/authorized_keys"; @@ -229,7 +230,7 @@ pub async fn sync_keys>(keys: &SshKeys, dest: P) -> Result<(), Er if tokio::fs::metadata(ssh_dir).await.is_err() { tokio::fs::create_dir_all(ssh_dir).await?; } - let mut f = tokio::fs::File::create(dest).await?; + let mut f = create_file(dest).await?; for key in keys.0.values() { f.write_all(key.0.to_key_format().as_bytes()).await?; f.write_all(b"\n").await?; diff --git a/core/startos/src/system.rs b/core/startos/src/system.rs index 50b17b54a..7a8cb9afe 100644 --- a/core/startos/src/system.rs +++ b/core/startos/src/system.rs @@ -20,6 +20,7 @@ use crate::prelude::*; use crate::rpc_continuations::RpcContinuations; use crate::shutdown::Shutdown; use crate::util::cpupower::{get_available_governors, set_governor, Governor}; +use crate::util::io::open_file; use crate::util::serde::{display_serializable, HandlerExtSerde, WithIoFormat}; use crate::util::Invoke; @@ -657,7 +658,7 @@ impl ProcStat { async fn get_proc_stat() -> Result { use tokio::io::AsyncBufReadExt; let mut cpu_line = String::new(); - let _n = tokio::io::BufReader::new(tokio::fs::File::open("/proc/stat").await?) + let _n = tokio::io::BufReader::new(open_file("/proc/stat").await?) .read_line(&mut cpu_line) .await?; let stats: Vec = cpu_line diff --git a/core/startos/src/update/mod.rs b/core/startos/src/update/mod.rs index dc164d2cd..79d852754 100644 --- a/core/startos/src/update/mod.rs +++ b/core/startos/src/update/mod.rs @@ -4,8 +4,8 @@ use std::time::Duration; use clap::{ArgAction, Parser}; use color_eyre::eyre::{eyre, Result}; -use emver::{Version, VersionRange}; -use futures::{FutureExt, TryStreamExt}; +use exver::{Version, VersionRange}; +use futures::TryStreamExt; use helpers::{AtomicFile, NonDetachingJoinHandle}; use imbl_value::json; use itertools::Itertools; diff --git a/core/startos/src/upload.rs b/core/startos/src/upload.rs index b922ab9d2..4735a63fb 100644 --- a/core/startos/src/upload.rs +++ b/core/startos/src/upload.rs @@ -1,3 +1,4 @@ +use std::io::SeekFrom; use std::pin::Pin; use std::sync::Arc; use std::task::Poll; @@ -5,20 +6,20 @@ use std::time::Duration; use axum::body::Body; use axum::response::Response; -use futures::StreamExt; +use futures::{ready, FutureExt, StreamExt}; use http::header::CONTENT_LENGTH; use http::StatusCode; use imbl_value::InternedString; use tokio::fs::File; -use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt}; +use tokio::io::{AsyncRead, AsyncSeek, AsyncSeekExt, AsyncWrite, AsyncWriteExt}; use tokio::sync::watch; use crate::context::RpcContext; use crate::prelude::*; use crate::rpc_continuations::{Guid, RpcContinuation}; -use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile; +use crate::s9pk::merkle_archive::source::multi_cursor_file::{FileCursor, MultiCursorFile}; use crate::s9pk::merkle_archive::source::ArchiveSource; -use crate::util::io::TmpDir; +use crate::util::io::{create_file, TmpDir}; pub async fn upload( ctx: &RpcContext, @@ -215,14 +216,15 @@ impl UploadingFile { pub async fn new() -> Result<(UploadHandle, Self), Error> { let progress = watch::channel(Progress::default()); let tmp_dir = Arc::new(TmpDir::new().await?); - let file = File::create(tmp_dir.join("upload.tmp")).await?; + let file = create_file(tmp_dir.join("upload.tmp")).await?; let uploading = Self { - tmp_dir, + tmp_dir: tmp_dir.clone(), file: MultiCursorFile::open(&file).await?, progress: progress.1, }; Ok(( UploadHandle { + tmp_dir, file, progress: progress.0, }, @@ -237,22 +239,127 @@ impl UploadingFile { } } impl ArchiveSource for UploadingFile { - type Reader = ::Reader; + type FetchReader = ::FetchReader; + type FetchAllReader = UploadingFileReader; async fn size(&self) -> Option { Progress::expected_size(&mut self.progress.clone()).await } - async fn fetch_all(&self) -> Result { - Progress::ready(&mut self.progress.clone()).await?; - self.file.fetch_all().await + async fn fetch_all(&self) -> Result { + let mut file = self.file.cursor().await?; + file.seek(SeekFrom::Start(0)).await?; + Ok(UploadingFileReader { + tmp_dir: self.tmp_dir.clone(), + file, + position: 0, + to_seek: None, + progress: self.progress.clone(), + }) } - async fn fetch(&self, position: u64, size: u64) -> Result { + async fn fetch(&self, position: u64, size: u64) -> Result { Progress::ready_for(&mut self.progress.clone(), position + size).await?; self.file.fetch(position, size).await } } +#[pin_project::pin_project(project = UploadingFileReaderProjection)] +pub struct UploadingFileReader { + tmp_dir: Arc, + position: u64, + to_seek: Option, + #[pin] + file: FileCursor, + progress: watch::Receiver, +} +impl<'a> UploadingFileReaderProjection<'a> { + fn poll_ready(&mut self, cx: &mut std::task::Context<'_>) -> Result { + let ready = Progress::ready(&mut *self.progress); + tokio::pin!(ready); + Ok(ready + .poll_unpin(cx) + .map_err(|e| std::io::Error::other(e.source))? + .is_ready()) + } + fn poll_ready_for( + &mut self, + cx: &mut std::task::Context<'_>, + size: u64, + ) -> Result { + let ready = Progress::ready_for(&mut *self.progress, size); + tokio::pin!(ready); + Ok(ready + .poll_unpin(cx) + .map_err(|e| std::io::Error::other(e.source))? + .is_ready()) + } +} +impl AsyncRead for UploadingFileReader { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + buf: &mut tokio::io::ReadBuf<'_>, + ) -> Poll> { + let mut this = self.project(); + + let position = *this.position; + if this.poll_ready(cx)? || this.poll_ready_for(cx, position + buf.remaining() as u64)? { + let start = buf.filled().len(); + let res = this.file.poll_read(cx, buf); + *this.position += (buf.filled().len() - start) as u64; + res + } else { + Poll::Pending + } + } +} +impl AsyncSeek for UploadingFileReader { + fn start_seek(self: Pin<&mut Self>, position: SeekFrom) -> std::io::Result<()> { + let this = self.project(); + *this.to_seek = Some(position); + Ok(()) + } + fn poll_complete( + self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + let mut this = self.project(); + if let Some(to_seek) = *this.to_seek { + let size = match to_seek { + SeekFrom::Current(n) => (*this.position as i64 + n) as u64, + SeekFrom::Start(n) => n, + SeekFrom::End(n) => { + let expected_size = this.progress.borrow().expected_size; + match expected_size { + Some(end) => (end as i64 + n) as u64, + None => { + if !this.poll_ready(cx)? { + return Poll::Pending; + } + (this.progress.borrow().expected_size.ok_or_else(|| { + std::io::Error::new( + std::io::ErrorKind::Other, + eyre!("upload maked complete without expected size"), + ) + })? as i64 + + n) as u64 + } + } + } + }; + if !this.poll_ready_for(cx, size)? { + return Poll::Pending; + } + } + if let Some(seek) = this.to_seek.take() { + this.file.as_mut().start_seek(seek)?; + } + *this.position = ready!(this.file.as_mut().poll_complete(cx)?); + Poll::Ready(Ok(*this.position)) + } +} + #[pin_project::pin_project(PinnedDrop)] pub struct UploadHandle { + tmp_dir: Arc, #[pin] file: File, progress: watch::Sender, diff --git a/core/startos/src/util/io.rs b/core/startos/src/util/io.rs index 9a6bab64b..1ec789f23 100644 --- a/core/startos/src/util/io.rs +++ b/core/startos/src/util/io.rs @@ -1,4 +1,4 @@ -use std::collections::{BTreeSet, VecDeque}; +use std::collections::VecDeque; use std::future::Future; use std::io::Cursor; use std::os::unix::prelude::MetadataExt; @@ -610,13 +610,13 @@ pub fn dir_copy<'a, P0: AsRef + 'a + Send + Sync, P1: AsRef + 'a + S let src_path = e.path(); let dst_path = dst_path.join(e.file_name()); if m.is_file() { - let mut dst_file = tokio::fs::File::create(&dst_path).await.with_ctx(|_| { + let mut dst_file = create_file(&dst_path).await.with_ctx(|_| { ( crate::ErrorKind::Filesystem, format!("create {}", dst_path.display()), ) })?; - let mut rdr = tokio::fs::File::open(&src_path).await.with_ctx(|_| { + let mut rdr = open_file(&src_path).await.with_ctx(|_| { ( crate::ErrorKind::Filesystem, format!("open {}", src_path.display()), @@ -706,16 +706,16 @@ impl AsyncRead for TimeoutStream { buf: &mut tokio::io::ReadBuf<'_>, ) -> std::task::Poll> { let mut this = self.project(); - if let std::task::Poll::Ready(_) = this.sleep.as_mut().poll(cx) { + let timeout = this.sleep.as_mut().poll(cx); + let res = this.stream.poll_read(cx, buf); + if res.is_ready() { + this.sleep.reset(Instant::now() + *this.timeout); + } else if timeout.is_ready() { return std::task::Poll::Ready(Err(std::io::Error::new( std::io::ErrorKind::TimedOut, "timed out", ))); } - let res = this.stream.poll_read(cx, buf); - if res.is_ready() { - this.sleep.reset(Instant::now() + *this.timeout); - } res } } @@ -725,10 +725,16 @@ impl AsyncWrite for TimeoutStream { cx: &mut std::task::Context<'_>, buf: &[u8], ) -> std::task::Poll> { - let this = self.project(); + let mut this = self.project(); + let timeout = this.sleep.as_mut().poll(cx); let res = this.stream.poll_write(cx, buf); if res.is_ready() { this.sleep.reset(Instant::now() + *this.timeout); + } else if timeout.is_ready() { + return std::task::Poll::Ready(Err(std::io::Error::new( + std::io::ErrorKind::TimedOut, + "timed out", + ))); } res } @@ -736,10 +742,16 @@ impl AsyncWrite for TimeoutStream { self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>, ) -> std::task::Poll> { - let this = self.project(); + let mut this = self.project(); + let timeout = this.sleep.as_mut().poll(cx); let res = this.stream.poll_flush(cx); if res.is_ready() { this.sleep.reset(Instant::now() + *this.timeout); + } else if timeout.is_ready() { + return std::task::Poll::Ready(Err(std::io::Error::new( + std::io::ErrorKind::TimedOut, + "timed out", + ))); } res } @@ -747,10 +759,16 @@ impl AsyncWrite for TimeoutStream { self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>, ) -> std::task::Poll> { - let this = self.project(); + let mut this = self.project(); + let timeout = this.sleep.as_mut().poll(cx); let res = this.stream.poll_shutdown(cx); if res.is_ready() { this.sleep.reset(Instant::now() + *this.timeout); + } else if timeout.is_ready() { + return std::task::Poll::Ready(Err(std::io::Error::new( + std::io::ErrorKind::TimedOut, + "timed out", + ))); } res } @@ -811,6 +829,13 @@ impl Drop for TmpDir { } } +pub async fn open_file(path: impl AsRef) -> Result { + let path = path.as_ref(); + File::open(path) + .await + .with_ctx(|_| (ErrorKind::Filesystem, lazy_format!("open {path:?}"))) +} + pub async fn create_file(path: impl AsRef) -> Result { let path = path.as_ref(); if let Some(parent) = path.parent() { diff --git a/core/startos/src/util/mod.rs b/core/startos/src/util/mod.rs index f2334632e..7200eaaba 100644 --- a/core/startos/src/util/mod.rs +++ b/core/startos/src/util/mod.rs @@ -26,6 +26,7 @@ use tokio::sync::{oneshot, Mutex, OwnedMutexGuard, RwLock}; use tracing::instrument; use crate::shutdown::Shutdown; +use crate::util::io::create_file; use crate::{Error, ErrorKind, ResultExt as _}; pub mod actor; pub mod clap; @@ -385,16 +386,16 @@ impl SOption for SNone {} #[async_trait] pub trait AsyncFileExt: Sized { - async fn maybe_open + Send + Sync>(path: P) -> std::io::Result>; + async fn maybe_open + Send + Sync>(path: P) -> Result, Error>; async fn delete + Send + Sync>(path: P) -> std::io::Result<()>; } #[async_trait] impl AsyncFileExt for File { - async fn maybe_open + Send + Sync>(path: P) -> std::io::Result> { - match File::open(path).await { + async fn maybe_open + Send + Sync>(path: P) -> Result, Error> { + match File::open(path.as_ref()).await { Ok(f) => Ok(Some(f)), Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(None), - Err(e) => Err(e), + Err(e) => Err(e).with_ctx(|_| (ErrorKind::Filesystem, path.as_ref().display())), } } async fn delete + Send + Sync>(path: P) -> std::io::Result<()> { @@ -590,9 +591,7 @@ impl FileLock { .await .with_ctx(|_| (crate::ErrorKind::Filesystem, parent.display().to_string()))?; } - let f = File::create(&path) - .await - .with_ctx(|_| (crate::ErrorKind::Filesystem, path.display().to_string()))?; + let f = create_file(&path).await?; let file_guard = tokio::task::spawn_blocking(move || { fd_lock_rs::FdLock::lock(f, fd_lock_rs::LockType::Exclusive, blocking) }) diff --git a/core/startos/src/util/rpc.rs b/core/startos/src/util/rpc.rs index e80aac6cb..54664833b 100644 --- a/core/startos/src/util/rpc.rs +++ b/core/startos/src/util/rpc.rs @@ -3,7 +3,6 @@ use std::path::Path; use clap::Parser; use rpc_toolkit::{from_fn_async, Context, ParentHandler}; use serde::{Deserialize, Serialize}; -use tokio::fs::File; use url::Url; use crate::context::CliContext; @@ -11,7 +10,7 @@ use crate::prelude::*; use crate::s9pk::merkle_archive::source::http::HttpSource; use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile; use crate::s9pk::merkle_archive::source::ArchiveSource; -use crate::util::io::ParallelBlake3Writer; +use crate::util::io::{open_file, ParallelBlake3Writer}; use crate::util::serde::Base16; use crate::util::Apply; use crate::CAP_10_MiB; @@ -40,7 +39,7 @@ pub async fn b3sum( path: impl AsRef, allow_mmap: bool, ) -> Result, Error> { - let file = MultiCursorFile::from(File::open(path).await?); + let file = MultiCursorFile::from(open_file(path).await?); if allow_mmap { return file.blake3_mmap().await.map(|h| *h.as_bytes()).map(Base16); } diff --git a/core/startos/src/util/serde.rs b/core/startos/src/util/serde.rs index 5d1289e7e..b3b2dea6a 100644 --- a/core/startos/src/util/serde.rs +++ b/core/startos/src/util/serde.rs @@ -1,4 +1,3 @@ -use std::any::TypeId; use std::collections::VecDeque; use std::marker::PhantomData; use std::ops::Deref; @@ -9,10 +8,9 @@ use clap::{ArgMatches, CommandFactory, FromArgMatches}; use color_eyre::eyre::eyre; use imbl::OrdMap; use openssl::pkey::{PKey, Private}; -use openssl::x509::{X509Ref, X509}; +use openssl::x509::X509; use rpc_toolkit::{ - CliBindings, Context, Handler, HandlerArgs, HandlerArgsFor, HandlerFor, HandlerTypes, - PrintCliResult, + CliBindings, Context, HandlerArgs, HandlerArgsFor, HandlerFor, HandlerTypes, PrintCliResult, }; use serde::de::DeserializeOwned; use serde::ser::{SerializeMap, SerializeSeq}; @@ -1188,7 +1186,7 @@ pub trait PemEncoding: Sized { impl PemEncoding for X509 { fn from_pem(pem: &str) -> Result { - X509::from_pem(pem.as_bytes()).map_err(E::custom) + Self::from_pem(pem.as_bytes()).map_err(E::custom) } fn to_pem(&self) -> Result { String::from_utf8((&**self).to_pem().map_err(E::custom)?).map_err(E::custom) @@ -1197,7 +1195,7 @@ impl PemEncoding for X509 { impl PemEncoding for PKey { fn from_pem(pem: &str) -> Result { - PKey::::private_key_from_pem(pem.as_bytes()).map_err(E::custom) + Self::private_key_from_pem(pem.as_bytes()).map_err(E::custom) } fn to_pem(&self) -> Result { String::from_utf8((&**self).private_key_to_pem_pkcs8().map_err(E::custom)?) @@ -1207,7 +1205,7 @@ impl PemEncoding for PKey { impl PemEncoding for ssh_key::PrivateKey { fn from_pem(pem: &str) -> Result { - ssh_key::PrivateKey::from_openssh(pem.as_bytes()).map_err(E::custom) + Self::from_openssh(pem.as_bytes()).map_err(E::custom) } fn to_pem(&self) -> Result { self.to_openssh(ssh_key::LineEnding::LF) @@ -1219,7 +1217,7 @@ impl PemEncoding for ssh_key::PrivateKey { impl PemEncoding for ed25519_dalek::VerifyingKey { fn from_pem(pem: &str) -> Result { use ed25519_dalek::pkcs8::DecodePublicKey; - ed25519_dalek::VerifyingKey::from_public_key_pem(pem).map_err(E::custom) + Self::from_public_key_pem(pem).map_err(E::custom) } fn to_pem(&self) -> Result { use ed25519_dalek::pkcs8::EncodePublicKey; @@ -1228,6 +1226,19 @@ impl PemEncoding for ed25519_dalek::VerifyingKey { } } +impl PemEncoding for ed25519_dalek::SigningKey { + fn from_pem(pem: &str) -> Result { + use ed25519_dalek::pkcs8::DecodePrivateKey; + Self::from_pkcs8_pem(pem).map_err(E::custom) + } + fn to_pem(&self) -> Result { + use ed25519_dalek::pkcs8::EncodePrivateKey; + self.to_pkcs8_pem(pkcs8::LineEnding::LF) + .map_err(E::custom) + .map(|s| s.as_str().to_owned()) + } +} + pub mod pem { use serde::{Deserialize, Deserializer, Serializer}; diff --git a/core/startos/src/version/mod.rs b/core/startos/src/version/mod.rs index d063558e2..003a44326 100644 --- a/core/startos/src/version/mod.rs +++ b/core/startos/src/version/mod.rs @@ -25,20 +25,20 @@ enum Version { V0_3_5_1(Wrapper), V0_3_5_2(Wrapper), V0_3_6(Wrapper), - Other(emver::Version), + Other(exver::Version), } impl Version { - fn from_util_version(version: crate::util::VersionString) -> Self { + fn from_exver_version(version: exver::Version) -> Self { serde_json::to_value(version.clone()) .and_then(serde_json::from_value) .unwrap_or_else(|_e| { tracing::warn!("Can't deserialize: {:?} and falling back to other", version); - Version::Other(version.into_version()) + Version::Other(version) }) } #[cfg(test)] - fn as_sem_ver(&self) -> emver::Version { + fn as_exver(&self) -> exver::Version { match self { Version::LT0_3_5(LTWrapper(_, x)) => x.clone(), Version::V0_3_5(Wrapper(x)) => x.semver(), @@ -56,8 +56,8 @@ where { type Previous: VersionT; fn new() -> Self; - fn semver(&self) -> emver::Version; - fn compat(&self) -> &'static emver::VersionRange; + fn semver(&self) -> exver::Version; + fn compat(&self) -> &'static exver::VersionRange; fn up(&self, db: &TypedPatchDb) -> impl Future> + Send; fn down(&self, db: &TypedPatchDb) -> impl Future> + Send; fn commit( @@ -158,7 +158,7 @@ where } #[derive(Debug, Clone)] -struct LTWrapper(T, emver::Version); +struct LTWrapper(T, exver::Version); impl serde::Serialize for LTWrapper where T: VersionT, @@ -172,10 +172,10 @@ where T: VersionT, { fn deserialize>(deserializer: D) -> Result { - let v = crate::util::VersionString::deserialize(deserializer)?; + let v = exver::Version::deserialize(deserializer)?; let version = T::new(); - if *v < version.semver() { - Ok(Self(version, v.into_version())) + if v < version.semver() { + Ok(Self(version, v)) } else { Err(serde::de::Error::custom("Mismatched Version")) } @@ -197,9 +197,9 @@ where T: VersionT, { fn deserialize>(deserializer: D) -> Result { - let v = crate::util::VersionString::deserialize(deserializer)?; + let v = exver::Version::deserialize(deserializer)?; let version = T::new(); - if *v == version.semver() { + if v == version.semver() { Ok(Wrapper(version)) } else { Err(serde::de::Error::custom("Mismatched Version")) @@ -212,7 +212,7 @@ pub async fn init( mut progress: PhaseProgressTrackerHandle, ) -> Result<(), Error> { progress.start(); - let version = Version::from_util_version( + let version = Version::from_exver_version( db.peek() .await .as_public() @@ -256,9 +256,18 @@ mod tests { use super::*; - fn em_version() -> impl Strategy { - any::<(usize, usize, usize, usize)>().prop_map(|(major, minor, patch, super_minor)| { - emver::Version::new(major, minor, patch, super_minor) + fn em_version() -> impl Strategy { + any::<(usize, usize, usize, bool)>().prop_map(|(major, minor, patch, alpha)| { + if alpha { + exver::Version::new( + [0, major, minor] + .into_iter() + .chain(Some(patch).filter(|n| *n != 0)), + [], + ) + } else { + exver::Version::new([major, minor, patch], []) + } }) } @@ -273,15 +282,15 @@ mod tests { proptest! { #[test] - fn emversion_isomorphic_version(original in em_version()) { - let version = Version::from_util_version(original.clone().into()); - let back = version.as_sem_ver(); + fn exversion_isomorphic_version(original in em_version()) { + let version = Version::from_exver_version(original.clone().into()); + let back = version.as_exver(); prop_assert_eq!(original, back, "All versions should round trip"); } #[test] fn version_isomorphic_em_version(version in versions()) { - let sem_ver = version.as_sem_ver(); - let back = Version::from_util_version(sem_ver.into()); + let sem_ver = version.as_exver(); + let back = Version::from_exver_version(sem_ver.into()); prop_assert_eq!(format!("{:?}",version), format!("{:?}", back), "All versions should round trip"); } } diff --git a/core/startos/src/version/v0_3_5.rs b/core/startos/src/version/v0_3_5.rs index 21be1ca49..167132784 100644 --- a/core/startos/src/version/v0_3_5.rs +++ b/core/startos/src/version/v0_3_5.rs @@ -1,4 +1,4 @@ -use emver::VersionRange; +use exver::{ExtendedVersion, VersionRange}; use super::VersionT; use crate::db::model::Database; @@ -6,17 +6,25 @@ use crate::prelude::*; use crate::version::Current; lazy_static::lazy_static! { - pub static ref V0_3_0_COMPAT: VersionRange = VersionRange::Conj( - Box::new(VersionRange::Anchor( - emver::GTE, - emver::Version::new(0, 3, 0, 0), - )), - Box::new(VersionRange::Anchor(emver::LTE, Current::new().semver())), + pub static ref V0_3_0_COMPAT: VersionRange = VersionRange::and( + VersionRange::anchor( + exver::GTE, + ExtendedVersion::new( + exver::Version::new([0, 3, 0], []), + exver::Version::default(), + ), + ), + VersionRange::anchor( + exver::LTE, + ExtendedVersion::new( + Current::new().semver(), + exver::Version::default(), + ) + ), ); + static ref V0_3_5: exver::Version = exver::Version::new([0, 3, 5], []); } -const V0_3_5: emver::Version = emver::Version::new(0, 3, 5, 0); - #[derive(Clone, Debug)] pub struct Version; @@ -25,8 +33,8 @@ impl VersionT for Version { fn new() -> Self { Version } - fn semver(&self) -> emver::Version { - V0_3_5 + fn semver(&self) -> exver::Version { + V0_3_5.clone() } fn compat(&self) -> &'static VersionRange { &V0_3_0_COMPAT diff --git a/core/startos/src/version/v0_3_5_1.rs b/core/startos/src/version/v0_3_5_1.rs index d0f99c153..c6c328f6d 100644 --- a/core/startos/src/version/v0_3_5_1.rs +++ b/core/startos/src/version/v0_3_5_1.rs @@ -1,11 +1,13 @@ -use emver::VersionRange; +use exver::VersionRange; use super::v0_3_5::V0_3_0_COMPAT; use super::{v0_3_5, VersionT}; use crate::db::model::Database; use crate::prelude::*; -const V0_3_5_1: emver::Version = emver::Version::new(0, 3, 5, 1); +lazy_static::lazy_static! { + static ref V0_3_5_1: exver::Version = exver::Version::new([0, 3, 5, 1], []); +} #[derive(Clone, Debug)] pub struct Version; @@ -15,8 +17,8 @@ impl VersionT for Version { fn new() -> Self { Version } - fn semver(&self) -> emver::Version { - V0_3_5_1 + fn semver(&self) -> exver::Version { + V0_3_5_1.clone() } fn compat(&self) -> &'static VersionRange { &V0_3_0_COMPAT diff --git a/core/startos/src/version/v0_3_5_2.rs b/core/startos/src/version/v0_3_5_2.rs index fae689997..00143f8cd 100644 --- a/core/startos/src/version/v0_3_5_2.rs +++ b/core/startos/src/version/v0_3_5_2.rs @@ -1,11 +1,13 @@ -use emver::VersionRange; +use exver::VersionRange; use super::v0_3_5::V0_3_0_COMPAT; use super::{v0_3_5_1, VersionT}; use crate::db::model::Database; use crate::prelude::*; -const V0_3_5_2: emver::Version = emver::Version::new(0, 3, 5, 2); +lazy_static::lazy_static! { + static ref V0_3_5_2: exver::Version = exver::Version::new([0, 3, 5, 2], []); +} #[derive(Clone, Debug)] pub struct Version; @@ -15,8 +17,8 @@ impl VersionT for Version { fn new() -> Self { Version } - fn semver(&self) -> emver::Version { - V0_3_5_2 + fn semver(&self) -> exver::Version { + V0_3_5_2.clone() } fn compat(&self) -> &'static VersionRange { &V0_3_0_COMPAT diff --git a/core/startos/src/version/v0_3_6.rs b/core/startos/src/version/v0_3_6.rs index 0ff6d662a..9564a7376 100644 --- a/core/startos/src/version/v0_3_6.rs +++ b/core/startos/src/version/v0_3_6.rs @@ -1,11 +1,13 @@ -use emver::VersionRange; +use exver::VersionRange; use super::v0_3_5::V0_3_0_COMPAT; use super::{v0_3_5_1, VersionT}; use crate::db::model::Database; use crate::prelude::*; -const V0_3_6: emver::Version = emver::Version::new(0, 3, 6, 0); +lazy_static::lazy_static! { + static ref V0_3_6: exver::Version = exver::Version::new([0, 3, 6], []); +} #[derive(Clone, Debug)] pub struct Version; @@ -15,8 +17,8 @@ impl VersionT for Version { fn new() -> Self { Version } - fn semver(&self) -> emver::Version { - V0_3_6 + fn semver(&self) -> exver::Version { + V0_3_6.clone() } fn compat(&self) -> &'static VersionRange { &V0_3_0_COMPAT diff --git a/debian/postinst b/debian/postinst index 238bd9457..96e392fc8 100755 --- a/debian/postinst +++ b/debian/postinst @@ -78,6 +78,7 @@ sed -i '/\(^\|#\)Compress=/c\Compress=yes' /etc/systemd/journald.conf sed -i '/\(^\|#\)SystemMaxUse=/c\SystemMaxUse=1G' /etc/systemd/journald.conf sed -i '/\(^\|#\)ForwardToSyslog=/c\ForwardToSyslog=no' /etc/systemd/journald.conf sed -i '/^\s*#\?\s*issue_discards\s*=\s*/c\issue_discards = 1' /etc/lvm/lvm.conf +sed -i '/\(^\|#\)\s*unqualified-search-registries\s*=\s*/c\unqualified-search-registries = ["docker.io"]' /etc/containers/registries.conf mkdir -p /etc/nginx/ssl diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..497f28c49 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "embassy-os", + "lockfileVersion": 2, + "requires": true, + "packages": {} +} diff --git a/patch-db b/patch-db index 7aa53249f..99076d349 160000 --- a/patch-db +++ b/patch-db @@ -1 +1 @@ -Subproject commit 7aa53249f9353162475ea347abac92abcfba5493 +Subproject commit 99076d349c6768000483ea8d47216d273586552e diff --git a/sdk/lib/StartSdk.ts b/sdk/lib/StartSdk.ts index 4208928c9..fac78a4af 100644 --- a/sdk/lib/StartSdk.ts +++ b/sdk/lib/StartSdk.ts @@ -480,7 +480,6 @@ export class StartSdk { }, List: { text: List.text, - number: List.number, obj: >( a: { name: string @@ -523,29 +522,6 @@ export class StartSdk { } >, ) => List.dynamicText(getA), - dynamicNumber: ( - getA: LazyBuild< - Store, - { - name: string - description?: string | null - warning?: string | null - /** Default = [] */ - default?: string[] - minLength?: number | null - maxLength?: number | null - disabled?: false | string - spec: { - integer: boolean - min?: number | null - max?: number | null - step?: number | null - units?: string | null - placeholder?: string | null - } - } - >, - ) => List.dynamicNumber(getA), }, Migration: { of: (options: { diff --git a/sdk/lib/config/builder/list.ts b/sdk/lib/config/builder/list.ts index 8a251069d..f230b8608 100644 --- a/sdk/lib/config/builder/list.ts +++ b/sdk/lib/config/builder/list.ts @@ -125,96 +125,6 @@ export class List { return built }, arrayOf(string)) } - static number( - a: { - name: string - description?: string | null - warning?: string | null - /** Default = [] */ - default?: string[] - minLength?: number | null - maxLength?: number | null - }, - aSpec: { - integer: boolean - min?: number | null - max?: number | null - step?: number | null - units?: string | null - placeholder?: string | null - }, - ) { - return new List(() => { - const spec = { - type: "number" as const, - placeholder: null, - min: null, - max: null, - step: null, - units: null, - ...aSpec, - } - const built: ValueSpecListOf<"number"> = { - description: null, - warning: null, - minLength: null, - maxLength: null, - default: [], - type: "list" as const, - disabled: false, - ...a, - spec, - } - return built - }, arrayOf(number)) - } - static dynamicNumber( - getA: LazyBuild< - Store, - { - name: string - description?: string | null - warning?: string | null - /** Default = [] */ - default?: string[] - minLength?: number | null - maxLength?: number | null - disabled?: false | string - spec: { - integer: boolean - min?: number | null - max?: number | null - step?: number | null - units?: string | null - placeholder?: string | null - } - } - >, - ) { - return new List(async (options) => { - const { spec: aSpec, ...a } = await getA(options) - const spec = { - type: "number" as const, - placeholder: null, - min: null, - max: null, - step: null, - units: null, - ...aSpec, - } - return { - description: null, - warning: null, - minLength: null, - maxLength: null, - default: [], - type: "list" as const, - disabled: false, - ...a, - spec, - } - }, arrayOf(number)) - } static obj, Store>( a: { name: string diff --git a/sdk/lib/config/builder/variants.ts b/sdk/lib/config/builder/variants.ts index 1e7a2a384..352f16828 100644 --- a/sdk/lib/config/builder/variants.ts +++ b/sdk/lib/config/builder/variants.ts @@ -69,8 +69,8 @@ export class Variants { const validator = anyOf( ...Object.entries(a).map(([name, { spec }]) => object({ - unionSelectKey: literals(name), - unionValueKey: spec.validator, + selection: literals(name), + value: spec.validator, }), ), ) as Parser @@ -78,9 +78,9 @@ export class Variants { return new Variants< { [K in keyof VariantValues]: { - unionSelectKey: K + selection: K // prettier-ignore - unionValueKey: + value: VariantValues[K]["spec"] extends (Config | Config) ? B : never } diff --git a/sdk/lib/config/configTypes.ts b/sdk/lib/config/configTypes.ts index 14e0e1d1d..14d857433 100644 --- a/sdk/lib/config/configTypes.ts +++ b/sdk/lib/config/configTypes.ts @@ -15,70 +15,93 @@ export type ValueType = export type ValueSpec = ValueSpecOf /** core spec types. These types provide the metadata for performing validations */ // prettier-ignore -export type ValueSpecOf = T extends "text" - ? ValueSpecText - : T extends "textarea" - ? ValueSpecTextarea - : T extends "number" - ? ValueSpecNumber - : T extends "color" - ? ValueSpecColor - : T extends "datetime" - ? ValueSpecDatetime - : T extends "toggle" - ? ValueSpecToggle - : T extends "select" - ? ValueSpecSelect - : T extends "multiselect" - ? ValueSpecMultiselect - : T extends "list" - ? ValueSpecList - : T extends "object" - ? ValueSpecObject - : T extends "file" - ? ValueSpecFile - : T extends "union" - ? ValueSpecUnion - : never +export type ValueSpecOf = + T extends "text" ? ValueSpecText : + T extends "textarea" ? ValueSpecTextarea : + T extends "number" ? ValueSpecNumber : + T extends "color" ? ValueSpecColor : + T extends "datetime" ? ValueSpecDatetime : + T extends "toggle" ? ValueSpecToggle : + T extends "select" ? ValueSpecSelect : + T extends "multiselect" ? ValueSpecMultiselect : + T extends "list" ? ValueSpecList : + T extends "object" ? ValueSpecObject : + T extends "file" ? ValueSpecFile : + T extends "union" ? ValueSpecUnion : + never + +export type ValueSpecText = { + name: string + description: string | null + warning: string | null + + type: "text" + patterns: Pattern[] + minLength: number | null + maxLength: number | null + masked: boolean + + inputmode: "text" | "email" | "tel" | "url" + placeholder: string | null -export interface ValueSpecText extends ListValueSpecText, WithStandalone { required: boolean default: DefaultString | null disabled: false | string generate: null | RandomString - /** Immutable means it can only be configed at the first config then never again */ + /** Immutable means it can only be configured at the first config then never again */ immutable: boolean } -export interface ValueSpecTextarea extends WithStandalone { +export type ValueSpecTextarea = { + name: string + description: string | null + warning: string | null + type: "textarea" placeholder: string | null minLength: number | null maxLength: number | null required: boolean disabled: false | string - /** Immutable means it can only be configed at the first config then never again */ + /** Immutable means it can only be configured at the first config then never again */ immutable: boolean } export type FilePath = { filePath: string } -export interface ValueSpecNumber extends ListValueSpecNumber, WithStandalone { +export type ValueSpecNumber = { + type: "number" + min: number | null + max: number | null + integer: boolean + step: number | null + units: string | null + placeholder: string | null + name: string + description: string | null + warning: string | null required: boolean default: number | null disabled: false | string - /** Immutable means it can only be configed at the first config then never again */ + /** Immutable means it can only be configured at the first config then never again */ immutable: boolean } -export interface ValueSpecColor extends WithStandalone { +export type ValueSpecColor = { + name: string + description: string | null + warning: string | null + type: "color" required: boolean default: string | null disabled: false | string - /** Immutable means it can only be configed at the first config then never again */ + /** Immutable means it can only be configured at the first config then never again */ immutable: boolean } -export interface ValueSpecDatetime extends WithStandalone { +export type ValueSpecDatetime = { + name: string + description: string | null + warning: string | null type: "datetime" required: boolean inputmode: "date" | "time" | "datetime-local" @@ -86,10 +109,14 @@ export interface ValueSpecDatetime extends WithStandalone { max: string | null default: string | null disabled: false | string - /** Immutable means it can only be configed at the first config then never again */ + /** Immutable means it can only be configured at the first config then never again */ immutable: boolean } -export interface ValueSpecSelect extends SelectBase, WithStandalone { +export type ValueSpecSelect = { + values: Record + name: string + description: string | null + warning: string | null type: "select" required: boolean default: string | null @@ -99,10 +126,16 @@ export interface ValueSpecSelect extends SelectBase, WithStandalone { * string[] means that the options are disabled */ disabled: false | string | string[] - /** Immutable means it can only be configed at the first config then never again */ + /** Immutable means it can only be configured at the first config then never again */ immutable: boolean } -export interface ValueSpecMultiselect extends SelectBase, WithStandalone { +export type ValueSpecMultiselect = { + values: Record + + name: string + description: string | null + warning: string | null + type: "multiselect" minLength: number | null maxLength: number | null @@ -113,17 +146,25 @@ export interface ValueSpecMultiselect extends SelectBase, WithStandalone { */ disabled: false | string | string[] default: string[] - /** Immutable means it can only be configed at the first config then never again */ + /** Immutable means it can only be configured at the first config then never again */ immutable: boolean } -export interface ValueSpecToggle extends WithStandalone { +export type ValueSpecToggle = { + name: string + description: string | null + warning: string | null + type: "toggle" default: boolean | null disabled: false | string - /** Immutable means it can only be configed at the first config then never again */ + /** Immutable means it can only be configured at the first config then never again */ immutable: boolean } -export interface ValueSpecUnion extends WithStandalone { +export type ValueSpecUnion = { + name: string + description: string | null + warning: string | null + type: "union" variants: Record< string, @@ -140,39 +181,37 @@ export interface ValueSpecUnion extends WithStandalone { disabled: false | string | string[] required: boolean default: string | null - /** Immutable means it can only be configed at the first config then never again */ + /** Immutable means it can only be configured at the first config then never again */ immutable: boolean } -export interface ValueSpecFile extends WithStandalone { +export type ValueSpecFile = { + name: string + description: string | null + warning: string | null type: "file" extensions: string[] required: boolean } -export interface ValueSpecObject extends WithStandalone { - type: "object" - spec: InputSpec -} -export interface WithStandalone { +export type ValueSpecObject = { name: string description: string | null warning: string | null + type: "object" + spec: InputSpec } -export interface SelectBase { - values: Record -} -export type ListValueSpecType = "text" | "number" | "object" +export type ListValueSpecType = "text" | "object" /** represents a spec for the values of a list */ -export type ListValueSpecOf = T extends "text" - ? ListValueSpecText - : T extends "number" - ? ListValueSpecNumber - : T extends "object" - ? ListValueSpecObject - : never +// prettier-ignore +export type ListValueSpecOf = + T extends "text" ? ListValueSpecText : + T extends "object" ? ListValueSpecObject : + never /** represents a spec for a list */ export type ValueSpecList = ValueSpecListOf -export interface ValueSpecListOf - extends WithStandalone { +export type ValueSpecListOf = { + name: string + description: string | null + warning: string | null type: "list" spec: ListValueSpecOf minLength: number | null @@ -180,19 +219,17 @@ export interface ValueSpecListOf disabled: false | string default: | string[] - | number[] | DefaultString[] | Record[] | readonly string[] - | readonly number[] | readonly DefaultString[] | readonly Record[] } -export interface Pattern { +export type Pattern = { regex: string description: string } -export interface ListValueSpecText { +export type ListValueSpecText = { type: "text" patterns: Pattern[] minLength: number | null @@ -203,16 +240,8 @@ export interface ListValueSpecText { inputmode: "text" | "email" | "tel" | "url" placeholder: string | null } -export interface ListValueSpecNumber { - type: "number" - min: number | null - max: number | null - integer: boolean - step: number | null - units: string | null - placeholder: string | null -} -export interface ListValueSpecObject { + +export type ListValueSpecObject = { type: "object" /** this is a mapped type of the config object at this level, replacing the object's values with specs on those values */ spec: InputSpec @@ -242,8 +271,3 @@ export function isValueSpecListOf( ): t is ValueSpecListOf & { spec: ListValueSpecOf } { return "spec" in t && t.spec.type === s } -export const unionSelectKey = "unionSelectKey" as const -export type UnionSelectKey = typeof unionSelectKey - -export const unionValueKey = "unionValueKey" as const -export type UnionValueKey = typeof unionValueKey diff --git a/sdk/lib/emverLite/mod.ts b/sdk/lib/emverLite/mod.ts index f69d4f35d..52fb4e347 100644 --- a/sdk/lib/emverLite/mod.ts +++ b/sdk/lib/emverLite/mod.ts @@ -2,9 +2,9 @@ import * as matches from "ts-matches" const starSub = /((\d+\.)*\d+)\.\*/ // prettier-ignore -export type ValidEmVer = `${number}${`.${number}` | ""}${`.${number}` | ""}${`-${string}` | ""}`; +export type ValidEmVer = string; // prettier-ignore -export type ValidEmVerRange = `${'>=' | '<='| '<' | '>' | ''}${'^' | '~' | ''}${number | '*'}${`.${number | '*'}` | ""}${`.${number | '*'}` | ""}${`-${string}` | ""}`; +export type ValidEmVerRange = string; function incrementLastNumber(list: number[]) { const newList = [...list] diff --git a/sdk/lib/index.browser.ts b/sdk/lib/index.browser.ts index d7c10093f..c7ab45e60 100644 --- a/sdk/lib/index.browser.ts +++ b/sdk/lib/index.browser.ts @@ -1,6 +1,7 @@ export { EmVer } from "./emverLite/mod" export { setupManifest } from "./manifest/setupManifest" export { setupExposeStore } from "./store/setupExposeStore" +export { S9pk } from "./s9pk" export * as config from "./config" export * as CB from "./config/builder" export * as CT from "./config/configTypes" @@ -11,4 +12,4 @@ export * as T from "./types" export * as yaml from "yaml" export * as matches from "ts-matches" -export * as util from "./util/index.browser" +export * as utils from "./util/index.browser" diff --git a/sdk/lib/index.ts b/sdk/lib/index.ts index 89d147ed1..c99798d72 100644 --- a/sdk/lib/index.ts +++ b/sdk/lib/index.ts @@ -6,6 +6,7 @@ export { setupManifest } from "./manifest/setupManifest" export { FileHelper } from "./util/fileHelper" export { setupExposeStore } from "./store/setupExposeStore" export { pathBuilder } from "./store/PathBuilder" +export { S9pk } from "./s9pk" export * as actions from "./actions" export * as backup from "./backup" diff --git a/sdk/lib/mainFn/Daemons.ts b/sdk/lib/mainFn/Daemons.ts index f48dd51c0..059d148ab 100644 --- a/sdk/lib/mainFn/Daemons.ts +++ b/sdk/lib/mainFn/Daemons.ts @@ -168,10 +168,6 @@ export class Daemons { } private updateMainHealth() { - if (this.healthDaemons.every((x) => x.health.status === "success")) { - this.effects.setMainStatus({ status: "running" }) - } else { - this.effects.setMainStatus({ status: "starting" }) - } + this.effects.setMainStatus({ status: "running" }) } } diff --git a/sdk/lib/osBindings/ExecuteAction.ts b/sdk/lib/osBindings/ExecuteAction.ts index abd8c151f..b4eb60949 100644 --- a/sdk/lib/osBindings/ExecuteAction.ts +++ b/sdk/lib/osBindings/ExecuteAction.ts @@ -1,6 +1,8 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Guid } from "./Guid" export type ExecuteAction = { + procedureId: Guid serviceId: string | null actionId: string input: any diff --git a/sdk/lib/osBindings/GetPackageParams.ts b/sdk/lib/osBindings/GetPackageParams.ts index 6dfecc9b2..8b852c35c 100644 --- a/sdk/lib/osBindings/GetPackageParams.ts +++ b/sdk/lib/osBindings/GetPackageParams.ts @@ -1,10 +1,11 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { PackageDetailLevel } from "./PackageDetailLevel" import type { PackageId } from "./PackageId" +import type { Version } from "./Version" export type GetPackageParams = { id: PackageId | null version: string | null - sourceVersion: string | null + sourceVersion: Version | null otherVersions: PackageDetailLevel | null } diff --git a/sdk/lib/osBindings/GetVersionParams.ts b/sdk/lib/osBindings/GetVersionParams.ts index 71762c8dd..853d76022 100644 --- a/sdk/lib/osBindings/GetVersionParams.ts +++ b/sdk/lib/osBindings/GetVersionParams.ts @@ -1,3 +1,8 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type GetVersionParams = { source: string | null; target: string | null } +export type GetVersionParams = { + source: string | null + target: string | null + serverId: string | null + arch: string | null +} diff --git a/sdk/lib/osBindings/InstalledVersionParams.ts b/sdk/lib/osBindings/InstalledVersionParams.ts new file mode 100644 index 000000000..637f9b6ce --- /dev/null +++ b/sdk/lib/osBindings/InstalledVersionParams.ts @@ -0,0 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { PackageId } from "./PackageId" + +export type InstalledVersionParams = { id: PackageId } diff --git a/sdk/lib/osBindings/Manifest.ts b/sdk/lib/osBindings/Manifest.ts index 15b96bd13..d808f47a2 100644 --- a/sdk/lib/osBindings/Manifest.ts +++ b/sdk/lib/osBindings/Manifest.ts @@ -28,6 +28,6 @@ export type Manifest = { dependencies: Dependencies hardwareRequirements: HardwareRequirements gitHash: string | null - osVersion: Version + osVersion: string hasConfig: boolean } diff --git a/sdk/lib/osBindings/PackageVersionInfo.ts b/sdk/lib/osBindings/PackageVersionInfo.ts index bdded46bd..364c530f2 100644 --- a/sdk/lib/osBindings/PackageVersionInfo.ts +++ b/sdk/lib/osBindings/PackageVersionInfo.ts @@ -4,7 +4,6 @@ import type { Description } from "./Description" import type { HardwareRequirements } from "./HardwareRequirements" import type { MerkleArchiveCommitment } from "./MerkleArchiveCommitment" import type { RegistryAsset } from "./RegistryAsset" -import type { Version } from "./Version" export type PackageVersionInfo = { title: string @@ -17,7 +16,7 @@ export type PackageVersionInfo = { upstreamRepo: string supportSite: string marketingSite: string - osVersion: Version + osVersion: string hardwareRequirements: HardwareRequirements sourceVersion: string | null s9pk: RegistryAsset diff --git a/sdk/lib/osBindings/ProcedureId.ts b/sdk/lib/osBindings/ProcedureId.ts new file mode 100644 index 000000000..4d9a0debd --- /dev/null +++ b/sdk/lib/osBindings/ProcedureId.ts @@ -0,0 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Guid } from "./Guid" + +export type ProcedureId = { procedureId: Guid } diff --git a/sdk/lib/osBindings/ServerInfo.ts b/sdk/lib/osBindings/ServerInfo.ts index 92b8b9b8f..935e3a99f 100644 --- a/sdk/lib/osBindings/ServerInfo.ts +++ b/sdk/lib/osBindings/ServerInfo.ts @@ -2,7 +2,6 @@ import type { Governor } from "./Governor" import type { IpInfo } from "./IpInfo" import type { ServerStatus } from "./ServerStatus" -import type { Version } from "./Version" import type { WifiInfo } from "./WifiInfo" export type ServerInfo = { @@ -10,7 +9,7 @@ export type ServerInfo = { platform: string id: string hostname: string - version: Version + version: string lastBackup: string | null eosVersionCompat: string lanAddress: string diff --git a/sdk/lib/osBindings/SetDependenciesParams.ts b/sdk/lib/osBindings/SetDependenciesParams.ts index 7b34b50c9..bbc9b325f 100644 --- a/sdk/lib/osBindings/SetDependenciesParams.ts +++ b/sdk/lib/osBindings/SetDependenciesParams.ts @@ -1,6 +1,8 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { DependencyRequirement } from "./DependencyRequirement" +import type { Guid } from "./Guid" export type SetDependenciesParams = { + procedureId: Guid dependencies: Array } diff --git a/sdk/lib/osBindings/SetMainStatusStatus.ts b/sdk/lib/osBindings/SetMainStatusStatus.ts index 6db32e7bf..03bb4a119 100644 --- a/sdk/lib/osBindings/SetMainStatusStatus.ts +++ b/sdk/lib/osBindings/SetMainStatusStatus.ts @@ -1,3 +1,3 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type SetMainStatusStatus = "running" | "stopped" | "starting" +export type SetMainStatusStatus = "running" | "stopped" diff --git a/sdk/lib/osBindings/index.ts b/sdk/lib/osBindings/index.ts index ac2e19e45..32e57956a 100644 --- a/sdk/lib/osBindings/index.ts +++ b/sdk/lib/osBindings/index.ts @@ -79,6 +79,7 @@ export { ImageMetadata } from "./ImageMetadata" export { ImageSource } from "./ImageSource" export { InitProgressRes } from "./InitProgressRes" export { InstalledState } from "./InstalledState" +export { InstalledVersionParams } from "./InstalledVersionParams" export { InstallingInfo } from "./InstallingInfo" export { InstallingState } from "./InstallingState" export { IpHostname } from "./IpHostname" @@ -108,6 +109,7 @@ export { PackageVersionInfo } from "./PackageVersionInfo" export { ParamsMaybePackageId } from "./ParamsMaybePackageId" export { ParamsPackageId } from "./ParamsPackageId" export { PasswordType } from "./PasswordType" +export { ProcedureId } from "./ProcedureId" export { Progress } from "./Progress" export { Public } from "./Public" export { RecoverySource } from "./RecoverySource" diff --git a/sdk/lib/s9pk/index.ts b/sdk/lib/s9pk/index.ts new file mode 100644 index 000000000..eba8ed3f8 --- /dev/null +++ b/sdk/lib/s9pk/index.ts @@ -0,0 +1,67 @@ +import { DataUrl, Manifest, MerkleArchiveCommitment } from "../osBindings" +import { ArrayBufferReader, MerkleArchive } from "./merkleArchive" +import mime from "mime" + +const magicAndVersion = new Uint8Array([59, 59, 2]) + +export function compare(a: Uint8Array, b: Uint8Array) { + if (a.length !== b.length) return false + for (let i = 0; i < a.length; i++) { + if (a[i] !== b[i]) return false + } + return true +} + +export class S9pk { + private constructor( + readonly manifest: Manifest, + readonly archive: MerkleArchive, + readonly size: number, + ) {} + static async deserialize( + source: Blob, + commitment: MerkleArchiveCommitment | null, + ): Promise { + const header = new ArrayBufferReader( + await source + .slice(0, magicAndVersion.length + MerkleArchive.headerSize) + .arrayBuffer(), + ) + const magicVersion = new Uint8Array(header.next(magicAndVersion.length)) + if (!compare(magicVersion, magicAndVersion)) { + throw new Error("Invalid Magic or Unexpected Version") + } + + const archive = await MerkleArchive.deserialize( + source, + "s9pk", + header, + commitment, + ) + + const manifest = JSON.parse( + new TextDecoder().decode( + await archive.contents + .getPath(["manifest.json"]) + ?.verifiedFileContents(), + ), + ) + + return new S9pk(manifest, archive, source.length) + } + async icon(): Promise { + const iconName = Object.keys(this.archive.contents.contents).find( + (name) => + name.startsWith("icon.") && mime.getType(name)?.startsWith("image/"), + ) + if (!iconName) { + throw new Error("no icon found in archive") + } + return ( + `data:${mime.getType(iconName)};base64,` + + Buffer.from( + await this.archive.contents.getPath([iconName])!.verifiedFileContents(), + ).toString("base64") + ) + } +} diff --git a/sdk/lib/s9pk/merkleArchive/directoryContents.ts b/sdk/lib/s9pk/merkleArchive/directoryContents.ts new file mode 100644 index 000000000..dab7ef53a --- /dev/null +++ b/sdk/lib/s9pk/merkleArchive/directoryContents.ts @@ -0,0 +1,80 @@ +import { ArrayBufferReader, Entry } from "." +import { blake3 } from "@noble/hashes/blake3" +import { serializeVarint } from "./varint" +import { FileContents } from "./fileContents" +import { compare } from ".." + +export class DirectoryContents { + static readonly headerSize = + 8 + // position: u64 BE + 8 // size: u64 BE + private constructor(readonly contents: { [name: string]: Entry }) {} + static async deserialize( + source: Blob, + header: ArrayBufferReader, + sighash: Uint8Array, + maxSize: bigint, + ): Promise { + const position = header.nextU64() + const size = header.nextU64() + if (size > maxSize) { + throw new Error("size is greater than signed") + } + + const tocReader = new ArrayBufferReader( + await source + .slice(Number(position), Number(position + size)) + .arrayBuffer(), + ) + const len = tocReader.nextVarint() + const entries: { [name: string]: Entry } = {} + for (let i = 0; i < len; i++) { + const name = tocReader.nextVarstring() + const entry = await Entry.deserialize(source, tocReader) + entries[name] = entry + } + + const res = new DirectoryContents(entries) + + if (!compare(res.sighash(), sighash)) { + throw new Error("hash sum does not match") + } + + return res + } + sighash(): Uint8Array { + const hasher = blake3.create({}) + const names = Object.keys(this.contents).sort() + hasher.update(new Uint8Array(serializeVarint(names.length))) + for (const name of names) { + const entry = this.contents[name] + const nameBuf = new TextEncoder().encode(name) + hasher.update(new Uint8Array(serializeVarint(nameBuf.length))) + hasher.update(nameBuf) + hasher.update(new Uint8Array(entry.hash)) + const sizeBuf = new Uint8Array(8) + new DataView(sizeBuf.buffer).setBigUint64(0, entry.size) + hasher.update(sizeBuf) + hasher.update(new Uint8Array([0])) + } + + return hasher.digest() + } + getPath(path: string[]): Entry | null { + if (path.length === 0) { + return null + } + const next = this.contents[path[0]] + const rest = path.slice(1) + if (next === undefined) { + return null + } + if (rest.length === 0) { + return next + } + if (next.contents instanceof DirectoryContents) { + return next.contents.getPath(rest) + } + return null + } +} diff --git a/sdk/lib/s9pk/merkleArchive/fileContents.ts b/sdk/lib/s9pk/merkleArchive/fileContents.ts new file mode 100644 index 000000000..7a936f1e8 --- /dev/null +++ b/sdk/lib/s9pk/merkleArchive/fileContents.ts @@ -0,0 +1,24 @@ +import { blake3 } from "@noble/hashes/blake3" +import { ArrayBufferReader } from "." +import { compare } from ".." + +export class FileContents { + private constructor(readonly contents: Blob) {} + static deserialize( + source: Blob, + header: ArrayBufferReader, + size: bigint, + ): FileContents { + const position = header.nextU64() + return new FileContents( + source.slice(Number(position), Number(position + size)), + ) + } + async verified(hash: Uint8Array): Promise { + const res = await this.contents.arrayBuffer() + if (!compare(hash, blake3(new Uint8Array(res)))) { + throw new Error("hash sum mismatch") + } + return res + } +} diff --git a/sdk/lib/s9pk/merkleArchive/index.ts b/sdk/lib/s9pk/merkleArchive/index.ts new file mode 100644 index 000000000..068363599 --- /dev/null +++ b/sdk/lib/s9pk/merkleArchive/index.ts @@ -0,0 +1,167 @@ +import { MerkleArchiveCommitment } from "../../osBindings" +import { DirectoryContents } from "./directoryContents" +import { FileContents } from "./fileContents" +import { ed25519ph } from "@noble/curves/ed25519" +import { sha512 } from "@noble/hashes/sha2" +import { VarIntProcessor } from "./varint" +import { compare } from ".." + +const maxVarstringLen = 1024 * 1024 + +export type Signer = { + pubkey: Uint8Array + signature: Uint8Array + maxSize: bigint + context: string +} + +export class ArrayBufferReader { + constructor(private buffer: ArrayBuffer) {} + next(length: number): ArrayBuffer { + const res = this.buffer.slice(0, length) + this.buffer = this.buffer.slice(length) + return res + } + nextU64(): bigint { + return new DataView(this.next(8)).getBigUint64(0) + } + nextVarint(): number { + const p = new VarIntProcessor() + while (!p.finished()) { + p.push(new Uint8Array(this.buffer.slice(0, 1))[0]) + this.buffer = this.buffer.slice(1) + } + const res = p.decode() + if (res === null) { + throw new Error("Reached EOF") + } + return res + } + nextVarstring(): string { + const len = Math.min(this.nextVarint(), maxVarstringLen) + return new TextDecoder().decode(this.next(len)) + } +} + +export class MerkleArchive { + static readonly headerSize = + 32 + // pubkey + 64 + // signature + 32 + // sighash + 8 + // size + DirectoryContents.headerSize + private constructor( + readonly signer: Signer, + readonly contents: DirectoryContents, + ) {} + static async deserialize( + source: Blob, + context: string, + header: ArrayBufferReader, + commitment: MerkleArchiveCommitment | null, + ): Promise { + const pubkey = new Uint8Array(header.next(32)) + const signature = new Uint8Array(header.next(64)) + const sighash = new Uint8Array(header.next(32)) + const rootMaxSizeBytes = header.next(8) + const maxSize = new DataView(rootMaxSizeBytes).getBigUint64(0) + + if ( + !ed25519ph.verify( + signature, + new Uint8Array( + await new Blob([sighash, rootMaxSizeBytes]).arrayBuffer(), + ), + pubkey, + { + context: new TextEncoder().encode(context), + zip215: true, + }, + ) + ) { + throw new Error("signature verification failed") + } + + if (commitment) { + if ( + !compare( + sighash, + new Uint8Array(Buffer.from(commitment.rootSighash, "base64").buffer), + ) + ) { + throw new Error("merkle root mismatch") + } + if (maxSize > commitment.rootMaxsize) { + throw new Error("root directory max size too large") + } + } else if (maxSize > 1024 * 1024) { + throw new Error( + "root directory max size over 1MiB, cancelling download in case of DOS attack", + ) + } + + const contents = await DirectoryContents.deserialize( + source, + header, + sighash, + maxSize, + ) + + return new MerkleArchive( + { + pubkey, + signature, + maxSize, + context, + }, + contents, + ) + } +} + +export class Entry { + private constructor( + readonly hash: Uint8Array, + readonly size: bigint, + readonly contents: EntryContents, + ) {} + static async deserialize( + source: Blob, + header: ArrayBufferReader, + ): Promise { + const hash = new Uint8Array(header.next(32)) + const size = header.nextU64() + const contents = await deserializeEntryContents(source, header, hash, size) + + return new Entry(new Uint8Array(hash), size, contents) + } + async verifiedFileContents(): Promise { + if (!this.contents) { + throw new Error("file is missing from archive") + } + if (!(this.contents instanceof FileContents)) { + throw new Error("is not a regular file") + } + return this.contents.verified(this.hash) + } +} + +export type EntryContents = null | FileContents | DirectoryContents +async function deserializeEntryContents( + source: Blob, + header: ArrayBufferReader, + hash: Uint8Array, + size: bigint, +): Promise { + const typeId = new Uint8Array(header.next(1))[0] + switch (typeId) { + case 0: + return null + case 1: + return FileContents.deserialize(source, header, size) + case 2: + return DirectoryContents.deserialize(source, header, hash, size) + default: + throw new Error(`Unknown type id ${typeId} found in MerkleArchive`) + } +} diff --git a/sdk/lib/s9pk/merkleArchive/varint.ts b/sdk/lib/s9pk/merkleArchive/varint.ts new file mode 100644 index 000000000..2bf4793b1 --- /dev/null +++ b/sdk/lib/s9pk/merkleArchive/varint.ts @@ -0,0 +1,62 @@ +const msb = 0x80 +const dropMsb = 0x7f +const maxSize = Math.floor((8 * 8 + 7) / 7) + +export class VarIntProcessor { + private buf: Uint8Array + private i: number + constructor() { + this.buf = new Uint8Array(maxSize) + this.i = 0 + } + push(b: number) { + if (this.i >= maxSize) { + throw new Error("Unterminated varint") + } + this.buf[this.i] = b + this.i += 1 + } + finished(): boolean { + return this.i > 0 && (this.buf[this.i - 1] & msb) === 0 + } + decode(): number | null { + let result = 0 + let shift = 0 + let success = false + for (let i = 0; i < this.i; i++) { + const b = this.buf[i] + const msbDropped = b & dropMsb + result |= msbDropped << shift + shift += 7 + + if ((b & msb) == 0 || shift > 9 * 7) { + success = (b & msb) === 0 + break + } + } + + if (success) { + return result + } else { + console.error(this.buf) + return null + } + } +} + +export function serializeVarint(int: number): ArrayBuffer { + const buf = new Uint8Array(maxSize) + let n = int + let i = 0 + + while (n >= msb) { + buf[i] = msb | n + i += 1 + n >>= 7 + } + + buf[i] = n + i += 1 + + return buf.slice(0, i).buffer +} diff --git a/sdk/lib/test/configBuilder.test.ts b/sdk/lib/test/configBuilder.test.ts index 9738475a6..c5003c55b 100644 --- a/sdk/lib/test/configBuilder.test.ts +++ b/sdk/lib/test/configBuilder.test.ts @@ -268,26 +268,9 @@ describe("values", () => { }), ) const validator = value.validator - validator.unsafeCast({ unionSelectKey: "a", unionValueKey: { b: false } }) + validator.unsafeCast({ selection: "a", value: { b: false } }) type Test = typeof validator._TYPE - testOutput()( - null, - ) - }) - test("list", async () => { - const value = Value.list( - List.number( - { - name: "test", - }, - { - integer: false, - }, - ), - ) - const validator = value.validator - validator.unsafeCast([1, 2, 3]) - testOutput()(null) + testOutput()(null) }) describe("dynamic", () => { @@ -577,12 +560,12 @@ describe("values", () => { }), ) const validator = value.validator - validator.unsafeCast({ unionSelectKey: "a", unionValueKey: { b: false } }) + validator.unsafeCast({ selection: "a", value: { b: false } }) type Test = typeof validator._TYPE testOutput< Test, - | { unionSelectKey: "a"; unionValueKey: { b: boolean } } - | { unionSelectKey: "b"; unionValueKey: { b: boolean } } + | { selection: "a"; value: { b: boolean } } + | { selection: "b"; value: { b: boolean } } >()(null) const built = await value.build({} as any) @@ -644,12 +627,12 @@ describe("values", () => { }), ) const validator = value.validator - validator.unsafeCast({ unionSelectKey: "a", unionValueKey: { b: false } }) + validator.unsafeCast({ selection: "a", value: { b: false } }) type Test = typeof validator._TYPE testOutput< Test, - | { unionSelectKey: "a"; unionValueKey: { b: boolean } } - | { unionSelectKey: "b"; unionValueKey: { b: boolean } } + | { selection: "a"; value: { b: boolean } } + | { selection: "b"; value: { b: boolean } } | null | undefined >()(null) @@ -736,24 +719,6 @@ describe("Builder List", () => { }) }) }) - test("number", async () => { - const value = Value.list( - List.dynamicNumber(() => ({ - name: "test", - spec: { integer: true }, - })), - ) - const validator = value.validator - expect(() => validator.unsafeCast(["test", "text"])).toThrowError() - validator.unsafeCast([4, 2]) - expect(() => validator.unsafeCast(null)).toThrowError() - validator.unsafeCast([]) - testOutput()(null) - expect(await value.build({} as any)).toMatchObject({ - name: "test", - spec: { integer: true }, - }) - }) }) describe("Nested nullable values", () => { diff --git a/sdk/lib/test/configTypes.test.ts b/sdk/lib/test/configTypes.test.ts index 7e3ff5ca6..6d0b9a3d8 100644 --- a/sdk/lib/test/configTypes.test.ts +++ b/sdk/lib/test/configTypes.test.ts @@ -1,15 +1,11 @@ -import { - ListValueSpecOf, - ValueSpec, - isValueSpecListOf, -} from "../config/configTypes" +import { ListValueSpecOf, isValueSpecListOf } from "../config/configTypes" import { Config } from "../config/builder/config" import { List } from "../config/builder/list" import { Value } from "../config/builder/value" describe("Config Types", () => { test("isValueSpecListOf", async () => { - const options = [List.obj, List.text, List.number] + const options = [List.obj, List.text] for (const option of options) { const test = (option as any)( {} as any, @@ -18,8 +14,6 @@ describe("Config Types", () => { const someList = await Value.list(test).build({} as any) if (isValueSpecListOf(someList, "text")) { someList.spec satisfies ListValueSpecOf<"text"> - } else if (isValueSpecListOf(someList, "number")) { - someList.spec satisfies ListValueSpecOf<"number"> } else if (isValueSpecListOf(someList, "object")) { someList.spec satisfies ListValueSpecOf<"object"> } else { diff --git a/sdk/lib/test/emverList.test.ts b/sdk/lib/test/emverList.test.ts index 43919aa83..07dbb5aaf 100644 --- a/sdk/lib/test/emverList.test.ts +++ b/sdk/lib/test/emverList.test.ts @@ -8,18 +8,14 @@ describe("EmVer", () => { checker.check("1.2") checker.check("1.2.3") checker.check("1.2.3.4") - // @ts-expect-error checker.check("1.2.3.4.5") - // @ts-expect-error checker.check("1.2.3.4.5.6") expect(checker.check("1")).toEqual(true) expect(checker.check("1.2")).toEqual(true) expect(checker.check("1.2.3.4")).toEqual(true) }) test("rangeOf('*') invalid", () => { - // @ts-expect-error expect(() => checker.check("a")).toThrow() - // @ts-expect-error expect(() => checker.check("")).toThrow() expect(() => checker.check("1..3")).toThrow() }) @@ -31,7 +27,6 @@ describe("EmVer", () => { expect(checker.check("2-beta123")).toEqual(true) expect(checker.check("2")).toEqual(true) expect(checker.check("1.2.3.5")).toEqual(true) - // @ts-expect-error expect(checker.check("1.2.3.4.1")).toEqual(true) }) @@ -58,7 +53,6 @@ describe("EmVer", () => { test(`rangeOf(">=1.2.3.4") valid`, () => { expect(checker.check("2")).toEqual(true) expect(checker.check("1.2.3.5")).toEqual(true) - // @ts-expect-error expect(checker.check("1.2.3.4.1")).toEqual(true) expect(checker.check("1.2.3.4")).toEqual(true) }) @@ -73,7 +67,6 @@ describe("EmVer", () => { test(`rangeOf("<1.2.3.4") invalid`, () => { expect(checker.check("2")).toEqual(false) expect(checker.check("1.2.3.5")).toEqual(false) - // @ts-expect-error expect(checker.check("1.2.3.4.1")).toEqual(false) expect(checker.check("1.2.3.4")).toEqual(false) }) @@ -88,7 +81,6 @@ describe("EmVer", () => { test(`rangeOf("<=1.2.3.4") invalid`, () => { expect(checker.check("2")).toEqual(false) expect(checker.check("1.2.3.5")).toEqual(false) - // @ts-expect-error expect(checker.check("1.2.3.4.1")).toEqual(false) }) @@ -196,7 +188,6 @@ describe("EmVer", () => { test(`rangeOf("!>1.2.3.4") invalid`, () => { expect(checker.check("2")).toEqual(false) expect(checker.check("1.2.3.5")).toEqual(false) - // @ts-expect-error expect(checker.check("1.2.3.4.1")).toEqual(false) }) diff --git a/sdk/lib/test/output.test.ts b/sdk/lib/test/output.test.ts index 2b3afb5de..1df84f3af 100644 --- a/sdk/lib/test/output.test.ts +++ b/sdk/lib/test/output.test.ts @@ -1,9 +1,3 @@ -import { - UnionSelectKey, - unionSelectKey, - UnionValueKey, - unionValueKey, -} from "../config/configTypes" import { ConfigSpec, matchConfigSpec } from "./output" import * as _I from "../index" import { camelCase } from "../../scripts/oldSpecToBuilder" @@ -30,13 +24,10 @@ testOutput< ConfigSpec["advanced"]["peers"]["addnode"][0]["hostname"], string | null | undefined >()(null) -testOutput< - ConfigSpec["testListUnion"][0]["union"][UnionValueKey]["name"], - string ->()(null) -testOutput()( +testOutput()( null, ) +testOutput()(null) testOutput>()( null, ) @@ -45,7 +36,7 @@ testOutput>()( testOutput()(null) // prettier-ignore // @ts-expect-error Expect that the string is the one above -testOutput()(null); +testOutput()(null); /// Here we test the output of the matchConfigSpec function describe("Inputs", () => { @@ -53,7 +44,7 @@ describe("Inputs", () => { mediasources: ["filebrowser"], testListUnion: [ { - union: { [unionSelectKey]: "lnd", [unionValueKey]: { name: "string" } }, + union: { selection: "lnd", value: { name: "string" } }, }, ], rpc: { @@ -92,8 +83,8 @@ describe("Inputs", () => { }, dbcache: 5, pruning: { - unionSelectKey: "disabled", - unionValueKey: {}, + selection: "disabled", + value: {}, }, blockfilters: { blockfilterindex: false, diff --git a/sdk/lib/util/fileHelper.ts b/sdk/lib/util/fileHelper.ts index 54f1eca06..383b4fd31 100644 --- a/sdk/lib/util/fileHelper.ts +++ b/sdk/lib/util/fileHelper.ts @@ -1,7 +1,7 @@ import * as matches from "ts-matches" import * as YAML from "yaml" import * as TOML from "@iarna/toml" -import _ from "lodash" +import merge from "lodash.merge" import * as T from "../types" import * as fs from "node:fs/promises" @@ -82,7 +82,7 @@ export class FileHelper { async merge(data: A, effects: T.Effects) { const fileData = (await this.read(effects).catch(() => ({}))) || {} - const mergeData = _.merge({}, fileData, data) + const mergeData = merge({}, fileData, data) return await this.write(mergeData, effects) } /** diff --git a/sdk/lib/util/getRandomCharInSet.ts b/sdk/lib/util/getRandomCharInSet.ts index b26eef648..7914209a3 100644 --- a/sdk/lib/util/getRandomCharInSet.ts +++ b/sdk/lib/util/getRandomCharInSet.ts @@ -1,9 +1,10 @@ // a,g,h,A-Z,,,,- -import * as crypto from "crypto" export function getRandomCharInSet(charset: string): string { const set = stringToCharSet(charset) - let charIdx = crypto.randomInt(0, set.len) + let charIdx = Math.floor( + (crypto.getRandomValues(new Uint32Array(1))[0] / 2 ** 32) * set.len, + ) for (let range of set.ranges) { if (range.len > charIdx) { return String.fromCharCode(range.start.charCodeAt(0) + charIdx) diff --git a/sdk/lib/util/getServiceInterface.ts b/sdk/lib/util/getServiceInterface.ts index 737cbbc16..a2f17be10 100644 --- a/sdk/lib/util/getServiceInterface.ts +++ b/sdk/lib/util/getServiceInterface.ts @@ -80,7 +80,7 @@ export const addressHostToUrl = ( ): UrlString[] => { const res = [] const fmt = (scheme: string | null, host: HostnameInfo, port: number) => { - const includePort = + const excludePort = scheme && scheme in knownProtocols && port === knownProtocols[scheme as keyof typeof knownProtocols].defaultPort @@ -96,7 +96,7 @@ export const addressHostToUrl = ( } return `${scheme ? `${scheme}://` : ""}${ username ? `${username}@` : "" - }${hostname}${includePort ? `:${port}` : ""}${suffix}` + }${hostname}${excludePort ? "" : `:${port}`}${suffix}` } if (host.hostname.sslPort !== null) { res.push(fmt(sslScheme, host, host.hostname.sslPort)) diff --git a/sdk/lib/util/index.browser.ts b/sdk/lib/util/index.browser.ts index 6ff7ed01c..94339e7f7 100644 --- a/sdk/lib/util/index.browser.ts +++ b/sdk/lib/util/index.browser.ts @@ -1,25 +1,10 @@ import * as T from "../types" +/// Currently being used +export { addressHostToUrl } from "./getServiceInterface" +export { getDefaultString } from "./getDefaultString" + +/// Not being used, but known to be browser compatible export { GetServiceInterface, getServiceInterface } from "./getServiceInterface" export { getServiceInterfaces } from "./getServiceInterfaces" -// prettier-ignore -export type FlattenIntersection = -T extends ArrayLike ? T : -T extends object ? {} & {[P in keyof T]: T[P]} : - T; - -export type _ = FlattenIntersection - -export const isKnownError = (e: unknown): e is T.KnownError => - e instanceof Object && ("error" in e || "error-code" in e) - -declare const affine: unique symbol - -export type Affine = { [affine]: A } - -type NeverPossible = { [affine]: string } -export type NoAny = NeverPossible extends A - ? keyof NeverPossible extends keyof A - ? never - : A - : A +export * from "./typeHelpers" diff --git a/sdk/lib/util/index.ts b/sdk/lib/util/index.ts index 9b19aeb38..63629dfaa 100644 --- a/sdk/lib/util/index.ts +++ b/sdk/lib/util/index.ts @@ -1,5 +1,3 @@ -import * as T from "../types" - import "./nullIfEmpty" import "./fileHelper" import "../store/getStore" @@ -12,26 +10,5 @@ export { GetServiceInterface, getServiceInterface } from "./getServiceInterface" export { getServiceInterfaces } from "./getServiceInterfaces" export { addressHostToUrl } from "./getServiceInterface" export { hostnameInfoToAddress } from "./Hostname" -// prettier-ignore -export type FlattenIntersection = -T extends ArrayLike ? T : -T extends object ? {} & {[P in keyof T]: T[P]} : - T; - -export type _ = FlattenIntersection - -export const isKnownError = (e: unknown): e is T.KnownError => - e instanceof Object && ("error" in e || "error-code" in e) - -declare const affine: unique symbol - -export type Affine = { [affine]: A } - -type NeverPossible = { [affine]: string } -export type NoAny = NeverPossible extends A - ? keyof NeverPossible extends keyof A - ? never - : A - : A - +export * from "./typeHelpers" export { getDefaultString } from "./getDefaultString" diff --git a/sdk/lib/util/typeHelpers.ts b/sdk/lib/util/typeHelpers.ts new file mode 100644 index 000000000..f45a46f1e --- /dev/null +++ b/sdk/lib/util/typeHelpers.ts @@ -0,0 +1,23 @@ +import * as T from "../types" + +// prettier-ignore +export type FlattenIntersection = +T extends ArrayLike ? T : +T extends object ? {} & {[P in keyof T]: T[P]} : + T; + +export type _ = FlattenIntersection + +export const isKnownError = (e: unknown): e is T.KnownError => + e instanceof Object && ("error" in e || "error-code" in e) + +declare const affine: unique symbol + +export type Affine = { [affine]: A } + +type NeverPossible = { [affine]: string } +export type NoAny = NeverPossible extends A + ? keyof NeverPossible extends keyof A + ? never + : A + : A diff --git a/sdk/package-lock.json b/sdk/package-lock.json index a50066b34..0a3655a7d 100644 --- a/sdk/package-lock.json +++ b/sdk/package-lock.json @@ -1,29 +1,32 @@ { "name": "@start9labs/start-sdk", - "version": "0.3.6-alpha1", + "version": "0.3.6-alpha5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@start9labs/start-sdk", - "version": "0.3.6-alpha1", + "version": "0.3.6-alpha5", "license": "MIT", "dependencies": { + "@iarna/toml": "^2.2.5", + "@noble/curves": "^1.4.0", + "@noble/hashes": "^1.4.0", "isomorphic-fetch": "^3.0.0", - "lodash": "^4.17.21", - "ts-matches": "^5.4.1" + "lodash.merge": "^4.6.2", + "mime": "^4.0.3", + "ts-matches": "^5.5.1", + "yaml": "^2.2.2" }, "devDependencies": { - "@iarna/toml": "^2.2.5", "@types/jest": "^29.4.0", - "@types/lodash": "^4.17.5", + "@types/lodash.merge": "^4.6.2", "jest": "^29.4.3", "prettier": "^3.2.5", "ts-jest": "^29.0.5", "ts-node": "^10.9.1", "tsx": "^4.7.1", - "typescript": "^5.0.4", - "yaml": "^2.2.2" + "typescript": "^5.0.4" } }, "node_modules/@ampproject/remapping": { @@ -653,8 +656,7 @@ "node_modules/@iarna/toml": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", - "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==", - "dev": true + "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==" }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", @@ -1006,6 +1008,28 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "node_modules/@noble/curves": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", + "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@sinclair/typebox": { "version": "0.25.24", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", @@ -1144,6 +1168,15 @@ "integrity": "sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw==", "dev": true }, + "node_modules/@types/lodash.merge": { + "version": "4.6.9", + "resolved": "https://registry.npmjs.org/@types/lodash.merge/-/lodash.merge-4.6.9.tgz", + "integrity": "sha512-23sHDPmzd59kUgWyKGiOMO2Qb9YtqRO/x4IhkgNUiPQ1+5MUVqi6bCZeq9nBJ17msjIMbEIO5u+XW4Kz6aGUhQ==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/node": { "version": "18.15.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.10.tgz", @@ -2849,17 +2882,17 @@ "node": ">=8" } }, - "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.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==", "dev": true }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -2918,6 +2951,20 @@ "node": ">=8.6" } }, + "node_modules/mime": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.3.tgz", + "integrity": "sha512-KgUb15Oorc0NEKPbvfa0wRU+PItIEZmiv+pyAO2i0oTIVTJhlzMclU7w4RXWQrSOVH5ax/p/CkIO7KI4OyFJTQ==", + "funding": [ + "https://github.com/sponsors/broofa" + ], + "bin": { + "mime": "bin/cli.js" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -3580,9 +3627,9 @@ "dev": true }, "node_modules/ts-matches": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ts-matches/-/ts-matches-5.4.1.tgz", - "integrity": "sha512-kXrY75F0s0WD15N2bWKDScKlKgwnusN6dTRzGs1N7LlxQRnazrsBISC1HL4sy2adsyk65Zbx3Ui3IGN8leAFOQ==" + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/ts-matches/-/ts-matches-5.5.1.tgz", + "integrity": "sha512-UFYaKgfqlg9FROK7bdpYqFwG1CJvP4kOJdjXuWoqxo9jCmANoDw1GxkSCpJgoTeIiSTaTH5Qr1klSspb8c+ydg==" }, "node_modules/ts-node": { "version": "10.9.1", @@ -4249,7 +4296,6 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.2.tgz", "integrity": "sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==", - "dev": true, "engines": { "node": ">= 14" } diff --git a/sdk/package.json b/sdk/package.json index d6c3a1ca5..8ed984a82 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -31,10 +31,13 @@ "homepage": "https://github.com/Start9Labs/start-sdk#readme", "dependencies": { "isomorphic-fetch": "^3.0.0", - "lodash": "^4.17.21", - "ts-matches": "^5.4.1", + "lodash.merge": "^4.6.2", + "mime": "^4.0.3", + "ts-matches": "^5.5.1", "yaml": "^2.2.2", - "@iarna/toml": "^2.2.5" + "@iarna/toml": "^2.2.5", + "@noble/curves": "^1.4.0", + "@noble/hashes": "^1.4.0" }, "prettier": { "trailingComma": "all", @@ -44,7 +47,7 @@ }, "devDependencies": { "@types/jest": "^29.4.0", - "@types/lodash": "^4.17.5", + "@types/lodash.merge": "^4.6.2", "jest": "^29.4.3", "prettier": "^3.2.5", "ts-jest": "^29.0.5", diff --git a/sdk/scripts/oldSpecToBuilder.ts b/sdk/scripts/oldSpecToBuilder.ts index ce8ea4e5f..6dd726e1b 100644 --- a/sdk/scripts/oldSpecToBuilder.ts +++ b/sdk/scripts/oldSpecToBuilder.ts @@ -285,26 +285,26 @@ const {Config, List, Value, Variants} = sdk maxLength: null, })})` } - case "number": { - return `${rangeToTodoComment(value?.range)}List.number(${JSON.stringify( - { - name: value.name || null, - minLength: null, - maxLength: null, - default: value.default || null, - description: value.description || null, - warning: value.warning || null, - }, - null, - 2, - )}, ${JSON.stringify({ - integer: value?.spec?.integral || false, - min: null, - max: null, - units: value?.spec?.units || null, - placeholder: value?.spec?.placeholder || null, - })})` - } + // case "number": { + // return `${rangeToTodoComment(value?.range)}List.number(${JSON.stringify( + // { + // name: value.name || null, + // minLength: null, + // maxLength: null, + // default: value.default || null, + // description: value.description || null, + // warning: value.warning || null, + // }, + // null, + // 2, + // )}, ${JSON.stringify({ + // integer: value?.spec?.integral || false, + // min: null, + // max: null, + // units: value?.spec?.units || null, + // placeholder: value?.spec?.placeholder || null, + // })})` + // } case "enum": { return "/* error!! list.enum */" } diff --git a/system-images/compat/src/config/mod.rs b/system-images/compat/src/config/mod.rs index ce591b06a..c677dd3d5 100644 --- a/system-images/compat/src/config/mod.rs +++ b/system-images/compat/src/config/mod.rs @@ -55,7 +55,7 @@ pub fn validate_configuration( Ok(_) => { // create temp config file serde_yaml::to_writer( - std::fs::File::create(config_path.with_extension("tmp"))?, + std::fs::create_file(config_path.with_extension("tmp"))?, &config, )?; std::fs::rename(config_path.with_extension("tmp"), config_path)?; diff --git a/web/angular.json b/web/angular.json index 3a91dd00b..cf6c113a4 100644 --- a/web/angular.json +++ b/web/angular.json @@ -302,6 +302,7 @@ } ], "styles": [ + "node_modules/@taiga-ui/core/styles/taiga-ui-theme.less", "projects/shared/styles/variables.scss", "projects/shared/styles/global.scss", "projects/shared/styles/shared.scss", @@ -393,136 +394,6 @@ } } }, - "diagnostic-ui": { - "projectType": "application", - "schematics": {}, - "root": "projects/diagnostic-ui", - "sourceRoot": "projects/diagnostic-ui/src", - "prefix": "app", - "architect": { - "build": { - "builder": "@angular-devkit/build-angular:browser", - "options": { - "outputPath": "dist/raw/diagnostic-ui", - "index": "projects/diagnostic-ui/src/index.html", - "main": "projects/diagnostic-ui/src/main.ts", - "polyfills": "projects/diagnostic-ui/src/polyfills.ts", - "tsConfig": "projects/diagnostic-ui/tsconfig.json", - "inlineStyleLanguage": "scss", - "assets": [ - { - "glob": "**/*", - "input": "projects/shared/assets", - "output": "assets" - }, - { - "glob": "**/*.svg", - "input": "node_modules/ionicons/dist/ionicons/svg", - "output": "./svg" - } - ], - "styles": [ - "projects/shared/styles/variables.scss", - "projects/shared/styles/global.scss", - "projects/shared/styles/shared.scss", - "projects/diagnostic-ui/src/styles.scss" - ], - "scripts": [] - }, - "configurations": { - "production": { - "fileReplacements": [ - { - "replace": "projects/diagnostic-ui/src/environments/environment.ts", - "with": "projects/diagnostic-ui/src/environments/environment.prod.ts" - } - ], - "optimization": true, - "outputHashing": "all", - "sourceMap": false, - "namedChunks": false, - "aot": true, - "extractLicenses": true, - "vendorChunk": false, - "buildOptimizer": true, - "budgets": [ - { - "type": "initial", - "maximumWarning": "2mb", - "maximumError": "5mb" - } - ] - }, - "ci": { - "progress": false - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "vendorChunk": true, - "extractLicenses": false, - "sourceMap": true, - "namedChunks": true - } - }, - "defaultConfiguration": "production" - }, - "serve": { - "builder": "@angular-devkit/build-angular:dev-server", - "options": { - "browserTarget": "diagnostic-ui:build" - }, - "configurations": { - "production": { - "browserTarget": "diagnostic-ui:build:production" - }, - "development": { - "browserTarget": "diagnostic-ui:build:development" - } - }, - "defaultConfiguration": "development" - }, - "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", - "options": { - "browserTarget": "diagnostic-ui:build" - } - }, - "lint": { - "builder": "@angular-eslint/builder:lint", - "options": { - "lintFilePatterns": [ - "projects/diagnostic-ui/src/**/*.ts", - "projects/diagnostic-ui/src/**/*.html" - ] - } - }, - "ionic-cordova-build": { - "builder": "@ionic/angular-toolkit:cordova-build", - "options": { - "browserTarget": "diagnostic-ui:build" - }, - "configurations": { - "production": { - "browserTarget": "diagnostic-ui:build:production" - } - } - }, - "ionic-cordova-serve": { - "builder": "@ionic/angular-toolkit:cordova-serve", - "options": { - "cordovaBuildTarget": "diagnostic-ui:ionic-cordova-build", - "devServerTarget": "diagnostic-ui:serve" - }, - "configurations": { - "production": { - "cordovaBuildTarget": "diagnostic-ui:ionic-cordova-build:production", - "devServerTarget": "diagnostic-ui:serve:production" - } - } - } - } - }, "marketplace": { "projectType": "library", "root": "projects/marketplace", diff --git a/web/package-lock.json b/web/package-lock.json index 97a049b98..e07531a96 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -20,21 +20,26 @@ "@angular/service-worker": "^14.2.2", "@ionic/angular": "^6.1.15", "@materia-ui/ngx-monaco-editor": "^6.0.0", - "@ng-web-apis/common": "^2.0.0", - "@ng-web-apis/mutation-observer": "^2.0.0", - "@ng-web-apis/resize-observer": "^2.0.0", + "@ng-web-apis/common": "^3.0.6", + "@ng-web-apis/mutation-observer": "^3.2.1", + "@ng-web-apis/resize-observer": "^3.2.1", + "@noble/curves": "^1.4.0", + "@noble/hashes": "^1.4.0", "@start9labs/argon2": "^0.2.2", "@start9labs/emver": "^0.1.5", "@start9labs/start-sdk": "file:../sdk/dist", - "@taiga-ui/addon-charts": "3.20.0", - "@taiga-ui/cdk": "3.20.0", - "@taiga-ui/core": "3.20.0", - "@taiga-ui/icons": "3.20.0", - "@taiga-ui/kit": "3.20.0", + "@taiga-ui/addon-charts": "3.84.0", + "@taiga-ui/cdk": "3.84.0", + "@taiga-ui/core": "3.84.0", + "@taiga-ui/experimental": "3.84.0", + "@taiga-ui/icons": "3.84.0", + "@taiga-ui/kit": "3.84.0", "@tinkoff/ng-dompurify": "4.0.0", + "@tinkoff/ng-event-plugins": "3.2.0", "angular-svg-round-progressbar": "^9.0.0", "ansi-to-html": "^0.7.2", "base64-js": "^1.5.1", + "buffer": "^6.0.3", "cbor": "npm:@jprochazk/cbor@^0.4.9", "cbor-web": "^8.1.0", "core-js": "^3.21.1", @@ -45,6 +50,7 @@ "jose": "^4.9.0", "js-yaml": "^4.1.0", "marked": "^4.0.0", + "mime": "^4.0.3", "monaco-editor": "^0.33.0", "mustache": "^4.2.0", "ng-qrcode": "^7.0.0", @@ -53,7 +59,7 @@ "pbkdf2": "^3.1.2", "rxjs": "^7.8.1", "swiper": "^8.2.4", - "ts-matches": "^5.2.1", + "ts-matches": "^5.5.1", "tslib": "^2.3.0", "uuid": "^8.3.2", "zone.js": "^0.11.5" @@ -107,1900 +113,41 @@ "rxjs": ">=7.0.0" } }, - "../patch-db/client/node_modules/@babel/code-frame": { - "version": "7.21.4", - "dev": true, + "../sdk/dist": { + "version": "0.3.6-alpha5", "license": "MIT", "dependencies": { - "@babel/highlight": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "../patch-db/client/node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "../patch-db/client/node_modules/@babel/highlight": { - "version": "7.18.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "../patch-db/client/node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "../patch-db/client/node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "../patch-db/client/node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "../patch-db/client/node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "../patch-db/client/node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "../patch-db/client/node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "../patch-db/client/node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "../patch-db/client/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "../patch-db/client/node_modules/@tsconfig/node10": { - "version": "1.0.9", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/@tsconfig/node12": { - "version": "1.0.11", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/@tsconfig/node14": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/@tsconfig/node16": { - "version": "1.0.4", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/@types/node": { - "version": "18.15.0", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/@types/parse-json": { - "version": "4.0.0", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/@types/uuid": { - "version": "8.3.1", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/acorn": { - "version": "8.8.2", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "../patch-db/client/node_modules/acorn-walk": { - "version": "8.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "../patch-db/client/node_modules/aggregate-error": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/ansi-escapes": { - "version": "4.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/ansi-regex": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "../patch-db/client/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "../patch-db/client/node_modules/arg": { - "version": "4.1.3", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/argparse": { - "version": "1.0.10", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "../patch-db/client/node_modules/astral-regex": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/balanced-match": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "../patch-db/client/node_modules/braces": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/builtin-modules": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "../patch-db/client/node_modules/callsites": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "../patch-db/client/node_modules/chalk": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "../patch-db/client/node_modules/ci-info": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/clean-stack": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "../patch-db/client/node_modules/cli-cursor": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/cli-truncate": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "slice-ansi": "^5.0.0", - "string-width": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "../patch-db/client/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/colorette": { - "version": "2.0.20", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/commander": { - "version": "10.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "../patch-db/client/node_modules/compare-versions": { - "version": "3.6.0", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/concat-map": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/cosmiconfig": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "../patch-db/client/node_modules/create-require": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/cross-spawn": { - "version": "7.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "../patch-db/client/node_modules/debug": { - "version": "4.3.4", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "../patch-db/client/node_modules/diff": { - "version": "4.0.2", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "../patch-db/client/node_modules/eastasianwidth": { - "version": "0.2.0", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/emoji-regex": { - "version": "9.2.2", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/error-ex": { - "version": "1.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "../patch-db/client/node_modules/escape-string-regexp": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "../patch-db/client/node_modules/esprima": { - "version": "4.0.1", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "../patch-db/client/node_modules/execa": { - "version": "7.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "../patch-db/client/node_modules/fill-range": { - "version": "7.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/find-up": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/find-versions": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "semver-regex": "^3.1.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/fs.realpath": { - "version": "1.0.0", - "dev": true, - "license": "ISC" - }, - "../patch-db/client/node_modules/function-bind": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/get-stream": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/glob": { - "version": "7.2.3", - "dev": true, - "license": "ISC", - "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" - } - }, - "../patch-db/client/node_modules/has": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "../patch-db/client/node_modules/has-flag": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/human-signals": { - "version": "4.3.1", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=14.18.0" - } - }, - "../patch-db/client/node_modules/husky": { - "version": "4.3.8", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "ci-info": "^2.0.0", - "compare-versions": "^3.6.0", - "cosmiconfig": "^7.0.0", - "find-versions": "^4.0.0", - "opencollective-postinstall": "^2.0.2", - "pkg-dir": "^5.0.0", - "please-upgrade-node": "^3.2.0", - "slash": "^3.0.0", - "which-pm-runs": "^1.0.0" - }, - "bin": { - "husky-run": "bin/run.js", - "husky-upgrade": "lib/upgrader/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/husky" - } - }, - "../patch-db/client/node_modules/import-fresh": { - "version": "3.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/indent-string": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/inflight": { - "version": "1.0.6", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "../patch-db/client/node_modules/inherits": { - "version": "2.0.4", - "dev": true, - "license": "ISC" - }, - "../patch-db/client/node_modules/is-arrayish": { - "version": "0.2.1", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/is-core-module": { - "version": "2.12.1", - "dev": true, - "license": "MIT", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "../patch-db/client/node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/is-number": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "../patch-db/client/node_modules/is-stream": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/isexe": { - "version": "2.0.0", - "dev": true, - "license": "ISC" - }, - "../patch-db/client/node_modules/js-tokens": { - "version": "4.0.0", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/js-yaml": { - "version": "3.14.1", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "../patch-db/client/node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/lilconfig": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "../patch-db/client/node_modules/lines-and-columns": { - "version": "1.2.4", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/lint-staged": { - "version": "13.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "5.2.0", - "cli-truncate": "^3.1.0", - "commander": "^10.0.0", - "debug": "^4.3.4", - "execa": "^7.0.0", - "lilconfig": "2.1.0", - "listr2": "^5.0.7", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-inspect": "^1.12.3", - "pidtree": "^0.6.0", - "string-argv": "^0.3.1", + "@iarna/toml": "^2.2.5", + "@noble/curves": "^1.4.0", + "@noble/hashes": "^1.4.0", + "isomorphic-fetch": "^3.0.0", + "lodash.merge": "^4.6.2", + "mime": "^4.0.3", + "ts-matches": "^5.5.1", "yaml": "^2.2.2" }, - "bin": { - "lint-staged": "bin/lint-staged.js" - }, - "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/lint-staged" - } - }, - "../patch-db/client/node_modules/lint-staged/node_modules/chalk": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "../patch-db/client/node_modules/lint-staged/node_modules/yaml": { - "version": "2.3.1", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 14" - } - }, - "../patch-db/client/node_modules/listr2": { - "version": "5.0.8", - "dev": true, - "license": "MIT", - "dependencies": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.19", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.8.0", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" - }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } - } - }, - "../patch-db/client/node_modules/listr2/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/listr2/node_modules/cli-truncate": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/listr2/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/listr2/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/listr2/node_modules/slice-ansi": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/listr2/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/listr2/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/locate-path": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/log-update": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/log-update/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/log-update/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/log-update/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/log-update/node_modules/slice-ansi": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "../patch-db/client/node_modules/log-update/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/log-update/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/log-update/node_modules/wrap-ansi": { - "version": "6.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/make-error": { - "version": "1.3.6", - "dev": true, - "license": "ISC" - }, - "../patch-db/client/node_modules/merge-stream": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/micromatch": { - "version": "4.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "../patch-db/client/node_modules/mimic-fn": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/minimatch": { - "version": "3.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "../patch-db/client/node_modules/minimist": { - "version": "1.2.8", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "../patch-db/client/node_modules/mkdirp": { - "version": "0.5.6", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "../patch-db/client/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/normalize-path": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "../patch-db/client/node_modules/npm-run-path": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/object-inspect": { - "version": "1.12.3", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "../patch-db/client/node_modules/once": { - "version": "1.4.0", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "../patch-db/client/node_modules/onetime": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/opencollective-postinstall": { - "version": "2.0.3", - "dev": true, - "license": "MIT", - "bin": { - "opencollective-postinstall": "index.js" - } - }, - "../patch-db/client/node_modules/p-limit": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/p-locate": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/p-map": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/parent-module": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "../patch-db/client/node_modules/parse-json": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/path-exists": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/path-is-absolute": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "../patch-db/client/node_modules/path-key": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/path-parse": { - "version": "1.0.7", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/path-type": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/picomatch": { - "version": "2.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "../patch-db/client/node_modules/pidtree": { - "version": "0.6.0", - "dev": true, - "license": "MIT", - "bin": { - "pidtree": "bin/pidtree.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "../patch-db/client/node_modules/pkg-dir": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^5.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "../patch-db/client/node_modules/please-upgrade-node": { - "version": "3.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "semver-compare": "^1.0.0" - } - }, - "../patch-db/client/node_modules/prettier": { - "version": "2.8.8", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "../patch-db/client/node_modules/resolve": { - "version": "1.22.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.11.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "../patch-db/client/node_modules/resolve-from": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "../patch-db/client/node_modules/restore-cursor": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/restore-cursor/node_modules/mimic-fn": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "../patch-db/client/node_modules/restore-cursor/node_modules/onetime": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/rfdc": { - "version": "1.3.0", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/rxjs": { - "version": "7.8.1", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "../patch-db/client/node_modules/semver": { - "version": "5.7.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "../patch-db/client/node_modules/semver-compare": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/semver-regex": { - "version": "3.1.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/shebang-command": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/shebang-regex": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "license": "ISC" - }, - "../patch-db/client/node_modules/slash": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/slice-ansi": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "../patch-db/client/node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "../patch-db/client/node_modules/sorted-btree": { - "version": "1.5.0", - "license": "MIT" - }, - "../patch-db/client/node_modules/sprintf-js": { - "version": "1.0.3", - "dev": true, - "license": "BSD-3-Clause" - }, - "../patch-db/client/node_modules/string-argv": { - "version": "0.3.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.6.19" - } - }, - "../patch-db/client/node_modules/string-width": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/strip-ansi": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "../patch-db/client/node_modules/strip-final-newline": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "../patch-db/client/node_modules/through": { - "version": "2.3.8", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/to-regex-range": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "../patch-db/client/node_modules/ts-node": { - "version": "10.9.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "../patch-db/client/node_modules/tslib": { - "version": "2.5.3", - "license": "0BSD" - }, - "../patch-db/client/node_modules/tslint": { - "version": "6.1.3", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.3", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.13.0", - "tsutils": "^2.29.0" - }, - "bin": { - "tslint": "bin/tslint" - }, - "engines": { - "node": ">=4.8.0" - }, - "peerDependencies": { - "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev" - } - }, - "../patch-db/client/node_modules/tslint/node_modules/ansi-styles": { - "version": "3.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "../patch-db/client/node_modules/tslint/node_modules/chalk": { - "version": "2.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "../patch-db/client/node_modules/tslint/node_modules/color-convert": { - "version": "1.9.3", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "../patch-db/client/node_modules/tslint/node_modules/color-name": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/tslint/node_modules/commander": { - "version": "2.20.3", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/tslint/node_modules/has-flag": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "../patch-db/client/node_modules/tslint/node_modules/supports-color": { - "version": "5.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "../patch-db/client/node_modules/tslint/node_modules/tslib": { - "version": "1.14.1", - "dev": true, - "license": "0BSD" - }, - "../patch-db/client/node_modules/tsutils": { - "version": "2.29.0", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^1.8.1" - }, - "peerDependencies": { - "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" - } - }, - "../patch-db/client/node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "dev": true, - "license": "0BSD" - }, - "../patch-db/client/node_modules/type-fest": { - "version": "0.21.3", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../patch-db/client/node_modules/typescript": { - "version": "4.9.5", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "../patch-db/client/node_modules/uuid": { - "version": "8.3.2", - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "../patch-db/client/node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/which": { - "version": "2.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "../patch-db/client/node_modules/which-pm-runs": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "../patch-db/client/node_modules/wrap-ansi": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "../patch-db/client/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "license": "MIT" - }, - "../patch-db/client/node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "../patch-db/client/node_modules/wrappy": { - "version": "1.0.2", - "dev": true, - "license": "ISC" - }, - "../patch-db/client/node_modules/yaml": { - "version": "1.10.2", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, - "../patch-db/client/node_modules/yn": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "../patch-db/client/node_modules/yocto-queue": { - "version": "0.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../sdk/dist": { - "name": "@start9labs/start-sdk", - "version": "0.3.6-alpha1", - "license": "MIT", - "dependencies": { - "isomorphic-fetch": "^3.0.0", - "ts-matches": "^5.4.1" - }, "devDependencies": { - "@iarna/toml": "^2.2.5", "@types/jest": "^29.4.0", + "@types/lodash.merge": "^4.6.2", "jest": "^29.4.3", "prettier": "^3.2.5", "ts-jest": "^29.0.5", "ts-node": "^10.9.1", "tsx": "^4.7.1", - "typescript": "^5.0.4", - "yaml": "^2.2.2" + "typescript": "^5.0.4" } }, "node_modules/@adobe/css-tools": { - "version": "4.0.1", - "dev": true, - "license": "MIT" + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", + "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==", + "dev": true }, "node_modules/@ampproject/remapping": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -2010,11 +157,12 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1402.3", + "version": "0.1402.13", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.13.tgz", + "integrity": "sha512-n0ISBuvkZHoOpAzuAZql1TU9VLHUE9e/a9g4VNOPHewjMzpN02VqeGKvJfOCKtzkCs6gVssIlILm2/SXxkIFxQ==", "devOptional": true, - "license": "MIT", "dependencies": { - "@angular-devkit/core": "14.2.3", + "@angular-devkit/core": "14.2.13", "rxjs": "6.6.7" }, "engines": { @@ -2025,8 +173,9 @@ }, "node_modules/@angular-devkit/architect/node_modules/rxjs": { "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "devOptional": true, - "license": "Apache-2.0", "dependencies": { "tslib": "^1.9.0" }, @@ -2036,18 +185,20 @@ }, "node_modules/@angular-devkit/architect/node_modules/tslib": { "version": "1.14.1", - "devOptional": true, - "license": "0BSD" + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "devOptional": true }, "node_modules/@angular-devkit/build-angular": { - "version": "14.2.3", + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-14.2.13.tgz", + "integrity": "sha512-FJZKQ3xYFvEJ807sxVy4bCVyGU2NMl3UUPNfLIdIdzwwDEP9tx/cc+c4VtVPEZZfU8jVenu8XOvL6L0vpjt3yg==", "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "2.2.0", - "@angular-devkit/architect": "0.1402.3", - "@angular-devkit/build-webpack": "0.1402.3", - "@angular-devkit/core": "14.2.3", + "@angular-devkit/architect": "0.1402.13", + "@angular-devkit/build-webpack": "0.1402.13", + "@angular-devkit/core": "14.2.13", "@babel/core": "7.18.10", "@babel/generator": "7.18.12", "@babel/helper-annotate-as-pure": "7.18.6", @@ -2058,7 +209,7 @@ "@babel/runtime": "7.18.9", "@babel/template": "7.18.10", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "14.2.3", + "@ngtools/webpack": "14.2.13", "ansi-colors": "4.1.3", "babel-loader": "8.2.5", "babel-plugin-istanbul": "6.1.1", @@ -2076,14 +227,14 @@ "less": "4.1.3", "less-loader": "11.0.0", "license-webpack-plugin": "4.0.2", - "loader-utils": "3.2.0", + "loader-utils": "3.2.1", "mini-css-extract-plugin": "2.6.1", "minimatch": "5.1.0", "open": "8.4.0", "ora": "5.4.1", "parse5-html-rewriting-stream": "6.0.1", "piscina": "3.2.0", - "postcss": "8.4.16", + "postcss": "8.4.31", "postcss-import": "15.0.0", "postcss-loader": "7.0.1", "postcss-preset-env": "7.8.0", @@ -2092,7 +243,7 @@ "rxjs": "6.6.7", "sass": "1.54.4", "sass-loader": "13.0.2", - "semver": "7.3.7", + "semver": "7.5.3", "source-map-loader": "4.0.0", "source-map-support": "0.5.21", "stylus": "0.59.0", @@ -2101,7 +252,7 @@ "text-table": "0.2.0", "tree-kill": "1.2.2", "tslib": "2.4.0", - "webpack": "5.74.0", + "webpack": "5.76.1", "webpack-dev-middleware": "5.3.3", "webpack-dev-server": "4.11.0", "webpack-merge": "5.8.0", @@ -2146,25 +297,194 @@ } } }, - "node_modules/@angular-devkit/build-angular/node_modules/@ngtools/webpack": { - "version": "14.2.3", + "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/ast": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || >=16.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "@angular/compiler-cli": "^14.0.0", - "typescript": ">=4.6.2 <4.9", - "webpack": "^5.54.0" + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" } }, + "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "dev": true + }, + "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "dev": true + }, + "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "dev": true + }, + "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "dev": true + }, + "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/ieee754": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/leb128": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/utf8": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "dev": true + }, + "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@angular-devkit/build-angular/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==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/es-module-lexer": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "dev": true + }, + "node_modules/@angular-devkit/build-angular/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/@angular-devkit/build-angular/node_modules/rxjs": { "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { "tslib": "^1.9.0" }, @@ -2174,15 +494,88 @@ }, "node_modules/@angular-devkit/build-angular/node_modules/rxjs/node_modules/tslib": { "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/@angular-devkit/build-angular/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==", "dev": true, - "license": "0BSD" + "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/@angular-devkit/build-angular/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true + }, + "node_modules/@angular-devkit/build-angular/node_modules/webpack": { + "version": "5.76.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.1.tgz", + "integrity": "sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.10.0", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "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.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.4.0", + "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/@angular-devkit/build-webpack": { - "version": "0.1402.3", + "version": "0.1402.13", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1402.13.tgz", + "integrity": "sha512-K27aJmuw86ZOdiu5PoGeGDJ2v7g2ZCK0bGwc8jzkjTLRfvd4FRKIIZumGv3hbQ3vQRLikiU6WMDRTFyCZky/EA==", "dev": true, - "license": "MIT", "dependencies": { - "@angular-devkit/architect": "0.1402.3", + "@angular-devkit/architect": "0.1402.13", "rxjs": "6.6.7" }, "engines": { @@ -2197,8 +590,9 @@ }, "node_modules/@angular-devkit/build-webpack/node_modules/rxjs": { "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { "tslib": "^1.9.0" }, @@ -2208,13 +602,14 @@ }, "node_modules/@angular-devkit/build-webpack/node_modules/tslib": { "version": "1.14.1", - "dev": true, - "license": "0BSD" + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true }, "node_modules/@angular-devkit/core": { - "version": "14.2.3", - "devOptional": true, - "license": "MIT", + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.13.tgz", + "integrity": "sha512-aIefeZcbjghQg/V6U9CTLtyB5fXDJ63KwYqVYkWP+i0XriS5A9puFgq2u/OVsWxAfYvqpDqp5AdQ0g0bi3CAsA==", "dependencies": { "ajv": "8.11.0", "ajv-formats": "2.1.1", @@ -2238,8 +633,8 @@ }, "node_modules/@angular-devkit/core/node_modules/rxjs": { "version": "6.6.7", - "devOptional": true, - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dependencies": { "tslib": "^1.9.0" }, @@ -2249,15 +644,15 @@ }, "node_modules/@angular-devkit/core/node_modules/tslib": { "version": "1.14.1", - "devOptional": true, - "license": "0BSD" + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@angular-devkit/schematics": { - "version": "14.2.3", - "devOptional": true, - "license": "MIT", + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.2.13.tgz", + "integrity": "sha512-2zczyeNzeBcrT2HOysv52X9SH3tZoHfWJvVf6H0SIa74rfDKEl7hFpKNXnh3x8sIMLj5mZn05n5RCqGxCczcIg==", "dependencies": { - "@angular-devkit/core": "14.2.3", + "@angular-devkit/core": "14.2.13", "jsonc-parser": "3.1.0", "magic-string": "0.26.2", "ora": "5.4.1", @@ -2271,8 +666,8 @@ }, "node_modules/@angular-devkit/schematics/node_modules/rxjs": { "version": "6.6.7", - "devOptional": true, - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dependencies": { "tslib": "^1.9.0" }, @@ -2282,12 +677,13 @@ }, "node_modules/@angular-devkit/schematics/node_modules/tslib": { "version": "1.14.1", - "devOptional": true, - "license": "0BSD" + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@angular/animations": { - "version": "14.2.2", - "license": "MIT", + "version": "14.3.0", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-14.3.0.tgz", + "integrity": "sha512-QoBcIKy1ZiU+4qJsAh5Ls20BupWiXiZzKb0s6L9/dntPt5Msr4Ao289XR2P6O1L+kTsCprH9Kt41zyGQ/bkRqg==", "dependencies": { "tslib": "^2.3.0" }, @@ -2295,18 +691,19 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/core": "14.2.2" + "@angular/core": "14.3.0" } }, "node_modules/@angular/cli": { - "version": "14.2.3", + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-14.2.13.tgz", + "integrity": "sha512-I5EepRem2CCyS3GDzQxZ2ZrqQwVqoGoLY+ZQhsK1QGWUnUyFOjbv3OlUGxRUYwcedu19V1EBAKjmQ96HzMIcVQ==", "devOptional": true, - "license": "MIT", "dependencies": { - "@angular-devkit/architect": "0.1402.3", - "@angular-devkit/core": "14.2.3", - "@angular-devkit/schematics": "14.2.3", - "@schematics/angular": "14.2.3", + "@angular-devkit/architect": "0.1402.13", + "@angular-devkit/core": "14.2.13", + "@angular-devkit/schematics": "14.2.13", + "@schematics/angular": "14.2.13", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.3", "debug": "4.3.4", @@ -2319,7 +716,7 @@ "ora": "5.4.1", "pacote": "13.6.2", "resolve": "1.22.1", - "semver": "7.3.7", + "semver": "7.5.3", "symbol-observable": "4.0.0", "uuid": "8.3.2", "yargs": "17.5.1" @@ -2334,8 +731,9 @@ } }, "node_modules/@angular/common": { - "version": "14.2.2", - "license": "MIT", + "version": "14.3.0", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-14.3.0.tgz", + "integrity": "sha512-pV9oyG3JhGWeQ+TFB0Qub6a1VZWMNZ6/7zEopvYivdqa5yDLLDSBRWb6P80RuONXyGnM1pa7l5nYopX+r/23GQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -2343,13 +741,14 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/core": "14.2.2", + "@angular/core": "14.3.0", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "14.2.2", - "license": "MIT", + "version": "14.3.0", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-14.3.0.tgz", + "integrity": "sha512-E15Rh0t3vA+bctbKnBCaDmLvc3ix+ZBt6yFZmhZalReQ+KpOlvOJv+L9oiFEgg+rYVl2QdvN7US1fvT0PqswLw==", "dependencies": { "tslib": "^2.3.0" }, @@ -2357,7 +756,7 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/core": "14.2.2" + "@angular/core": "14.3.0" }, "peerDependenciesMeta": { "@angular/core": { @@ -2366,9 +765,10 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "14.2.2", + "version": "14.3.0", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-14.3.0.tgz", + "integrity": "sha512-eoKpKdQ2X6axMgzcPUMZVYl3bIlTMzMeTo5V29No4BzgiUB+QoOTYGNJZkGRyqTNpwD9uSBJvmT2vG9+eC4ghQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/core": "^7.17.2", "chokidar": "^3.0.0", @@ -2390,13 +790,14 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/compiler": "14.2.2", + "@angular/compiler": "14.3.0", "typescript": ">=4.6.2 <4.9" } }, "node_modules/@angular/core": { - "version": "14.2.2", - "license": "MIT", + "version": "14.3.0", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-14.3.0.tgz", + "integrity": "sha512-wYiwItc0Uyn4FWZ/OAx/Ubp2/WrD3EgUJ476y1XI7yATGPF8n9Ld5iCXT08HOvc4eBcYlDfh90kTXR6/MfhzdQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -2405,12 +806,13 @@ }, "peerDependencies": { "rxjs": "^6.5.3 || ^7.4.0", - "zone.js": "~0.11.4" + "zone.js": "~0.11.4 || ~0.12.0" } }, "node_modules/@angular/forms": { - "version": "14.2.2", - "license": "MIT", + "version": "14.3.0", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-14.3.0.tgz", + "integrity": "sha512-fBZZC2UFMom2AZPjGQzROPXFWO6kvCsPDKctjJwClVC8PuMrkm+RRyiYRdBbt2qxWHEqOZM2OCQo73xUyZOYHw==", "dependencies": { "tslib": "^2.3.0" }, @@ -2418,23 +820,25 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/common": "14.2.2", - "@angular/core": "14.2.2", - "@angular/platform-browser": "14.2.2", + "@angular/common": "14.3.0", + "@angular/core": "14.3.0", + "@angular/platform-browser": "14.3.0", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/language-service": { - "version": "14.2.2", + "version": "14.3.0", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-14.3.0.tgz", + "integrity": "sha512-Sij3OQzj1UGs1O8H9PxVAY/o27+oqZwQRnib66rsWvtbIBTjHp4FV3dTs5iVcr62GGv4V4Mff/2I82NP10GPQg==", "dev": true, - "license": "MIT", "engines": { "node": "^14.15.0 || >=16.10.0" } }, "node_modules/@angular/platform-browser": { - "version": "14.2.2", - "license": "MIT", + "version": "14.3.0", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-14.3.0.tgz", + "integrity": "sha512-w9Y3740UmTz44T0Egvc+4QV9sEbO61L+aRHbpkLTJdlEGzHByZvxJmJyBYmdqeyTPwc/Zpy7c02frlpfAlyB7A==", "dependencies": { "tslib": "^2.3.0" }, @@ -2442,9 +846,9 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/animations": "14.2.2", - "@angular/common": "14.2.2", - "@angular/core": "14.2.2" + "@angular/animations": "14.3.0", + "@angular/common": "14.3.0", + "@angular/core": "14.3.0" }, "peerDependenciesMeta": { "@angular/animations": { @@ -2453,8 +857,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "14.2.2", - "license": "MIT", + "version": "14.3.0", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-14.3.0.tgz", + "integrity": "sha512-rneZiMrIiYRhrkQvdL40E2ErKRn4Zdo6EtjBM9pAmWeyoM8oMnOZb9gz5vhrkNWg06kVMVg0yKqluP5How7j3A==", "dependencies": { "tslib": "^2.3.0" }, @@ -2462,18 +867,19 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/common": "14.2.2", - "@angular/compiler": "14.2.2", - "@angular/core": "14.2.2", - "@angular/platform-browser": "14.2.2" + "@angular/common": "14.3.0", + "@angular/compiler": "14.3.0", + "@angular/core": "14.3.0", + "@angular/platform-browser": "14.3.0" } }, "node_modules/@angular/pwa": { - "version": "14.1.0", - "license": "MIT", + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@angular/pwa/-/pwa-14.2.13.tgz", + "integrity": "sha512-WPkTgT3+VC/KeZMydZnTQJWTG5IVTSdkJfqmNQWfHXzpmm1CG4KvFRj3xEOXvaDmcL56nnqKhL/o66kpai15Qw==", "dependencies": { - "@angular-devkit/schematics": "14.1.0", - "@schematics/angular": "14.1.0", + "@angular-devkit/schematics": "14.2.13", + "@schematics/angular": "14.2.13", "parse5-html-rewriting-stream": "6.0.1" }, "engines": { @@ -2490,77 +896,10 @@ } } }, - "node_modules/@angular/pwa/node_modules/@angular-devkit/core": { - "version": "14.1.0", - "license": "MIT", - "dependencies": { - "ajv": "8.11.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.1.0", - "rxjs": "6.6.7", - "source-map": "0.7.4" - }, - "engines": { - "node": "^14.15.0 || >=16.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular/pwa/node_modules/@angular-devkit/schematics": { - "version": "14.1.0", - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "14.1.0", - "jsonc-parser": "3.1.0", - "magic-string": "0.26.2", - "ora": "5.4.1", - "rxjs": "6.6.7" - }, - "engines": { - "node": "^14.15.0 || >=16.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular/pwa/node_modules/@schematics/angular": { - "version": "14.1.0", - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "14.1.0", - "@angular-devkit/schematics": "14.1.0", - "jsonc-parser": "3.1.0" - }, - "engines": { - "node": "^14.15.0 || >=16.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular/pwa/node_modules/rxjs": { - "version": "6.6.7", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/@angular/pwa/node_modules/tslib": { - "version": "1.14.1", - "license": "0BSD" - }, "node_modules/@angular/router": { - "version": "14.2.2", - "license": "MIT", + "version": "14.3.0", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-14.3.0.tgz", + "integrity": "sha512-uip0V7w7k7xyxxpTPbr7EuMnYLj3FzJrwkLVJSEw3TMMGHt5VU5t4BBa9veGZOta2C205XFrTAHnp8mD+XYY1w==", "dependencies": { "tslib": "^2.3.0" }, @@ -2568,15 +907,16 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/common": "14.2.2", - "@angular/core": "14.2.2", - "@angular/platform-browser": "14.2.2", + "@angular/common": "14.3.0", + "@angular/core": "14.3.0", + "@angular/platform-browser": "14.3.0", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/service-worker": { - "version": "14.2.2", - "license": "MIT", + "version": "14.3.0", + "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-14.3.0.tgz", + "integrity": "sha512-i5O7m1gQijWm7cgva0XTmOVBFrPrttNxFDwoMLMYCh8rHOCQUQ4DcVO1qTBPWU4SrY5BYPEvR+r05dYQLFYCBw==", "dependencies": { "tslib": "^2.3.0" }, @@ -2587,38 +927,43 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/common": "14.2.2", - "@angular/core": "14.2.2" + "@angular/common": "14.3.0", + "@angular/core": "14.3.0" } }, "node_modules/@assemblyscript/loader": { "version": "0.10.1", - "dev": true, - "license": "Apache-2.0" + "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.10.1.tgz", + "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==", + "dev": true }, "node_modules/@babel/code-frame": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.19.1", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.10.tgz", + "integrity": "sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==", "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", @@ -2645,17 +990,19 @@ } }, "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { "version": "7.18.12", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.12.tgz", + "integrity": "sha512-dfQ8ebCN98SvyL7IxNMCUtZQSq5R7kxgN+r8qYTGDmmSion1hX2C0zq2yo1bsCDhXixokv1SAWTZUMYbO/V5zg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.18.10", "@jridgewell/gen-mapping": "^0.3.2", @@ -2666,13 +1013,14 @@ } }, "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -2680,8 +1028,9 @@ }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.18.6" }, @@ -2690,54 +1039,58 @@ } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", + "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.19.1", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.19.1", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.19.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", + "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.9", - "@babel/helper-split-export-declaration": "^7.18.6" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -2746,13 +1099,36 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.19.0", + "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.1.0" + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.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==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz", + "integrity": "sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -2761,10 +1137,32 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.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==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-define-polyfill-provider": { "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.17.7", "@babel/helper-plugin-utils": "^7.16.7", @@ -2778,123 +1176,102 @@ } }, "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": { - "version": "6.3.0", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.19.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name/node_modules/@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.18.9", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", + "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.18.9" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.19.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.19.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2903,122 +1280,214 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.19.1", + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.18.6", + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz", + "integrity": "sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-wrap-function": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", + "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.18.9", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.18.9" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.18.10", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.19.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz", + "integrity": "sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/helper-function-name": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function/node_modules/@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.19.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", + "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.19.1", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", "dev": true, - "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -3027,11 +1496,12 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.18.6", + "version": "7.24.7", + "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.7.tgz", + "integrity": "sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3041,13 +1511,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.9", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", + "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-proposal-optional-chaining": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3058,8 +1529,10 @@ }, "node_modules/@babel/plugin-proposal-async-generator-functions": { "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.10.tgz", + "integrity": "sha512-1mFuY2TOsR1hxbjCo4QL+qlIjV07p4H4EUYw2J/WCqsvFV6V9X9z9YhXbWndc/4fw+hYGlDT7egYxliMp5O6Ew==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead.", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-plugin-utils": "^7.18.9", @@ -3075,8 +1548,10 @@ }, "node_modules/@babel/plugin-proposal-class-properties": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -3089,12 +1564,14 @@ } }, "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.18.6", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz", + "integrity": "sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-static-block instead.", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, "engines": { @@ -3106,8 +1583,10 @@ }, "node_modules/@babel/plugin-proposal-dynamic-import": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", + "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-dynamic-import instead.", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-dynamic-import": "^7.8.3" @@ -3121,8 +1600,10 @@ }, "node_modules/@babel/plugin-proposal-export-namespace-from": { "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", + "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-export-namespace-from instead.", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.9", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" @@ -3136,8 +1617,10 @@ }, "node_modules/@babel/plugin-proposal-json-strings": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", + "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-json-strings instead.", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-json-strings": "^7.8.3" @@ -3150,11 +1633,13 @@ } }, "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.9", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz", + "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-logical-assignment-operators instead.", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { @@ -3166,8 +1651,10 @@ }, "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" @@ -3181,8 +1668,10 @@ }, "node_modules/@babel/plugin-proposal-numeric-separator": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-numeric-separator": "^7.10.4" @@ -3195,15 +1684,17 @@ } }, "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.18.9", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", + "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.", "dev": true, - "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.18.8", - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9", + "@babel/compat-data": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.18.8" + "@babel/plugin-transform-parameters": "^7.20.7" }, "engines": { "node": ">=6.9.0" @@ -3214,8 +1705,10 @@ }, "node_modules/@babel/plugin-proposal-optional-catch-binding": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", + "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-catch-binding instead.", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" @@ -3228,12 +1721,14 @@ } }, "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.18.9", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { @@ -3245,8 +1740,10 @@ }, "node_modules/@babel/plugin-proposal-private-methods": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -3259,13 +1756,15 @@ } }, "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.18.6", + "version": "7.21.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz", + "integrity": "sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead.", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { @@ -3277,8 +1776,10 @@ }, "node_modules/@babel/plugin-proposal-unicode-property-regex": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-unicode-property-regex instead.", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -3292,8 +1793,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -3303,8 +1805,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -3314,8 +1817,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -3328,8 +1832,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -3339,8 +1844,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" }, @@ -3349,11 +1855,12 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", + "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3364,8 +1871,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -3375,8 +1883,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -3386,8 +1895,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -3397,8 +1907,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -3408,8 +1919,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -3419,8 +1931,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -3430,8 +1943,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -3441,8 +1955,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -3455,8 +1970,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -3468,11 +1984,12 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", + "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3483,8 +2000,9 @@ }, "node_modules/@babel/plugin-transform-async-to-generator": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", + "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6", @@ -3498,11 +2016,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", + "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3512,11 +2031,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.18.9", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz", + "integrity": "sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3526,18 +2046,18 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.19.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.7.tgz", + "integrity": "sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.19.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-replace-supers": "^7.18.9", - "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", "globals": "^11.1.0" }, "engines": { @@ -3547,12 +2067,26 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.18.9", + "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", + "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/template": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3561,12 +2095,27 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.18.13", + "node_modules/@babel/plugin-transform-computed-properties/node_modules/@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz", + "integrity": "sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3576,12 +2125,13 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", + "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3591,11 +2141,12 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", + "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3605,12 +2156,13 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", + "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3620,11 +2172,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.18.8", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", + "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3634,13 +2188,14 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.18.9", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz", + "integrity": "sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3650,11 +2205,12 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.18.9", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", + "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3664,11 +2220,12 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", + "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3678,13 +2235,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", + "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3694,14 +2251,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz", + "integrity": "sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3711,15 +2268,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.19.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz", + "integrity": "sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-validator-identifier": "^7.18.6", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3729,12 +2286,13 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", + "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3744,12 +2302,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.19.1", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", + "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3759,11 +2318,12 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", + "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3773,12 +2333,30 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", + "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.7.tgz", + "integrity": "sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -3788,11 +2366,12 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.18.8", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", + "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3802,11 +2381,12 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", + "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3816,12 +2396,13 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", + "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "regenerator-transform": "^0.15.0" + "@babel/helper-plugin-utils": "^7.24.7", + "regenerator-transform": "^0.15.2" }, "engines": { "node": ">=6.9.0" @@ -3831,11 +2412,12 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", + "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3846,8 +2428,9 @@ }, "node_modules/@babel/plugin-transform-runtime": { "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.10.tgz", + "integrity": "sha512-q5mMeYAdfEbpBAgzl7tBre/la3LeCxmDO1+wMXRdPWbcoMjR3GiXlCLk7JBZVVye0bqTGNMbt0yYVXX1B1jEWQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.9", @@ -3864,19 +2447,21 @@ } }, "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { - "version": "6.3.0", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", + "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3886,12 +2471,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.19.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", + "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3901,11 +2487,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", + "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3915,11 +2502,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.18.9", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", + "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3929,11 +2517,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.7.tgz", + "integrity": "sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3943,11 +2532,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", + "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3957,12 +2547,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", + "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3973,8 +2564,9 @@ }, "node_modules/@babel/preset-env": { "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.18.10.tgz", + "integrity": "sha512-wVxs1yjFdW3Z/XkNfXKoblxoHgbtUF7/l3PvvP4m02Qz9TZ6uZGxRVYjSQeR87oQmHco9zWitW5J82DJ7sCjvA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/compat-data": "^7.18.8", "@babel/helper-compilation-targets": "^7.18.9", @@ -4060,17 +2652,19 @@ } }, "node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.0", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/preset-modules": { - "version": "0.1.5", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6.tgz", + "integrity": "sha512-ID2yj6K/4lKfhuU3+EX4UvNbIt7eACFbHmNUjzA+ep+B5971CknnA/9DEWKbRokfbbtblxxxXFJJrH47UEAMVg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", @@ -4079,13 +2673,20 @@ "esutils": "^2.0.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.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==", + "dev": true + }, "node_modules/@babel/runtime": { "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz", + "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==", "dev": true, - "license": "MIT", "dependencies": { "regenerator-runtime": "^0.13.4" }, @@ -4095,8 +2696,9 @@ }, "node_modules/@babel/template": { "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/code-frame": "^7.18.6", "@babel/parser": "^7.18.10", @@ -4107,19 +2709,20 @@ } }, "node_modules/@babel/traverse": { - "version": "7.19.1", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", + "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.19.1", - "@babel/types": "^7.19.0", - "debug": "^4.1.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -4127,12 +2730,14 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/generator": { - "version": "7.19.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.19.0", - "@jridgewell/gen-mapping": "^0.3.2", + "@babel/types": "^7.24.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { @@ -4140,25 +2745,27 @@ } }, "node_modules/@babel/traverse/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/types": { - "version": "7.19.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -4167,8 +2774,9 @@ }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -4178,8 +2786,9 @@ }, "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -4187,8 +2796,9 @@ }, "node_modules/@csstools/postcss-cascade-layers": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", + "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", "dev": true, - "license": "CC0-1.0", "dependencies": { "@csstools/selector-specificity": "^2.0.2", "postcss-selector-parser": "^6.0.10" @@ -4206,8 +2816,9 @@ }, "node_modules/@csstools/postcss-color-function": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz", + "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==", "dev": true, - "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", "postcss-value-parser": "^4.2.0" @@ -4225,8 +2836,9 @@ }, "node_modules/@csstools/postcss-font-format-keywords": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz", + "integrity": "sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -4243,8 +2855,9 @@ }, "node_modules/@csstools/postcss-hwb-function": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz", + "integrity": "sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -4261,8 +2874,9 @@ }, "node_modules/@csstools/postcss-ic-unit": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz", + "integrity": "sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==", "dev": true, - "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", "postcss-value-parser": "^4.2.0" @@ -4280,8 +2894,9 @@ }, "node_modules/@csstools/postcss-is-pseudo-class": { "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz", + "integrity": "sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==", "dev": true, - "license": "CC0-1.0", "dependencies": { "@csstools/selector-specificity": "^2.0.0", "postcss-selector-parser": "^6.0.10" @@ -4299,8 +2914,9 @@ }, "node_modules/@csstools/postcss-nested-calc": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz", + "integrity": "sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -4317,8 +2933,9 @@ }, "node_modules/@csstools/postcss-normalize-display-values": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz", + "integrity": "sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -4335,8 +2952,9 @@ }, "node_modules/@csstools/postcss-oklab-function": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz", + "integrity": "sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==", "dev": true, - "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", "postcss-value-parser": "^4.2.0" @@ -4354,8 +2972,9 @@ }, "node_modules/@csstools/postcss-progressive-custom-properties": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", + "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -4368,8 +2987,9 @@ }, "node_modules/@csstools/postcss-stepped-value-functions": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz", + "integrity": "sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -4386,8 +3006,9 @@ }, "node_modules/@csstools/postcss-text-decoration-shorthand": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz", + "integrity": "sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -4404,8 +3025,9 @@ }, "node_modules/@csstools/postcss-trigonometric-functions": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz", + "integrity": "sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -4422,8 +3044,9 @@ }, "node_modules/@csstools/postcss-unset-value": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", + "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==", "dev": true, - "license": "CC0-1.0", "engines": { "node": "^12 || ^14 || >=16" }, @@ -4436,39 +3059,59 @@ } }, "node_modules/@csstools/selector-specificity": { - "version": "2.0.2", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", "dev": true, - "license": "CC0-1.0", "engines": { - "node": "^12 || ^14 || >=16" + "node": "^14 || ^16 || >=18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "postcss": "^8.2", "postcss-selector-parser": "^6.0.10" } }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">=10.0.0" } }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.5.tgz", + "integrity": "sha512-UHkDFCfSGTuXq08oQltXxSZmH1TXyWsL+4QhZDWvvLl6mEJQqk3u7/wq1LjhrrAXYIllaTtRSzUXl4Olkf2J8A==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@gar/promisify": { "version": "1.1.3", - "devOptional": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "devOptional": true }, "node_modules/@ionic/angular": { - "version": "6.2.7", - "license": "MIT", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-6.7.5.tgz", + "integrity": "sha512-nV8HP7RedjYkIAT8nVr5ifHNT0D3XzA74RPG3/WCCFJKunERNJ9SBiNkCTWhUpSkqsYYwEB4+SOOHz+R5NLk/w==", "dependencies": { - "@ionic/core": "^6.2.7", + "@ionic/core": "6.7.5", + "ionicons": "^6.1.3", "jsonc-parser": "^3.0.0", "tslib": "^2.0.0" }, @@ -4481,9 +3124,10 @@ } }, "node_modules/@ionic/cli": { - "version": "6.20.1", + "version": "6.20.9", + "resolved": "https://registry.npmjs.org/@ionic/cli/-/cli-6.20.9.tgz", + "integrity": "sha512-sItLCi7zXq1zARWIpZDinHhK8hvy+wzOx176QMOJV90BjDybkjGYu3rGu5TBjoqn104dRIZTC8rtCsnD/P3cQw==", "dev": true, - "license": "MIT", "dependencies": { "@ionic/cli-framework": "5.1.3", "@ionic/cli-framework-output": "2.2.5", @@ -4521,8 +3165,9 @@ }, "node_modules/@ionic/cli-framework": { "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@ionic/cli-framework/-/cli-framework-5.1.3.tgz", + "integrity": "sha512-T2KN/TurzNoAcc3iDt1KHU6GeEa7x9kXngMnu5xs+DzJv5HhBKjVOoo74b8rgVxdPx+dLOV8aLrorlyvsHR/tQ==", "dev": true, - "license": "MIT", "dependencies": { "@ionic/cli-framework-output": "2.2.5", "@ionic/utils-array": "2.1.5", @@ -4546,8 +3191,9 @@ }, "node_modules/@ionic/cli-framework-output": { "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@ionic/cli-framework-output/-/cli-framework-output-2.2.5.tgz", + "integrity": "sha512-YeDLTnTaE6V4IDUxT8GDIep0GuRIFaR7YZDLANMuuWJZDmnTku6DP+MmQoltBeLmVvz1BAAZgk41xzxdq6H2FQ==", "dev": true, - "license": "MIT", "dependencies": { "@ionic/utils-terminal": "2.3.3", "debug": "^4.0.0", @@ -4559,8 +3205,9 @@ }, "node_modules/@ionic/cli-framework-prompts": { "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@ionic/cli-framework-prompts/-/cli-framework-prompts-2.1.10.tgz", + "integrity": "sha512-h8HbA0teR0vWtGKB3ahzRbDq4yYaxfukgbOqhu9CAEJHosoFlBmDB8PbPnGFYxUg2J1MuCqeiN2ftJQYV/BO1w==", "dev": true, - "license": "MIT", "dependencies": { "@ionic/utils-terminal": "2.3.3", "debug": "^4.0.0", @@ -4573,8 +3220,9 @@ }, "node_modules/@ionic/cli-framework-prompts/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -4587,8 +3235,9 @@ }, "node_modules/@ionic/cli-framework-prompts/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4602,8 +3251,9 @@ }, "node_modules/@ionic/cli-framework-prompts/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -4613,21 +3263,24 @@ }, "node_modules/@ionic/cli-framework-prompts/node_modules/color-name": { "version": "1.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/@ionic/cli-framework-prompts/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@ionic/cli-framework-prompts/node_modules/inquirer": { "version": "7.3.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", + "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.0", @@ -4649,8 +3302,9 @@ }, "node_modules/@ionic/cli-framework-prompts/node_modules/rxjs": { "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { "tslib": "^1.9.0" }, @@ -4660,13 +3314,15 @@ }, "node_modules/@ionic/cli-framework-prompts/node_modules/rxjs/node_modules/tslib": { "version": "1.14.1", - "dev": true, - "license": "0BSD" + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true }, "node_modules/@ionic/cli-framework-prompts/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -4676,8 +3332,9 @@ }, "node_modules/@ionic/cli-framework/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -4690,8 +3347,9 @@ }, "node_modules/@ionic/cli-framework/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4705,8 +3363,9 @@ }, "node_modules/@ionic/cli-framework/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -4716,21 +3375,24 @@ }, "node_modules/@ionic/cli-framework/node_modules/color-name": { "version": "1.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/@ionic/cli-framework/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@ionic/cli-framework/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -4740,8 +3402,9 @@ }, "node_modules/@ionic/cli/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -4754,8 +3417,9 @@ }, "node_modules/@ionic/cli/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4769,8 +3433,9 @@ }, "node_modules/@ionic/cli/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -4780,21 +3445,24 @@ }, "node_modules/@ionic/cli/node_modules/color-name": { "version": "1.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/@ionic/cli/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@ionic/cli/node_modules/open": { "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", "dev": true, - "license": "MIT", "dependencies": { "is-docker": "^2.0.0", "is-wsl": "^2.1.1" @@ -4808,8 +3476,9 @@ }, "node_modules/@ionic/cli/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -4818,18 +3487,20 @@ } }, "node_modules/@ionic/core": { - "version": "6.2.7", - "license": "MIT", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.7.5.tgz", + "integrity": "sha512-zRkRn+h/Vs3xt/EVgBdShMKDyeGOM4RU31NPF2icfu3CUTH+VrMV569MUnNjYvd1Lu2xK90pYy4TaicSWmC1Pw==", "dependencies": { - "@stencil/core": "^2.17.4", - "ionicons": "^6.0.3", + "@stencil/core": "^2.18.0", + "ionicons": "^6.1.3", "tslib": "^2.1.0" } }, "node_modules/@ionic/utils-array": { "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-array/-/utils-array-2.1.5.tgz", + "integrity": "sha512-HD72a71IQVBmQckDwmA8RxNVMTbxnaLbgFOl+dO5tbvW9CkkSFCv41h6fUuNsSEVgngfkn0i98HDuZC8mk+lTA==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.0.0", "tslib": "^2.0.1" @@ -4840,8 +3511,9 @@ }, "node_modules/@ionic/utils-fs": { "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@ionic/utils-fs/-/utils-fs-3.1.6.tgz", + "integrity": "sha512-eikrNkK89CfGPmexjTfSWl4EYqsPSBh0Ka7by4F0PLc1hJZYtJxUZV3X4r5ecA8ikjicUmcbU7zJmAjmqutG/w==", "dev": true, - "license": "MIT", "dependencies": { "@types/fs-extra": "^8.0.0", "debug": "^4.0.0", @@ -4854,8 +3526,9 @@ }, "node_modules/@ionic/utils-network": { "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-network/-/utils-network-2.1.5.tgz", + "integrity": "sha512-HUQ1Ec4Mh2MXzzKdbbbDS6xYKwpFJ2XRY7SYXbaZT8+jiNahfHbsOfe62/p8bk41Yil7E9EagzGC2JvIFJh01w==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.0.0", "tslib": "^2.0.1" @@ -4866,8 +3539,9 @@ }, "node_modules/@ionic/utils-object": { "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-object/-/utils-object-2.1.5.tgz", + "integrity": "sha512-XnYNSwfewUqxq+yjER1hxTKggftpNjFLJH0s37jcrNDwbzmbpFTQTVAp4ikNK4rd9DOebX/jbeZb8jfD86IYxw==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.0.0", "tslib": "^2.0.1" @@ -4878,8 +3552,9 @@ }, "node_modules/@ionic/utils-process": { "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@ionic/utils-process/-/utils-process-2.1.10.tgz", + "integrity": "sha512-mZ7JEowcuGQK+SKsJXi0liYTcXd2bNMR3nE0CyTROpMECUpJeAvvaBaPGZf5ERQUPeWBVuwqAqjUmIdxhz5bxw==", "dev": true, - "license": "MIT", "dependencies": { "@ionic/utils-object": "2.1.5", "@ionic/utils-terminal": "2.3.3", @@ -4894,8 +3569,9 @@ }, "node_modules/@ionic/utils-stream": { "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-stream/-/utils-stream-3.1.5.tgz", + "integrity": "sha512-hkm46uHvEC05X/8PHgdJi4l4zv9VQDELZTM+Kz69odtO9zZYfnt8DkfXHJqJ+PxmtiE5mk/ehJWLnn/XAczTUw==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.0.0", "tslib": "^2.0.1" @@ -4906,8 +3582,9 @@ }, "node_modules/@ionic/utils-subprocess": { "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@ionic/utils-subprocess/-/utils-subprocess-2.1.11.tgz", + "integrity": "sha512-6zCDixNmZCbMCy5np8klSxOZF85kuDyzZSTTQKQP90ZtYNCcPYmuFSzaqDwApJT4r5L3MY3JrqK1gLkc6xiUPw==", "dev": true, - "license": "MIT", "dependencies": { "@ionic/utils-array": "2.1.5", "@ionic/utils-fs": "3.1.6", @@ -4924,8 +3601,9 @@ }, "node_modules/@ionic/utils-terminal": { "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@ionic/utils-terminal/-/utils-terminal-2.3.3.tgz", + "integrity": "sha512-RnuSfNZ5fLEyX3R5mtcMY97cGD1A0NVBbarsSQ6yMMfRJ5YHU7hHVyUfvZeClbqkBC/pAqI/rYJuXKCT9YeMCQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/slice-ansi": "^4.0.0", "debug": "^4.0.0", @@ -4943,8 +3621,9 @@ }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, - "license": "ISC", "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -4958,16 +3637,18 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/@istanbuljs/load-nyc-config/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==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -4976,18 +3657,26 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jridgewell/gen-mapping": { "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -4997,65 +3686,106 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.2", + "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==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "dev": true, - "license": "MIT" + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.15", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.4", - "dev": true, - "license": "MIT" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true + }, + "node_modules/@maskito/angular": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@maskito/angular/-/angular-1.9.0.tgz", + "integrity": "sha512-Wa/9nM9Nv0oieVZ6yxQNXfDRA4obFDR15xO16o1GKF8i9W1IdQQn+tuMRjkmx6HhJDN9+x3k8OTJ1f80BIrhjA==", + "dependencies": { + "tslib": "2.6.2" + }, + "peerDependencies": { + "@angular/common": ">=12.0.0", + "@angular/core": ">=12.0.0", + "@angular/forms": ">=12.0.0", + "@maskito/core": "^1.9.0", + "rxjs": ">=6.0.0" + } + }, + "node_modules/@maskito/angular/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/@maskito/core": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@maskito/core/-/core-1.9.0.tgz", + "integrity": "sha512-WQIUrwkdIUg6PzAb4Apa0RjTPHB0EqZLc9/7kWCKVIixhkITRFXFg2BhiDVSRv0mIKVlAEJcOvvjHK5T3UaIig==" + }, + "node_modules/@maskito/kit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@maskito/kit/-/kit-1.9.0.tgz", + "integrity": "sha512-LNNgOJ0tAfrPoPehvoP+ZyYF9giOYL02sOMKyDC3IcqDNA8BAU0PARmS7TNsVEBpvSuJhU6xVt40nxJaONgUdw==", + "peerDependencies": { + "@maskito/core": "^1.9.0" + } }, "node_modules/@materia-ui/ngx-monaco-editor": { "version": "6.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@materia-ui/ngx-monaco-editor/-/ngx-monaco-editor-6.0.0.tgz", + "integrity": "sha512-gTqNQjOGznZxOC0NlmKdKSGCJuTts8YmK4dsTQAGc5IgIV7cZdQWiW6AL742h0ruED6q0cAunEYjXT6jzHBoIQ==", "dependencies": { "tslib": "^2.0.0" }, @@ -5065,8 +3795,9 @@ } }, "node_modules/@ng-web-apis/common": { - "version": "2.1.0", - "license": "MIT", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@ng-web-apis/common/-/common-3.0.6.tgz", + "integrity": "sha512-ral+lzGpFS3aOCFB5DcHOI4lZhhp8GH4BnjSbngH2Xk8J0FKYdxRzvcPQVy7hS+TPUu0tW9uFVp6cC7odu3iyQ==", "dependencies": { "tslib": "^2.2.0" }, @@ -5077,8 +3808,9 @@ } }, "node_modules/@ng-web-apis/intersection-observer": { - "version": "3.0.0", - "license": "MIT", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@ng-web-apis/intersection-observer/-/intersection-observer-3.2.0.tgz", + "integrity": "sha512-EhwqEZJFKR9pz55TWp82qyWTXdg8TZeMP6bUw26bVHz8CTkgrpzaXdtxurMTvJ/+gwuFy4JSJLjBeV9nfZ/SXA==", "dependencies": { "tslib": "^2.2.0" }, @@ -5088,8 +3820,9 @@ } }, "node_modules/@ng-web-apis/mutation-observer": { - "version": "2.0.0", - "license": "MIT", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@ng-web-apis/mutation-observer/-/mutation-observer-3.2.1.tgz", + "integrity": "sha512-a7krkMx0e9cfnutClwDylWjbTQVRHUP3oUik/nBvUdKlk/Q4anNww9aIKJ64VgiXR+1ZF8OmHGl0+XUzN6xP9Q==", "dependencies": { "tslib": "^2.2.0" }, @@ -5099,8 +3832,9 @@ } }, "node_modules/@ng-web-apis/resize-observer": { - "version": "2.0.0", - "license": "MIT", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@ng-web-apis/resize-observer/-/resize-observer-3.2.1.tgz", + "integrity": "sha512-r1YaZUo6DIDeR+4/C/pM4Ar0eTQBxjK0FUhYYJ512EnN8RqAn8d3a0wM8ZYunucwDICwW1sx4IIV6PZ2G77xsg==", "dependencies": { "tslib": "^2.2.0" }, @@ -5109,10 +3843,49 @@ "@ng-web-apis/common": ">=2.0.0" } }, + "node_modules/@ngtools/webpack": { + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.2.13.tgz", + "integrity": "sha512-RQx/rGX7K/+R55x1R6Ax1JzyeHi8cW11dEXpzHWipyuSpusQLUN53F02eMB4VTakXsL3mFNWWy4bX3/LSq8/9w==", + "dev": true, + "engines": { + "node": "^14.15.0 || >=16.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^14.0.0", + "typescript": ">=4.6.2 <4.9", + "webpack": "^5.54.0" + } + }, + "node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "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==", "devOptional": true, - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -5123,16 +3896,18 @@ }, "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==", "devOptional": true, - "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "devOptional": true, - "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -5143,8 +3918,9 @@ }, "node_modules/@npmcli/fs": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", + "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", "devOptional": true, - "license": "ISC", "dependencies": { "@gar/promisify": "^1.1.3", "semver": "^7.3.5" @@ -5155,8 +3931,9 @@ }, "node_modules/@npmcli/git": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-3.0.2.tgz", + "integrity": "sha512-CAcd08y3DWBJqJDpfuVL0uijlq5oaXaOJEKHKc4wqrjd00gkvTZB+nFuLn+doOOKddaQS9JfqtNoFCO2LCvA3w==", "devOptional": true, - "license": "ISC", "dependencies": { "@npmcli/promise-spawn": "^3.0.0", "lru-cache": "^7.4.4", @@ -5172,10 +3949,20 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "devOptional": true, + "engines": { + "node": ">=12" + } + }, "node_modules/@npmcli/installed-package-contents": { "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz", + "integrity": "sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw==", "devOptional": true, - "license": "ISC", "dependencies": { "npm-bundled": "^1.1.1", "npm-normalize-package-bin": "^1.0.1" @@ -5189,8 +3976,10 @@ }, "node_modules/@npmcli/move-file": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", + "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", + "deprecated": "This functionality has been moved to @npmcli/fs", "devOptional": true, - "license": "MIT", "dependencies": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" @@ -5201,16 +3990,18 @@ }, "node_modules/@npmcli/node-gyp": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-2.0.0.tgz", + "integrity": "sha512-doNI35wIe3bBaEgrlPfdJPaCpUR89pJWep4Hq3aRdh6gKazIVWfs0jHttvSSoq47ZXgC7h73kDsUl8AoIQUB+A==", "devOptional": true, - "license": "ISC", "engines": { "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/@npmcli/promise-spawn": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-3.0.0.tgz", + "integrity": "sha512-s9SgS+p3a9Eohe68cSI3fi+hpcZUmXq5P7w0kMlAsWVtR7XbK3ptkZqKT2cK1zLDObJ3sR+8P59sJE0w/KTL1g==", "devOptional": true, - "license": "ISC", "dependencies": { "infer-owner": "^1.0.4" }, @@ -5220,8 +4011,9 @@ }, "node_modules/@npmcli/run-script": { "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-4.2.1.tgz", + "integrity": "sha512-7dqywvVudPSrRCW5nTHpHgeWnbBtz8cFkOuKrecm6ih+oO9ciydhWt6OF7HlqupRRmB8Q/gECVdB9LMfToJbRg==", "devOptional": true, - "license": "ISC", "dependencies": { "@npmcli/node-gyp": "^2.0.0", "@npmcli/promise-spawn": "^3.0.0", @@ -5234,14 +4026,16 @@ } }, "node_modules/@polka/url": { - "version": "1.0.0-next.21", - "dev": true, - "license": "MIT" + "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==", + "dev": true }, "node_modules/@rollup/plugin-json": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", + "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", "dev": true, - "license": "MIT", "dependencies": { "@rollup/pluginutils": "^3.0.8" }, @@ -5251,8 +4045,9 @@ }, "node_modules/@rollup/plugin-node-resolve": { "version": "13.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.3.0.tgz", + "integrity": "sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==", "dev": true, - "license": "MIT", "dependencies": { "@rollup/pluginutils": "^3.1.0", "@types/resolve": "1.17.1", @@ -5270,8 +4065,9 @@ }, "node_modules/@rollup/pluginutils": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", "dev": true, - "license": "MIT", "dependencies": { "@types/estree": "0.0.39", "estree-walker": "^1.0.1", @@ -5286,16 +4082,17 @@ }, "node_modules/@rollup/pluginutils/node_modules/@types/estree": { "version": "0.0.39", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true }, "node_modules/@schematics/angular": { - "version": "14.2.3", - "devOptional": true, - "license": "MIT", + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-14.2.13.tgz", + "integrity": "sha512-MLxTpTU3E8QACQ/5c0sENMR2gRiMXpGaKeD5IHY+3wyU2fUSJVB0QPU/l1WhoyZbX8N9ospBgf5UEG7taVF9rg==", "dependencies": { - "@angular-devkit/core": "14.2.3", - "@angular-devkit/schematics": "14.2.3", + "@angular-devkit/core": "14.2.13", + "@angular-devkit/schematics": "14.2.13", "jsonc-parser": "3.1.0" }, "engines": { @@ -5311,15 +4108,17 @@ }, "node_modules/@start9labs/emver": { "version": "0.1.5", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@start9labs/emver/-/emver-0.1.5.tgz", + "integrity": "sha512-1dhiG03VkfEwSLx/JPKVms6srAbYFQgwfSGhwpUKMDliMXuAHGVaueStmqzVxn3JpH/HEVz0QW8w/PXHqjdiIg==" }, "node_modules/@start9labs/start-sdk": { "resolved": "../sdk/dist", "link": true }, "node_modules/@stencil/core": { - "version": "2.18.0", - "license": "MIT", + "version": "2.22.3", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.22.3.tgz", + "integrity": "sha512-kmVA0M/HojwsfkeHsifvHVIYe4l5tin7J5+DLgtl8h6WWfiMClND5K3ifCXXI2ETDNKiEk21p6jql3Fx9o2rng==", "bin": { "stencil": "bin/stencil" }, @@ -5329,33 +4128,59 @@ } }, "node_modules/@taiga-ui/addon-charts": { - "version": "3.20.0", - "license": "Apache-2.0", + "version": "3.84.0", + "resolved": "https://registry.npmjs.org/@taiga-ui/addon-charts/-/addon-charts-3.84.0.tgz", + "integrity": "sha512-XR7UFywnrv4NRLHOCbba63gXDYYDL4Rt0MbjnF54p5U2EXnbt2of7VbjlB6cPx40XkQqfqa3CNayYxWZP82Ijg==", "dependencies": { - "tslib": ">=2.0.0" + "tslib": "^2.6.2" }, "peerDependencies": { "@angular/common": ">=12.0.0", "@angular/core": ">=12.0.0", - "@ng-web-apis/common": ">=2.0.0", - "@taiga-ui/cdk": ">=3.20.0", - "@taiga-ui/core": ">=3.20.0", - "@tinkoff/ng-polymorpheus": ">=4.0.0" + "@ng-web-apis/common": "^3.0.6", + "@taiga-ui/cdk": "^3.84.0", + "@taiga-ui/core": "^3.84.0", + "@tinkoff/ng-polymorpheus": "^4.3.0" + } + }, + "node_modules/@taiga-ui/addon-commerce": { + "version": "3.84.0", + "resolved": "https://registry.npmjs.org/@taiga-ui/addon-commerce/-/addon-commerce-3.84.0.tgz", + "integrity": "sha512-1zqLwnZLAYYcHvjH89d7JmtV2+QeZ2YnSJ3YWEMNLjGPzpev4RvQXtDfglIyu0LCyTxqpXmuzes9v/cgq2P5TQ==", + "peer": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "peerDependencies": { + "@angular/common": ">=12.0.0", + "@angular/core": ">=12.0.0", + "@angular/forms": ">=12.0.0", + "@maskito/angular": "^1.9.0", + "@maskito/core": "^1.9.0", + "@maskito/kit": "^1.9.0", + "@ng-web-apis/common": "^3.0.6", + "@taiga-ui/cdk": "^3.84.0", + "@taiga-ui/core": "^3.84.0", + "@taiga-ui/i18n": "^3.84.0", + "@taiga-ui/kit": "^3.84.0", + "@tinkoff/ng-polymorpheus": "^4.3.0", + "rxjs": ">=6.0.0" } }, "node_modules/@taiga-ui/cdk": { - "version": "3.20.0", - "license": "Apache-2.0", + "version": "3.84.0", + "resolved": "https://registry.npmjs.org/@taiga-ui/cdk/-/cdk-3.84.0.tgz", + "integrity": "sha512-0umw/CUmYNEYOCUNQVTQS53zXzxZsH/6+lj1mFVzocvfJFJWAUT6ltCH9QvxYmxSDDGWwNGg16AaVo2K+aGL0w==", "dependencies": { - "@ng-web-apis/common": "2.1.0", - "@ng-web-apis/mutation-observer": "2.0.0", - "@ng-web-apis/resize-observer": "2.0.0", - "@tinkoff/ng-event-plugins": "3.1.0", - "@tinkoff/ng-polymorpheus": "4.0.10", - "tslib": "2.5.0" + "@ng-web-apis/common": "3.0.6", + "@ng-web-apis/mutation-observer": "3.1.0", + "@ng-web-apis/resize-observer": "3.0.6", + "@tinkoff/ng-event-plugins": "3.2.0", + "@tinkoff/ng-polymorpheus": "4.3.0", + "tslib": "2.6.2" }, "optionalDependencies": { - "ng-morph": "2.1.0", + "ng-morph": "4.0.5", "parse5": "6.0.1" }, "peerDependencies": { @@ -5366,16 +4191,42 @@ "rxjs": ">=6.0.0" } }, + "node_modules/@taiga-ui/cdk/node_modules/@ng-web-apis/mutation-observer": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@ng-web-apis/mutation-observer/-/mutation-observer-3.1.0.tgz", + "integrity": "sha512-MFN0TLLBMFJJPpXkGFe9ChRCSOKvMHZRRtBq5jHWS7tv5/CtdUkqW5CU7RC9KTzZjGeMzYe0cXO4JRkjL5aZ9g==", + "dependencies": { + "tslib": "^2.2.0" + }, + "peerDependencies": { + "@angular/core": ">=12.0.0", + "@ng-web-apis/common": ">=2.0.0" + } + }, + "node_modules/@taiga-ui/cdk/node_modules/@ng-web-apis/resize-observer": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@ng-web-apis/resize-observer/-/resize-observer-3.0.6.tgz", + "integrity": "sha512-QdGYdEdC0AzFonLfNOnyYyeCwnvK9jlskoeefvJN3Yyvds3ivBrrTjpeDOdiLsQpCPBp9/673imgq7355vkQow==", + "dependencies": { + "tslib": "^2.2.0" + }, + "peerDependencies": { + "@angular/core": ">=12.0.0", + "@ng-web-apis/common": ">=2.0.0" + } + }, "node_modules/@taiga-ui/cdk/node_modules/tslib": { - "version": "2.5.0", - "license": "0BSD" + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/@taiga-ui/core": { - "version": "3.20.0", - "license": "Apache-2.0", + "version": "3.84.0", + "resolved": "https://registry.npmjs.org/@taiga-ui/core/-/core-3.84.0.tgz", + "integrity": "sha512-FZy77z0E4qjYcszVcp+qPFkPwJPl8qXZb7t2P+juUtJvSmSn2foQHHdyhbIYN808H26tqCdgkTMG1BWQxVuDSg==", "dependencies": { - "@taiga-ui/i18n": "^3.20.0", - "tslib": ">=2.0.0" + "@taiga-ui/i18n": "^3.84.0", + "tslib": "^2.6.2" }, "peerDependencies": { "@angular/animations": ">=12.0.0", @@ -5384,52 +4235,81 @@ "@angular/forms": ">=12.0.0", "@angular/platform-browser": ">=12.0.0", "@angular/router": ">=12.0.0", - "@ng-web-apis/common": ">=2.0.0", - "@ng-web-apis/mutation-observer": ">=2.0.0", - "@taiga-ui/cdk": ">=3.20.0", - "@taiga-ui/i18n": ">=3.20.0", - "@tinkoff/ng-event-plugins": ">=3.1.0", - "@tinkoff/ng-polymorpheus": ">=4.0.0", + "@ng-web-apis/common": "^3.0.6", + "@ng-web-apis/mutation-observer": "^3.1.0", + "@taiga-ui/cdk": "^3.84.0", + "@taiga-ui/i18n": "^3.84.0", + "@tinkoff/ng-event-plugins": "^3.2.0", + "@tinkoff/ng-polymorpheus": "^4.3.0", + "rxjs": ">=6.0.0" + } + }, + "node_modules/@taiga-ui/experimental": { + "version": "3.84.0", + "resolved": "https://registry.npmjs.org/@taiga-ui/experimental/-/experimental-3.84.0.tgz", + "integrity": "sha512-q0hNVy+EmywCG8hpZlg/+haKIFhnmxicQiSeV/D1P7CHO10safjGo0ptT6e1hYMFa5/cJZOM4OwDPen2xs17Wg==", + "dependencies": { + "tslib": "^2.6.2" + }, + "peerDependencies": { + "@angular/common": ">=12.0.0", + "@angular/core": ">=12.0.0", + "@taiga-ui/addon-commerce": "^3.84.0", + "@taiga-ui/cdk": "^3.84.0", + "@taiga-ui/core": "^3.84.0", + "@taiga-ui/kit": "^3.84.0", + "@tinkoff/ng-polymorpheus": "^4.3.0", "rxjs": ">=6.0.0" } }, "node_modules/@taiga-ui/i18n": { - "version": "3.20.0", - "license": "Apache-2.0", + "version": "3.85.0", + "resolved": "https://registry.npmjs.org/@taiga-ui/i18n/-/i18n-3.85.0.tgz", + "integrity": "sha512-CGoxfq9WY+psX5ZOfWmuQZ6OA/0CAPYJTlbHkw5sRKAyhEQ3NM/Wbx3xcwrcYRRJDnt9yOlfibz+3a+WDF2bFA==", "dependencies": { - "tslib": ">=2.0.0" + "tslib": "^2.6.2" }, "peerDependencies": { "@angular/core": ">=12.0.0", + "@ng-web-apis/common": "^3.0.6", "rxjs": ">=6.0.0" } }, "node_modules/@taiga-ui/icons": { - "version": "3.20.0", - "license": "Apache-2.0", + "version": "3.84.0", + "resolved": "https://registry.npmjs.org/@taiga-ui/icons/-/icons-3.84.0.tgz", + "integrity": "sha512-KiH7BJRZ6wbkOHlJAS0XHq2gYnQTpRgdEogKW+GoD0da/4trCdM66vhDk2j0DwDFdBGq5U0inHJCjnskBI1nSQ==", "dependencies": { - "tslib": "^2.2.0" + "tslib": "^2.6.2" + }, + "peerDependencies": { + "@taiga-ui/cdk": "^3.84.0" } }, "node_modules/@taiga-ui/kit": { - "version": "3.20.0", - "license": "Apache-2.0", + "version": "3.84.0", + "resolved": "https://registry.npmjs.org/@taiga-ui/kit/-/kit-3.84.0.tgz", + "integrity": "sha512-lSUPDco5FeBYK3ESnXeEPLCdMCmNXwcdHNK/we+0ZoH4VPx/OGg2hpEP0Fej7jfGHwXFTzDbufQD0hT6WlfTAw==", "dependencies": { - "@ng-web-apis/intersection-observer": "3.0.0", + "@maskito/angular": "1.9.0", + "@maskito/core": "1.9.0", + "@maskito/kit": "1.9.0", + "@ng-web-apis/intersection-observer": "3.2.0", "text-mask-core": "5.1.2", - "tslib": ">=2.0.0" + "tslib": "^2.6.2" }, "peerDependencies": { "@angular/common": ">=12.0.0", "@angular/core": ">=12.0.0", "@angular/forms": ">=12.0.0", "@angular/router": ">=12.0.0", - "@ng-web-apis/common": ">=2.0.0", - "@ng-web-apis/mutation-observer": ">=2.0.0", - "@taiga-ui/cdk": ">=3.20.0", - "@taiga-ui/core": ">=3.20.0", - "@taiga-ui/i18n": ">=3.20.0", - "@tinkoff/ng-polymorpheus": ">=4.0.0", + "@ng-web-apis/common": "3.0.6", + "@ng-web-apis/mutation-observer": "^3.1.0", + "@ng-web-apis/resize-observer": "^3.0.6", + "@taiga-ui/cdk": "^3.84.0", + "@taiga-ui/core": "^3.84.0", + "@taiga-ui/i18n": "^3.84.0", + "@tinkoff/ng-polymorpheus": "^4.3.0", "rxjs": ">=6.0.0" } }, @@ -5448,8 +4328,9 @@ } }, "node_modules/@tinkoff/ng-event-plugins": { - "version": "3.1.0", - "license": "Apache-2.0", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@tinkoff/ng-event-plugins/-/ng-event-plugins-3.2.0.tgz", + "integrity": "sha512-n56R5xNfiytabh2WmWdQXfNU6m7dfOo3LLxlARE+DX7f5yciW2xBdDkuEHX74q8dlCuAVlW9aslSfz8c//ymwA==", "dependencies": { "tslib": "^2.2.0" }, @@ -5460,128 +4341,158 @@ } }, "node_modules/@tinkoff/ng-polymorpheus": { - "version": "4.0.10", - "license": "Apache-2.0", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tinkoff/ng-polymorpheus/-/ng-polymorpheus-4.3.0.tgz", + "integrity": "sha512-Ck/XCLuBwlUgvK22PxTlLTZhGG6I32kLqLYtDQh8N/QZZhs40+hb/78/ElFGzD567CCvrzNnueFkaOoXhuEVrw==", "dependencies": { - "tslib": "^2.0.0" + "tslib": "2.6.2" }, "peerDependencies": { - "@angular/core": ">=12.0.0" + "@angular/core": ">=12.0.0", + "@angular/platform-browser": ">=12.0.0" } }, + "node_modules/@tinkoff/ng-polymorpheus/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/@tootallnate/once": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "devOptional": true, - "license": "MIT", "engines": { "node": ">= 10" } }, "node_modules/@ts-morph/common": { - "version": "0.9.2", - "license": "MIT", + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.22.0.tgz", + "integrity": "sha512-HqNBuV/oIlMKdkLshXd1zKBqNQCsuPEsgQOkfFQ/eUKjRlwndXW1AjN9LVkBEIukm00gGXSRmfkl0Wv5VXLnlw==", "optional": true, "dependencies": { - "fast-glob": "^3.2.5", - "minimatch": "^3.0.4", - "mkdirp": "^1.0.4", + "fast-glob": "^3.3.2", + "minimatch": "^9.0.3", + "mkdirp": "^3.0.1", "path-browserify": "^1.0.1" } }, - "node_modules/@ts-morph/common/node_modules/brace-expansion": { - "version": "1.1.11", - "license": "MIT", - "optional": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/@ts-morph/common/node_modules/minimatch": { - "version": "3.1.2", - "license": "ISC", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "optional": true, "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@ts-morph/common/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "optional": true, + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "dev": true, - "license": "MIT" + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true }, "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "dev": true, - "license": "MIT" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true }, "node_modules/@types/body-parser": { - "version": "1.19.2", + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dev": true, - "license": "MIT", "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "node_modules/@types/bonjour": { - "version": "3.5.10", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/connect": { - "version": "3.4.35", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/connect-history-api-fallback": { - "version": "1.3.5", + "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==", "dev": true, - "license": "MIT", "dependencies": { "@types/express-serve-static-core": "*", "@types/node": "*" } }, "node_modules/@types/dompurify": { - "version": "2.3.4", - "license": "MIT", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-2.4.0.tgz", + "integrity": "sha512-IDBwO5IZhrKvHFUl+clZxgf3hn2b/lU6H1KaBShPkQyGJUQ0xwebezIPSuiyGwfz1UzJWQl4M7BDxtHtCCPlTg==", "dependencies": { "@types/trusted-types": "*" } }, "node_modules/@types/eslint": { - "version": "8.4.6", + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "node_modules/@types/eslint-scope": { - "version": "3.7.4", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, - "license": "MIT", "dependencies": { "@types/eslint": "*", "@types/estree": "*" @@ -5589,332 +4500,422 @@ }, "node_modules/@types/estree": { "version": "0.0.51", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", + "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "dev": true }, "node_modules/@types/express": { - "version": "4.17.14", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", + "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "*" } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.31", + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", - "@types/range-parser": "*" + "@types/range-parser": "*", + "@types/send": "*" } }, "node_modules/@types/fs-extra": { - "version": "8.1.2", + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz", + "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, + "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==", + "dev": true + }, "node_modules/@types/http-proxy": { - "version": "1.17.9", + "version": "1.17.14", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", + "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/js-yaml": { - "version": "4.0.5", - "dev": true, - "license": "MIT" + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "dev": true }, "node_modules/@types/json-schema": { - "version": "7.0.11", - "dev": true, - "license": "MIT" + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true }, "node_modules/@types/marked": { - "version": "4.0.7", - "dev": true, - "license": "MIT" + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.3.2.tgz", + "integrity": "sha512-a79Yc3TOk6dGdituy8hmTTJXjOkZ7zsFYV10L337ttq/rec8lRMDBpV7fL3uLx6TgbFCa5DU/h8FmIBQPSbU0w==", + "dev": true }, "node_modules/@types/mime": { - "version": "3.0.1", - "dev": true, - "license": "MIT" + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true }, "node_modules/@types/minimatch": { "version": "3.0.5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", "optional": true }, "node_modules/@types/mustache": { - "version": "4.2.1", - "dev": true, - "license": "MIT" + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-4.2.5.tgz", + "integrity": "sha512-PLwiVvTBg59tGFL/8VpcGvqOu3L4OuveNvPi0EYbWchRdEVP++yRUXJPFl+CApKEq13017/4Nf7aQ5lTtHUNsA==", + "dev": true }, "node_modules/@types/node": { - "version": "16.11.59", + "version": "16.18.101", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.101.tgz", + "integrity": "sha512-AAsx9Rgz2IzG8KJ6tXd6ndNkVcu+GYB6U/SnFAaokSPNx2N7dcIIfnighYUNumvj6YS2q39Dejz5tT0NCV7CWA==", + "dev": true + }, + "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==", "dev": true, - "license": "MIT" + "dependencies": { + "@types/node": "*" + } }, "node_modules/@types/node-jose": { - "version": "1.1.10", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@types/node-jose/-/node-jose-1.1.13.tgz", + "integrity": "sha512-QjMd4yhwy1EvSToQn0YI3cD29YhyfxFwj7NecuymjLys2/P0FwxWnkgBlFxCai6Y3aBCe7rbwmqwJJawxlgcXw==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/parse-json": { - "version": "4.0.0", - "dev": true, - "license": "MIT" + "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==", + "dev": true }, "node_modules/@types/pbkdf2": { - "version": "3.1.0", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/qs": { - "version": "6.9.7", - "dev": true, - "license": "MIT" + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "dev": true }, "node_modules/@types/range-parser": { - "version": "1.2.4", - "dev": true, - "license": "MIT" + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true }, "node_modules/@types/resolve": { "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, "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==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dev": true, - "license": "MIT" + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } }, "node_modules/@types/serve-index": { - "version": "1.9.1", + "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==", "dev": true, - "license": "MIT", "dependencies": { "@types/express": "*" } }, "node_modules/@types/serve-static": { - "version": "1.15.0", + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", "dev": true, - "license": "MIT", "dependencies": { - "@types/mime": "*", - "@types/node": "*" + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" } }, "node_modules/@types/slice-ansi": { "version": "4.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-+OpjSaq85gvlZAYINyzKpLeiFkSC4EsC6IIiT6v6TLSU5k5U83fHGj9Lel8oKEXM0HqgrMVCjXPDPVICtxF7EQ==", + "dev": true }, "node_modules/@types/sockjs": { - "version": "0.3.33", + "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==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/trusted-types": { - "version": "2.0.2", - "license": "MIT" + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" }, "node_modules/@types/uuid": { "version": "8.3.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "dev": true }, "node_modules/@types/ws": { - "version": "8.5.3", + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.1", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", + "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==", "dev": true, - "license": "MIT" + "peer": true }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.1", + "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==", "dev": true, - "license": "MIT" + "peer": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.1", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", "dev": true, - "license": "MIT" + "peer": true }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.1", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", + "@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.1", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true, - "license": "MIT" + "peer": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@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.1", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.1", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, - "license": "Apache-2.0", + "peer": true, "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.1", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true, - "license": "MIT" + "peer": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.1", + "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@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.11.1", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@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.11.1", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@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.11.1", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@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.11.1", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", - "dev": true, - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true }, "node_modules/@xtuc/long": { "version": "4.2.2", - "dev": true, - "license": "Apache-2.0" + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true }, "node_modules/@yarnpkg/lockfile": { "version": "1.1.0", - "devOptional": true, - "license": "BSD-2-Clause" + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "devOptional": true }, "node_modules/abab": { "version": "2.0.6", - "dev": true, - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", + "dev": true }, "node_modules/abbrev": { "version": "1.1.1", - "devOptional": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "devOptional": true }, "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==", "dev": true, - "license": "MIT", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -5924,9 +4925,10 @@ } }, "node_modules/acorn": { - "version": "8.8.0", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, - "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -5935,25 +4937,41 @@ } }, "node_modules/acorn-import-assertions": { - "version": "1.8.0", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, - "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, + "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==", + "dev": true, + "peer": true, "peerDependencies": { "acorn": "^8" } }, "node_modules/acorn-walk": { - "version": "8.2.0", + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", "dev": true, - "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, "engines": { "node": ">=0.4.0" } }, "node_modules/adjust-sourcemap-loader": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", "dev": true, - "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", "regex-parser": "^2.2.11" @@ -5964,8 +4982,9 @@ }, "node_modules/adjust-sourcemap-loader/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==", "dev": true, - "license": "MIT", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -5977,8 +4996,9 @@ }, "node_modules/agent-base": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "devOptional": true, - "license": "MIT", "dependencies": { "debug": "4" }, @@ -5987,12 +5007,11 @@ } }, "node_modules/agentkeepalive": { - "version": "4.2.1", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", "devOptional": true, - "license": "MIT", "dependencies": { - "debug": "^4.1.0", - "depd": "^1.1.2", "humanize-ms": "^1.2.1" }, "engines": { @@ -6001,8 +5020,9 @@ }, "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==", "devOptional": true, - "license": "MIT", "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -6013,7 +5033,8 @@ }, "node_modules/ajv": { "version": "8.11.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -6027,7 +5048,8 @@ }, "node_modules/ajv-formats": { "version": "2.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "dependencies": { "ajv": "^8.0.0" }, @@ -6042,8 +5064,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -6053,7 +5076,8 @@ }, "node_modules/angular-svg-round-progressbar": { "version": "9.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/angular-svg-round-progressbar/-/angular-svg-round-progressbar-9.0.0.tgz", + "integrity": "sha512-q8d2AEG9u+GMAMrZY40NgejN5fHwR4iK+rRxtJ7NnMEvvuAMqt9UEtKe0SqVQHvZYE6W16L5J9yaO+TEtfRjpw==", "dependencies": { "tslib": "^2.3.0" }, @@ -6064,16 +5088,18 @@ }, "node_modules/ansi-colors": { "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/ansi-escapes": { "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "devOptional": true, - "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -6086,26 +5112,29 @@ }, "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==", "dev": true, "engines": [ "node >= 0.8.0" ], - "license": "Apache-2.0", "bin": { "ansi-html": "bin/ansi-html" } }, "node_modules/ansi-regex": { "version": "5.0.1", - "license": "MIT", + "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": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -6115,7 +5144,8 @@ }, "node_modules/ansi-to-html": { "version": "0.7.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.7.2.tgz", + "integrity": "sha512-v6MqmEpNlxF+POuyhKkidusCHWWkaLcGRURzivcU3I9tv7k4JVhFcnukrM5Rlk2rUywdZuzYAZ+kbZqWCnfN3g==", "dependencies": { "entities": "^2.2.0" }, @@ -6127,9 +5157,10 @@ } }, "node_modules/anymatch": { - "version": "3.1.2", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "devOptional": true, - "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -6140,13 +5171,16 @@ }, "node_modules/aproba": { "version": "2.0.0", - "devOptional": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "devOptional": true }, "node_modules/are-we-there-yet": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "deprecated": "This package is no longer supported.", "devOptional": true, - "license": "ISC", "dependencies": { "delegates": "^1.0.0", "readable-stream": "^3.6.0" @@ -6157,29 +5191,34 @@ }, "node_modules/arg": { "version": "4.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true }, "node_modules/argparse": { "version": "2.0.1", - "license": "Python-2.0" + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/array-differ": { "version": "3.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", "optional": true, "engines": { "node": ">=8" } }, "node_modules/array-flatten": { - "version": "2.1.2", - "dev": true, - "license": "MIT" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true }, "node_modules/array-union": { "version": "2.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "optional": true, "engines": { "node": ">=8" @@ -6187,7 +5226,8 @@ }, "node_modules/arrify": { "version": "2.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", "optional": true, "engines": { "node": ">=8" @@ -6195,8 +5235,9 @@ }, "node_modules/ast-types": { "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.0.1" }, @@ -6206,29 +5247,33 @@ }, "node_modules/astral-regex": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/asynckit": { "version": "0.4.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true }, "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==", "dev": true, - "license": "ISC", "engines": { "node": ">= 4.0.0" } }, "node_modules/atob": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true, - "license": "(MIT OR Apache-2.0)", "bin": { "atob": "bin/atob.js" }, @@ -6237,7 +5282,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.11", + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", + "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", "dev": true, "funding": [ { @@ -6247,13 +5294,16 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "browserslist": "^4.21.3", - "caniuse-lite": "^1.0.30001399", - "fraction.js": "^4.2.0", + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001599", + "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", "postcss-value-parser": "^4.2.0" @@ -6270,8 +5320,9 @@ }, "node_modules/babel-loader": { "version": "8.2.5", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.5.tgz", + "integrity": "sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ==", "dev": true, - "license": "MIT", "dependencies": { "find-cache-dir": "^3.3.1", "loader-utils": "^2.0.0", @@ -6288,8 +5339,9 @@ }, "node_modules/babel-loader/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==", "dev": true, - "license": "MIT", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -6299,18 +5351,11 @@ "node": ">=8.9.0" } }, - "node_modules/babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "dev": true, - "license": "MIT", - "dependencies": { - "object.assign": "^4.1.0" - } - }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -6324,8 +5369,9 @@ }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/compat-data": "^7.17.7", "@babel/helper-define-polyfill-provider": "^0.3.3", @@ -6336,17 +5382,19 @@ } }, "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.0", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/babel-plugin-polyfill-corejs3": { "version": "0.5.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.3.tgz", + "integrity": "sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.3.2", "core-js-compat": "^3.21.0" @@ -6357,8 +5405,9 @@ }, "node_modules/babel-plugin-polyfill-regenerator": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.3.3" }, @@ -6368,11 +5417,14 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "devOptional": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "devOptional": true }, "node_modules/base64-js": { "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "funding": [ { "type": "github", @@ -6386,40 +5438,47 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/base64url": { "version": "3.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", "engines": { "node": ">=6.0.0" } }, "node_modules/batch": { "version": "0.6.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true }, "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==", "dev": true, - "license": "MIT", "engines": { "node": "*" } }, "node_modules/binary-extensions": { - "version": "2.2.0", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/bl": { "version": "4.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -6428,6 +5487,8 @@ }, "node_modules/bl/node_modules/buffer": { "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "funding": [ { "type": "github", @@ -6442,27 +5503,27 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "node_modules/body-parser": { - "version": "1.20.0", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dev": true, - "license": "MIT", "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "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.10.3", - "raw-body": "2.5.1", + "qs": "6.11.0", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -6473,29 +5534,24 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.0.0" } }, - "node_modules/body-parser/node_modules/depd": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, "node_modules/body-parser/node_modules/qs": { - "version": "6.10.3", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.4" }, @@ -6507,42 +5563,46 @@ } }, "node_modules/bonjour-service": { - "version": "1.0.14", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", "dev": true, - "license": "MIT", "dependencies": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" } }, "node_modules/boolbase": { "version": "1.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true }, "node_modules/brace-expansion": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "devOptional": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/braces": { - "version": "3.0.2", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "devOptional": true, - "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/browserslist": { - "version": "4.21.4", + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", + "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", "dev": true, "funding": [ { @@ -6552,14 +5612,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" + "caniuse-lite": "^1.0.30001629", + "electron-to-chromium": "^1.4.796", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.16" }, "bin": { "browserslist": "cli.js" @@ -6570,6 +5633,8 @@ }, "node_modules/buffer": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "funding": [ { "type": "github", @@ -6584,7 +5649,6 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -6592,13 +5656,15 @@ }, "node_modules/buffer-from": { "version": "1.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true }, "node_modules/builtin-modules": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" }, @@ -6607,25 +5673,28 @@ } }, "node_modules/builtins": { - "version": "5.0.1", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", + "integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==", "devOptional": true, - "license": "MIT", "dependencies": { "semver": "^7.0.0" } }, "node_modules/bytes": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/cacache": { "version": "16.1.2", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.2.tgz", + "integrity": "sha512-Xx+xPlfCZIUHagysjjOAje9nRo8pRDczQCcXb4J2O0BLtH+xeVue6ba4y1kfJfQMAnM2mkcoMIAyOctlaRGWYA==", "devOptional": true, - "license": "ISC", "dependencies": { "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^2.0.0", @@ -6650,13 +5719,29 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "devOptional": true, + "engines": { + "node": ">=12" + } + }, "node_modules/call-bind": { - "version": "1.0.2", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, - "license": "MIT", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "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" @@ -6664,21 +5749,25 @@ }, "node_modules/callsites": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/camelcase": { "version": "5.3.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001407", + "version": "1.0.30001640", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz", + "integrity": "sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==", "dev": true, "funding": [ { @@ -6688,26 +5777,32 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } - ], - "license": "CC-BY-4.0" + ] }, "node_modules/cbor": { "name": "@jprochazk/cbor", "version": "0.4.9", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@jprochazk/cbor/-/cbor-0.4.9.tgz", + "integrity": "sha512-FWNnkOtWrFOLXKG2nzOHR/EnCCGZZPvatAvWXDmkTDxgjj9JHDK3DkMUHcFCY3a9weylMCSO/nLOUM170NAO0Q==" }, "node_modules/cbor-web": { "version": "8.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cbor-web/-/cbor-web-8.1.0.tgz", + "integrity": "sha512-2hWHHMVrfffgoEmsAUh8vCxHoLa1vgodtC73+C5cSarkJlwTapnqAzcHINlP6Ej0DXuP4OmmJ9LF+JaNM5Lj/g==", "engines": { "node": ">=12.19" } }, "node_modules/chalk": { "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -6719,19 +5814,15 @@ }, "node_modules/chardet": { "version": "0.7.0", - "devOptional": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "devOptional": true }, "node_modules/chokidar": { - "version": "3.5.3", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "devOptional": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -6744,34 +5835,41 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "node_modules/chownr": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "devOptional": true, - "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/chrome-trace-event": { - "version": "1.0.3", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0" } }, "node_modules/ci-info": { "version": "2.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true }, "node_modules/cipher-base": { "version": "1.0.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -6779,15 +5877,17 @@ }, "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==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/cli-cursor": { "version": "3.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dependencies": { "restore-cursor": "^3.1.0" }, @@ -6796,8 +5896,9 @@ } }, "node_modules/cli-spinners": { - "version": "2.7.0", - "license": "MIT", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", "engines": { "node": ">=6" }, @@ -6807,8 +5908,9 @@ }, "node_modules/cli-truncate": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", "dev": true, - "license": "MIT", "dependencies": { "slice-ansi": "^5.0.0", "string-width": "^5.0.0" @@ -6822,8 +5924,9 @@ }, "node_modules/cli-truncate/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==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -6832,9 +5935,10 @@ } }, "node_modules/cli-truncate/node_modules/ansi-styles": { - "version": "6.1.1", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -6844,13 +5948,15 @@ }, "node_modules/cli-truncate/node_modules/emoji-regex": { "version": "9.2.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true }, "node_modules/cli-truncate/node_modules/is-fullwidth-code-point": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -6860,8 +5966,9 @@ }, "node_modules/cli-truncate/node_modules/slice-ansi": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" @@ -6875,8 +5982,9 @@ }, "node_modules/cli-truncate/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==", "dev": true, - "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -6890,9 +5998,10 @@ } }, "node_modules/cli-truncate/node_modules/strip-ansi": { - "version": "7.0.1", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -6905,16 +6014,18 @@ }, "node_modules/cli-width": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", "devOptional": true, - "license": "ISC", "engines": { "node": ">= 10" } }, "node_modules/cliui": { "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "devOptional": true, - "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -6923,15 +6034,17 @@ }, "node_modules/clone": { "version": "1.0.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "engines": { "node": ">=0.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==", "dev": true, - "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4", "kind-of": "^6.0.2", @@ -6942,40 +6055,46 @@ } }, "node_modules/code-block-writer": { - "version": "10.1.1", - "license": "MIT", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-12.0.0.tgz", + "integrity": "sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==", "optional": true }, "node_modules/color-convert": { "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "1.1.3" } }, "node_modules/color-name": { "version": "1.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true }, "node_modules/color-support": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "devOptional": true, - "license": "ISC", "bin": { "color-support": "bin.js" } }, "node_modules/colorette": { - "version": "2.0.19", - "dev": true, - "license": "MIT" + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true }, "node_modules/combined-stream": { "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, - "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -6984,32 +6103,40 @@ } }, "node_modules/commander": { - "version": "9.4.0", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", "dev": true, - "license": "MIT", "engines": { "node": "^12.20.0 || >=14" } }, "node_modules/commondir": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true }, "node_modules/compare-versions": { "version": "3.6.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", + "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", + "dev": true }, "node_modules/component-emitter": { - "version": "1.3.0", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", "dev": true, - "license": "MIT" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/compressible": { "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, - "license": "MIT", "dependencies": { "mime-db": ">= 1.43.0 < 2" }, @@ -7019,8 +6146,9 @@ }, "node_modules/compression": { "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dev": true, - "license": "MIT", "dependencies": { "accepts": "~1.3.5", "bytes": "3.0.0", @@ -7036,47 +6164,60 @@ }, "node_modules/compression/node_modules/bytes": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.8" } }, "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==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/compression/node_modules/ms": { "version": "2.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "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==", + "dev": true }, "node_modules/concat-map": { "version": "0.0.1", - "devOptional": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "devOptional": true }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8" } }, "node_modules/console-control-strings": { "version": "1.1.0", - "devOptional": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "devOptional": true }, "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==", "dev": true, - "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" }, @@ -7084,63 +6225,47 @@ "node": ">= 0.6" } }, - "node_modules/content-disposition/node_modules/safe-buffer": { - "version": "5.2.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/content-type": { - "version": "1.0.4", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/convert-source-map": { - "version": "1.8.0", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.1" - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true }, "node_modules/cookie": { - "version": "0.5.0", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/cookie-signature": { "version": "1.0.6", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true }, "node_modules/cookiejar": { "version": "2.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", + "dev": true }, "node_modules/copy-anything": { "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", "dev": true, - "license": "MIT", "dependencies": { "is-what": "^3.14.1" }, @@ -7150,8 +6275,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "fast-glob": "^3.2.11", "glob-parent": "^6.0.1", @@ -7173,8 +6299,9 @@ }, "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==", "dev": true, - "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -7183,14 +6310,15 @@ } }, "node_modules/copy-webpack-plugin/node_modules/schema-utils": { - "version": "4.0.0", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, - "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", + "ajv": "^8.9.0", "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" + "ajv-keywords": "^5.1.0" }, "engines": { "node": ">= 12.13.0" @@ -7201,20 +6329,22 @@ } }, "node_modules/core-js": { - "version": "3.25.2", + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", + "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==", "hasInstallScript": true, - "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" } }, "node_modules/core-js-compat": { - "version": "3.25.2", + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", + "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", "dev": true, - "license": "MIT", "dependencies": { - "browserslist": "^4.21.4" + "browserslist": "^4.23.0" }, "funding": { "type": "opencollective", @@ -7223,13 +6353,15 @@ }, "node_modules/core-util-is": { "version": "1.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true }, "node_modules/cosmiconfig": { - "version": "7.0.1", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, - "license": "MIT", "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -7243,7 +6375,8 @@ }, "node_modules/create-hash": { "version": "1.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dependencies": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -7254,7 +6387,8 @@ }, "node_modules/create-hmac": { "version": "1.1.7", - "license": "MIT", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dependencies": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", @@ -7266,13 +6400,15 @@ }, "node_modules/create-require": { "version": "1.1.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true }, "node_modules/critters": { "version": "0.0.16", + "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.16.tgz", + "integrity": "sha512-JwjgmO6i3y6RWtLYmXwO5jMd+maZt8Tnfu7VVISmEWyQqfLpB8soBswf8/2bu6SBXxtKA68Al3c+qIG1ApT68A==", "dev": true, - "license": "Apache-2.0", "dependencies": { "chalk": "^4.1.0", "css-select": "^4.2.0", @@ -7284,8 +6420,9 @@ }, "node_modules/critters/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -7298,8 +6435,9 @@ }, "node_modules/critters/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -7313,8 +6451,9 @@ }, "node_modules/critters/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -7324,21 +6463,24 @@ }, "node_modules/critters/node_modules/color-name": { "version": "1.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/critters/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/critters/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -7348,8 +6490,9 @@ }, "node_modules/cross-spawn": { "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -7361,8 +6504,9 @@ }, "node_modules/css-blank-pseudo": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", + "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.9" }, @@ -7378,8 +6522,9 @@ }, "node_modules/css-has-pseudo": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", + "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.9" }, @@ -7395,8 +6540,9 @@ }, "node_modules/css-loader": { "version": "6.7.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.1.tgz", + "integrity": "sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==", "dev": true, - "license": "MIT", "dependencies": { "icss-utils": "^5.1.0", "postcss": "^8.4.7", @@ -7420,8 +6566,9 @@ }, "node_modules/css-prefers-color-scheme": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", + "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", "dev": true, - "license": "CC0-1.0", "bin": { "css-prefers-color-scheme": "dist/cli.cjs" }, @@ -7434,8 +6581,9 @@ }, "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==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.0.1", @@ -7449,8 +6597,9 @@ }, "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==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">= 6" }, @@ -7459,18 +6608,26 @@ } }, "node_modules/cssdb": { - "version": "7.0.1", + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.11.2.tgz", + "integrity": "sha512-lhQ32TFkc1X4eTefGfYPvgovRSzIMofHkigfH8nWtyRL4XJLsRhJFreRvEgKzept7x1rjBuy3J/MurXLaFxW/A==", "dev": true, - "license": "CC0-1.0", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + } + ] }, "node_modules/cssesc": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true, - "license": "MIT", "bin": { "cssesc": "bin/cssesc" }, @@ -7480,21 +6637,30 @@ }, "node_modules/cuint": { "version": "0.2.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", + "integrity": "sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw==", + "dev": true }, "node_modules/data-uri-to-buffer": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", + "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==", "dev": true, - "license": "MIT", "engines": { "node": ">= 6" } }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true + }, "node_modules/debug": { "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "devOptional": true, - "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -7509,36 +6675,41 @@ }, "node_modules/decamelize": { "version": "1.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "engines": { "node": ">=0.10.0" } }, "node_modules/decode-uri-component": { "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10" } }, "node_modules/deep-is": { "version": "0.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true }, "node_modules/deepmerge": { - "version": "4.2.2", + "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==", "dev": true, - "license": "MIT", "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==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "execa": "^5.0.0" }, @@ -7547,43 +6718,25 @@ } }, "node_modules/defaults": { - "version": "1.0.3", - "license": "MIT", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "dependencies": { "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/define-data-property": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.0.tgz", - "integrity": "sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==", + "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==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "devOptional": true, - "license": "MIT", - "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==", - "dev": true, - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -7592,15 +6745,25 @@ "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==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/degenerator": { - "version": "3.0.2", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-3.0.4.tgz", + "integrity": "sha512-Z66uPeBfHZAHVmue3HPfyKu2Q0rC2cRxbTOsvmU/po5fvvcx27W4mIu9n0PUlQih4oUYvcG1BsbtVv8x7KDOSw==", "dev": true, - "license": "MIT", "dependencies": { "ast-types": "^0.13.2", "escodegen": "^1.8.1", "esprima": "^4.0.0", - "vm2": "^3.9.8" + "vm2": "^3.9.17" }, "engines": { "node": ">= 6" @@ -7608,37 +6771,42 @@ }, "node_modules/delayed-stream": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/delegates": { "version": "1.0.0", - "devOptional": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "devOptional": true }, "node_modules/depd": { - "version": "1.1.2", - "devOptional": true, - "license": "MIT", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/dependency-graph": { "version": "0.11.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", + "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6.0" } }, "node_modules/destroy": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -7646,25 +6814,29 @@ }, "node_modules/detect-node": { "version": "2.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true }, "node_modules/diff": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/dijkstrajs": { - "version": "1.0.2", - "license": "MIT" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz", + "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==" }, "node_modules/dir-glob": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -7672,15 +6844,11 @@ "node": ">=8" } }, - "node_modules/dns-equal": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/dns-packet": { - "version": "5.4.0", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", "dev": true, - "license": "MIT", "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" }, @@ -7690,8 +6858,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", @@ -7702,27 +6871,30 @@ } }, "node_modules/dom7": { - "version": "4.0.4", - "license": "MIT", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/dom7/-/dom7-4.0.6.tgz", + "integrity": "sha512-emjdpPLhpNubapLFdjNL9tP06Sr+GZkrIHEXLWvOGsytACUrkbeIdjO5g77m00BrHTznnlcNqgmn7pCN192TBA==", "dependencies": { "ssr-window": "^4.0.0" } }, "node_modules/domelementtype": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/fb55" } - ], - "license": "BSD-2-Clause" + ] }, "node_modules/domhandler": { "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.2.0" }, @@ -7734,13 +6906,15 @@ } }, "node_modules/dompurify": { - "version": "2.4.0", - "license": "(MPL-2.0 OR Apache-2.0)" + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.5.5.tgz", + "integrity": "sha512-FgbqnEPiv5Vdtwt6Mxl7XSylttCC03cqP5ldNT2z+Kj0nLxPHJH4+1Cyf5Jasxhw93Rl4Oo11qRoUV72fmya2Q==" }, "node_modules/domutils": { "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", @@ -7752,21 +6926,24 @@ }, "node_modules/duplexer": { "version": "0.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true }, "node_modules/duplexer2": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "readable-stream": "^2.0.2" } }, "node_modules/duplexer2/node_modules/readable-stream": { - "version": "2.3.7", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -7777,33 +6954,44 @@ "util-deprecate": "~1.0.1" } }, + "node_modules/duplexer2/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==", + "dev": true + }, "node_modules/duplexer2/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==", "dev": true, - "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/eastasianwidth": { "version": "0.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true }, "node_modules/ee-first": { "version": "1.1.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.255", - "dev": true, - "license": "ISC" + "version": "1.4.816", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.816.tgz", + "integrity": "sha512-EKH5X5oqC6hLmiS7/vYtZHZFTNdhsYG5NVPRN6Yn0kQHNBlT59+xSM8HBy66P5fxWpKgZbPqb+diC64ng295Jw==", + "dev": true }, "node_modules/elementtree": { "version": "0.1.7", + "resolved": "https://registry.npmjs.org/elementtree/-/elementtree-0.1.7.tgz", + "integrity": "sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==", "dev": true, - "license": "Apache-2.0", "dependencies": { "sax": "1.1.4" }, @@ -7813,32 +7001,37 @@ }, "node_modules/emoji-regex": { "version": "8.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/emojis-list": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/encode-utf8": { "version": "1.0.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", + "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==" }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/encoding": { "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { "iconv-lite": "^0.6.2" @@ -7846,8 +7039,9 @@ }, "node_modules/encoding/node_modules/iconv-lite": { "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -7858,16 +7052,18 @@ }, "node_modules/end-of-stream": { "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, - "license": "MIT", "dependencies": { "once": "^1.4.0" } }, "node_modules/enhanced-resolve": { - "version": "5.10.0", + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", + "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", "dev": true, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -7878,28 +7074,32 @@ }, "node_modules/entities": { "version": "2.2.0", - "license": "BSD-2-Clause", + "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/env-paths": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/err-code": { "version": "2.0.3", - "devOptional": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "devOptional": true }, "node_modules/errno": { "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { "prr": "~1.0.1" @@ -7910,26 +7110,52 @@ }, "node_modules/error-ex": { "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, - "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } }, - "node_modules/es-module-lexer": { - "version": "0.9.3", + "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==", "dev": true, - "license": "MIT" + "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==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true, + "peer": true }, "node_modules/es6-promise": { "version": "4.2.8", - "license": "MIT" + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" }, "node_modules/esbuild": { "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.5.tgz", + "integrity": "sha512-VSf6S1QVqvxfIsSKb3UKr3VhUCis7wgDbtF4Vd9z84UJr05/Sp2fRKmzC+CSPG/dNAPPJZ0BTBLTT1Fhd6N9Gg==", "dev": true, "hasInstallScript": true, - "license": "MIT", "optional": true, "bin": { "esbuild": "bin/esbuild" @@ -7961,13 +7187,46 @@ "esbuild-windows-arm64": "0.15.5" } }, - "node_modules/esbuild-darwin-arm64": { + "node_modules/esbuild-android-64": { "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.5.tgz", + "integrity": "sha512-dYPPkiGNskvZqmIK29OPxolyY3tp+c47+Fsc2WYSOVjEPWNCHNyqhtFqQadcXMJDQt8eN0NMDukbyQgFcHquXg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.5.tgz", + "integrity": "sha512-YyEkaQl08ze3cBzI/4Cm1S+rVh8HMOpCdq8B78JLbNFHhzi4NixVN93xDrHZLztlocEYqi45rHHCgA8kZFidFg==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-64": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.5.tgz", + "integrity": "sha512-Cr0iIqnWKx3ZTvDUAzG0H/u9dWjLE4c2gTtRLz4pqOBGjfjqdcZSfAObFzKTInLLSmD0ZV1I/mshhPoYSBMMCQ==", + "cpu": [ + "x64" + ], + "dev": true, "optional": true, "os": [ "darwin" @@ -7976,10 +7235,235 @@ "node": ">=12" } }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.5.tgz", + "integrity": "sha512-WIfQkocGtFrz7vCu44ypY5YmiFXpsxvz2xqwe688jFfSVCnUsCn2qkEVDo7gT8EpsLOz1J/OmqjExePL1dr1Kg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.5.tgz", + "integrity": "sha512-M5/EfzV2RsMd/wqwR18CELcenZ8+fFxQAAEO7TJKDmP3knhWSbD72ILzrXFMMwshlPAS1ShCZ90jsxkm+8FlaA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.5.tgz", + "integrity": "sha512-2JQQ5Qs9J0440F/n/aUBNvY6lTo4XP/4lt1TwDfHuo0DY3w5++anw+jTjfouLzbJmFFiwmX7SmUhMnysocx96w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.5.tgz", + "integrity": "sha512-gO9vNnIN0FTUGjvTFucIXtBSr1Woymmx/aHQtuU+2OllGU6YFLs99960UD4Dib1kFovVgs59MTXwpFdVoSMZoQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.5.tgz", + "integrity": "sha512-ne0GFdNLsm4veXbTnYAWjbx3shpNKZJUd6XpNbKNUZaNllDZfYQt0/zRqOg0sc7O8GQ+PjSMv9IpIEULXVTVmg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.5.tgz", + "integrity": "sha512-wvAoHEN+gJ/22gnvhZnS/+2H14HyAxM07m59RSLn3iXrQsdS518jnEWRBnJz3fR6BJa+VUTo0NxYjGaNt7RA7Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.5.tgz", + "integrity": "sha512-7EgFyP2zjO065XTfdCxiXVEk+f83RQ1JsryN1X/VSX2li9rnHAt2swRbpoz5Vlrl6qjHrCmq5b6yxD13z6RheA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.5.tgz", + "integrity": "sha512-KdnSkHxWrJ6Y40ABu+ipTZeRhFtc8dowGyFsZY5prsmMSr1ZTG9zQawguN4/tunJ0wy3+kD54GaGwdcpwWAvZQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.5.tgz", + "integrity": "sha512-QdRHGeZ2ykl5P0KRmfGBZIHmqcwIsUKWmmpZTOq573jRWwmpfRmS7xOhmDHBj9pxv+6qRMH8tLr2fe+ZKQvCYw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.5.tgz", + "integrity": "sha512-p+WE6RX+jNILsf+exR29DwgV6B73khEQV0qWUbzxaycxawZ8NE0wA6HnnTxbiw5f4Gx9sJDUBemh9v49lKOORA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.5.tgz", + "integrity": "sha512-J2ngOB4cNzmqLHh6TYMM/ips8aoZIuzxJnDdWutBw5482jGXiOzsPoEF4j2WJ2mGnm7FBCO4StGcwzOgic70JQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.5.tgz", + "integrity": "sha512-MmKUYGDizYjFia0Rwt8oOgmiFH7zaYlsoQ3tIOfPxOqLssAsEgG0MUdRDm5lliqjiuoog8LyDu9srQk5YwWF3w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.5.tgz", + "integrity": "sha512-2mMFfkLk3oPWfopA9Plj4hyhqHNuGyp5KQyTT9Rc8hFd8wAn5ZrbJg+gNcLMo2yzf8Uiu0RT6G9B15YN9WQyMA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.5.tgz", + "integrity": "sha512-2sIzhMUfLNoD+rdmV6AacilCHSxZIoGAU2oT7XmJ0lXcZWnCvCtObvO6D4puxX9YRE97GodciRGDLBaiC6x1SA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/esbuild-wasm": { "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.15.5.tgz", + "integrity": "sha512-lTJOEKekN/4JI/eOEq0wLcx53co2N6vaT/XjBz46D1tvIVoUEyM0o2K6txW6gEotf31szFD/J1PbxmnbkGlK9A==", "dev": true, - "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -7987,31 +7471,83 @@ "node": ">=12" } }, + "node_modules/esbuild-windows-32": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.5.tgz", + "integrity": "sha512-e+duNED9UBop7Vnlap6XKedA/53lIi12xv2ebeNS4gFmu7aKyTrok7DPIZyU5w/ftHD4MUDs5PJUkQPP9xJRzg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.5.tgz", + "integrity": "sha512-v+PjvNtSASHOjPDMIai9Yi+aP+Vwox+3WVdg2JB8N9aivJ7lyhp4NVU+J0MV2OkWFPnVO8AE/7xH+72ibUUEnw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.15.5", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.5.tgz", + "integrity": "sha512-Yz8w/D8CUPYstvVQujByu6mlf48lKmXkq6bkeSZZxTA626efQOJb26aDGLzmFWx6eg/FwrXgt6SZs9V8Pwy/aA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/escalade": { - "version": "3.1.1", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-html": { "version": "1.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true }, "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==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/escodegen": { "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", "estraverse": "^4.2.0", @@ -8031,8 +7567,9 @@ }, "node_modules/escodegen/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==", "dev": true, - "license": "BSD-3-Clause", "optional": true, "engines": { "node": ">=0.10.0" @@ -8040,8 +7577,9 @@ }, "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==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -8052,8 +7590,9 @@ }, "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==", "dev": true, - "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -8064,8 +7603,9 @@ }, "node_modules/esrecurse": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -8075,63 +7615,72 @@ }, "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==", "dev": true, - "license": "BSD-2-Clause", "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==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/estree-walker": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true }, "node_modules/esutils": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/etag": { "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/eventemitter-asyncresource": { "version": "1.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz", + "integrity": "sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ==", + "dev": true }, "node_modules/eventemitter3": { "version": "4.0.7", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true }, "node_modules/events": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, - "license": "MIT", "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==", "dev": true, - "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -8150,17 +7699,24 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "devOptional": true + }, "node_modules/express": { - "version": "4.18.1", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dev": true, - "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.0", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -8176,7 +7732,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.10.3", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.18.0", @@ -8191,36 +7747,26 @@ "node": ">= 0.10.0" } }, - "node_modules/express/node_modules/array-flatten": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, "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==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.0.0" } }, - "node_modules/express/node_modules/depd": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/express/node_modules/ms": { "version": "2.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, "node_modules/express/node_modules/qs": { - "version": "6.10.3", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.4" }, @@ -8231,29 +7777,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/express/node_modules/safe-buffer": { - "version": "5.2.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/external-editor": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "devOptional": true, - "license": "MIT", "dependencies": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", @@ -8269,9 +7797,10 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { - "version": "3.2.12", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "devOptional": true, - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -8285,35 +7814,41 @@ }, "node_modules/fast-json-patch": { "version": "3.1.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", + "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true }, "node_modules/fast-safe-stringify": { "version": "2.1.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true }, "node_modules/fastq": { - "version": "1.13.0", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "devOptional": true, - "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, "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==", "dev": true, - "license": "Apache-2.0", "dependencies": { "websocket-driver": ">=0.5.1" }, @@ -8323,8 +7858,9 @@ }, "node_modules/figures": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "devOptional": true, - "license": "MIT", "dependencies": { "escape-string-regexp": "^1.0.5" }, @@ -8337,16 +7873,18 @@ }, "node_modules/file-uri-to-path": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz", + "integrity": "sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/fill-range": { - "version": "7.0.1", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "devOptional": true, - "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -8356,8 +7894,9 @@ }, "node_modules/finalhandler": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dev": true, - "license": "MIT", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -8373,21 +7912,24 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, "node_modules/find-cache-dir": { "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, - "license": "MIT", "dependencies": { "commondir": "^1.0.1", "make-dir": "^3.0.2", @@ -8402,7 +7944,8 @@ }, "node_modules/find-up": { "version": "4.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -8413,8 +7956,9 @@ }, "node_modules/find-versions": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", + "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", "dev": true, - "license": "MIT", "dependencies": { "semver-regex": "^3.1.2" }, @@ -8426,7 +7970,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.2", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true, "funding": [ { @@ -8434,7 +7980,6 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], - "license": "MIT", "engines": { "node": ">=4.0" }, @@ -8446,8 +7991,9 @@ }, "node_modules/form-data": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "dev": true, - "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -8459,44 +8005,50 @@ }, "node_modules/formidable": { "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", + "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", "dev": true, - "license": "MIT", "funding": { "url": "https://ko-fi.com/tunnckoCore/commissions" } }, "node_modules/forwarded": { "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/fraction.js": { - "version": "4.2.0", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", "dev": true, - "license": "MIT", "engines": { "node": "*" }, "funding": { "type": "patreon", - "url": "https://www.patreon.com/infusion" + "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==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } }, "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==", "dev": true, - "license": "MIT", "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -8509,8 +8061,9 @@ }, "node_modules/fs-minipass": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "devOptional": true, - "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -8519,19 +8072,23 @@ } }, "node_modules/fs-monkey": { - "version": "1.0.3", - "dev": true, - "license": "Unlicense" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", + "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", + "dev": true }, "node_modules/fs.realpath": { "version": "1.0.0", - "devOptional": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "devOptional": true }, "node_modules/fsevents": { - "version": "2.3.2", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, - "license": "MIT", + "hasInstallScript": true, "optional": true, "os": [ "darwin" @@ -8542,6 +8099,8 @@ }, "node_modules/ftp": { "version": "0.3.10", + "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", + "integrity": "sha512-faFVML1aBx2UoDStmLwv2Wptt4vw5x03xxX172nhA5Y5HBshW5JweqQ2W4xL4dezQTG8inJsuYcpPHHU3X5OTQ==", "dev": true, "dependencies": { "readable-stream": "1.1.x", @@ -8553,13 +8112,15 @@ }, "node_modules/ftp/node_modules/isarray": { "version": "0.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true }, "node_modules/ftp/node_modules/readable-stream": { "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "dev": true, - "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -8569,25 +8130,33 @@ }, "node_modules/ftp/node_modules/string_decoder": { "version": "0.10.31", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true }, "node_modules/function-bind": { - "version": "1.1.1", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "devOptional": true, - "license": "MIT" + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/fuse.js": { "version": "6.6.2", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.6.2.tgz", + "integrity": "sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==", "engines": { "node": ">=10" } }, "node_modules/gauge": { "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "deprecated": "This package is no longer supported.", "devOptional": true, - "license": "ISC", "dependencies": { "aproba": "^1.0.3 || ^2.0.0", "color-support": "^1.1.3", @@ -8604,29 +8173,35 @@ }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/get-caller-file": { "version": "2.0.5", - "license": "ISC", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8634,16 +8209,18 @@ }, "node_modules/get-package-type": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.0.0" } }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -8653,8 +8230,9 @@ }, "node_modules/get-uri": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz", + "integrity": "sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==", "dev": true, - "license": "MIT", "dependencies": { "@tootallnate/once": "1", "data-uri-to-buffer": "3", @@ -8669,16 +8247,18 @@ }, "node_modules/get-uri/node_modules/@tootallnate/once": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/get-uri/node_modules/fs-extra": { "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", @@ -8690,24 +8270,28 @@ }, "node_modules/get-uri/node_modules/jsonfile": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, - "license": "MIT", "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "node_modules/get-uri/node_modules/universalify": { "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 4.0.0" } }, "node_modules/glob": { "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", + "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", "devOptional": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -8724,8 +8308,9 @@ }, "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==", "devOptional": true, - "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -8735,25 +8320,28 @@ }, "node_modules/glob-to-regexp": { "version": "0.4.1", - "dev": true, - "license": "BSD-2-Clause" + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/globby": { - "version": "13.1.2", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", "dev": true, - "license": "MIT", "dependencies": { "dir-glob": "^3.0.1", - "fast-glob": "^3.2.11", - "ignore": "^5.2.0", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", "merge2": "^1.4.1", "slash": "^4.0.0" }, @@ -8777,14 +8365,16 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.10", - "devOptional": true, - "license": "ISC" + "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==", + "devOptional": true }, "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==", "dev": true, - "license": "MIT", "dependencies": { "duplexer": "^0.1.2" }, @@ -8797,43 +8387,35 @@ }, "node_modules/handle-thing": { "version": "2.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/has": { - "version": "1.0.3", - "devOptional": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true }, "node_modules/has-flag": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, - "license": "MIT", "dependencies": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, "engines": { "node": ">= 0.4" @@ -8844,8 +8426,9 @@ }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -8855,12 +8438,14 @@ }, "node_modules/has-unicode": { "version": "2.0.1", - "devOptional": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "devOptional": true }, "node_modules/hash-base": { "version": "3.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", "dependencies": { "inherits": "^2.0.4", "readable-stream": "^3.6.0", @@ -8870,28 +8455,23 @@ "node": ">=4" } }, - "node_modules/hash-base/node_modules/safe-buffer": { - "version": "5.2.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "devOptional": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } }, "node_modules/hdr-histogram-js": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hdr-histogram-js/-/hdr-histogram-js-2.0.3.tgz", + "integrity": "sha512-Hkn78wwzWHNCp2uarhzQ2SGFLU3JY8SBDDd3TAABK4fc30wm+MuPOrg5QVFVfkKOQd6Bfz3ukJEI+q9sXEkK1g==", "dev": true, - "license": "BSD", "dependencies": { "@assemblyscript/loader": "^0.10.1", "base64-js": "^1.2.0", @@ -8900,26 +8480,30 @@ }, "node_modules/hdr-histogram-js/node_modules/pako": { "version": "1.0.11", - "dev": true, - "license": "(MIT AND Zlib)" + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true }, "node_modules/hdr-histogram-percentiles-obj": { "version": "3.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/hdr-histogram-percentiles-obj/-/hdr-histogram-percentiles-obj-3.0.0.tgz", + "integrity": "sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw==", + "dev": true }, "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==", "dev": true, - "license": "MIT", "bin": { "he": "bin/he" } }, "node_modules/hosted-git-info": { - "version": "5.1.0", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.2.1.tgz", + "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", "devOptional": true, - "license": "ISC", "dependencies": { "lru-cache": "^7.5.1" }, @@ -8927,10 +8511,20 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "devOptional": true, + "engines": { + "node": ">=12" + } + }, "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==", "dev": true, - "license": "MIT", "dependencies": { "inherits": "^2.0.1", "obuf": "^1.0.0", @@ -8939,9 +8533,10 @@ } }, "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.7", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -8952,33 +8547,60 @@ "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==", + "dev": true + }, "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==", "dev": true, - "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/html-entities": { - "version": "2.3.3", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", "dev": true, - "license": "MIT" + "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==", + "dev": true }, "node_modules/http-cache-semantics": { "version": "4.1.1", - "devOptional": true, - "license": "BSD-2-Clause" + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "devOptional": true }, "node_modules/http-deceiver": { "version": "1.2.7", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true }, "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==", "dev": true, - "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -8990,23 +8612,17 @@ "node": ">= 0.8" } }, - "node_modules/http-errors/node_modules/depd": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/http-parser-js": { "version": "0.5.8", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true }, "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==", "dev": true, - "license": "MIT", "dependencies": { "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", @@ -9018,8 +8634,9 @@ }, "node_modules/http-proxy-agent": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "devOptional": true, - "license": "MIT", "dependencies": { "@tootallnate/once": "2", "agent-base": "6", @@ -9031,8 +8648,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", @@ -9054,8 +8672,9 @@ }, "node_modules/https-proxy-agent": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "devOptional": true, - "license": "MIT", "dependencies": { "agent-base": "6", "debug": "4" @@ -9066,25 +8685,28 @@ }, "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==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } }, "node_modules/humanize-ms": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", "devOptional": true, - "license": "MIT", "dependencies": { "ms": "^2.0.0" } }, "node_modules/husky": { "version": "4.3.8", + "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", + "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", "dev": true, "hasInstallScript": true, - "license": "MIT", "dependencies": { "chalk": "^4.0.0", "ci-info": "^2.0.0", @@ -9111,8 +8733,9 @@ }, "node_modules/husky/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -9125,8 +8748,9 @@ }, "node_modules/husky/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -9140,8 +8764,9 @@ }, "node_modules/husky/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -9151,13 +8776,15 @@ }, "node_modules/husky/node_modules/color-name": { "version": "1.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/husky/node_modules/find-up": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, - "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -9171,16 +8798,18 @@ }, "node_modules/husky/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/husky/node_modules/locate-path": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, - "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -9193,8 +8822,9 @@ }, "node_modules/husky/node_modules/p-limit": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -9207,8 +8837,9 @@ }, "node_modules/husky/node_modules/p-locate": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, - "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -9221,8 +8852,9 @@ }, "node_modules/husky/node_modules/pkg-dir": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", + "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", "dev": true, - "license": "MIT", "dependencies": { "find-up": "^5.0.0" }, @@ -9232,16 +8864,18 @@ }, "node_modules/husky/node_modules/slash": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/husky/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -9251,8 +8885,9 @@ }, "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==", "devOptional": true, - "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -9262,8 +8897,9 @@ }, "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==", "dev": true, - "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" }, @@ -9273,6 +8909,8 @@ }, "node_modules/ieee754": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", @@ -9286,21 +8924,22 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "BSD-3-Clause" + ] }, "node_modules/ignore": { - "version": "5.2.0", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/ignore-walk": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-5.0.1.tgz", + "integrity": "sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw==", "devOptional": true, - "license": "ISC", "dependencies": { "minimatch": "^5.0.1" }, @@ -9310,8 +8949,9 @@ }, "node_modules/image-size": { "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", "dev": true, - "license": "MIT", "optional": true, "bin": { "image-size": "bin/image-size.js" @@ -9321,14 +8961,16 @@ } }, "node_modules/immutable": { - "version": "4.1.0", - "dev": true, - "license": "MIT" + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz", + "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==", + "dev": true }, "node_modules/import-fresh": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, - "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -9342,37 +8984,43 @@ }, "node_modules/import-fresh/node_modules/resolve-from": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/imurmurhash": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "devOptional": true, - "license": "MIT", "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==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/infer-owner": { "version": "1.0.4", - "devOptional": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "devOptional": true }, "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==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "devOptional": true, - "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -9380,28 +9028,32 @@ }, "node_modules/inherits": { "version": "2.0.4", - "license": "ISC" + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.0.tgz", + "integrity": "sha512-TxYQaeNW/N8ymDvwAxPyRbhMBtnEwuvaTYpOQkFx1nSeusgezHniEc/l35Vo4iCq/mMiTJbpD7oYxN98hFlfmw==", "devOptional": true, - "license": "ISC", "engines": { "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/injection-js": { "version": "2.4.0", + "resolved": "https://registry.npmjs.org/injection-js/-/injection-js-2.4.0.tgz", + "integrity": "sha512-6jiJt0tCAo9zjHbcwLiPL+IuNe9SQ6a9g0PEzafThW3fOQi0mrmiJGBJvDD6tmhPh8cQHIQtCOrJuBfQME4kPA==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.0.0" } }, "node_modules/inquirer": { "version": "8.2.4", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", + "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", "devOptional": true, - "license": "MIT", "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.1", @@ -9425,8 +9077,9 @@ }, "node_modules/inquirer/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==", "devOptional": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -9439,8 +9092,9 @@ }, "node_modules/inquirer/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "devOptional": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -9454,8 +9108,9 @@ }, "node_modules/inquirer/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==", "devOptional": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -9465,21 +9120,24 @@ }, "node_modules/inquirer/node_modules/color-name": { "version": "1.1.4", - "devOptional": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true }, "node_modules/inquirer/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==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/inquirer/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==", "devOptional": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -9488,45 +9146,52 @@ } }, "node_modules/ionicons": { - "version": "6.0.3", - "license": "MIT", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.1.3.tgz", + "integrity": "sha512-ptzz38dd/Yq+PgjhXegh7yhb/SLIk1bvL9vQDtLv1aoSc7alO6mX2DIMgcKYzt9vrNWkRu1f9Jr78zIFFyOXqw==", "dependencies": { - "@stencil/core": "~2.16.0" - } - }, - "node_modules/ionicons/node_modules/@stencil/core": { - "version": "2.16.1", - "license": "MIT", - "bin": { - "stencil": "bin/stencil" - }, - "engines": { - "node": ">=12.10.0", - "npm": ">=6.0.0" + "@stencil/core": "^2.18.0" } }, "node_modules/ip": { - "version": "2.0.0", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==", + "dev": true + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", "devOptional": true, - "license": "MIT" + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } }, "node_modules/ipaddr.js": { - "version": "2.0.1", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 10" } }, "node_modules/is-arrayish": { "version": "0.2.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true }, "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==", "devOptional": true, - "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -9535,9 +9200,10 @@ } }, "node_modules/is-builtin-module": { - "version": "3.2.0", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", "dev": true, - "license": "MIT", "dependencies": { "builtin-modules": "^3.3.0" }, @@ -9549,11 +9215,15 @@ } }, "node_modules/is-core-module": { - "version": "2.10.0", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", + "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", "devOptional": true, - "license": "MIT", "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9561,8 +9231,9 @@ }, "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==", "devOptional": true, - "license": "MIT", "bin": { "is-docker": "cli.js" }, @@ -9575,23 +9246,26 @@ }, "node_modules/is-extglob": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "license": "MIT", + "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==", "devOptional": true, - "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -9601,33 +9275,38 @@ }, "node_modules/is-interactive": { "version": "1.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "engines": { "node": ">=8" } }, "node_modules/is-lambda": { "version": "1.0.1", - "devOptional": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "devOptional": true }, "node_modules/is-module": { "version": "1.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true }, "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==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=0.12.0" } }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -9637,8 +9316,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -9648,8 +9328,9 @@ }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, @@ -9659,12 +9340,14 @@ }, "node_modules/is-typedarray": { "version": "1.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true }, "node_modules/is-unicode-supported": { "version": "0.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "engines": { "node": ">=10" }, @@ -9674,13 +9357,15 @@ }, "node_modules/is-what": { "version": "3.14.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true }, "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==", "devOptional": true, - "license": "MIT", "dependencies": { "is-docker": "^2.0.0" }, @@ -9690,34 +9375,39 @@ }, "node_modules/isarray": { "version": "1.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true }, "node_modules/isexe": { "version": "2.0.0", - "devOptional": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "devOptional": true }, "node_modules/isobject": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-instrument": { - "version": "5.2.0", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", @@ -9730,17 +9420,19 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "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==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -9752,16 +9444,18 @@ }, "node_modules/jest-worker/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "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==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -9773,20 +9467,23 @@ } }, "node_modules/jose": { - "version": "4.9.3", - "license": "MIT", + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", "funding": { "url": "https://github.com/sponsors/panva" } }, "node_modules/js-tokens": { "version": "4.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "node_modules/js-yaml": { "version": "4.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dependencies": { "argparse": "^2.0.1" }, @@ -9794,10 +9491,17 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "devOptional": true + }, "node_modules/jsesc": { "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, - "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -9807,17 +9511,20 @@ }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "devOptional": true, - "license": "MIT" + "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==", + "devOptional": true }, "node_modules/json-schema-traverse": { "version": "1.0.0", - "license": "MIT" + "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==", "dev": true, - "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -9827,12 +9534,14 @@ }, "node_modules/jsonc-parser": { "version": "3.1.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.1.0.tgz", + "integrity": "sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg==" }, "node_modules/jsonfile": { "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, - "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -9842,40 +9551,45 @@ }, "node_modules/jsonparse": { "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", "devOptional": true, "engines": [ "node >= 0.2.0" - ], - "license": "MIT" + ] }, "node_modules/karma-source-map-support": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", + "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", "dev": true, - "license": "MIT", "dependencies": { "source-map-support": "^0.5.5" } }, "node_modules/kind-of": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/klona": { - "version": "2.0.5", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/leek": { "version": "0.0.24", + "resolved": "https://registry.npmjs.org/leek/-/leek-0.0.24.tgz", + "integrity": "sha512-6PVFIYXxlYF0o6hrAsHtGpTmi06otkwNrMcmQ0K96SeSRHPREPa9J3nJZ1frliVH7XT0XFswoJFQoXsDukzGNQ==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^2.1.0", "lodash.assign": "^3.2.0", @@ -9884,21 +9598,24 @@ }, "node_modules/leek/node_modules/debug": { "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/leek/node_modules/ms": { "version": "2.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, "node_modules/less": { "version": "4.1.3", + "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz", + "integrity": "sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==", "dev": true, - "license": "Apache-2.0", "dependencies": { "copy-anything": "^2.0.1", "parse-node-version": "^1.0.1", @@ -9922,8 +9639,9 @@ }, "node_modules/less-loader": { "version": "11.0.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-11.0.0.tgz", + "integrity": "sha512-9+LOWWjuoectIEx3zrfN83NAGxSUB5pWEabbbidVQVgZhN+wN68pOvuyirVlH1IK4VT1f3TmlyvAnCXh8O5KEw==", "dev": true, - "license": "MIT", "dependencies": { "klona": "^2.0.4" }, @@ -9941,8 +9659,9 @@ }, "node_modules/less/node_modules/make-dir": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { "pify": "^4.0.1", @@ -9952,19 +9671,34 @@ "node": ">=6" } }, + "node_modules/less/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/less/node_modules/pify": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true, - "license": "MIT", "optional": true, "engines": { "node": ">=6" } }, "node_modules/less/node_modules/semver": { - "version": "5.7.1", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "license": "ISC", "optional": true, "bin": { "semver": "bin/semver" @@ -9972,8 +9706,9 @@ }, "node_modules/less/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==", "dev": true, - "license": "BSD-3-Clause", "optional": true, "engines": { "node": ">=0.10.0" @@ -9981,8 +9716,9 @@ }, "node_modules/levn": { "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dev": true, - "license": "MIT", "dependencies": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" @@ -9993,8 +9729,9 @@ }, "node_modules/license-webpack-plugin": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", + "integrity": "sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==", "dev": true, - "license": "ISC", "dependencies": { "webpack-sources": "^3.0.0" }, @@ -10009,21 +9746,24 @@ }, "node_modules/lilconfig": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz", + "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/lines-and-columns": { "version": "1.2.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true }, "node_modules/lint-staged": { "version": "12.5.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.5.0.tgz", + "integrity": "sha512-BKLUjWDsKquV/JuIcoQW4MSAI3ggwEImF1+sB4zaKvyVx1wBk3FsG7UK9bpnmBTN1pm7EH2BBcMwINJzCRv12g==", "dev": true, - "license": "MIT", "dependencies": { "cli-truncate": "^3.1.0", "colorette": "^2.0.16", @@ -10051,9 +9791,10 @@ } }, "node_modules/lint-staged/node_modules/supports-color": { - "version": "9.2.3", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz", + "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -10063,8 +9804,9 @@ }, "node_modules/listr2": { "version": "4.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", + "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==", "dev": true, - "license": "MIT", "dependencies": { "cli-truncate": "^2.1.0", "colorette": "^2.0.16", @@ -10089,8 +9831,9 @@ }, "node_modules/listr2/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -10103,8 +9846,9 @@ }, "node_modules/listr2/node_modules/cli-truncate": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", "dev": true, - "license": "MIT", "dependencies": { "slice-ansi": "^3.0.0", "string-width": "^4.2.0" @@ -10118,8 +9862,9 @@ }, "node_modules/listr2/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -10129,13 +9874,15 @@ }, "node_modules/listr2/node_modules/color-name": { "version": "1.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/listr2/node_modules/slice-ansi": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -10147,23 +9894,26 @@ }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.11.5" } }, "node_modules/loader-utils": { - "version": "3.2.0", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 12.13.0" } }, "node_modules/locate-path": { "version": "5.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dependencies": { "p-locate": "^4.1.0" }, @@ -10173,12 +9923,14 @@ }, "node_modules/lodash": { "version": "4.17.21", - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash._baseassign": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha512-t3N26QR2IdSN+gqSy9Ds9pBu/J1EAFEshKlUHpJG3rvyJOYgcELIxcIeKKfZk7sjOz11cFfzJRsyFry/JyabJQ==", "dev": true, - "license": "MIT", "dependencies": { "lodash._basecopy": "^3.0.0", "lodash.keys": "^3.0.0" @@ -10186,18 +9938,21 @@ }, "node_modules/lodash._basecopy": { "version": "3.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha512-rFR6Vpm4HeCK1WPGvjZSJ+7yik8d8PVUdCJx5rT2pogG4Ve/2ZS7kfmO5l5T2o5V2mqlNIfSF5MZlr1+xOoYQQ==", + "dev": true }, "node_modules/lodash._bindcallback": { "version": "3.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", + "integrity": "sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ==", + "dev": true }, "node_modules/lodash._createassigner": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz", + "integrity": "sha512-LziVL7IDnJjQeeV95Wvhw6G28Z8Q6da87LWKOPWmzBLv4u6FAT/x5v00pyGW0u38UoogNF2JnD3bGgZZDaNEBw==", "dev": true, - "license": "MIT", "dependencies": { "lodash._bindcallback": "^3.0.0", "lodash._isiterateecall": "^3.0.0", @@ -10206,18 +9961,21 @@ }, "node_modules/lodash._getnative": { "version": "3.9.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA==", + "dev": true }, "node_modules/lodash._isiterateecall": { "version": "3.0.9", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha512-De+ZbrMu6eThFti/CSzhRvTKMgQToLxbij58LMfM8JnYDNSOjkjTCIaa8ixglOeGh2nyPlakbt5bJWJ7gvpYlQ==", + "dev": true }, "node_modules/lodash.assign": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-3.2.0.tgz", + "integrity": "sha512-/VVxzgGBmbphasTg51FrztxQJ/VgAUpol6zmJuSVSGcNg4g7FA4z7rQV8Ovr9V3vFBNWZhvKWHfpAytjTVUfFA==", "dev": true, - "license": "MIT", "dependencies": { "lodash._baseassign": "^3.0.0", "lodash._createassigner": "^3.0.0", @@ -10226,23 +9984,27 @@ }, "node_modules/lodash.debounce": { "version": "4.0.8", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true }, "node_modules/lodash.isarguments": { "version": "3.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", + "dev": true }, "node_modules/lodash.isarray": { "version": "3.0.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha512-JwObCrNJuT0Nnbuecmqr5DgtuBppuCvGD9lxjFpAzwnVtdGoDQ1zig+5W8k5/6Gcn0gZ3936HDAlGd28i7sOGQ==", + "dev": true }, "node_modules/lodash.keys": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha512-CuBsapFjcubOGMn3VD+24HOAPxM79tH+V6ivJL3CHYjtrawauDJHUk//Yew9Hvc6e9rbCrURGk8z6PC+8WJBfQ==", "dev": true, - "license": "MIT", "dependencies": { "lodash._getnative": "^3.0.0", "lodash.isarguments": "^3.0.0", @@ -10251,12 +10013,14 @@ }, "node_modules/lodash.restparam": { "version": "3.6.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha512-L4/arjjuq4noiUJpt3yS6KIKDtJwNe2fIYgMqyYYKoeIfV1iEqvPwhCx23o+R9dzouGihDAPN1dTIRWa7zk8tw==", + "dev": true }, "node_modules/log-symbols": { "version": "4.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -10270,7 +10034,8 @@ }, "node_modules/log-symbols/node_modules/ansi-styles": { "version": "4.3.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, @@ -10283,7 +10048,8 @@ }, "node_modules/log-symbols/node_modules/chalk": { "version": "4.1.2", - "license": "MIT", + "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" @@ -10297,7 +10063,8 @@ }, "node_modules/log-symbols/node_modules/color-convert": { "version": "2.0.1", - "license": "MIT", + "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" }, @@ -10307,18 +10074,21 @@ }, "node_modules/log-symbols/node_modules/color-name": { "version": "1.1.4", - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/log-symbols/node_modules/has-flag": { "version": "4.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "engines": { "node": ">=8" } }, "node_modules/log-symbols/node_modules/supports-color": { "version": "7.2.0", - "license": "MIT", + "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" }, @@ -10328,8 +10098,9 @@ }, "node_modules/log-update": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", "dev": true, - "license": "MIT", "dependencies": { "ansi-escapes": "^4.3.0", "cli-cursor": "^3.1.0", @@ -10345,8 +10116,9 @@ }, "node_modules/log-update/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -10359,8 +10131,9 @@ }, "node_modules/log-update/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -10370,13 +10143,15 @@ }, "node_modules/log-update/node_modules/color-name": { "version": "1.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/log-update/node_modules/wrap-ansi": { "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -10387,21 +10162,24 @@ } }, "node_modules/long": { - "version": "5.2.0", - "license": "Apache-2.0" + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, "node_modules/lru-cache": { - "version": "7.14.0", - "devOptional": true, - "license": "ISC", - "engines": { - "node": ">=12" + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" } }, "node_modules/macos-release": { - "version": "2.5.0", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.1.tgz", + "integrity": "sha512-DXqXhEM7gW59OjZO8NIjBCz9AQ1BEMrfiOAl4AYByHCtVHRF4KoGNO8mqQeM8lRCtQe/UnJ4imO/d2HdkKsd+A==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" }, @@ -10411,7 +10189,8 @@ }, "node_modules/magic-string": { "version": "0.26.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.2.tgz", + "integrity": "sha512-NzzlXpclt5zAbmo6h6jNc8zl2gNRGHvmsZW4IvZhTC4W7k4OlLP+S5YLussa/r3ixNT66KOQfNORlXHSOy/X4A==", "dependencies": { "sourcemap-codec": "^1.4.8" }, @@ -10421,8 +10200,9 @@ }, "node_modules/make-dir": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, - "license": "MIT", "dependencies": { "semver": "^6.0.0" }, @@ -10434,22 +10214,25 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/make-error": { "version": "1.3.6", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true }, "node_modules/make-fetch-happen": { "version": "10.2.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", + "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", "devOptional": true, - "license": "ISC", "dependencies": { "agentkeepalive": "^4.2.1", "cacache": "^16.1.0", @@ -10472,9 +10255,19 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/make-fetch-happen/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "devOptional": true, + "engines": { + "node": ">=12" + } + }, "node_modules/marked": { - "version": "4.1.0", - "license": "MIT", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", "bin": { "marked": "bin/marked.js" }, @@ -10484,7 +10277,8 @@ }, "node_modules/md5.js": { "version": "1.3.5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1", @@ -10493,18 +10287,20 @@ }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/memfs": { - "version": "3.4.7", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, - "license": "Unlicense", "dependencies": { - "fs-monkey": "^1.0.3" + "fs-monkey": "^1.0.4" }, "engines": { "node": ">= 4.0.0" @@ -10512,36 +10308,41 @@ }, "node_modules/merge-descriptors": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true }, "node_modules/merge-stream": { "version": "2.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true }, "node_modules/merge2": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "devOptional": true, - "license": "MIT", "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==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/micromatch": { - "version": "4.0.5", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "devOptional": true, - "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -10549,28 +10350,33 @@ } }, "node_modules/mime": { - "version": "1.6.0", - "dev": true, - "license": "MIT", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.3.tgz", + "integrity": "sha512-KgUb15Oorc0NEKPbvfa0wRU+PItIEZmiv+pyAO2i0oTIVTJhlzMclU7w4RXWQrSOVH5ax/p/CkIO7KI4OyFJTQ==", + "funding": [ + "https://github.com/sponsors/broofa" + ], "bin": { - "mime": "cli.js" + "mime": "bin/cli.js" }, "engines": { - "node": ">=4" + "node": ">=16" } }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, - "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -10580,15 +10386,17 @@ }, "node_modules/mimic-fn": { "version": "2.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "engines": { "node": ">=6" } }, "node_modules/mini-css-extract-plugin": { "version": "2.6.1", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz", + "integrity": "sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg==", "dev": true, - "license": "MIT", "dependencies": { "schema-utils": "^4.0.0" }, @@ -10604,14 +10412,15 @@ } }, "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { - "version": "4.0.0", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, - "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", + "ajv": "^8.9.0", "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" + "ajv-keywords": "^5.1.0" }, "engines": { "node": ">= 12.13.0" @@ -10623,13 +10432,15 @@ }, "node_modules/minimalistic-assert": { "version": "1.0.1", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true }, "node_modules/minimatch": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", "devOptional": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -10638,14 +10449,19 @@ } }, "node_modules/minimist": { - "version": "1.2.6", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, - "license": "MIT" + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/minipass": { - "version": "3.3.4", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "devOptional": true, - "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -10655,8 +10471,9 @@ }, "node_modules/minipass-collect": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", "devOptional": true, - "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -10666,8 +10483,9 @@ }, "node_modules/minipass-fetch": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", + "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", "devOptional": true, - "license": "MIT", "dependencies": { "minipass": "^3.1.6", "minipass-sized": "^1.0.3", @@ -10682,8 +10500,9 @@ }, "node_modules/minipass-flush": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", "devOptional": true, - "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -10693,8 +10512,9 @@ }, "node_modules/minipass-json-stream": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", + "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", "devOptional": true, - "license": "MIT", "dependencies": { "jsonparse": "^1.3.1", "minipass": "^3.0.0" @@ -10702,8 +10522,9 @@ }, "node_modules/minipass-pipeline": { "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", "devOptional": true, - "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -10713,8 +10534,9 @@ }, "node_modules/minipass-sized": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", "devOptional": true, - "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -10722,10 +10544,17 @@ "node": ">=8" } }, + "node_modules/minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "devOptional": true + }, "node_modules/minizlib": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "devOptional": true, - "license": "MIT", "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -10734,10 +10563,17 @@ "node": ">= 8" } }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "devOptional": true + }, "node_modules/mkdirp": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "devOptional": true, - "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" }, @@ -10747,25 +10583,29 @@ }, "node_modules/monaco-editor": { "version": "0.33.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.33.0.tgz", + "integrity": "sha512-VcRWPSLIUEgQJQIE0pVT8FcGBIgFoxz7jtqctE+IiCxWugD0DwgyQBcZBhdSrdMC84eumoqMZsGl2GTreOzwqw==" }, "node_modules/mrmime": { - "version": "1.0.1", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/ms": { "version": "2.1.2", - "devOptional": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "devOptional": true }, "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==", "dev": true, - "license": "MIT", "dependencies": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" @@ -10776,7 +10616,8 @@ }, "node_modules/multimatch": { "version": "5.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", + "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", "optional": true, "dependencies": { "@types/minimatch": "^3.0.3", @@ -10794,7 +10635,8 @@ }, "node_modules/multimatch/node_modules/brace-expansion": { "version": "1.1.11", - "license": "MIT", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "optional": true, "dependencies": { "balanced-match": "^1.0.0", @@ -10803,7 +10645,8 @@ }, "node_modules/multimatch/node_modules/minimatch": { "version": "3.1.2", - "license": "ISC", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "optional": true, "dependencies": { "brace-expansion": "^1.1.7" @@ -10814,20 +10657,29 @@ }, "node_modules/mustache": { "version": "4.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", "bin": { "mustache": "bin/mustache" } }, "node_modules/mute-stream": { "version": "0.0.8", - "devOptional": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "devOptional": true }, "node_modules/nanoid": { - "version": "3.3.4", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true, - "license": "MIT", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -10836,12 +10688,12 @@ } }, "node_modules/needle": { - "version": "3.1.0", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", + "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { - "debug": "^3.2.6", "iconv-lite": "^0.6.3", "sax": "^1.2.4" }, @@ -10852,19 +10704,11 @@ "node": ">= 4.4.x" } }, - "node_modules/needle/node_modules/debug": { - "version": "3.2.7", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "ms": "^2.1.1" - } - }, "node_modules/needle/node_modules/iconv-lite": { "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -10874,76 +10718,85 @@ } }, "node_modules/needle/node_modules/sax": { - "version": "1.2.4", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", "dev": true, - "license": "ISC", "optional": true }, "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==", "devOptional": true, - "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/neo-async": { "version": "2.6.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true }, "node_modules/netmask": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4.0" } }, "node_modules/ng-morph": { - "version": "2.1.0", - "license": "Apache-2.0", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/ng-morph/-/ng-morph-4.0.5.tgz", + "integrity": "sha512-5tnlb5WrGKeo2E7VRcV7ZHhScyNgliYqpbXqt103kynmfj6Ic8kzhJAhHu9iLkF1yRnKv2kyCE+O7UGZx5RraQ==", "optional": true, "dependencies": { - "jsonc-parser": "3.0.0", - "minimatch": "3.0.4", + "jsonc-parser": "3.2.0", + "minimatch": "9.0.3", "multimatch": "5.0.0", - "ts-morph": "10.0.2" + "ts-morph": "21.0.1", + "tslib": "2.6.2" }, "peerDependencies": { "@angular-devkit/core": ">=11.0.0", "@angular-devkit/schematics": ">=11.0.0" } }, - "node_modules/ng-morph/node_modules/brace-expansion": { - "version": "1.1.11", - "license": "MIT", - "optional": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/ng-morph/node_modules/jsonc-parser": { - "version": "3.0.0", - "license": "MIT", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", "optional": true }, "node_modules/ng-morph/node_modules/minimatch": { - "version": "3.0.4", - "license": "ISC", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "optional": true, "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/ng-morph/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "optional": true + }, "node_modules/ng-packagr": { - "version": "14.2.1", + "version": "14.2.2", + "resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-14.2.2.tgz", + "integrity": "sha512-AqwHcMM6x+JkCHT++IsbulnTdyoXcC2Cr4tbPamuieacc77+fFbB195hdcqEFwsKX5410cymx/ZUyHird9rxlg==", "dev": true, - "license": "MIT", "dependencies": { "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^13.1.3", @@ -10987,7 +10840,8 @@ }, "node_modules/ng-qrcode": { "version": "7.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ng-qrcode/-/ng-qrcode-7.0.0.tgz", + "integrity": "sha512-Mx7nf8rtGMVYxGe2qfy8/JNiCnxKD7uFsqpP2Hm5eJSQrOEapQl9FR0yuK0I4MMQorJ7s8mZZDxmszQiH8R2Kg==", "dependencies": { "qrcode": "^1.5.0", "tslib": "^2.4.0" @@ -10999,9 +10853,10 @@ }, "node_modules/nice-napi": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz", + "integrity": "sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==", "dev": true, "hasInstallScript": true, - "license": "MIT", "optional": true, "os": [ "!win32" @@ -11013,27 +10868,31 @@ }, "node_modules/node-addon-api": { "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", "dev": true, - "license": "MIT", "optional": true }, "node_modules/node-forge": { "version": "1.3.1", - "license": "(BSD-3-Clause OR GPL-2.0)", + "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-gyp": { - "version": "9.1.0", + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz", + "integrity": "sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==", "devOptional": true, - "license": "MIT", "dependencies": { "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", "glob": "^7.1.4", "graceful-fs": "^4.2.6", "make-fetch-happen": "^10.0.3", - "nopt": "^5.0.0", + "nopt": "^6.0.0", "npmlog": "^6.0.0", "rimraf": "^3.0.2", "semver": "^7.3.5", @@ -11044,13 +10903,14 @@ "node-gyp": "bin/node-gyp.js" }, "engines": { - "node": "^12.22 || ^14.13 || >=16" + "node": "^12.13 || ^14.13 || >=16" } }, "node_modules/node-gyp-build": { - "version": "4.5.0", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", + "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", "dev": true, - "license": "MIT", "optional": true, "bin": { "node-gyp-build": "bin.js", @@ -11060,8 +10920,9 @@ }, "node_modules/node-gyp/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==", "devOptional": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -11069,8 +10930,10 @@ }, "node_modules/node-gyp/node_modules/glob": { "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "devOptional": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -11088,8 +10951,9 @@ }, "node_modules/node-gyp/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "devOptional": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -11099,8 +10963,9 @@ }, "node_modules/node-html-parser": { "version": "5.4.2", + "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-5.4.2.tgz", + "integrity": "sha512-RaBPP3+51hPne/OolXxcz89iYvQvKOydaqoePpOgXcrOKZhjVIzmpKZz+Hd/RBO2/zN2q6CNJhQzucVz+u3Jyw==", "dev": true, - "license": "MIT", "dependencies": { "css-select": "^4.2.1", "he": "1.2.0" @@ -11108,7 +10973,8 @@ }, "node_modules/node-jose": { "version": "2.2.0", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/node-jose/-/node-jose-2.2.0.tgz", + "integrity": "sha512-XPCvJRr94SjLrSIm4pbYHKLEaOsDvJCpyFw/6V/KK/IXmyZ6SFBzAUDO9HQf4DB/nTEFcRGH87mNciOP23kFjw==", "dependencies": { "base64url": "^3.0.1", "buffer": "^6.0.3", @@ -11122,35 +10988,43 @@ } }, "node_modules/node-jose/node_modules/uuid": { - "version": "9.0.0", - "license": "MIT", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/node-releases": { - "version": "2.0.6", - "dev": true, - "license": "MIT" + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true }, "node_modules/nopt": { - "version": "5.0.0", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", "devOptional": true, - "license": "ISC", "dependencies": { - "abbrev": "1" + "abbrev": "^1.0.0" }, "bin": { "nopt": "bin/nopt.js" }, "engines": { - "node": ">=6" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/normalize-package-data": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-4.0.1.tgz", + "integrity": "sha512-EBk5QKKuocMJhB3BILuKhmaPjI8vNRSpIfO9woLC6NyHVkKKdVEdAO1mrT0ZfxNR1lKwCcTkuZfmGIFdizZ8Pg==", "devOptional": true, - "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^5.0.0", "is-core-module": "^2.8.1", @@ -11163,32 +11037,36 @@ }, "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==", "devOptional": true, - "license": "MIT", "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==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/npm-bundled": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", + "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", "devOptional": true, - "license": "ISC", "dependencies": { "npm-normalize-package-bin": "^1.0.1" } }, "node_modules/npm-install-checks": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-5.0.0.tgz", + "integrity": "sha512-65lUsMI8ztHCxFz5ckCEC44DRvEGdZX5usQFriauxHEwt7upv1FKaQEmAtU0YnOAdwuNWCmk64xYiQABNrEyLA==", "devOptional": true, - "license": "BSD-2-Clause", "dependencies": { "semver": "^7.1.1" }, @@ -11198,13 +11076,15 @@ }, "node_modules/npm-normalize-package-bin": { "version": "1.0.1", - "devOptional": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "devOptional": true }, "node_modules/npm-package-arg": { "version": "9.1.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.1.0.tgz", + "integrity": "sha512-4J0GL+u2Nh6OnhvUKXRr2ZMG4lR8qtLp+kv7UiV00Y+nGiSxtttCyIRHCt5L5BNkXQld/RceYItau3MDOoGiBw==", "devOptional": true, - "license": "ISC", "dependencies": { "hosted-git-info": "^5.0.0", "proc-log": "^2.0.1", @@ -11217,8 +11097,9 @@ }, "node_modules/npm-packlist": { "version": "5.1.3", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-5.1.3.tgz", + "integrity": "sha512-263/0NGrn32YFYi4J533qzrQ/krmmrWwhKkzwTuM4f/07ug51odoaNjUexxO4vxlzURHcmYMH1QjvHjsNDKLVg==", "devOptional": true, - "license": "ISC", "dependencies": { "glob": "^8.0.1", "ignore-walk": "^5.0.1", @@ -11234,8 +11115,9 @@ }, "node_modules/npm-packlist/node_modules/npm-bundled": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-2.0.1.tgz", + "integrity": "sha512-gZLxXdjEzE/+mOstGDqR6b0EkhJ+kM6fxM6vUuckuctuVPh80Q6pw/rSZj9s4Gex9GxWtIicO1pc8DB9KZWudw==", "devOptional": true, - "license": "ISC", "dependencies": { "npm-normalize-package-bin": "^2.0.0" }, @@ -11245,16 +11127,18 @@ }, "node_modules/npm-packlist/node_modules/npm-normalize-package-bin": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz", + "integrity": "sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==", "devOptional": true, - "license": "ISC", "engines": { "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/npm-pick-manifest": { "version": "7.0.1", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-7.0.1.tgz", + "integrity": "sha512-IA8+tuv8KujbsbLQvselW2XQgmXWS47t3CB0ZrzsRZ82DbDfkcFunOaPm4X7qNuhMfq+FmV7hQT4iFVpHqV7mg==", "devOptional": true, - "license": "ISC", "dependencies": { "npm-install-checks": "^5.0.0", "npm-normalize-package-bin": "^1.0.1", @@ -11267,8 +11151,9 @@ }, "node_modules/npm-registry-fetch": { "version": "13.3.1", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-13.3.1.tgz", + "integrity": "sha512-eukJPi++DKRTjSBRcDZSDDsGqRK3ehbxfFUcgaRd0Yp6kRwOwh2WVn0r+8rMB4nnuzvAk6rQVzl6K5CkYOmnvw==", "devOptional": true, - "license": "ISC", "dependencies": { "make-fetch-happen": "^10.0.6", "minipass": "^3.1.6", @@ -11284,8 +11169,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -11295,8 +11181,10 @@ }, "node_modules/npmlog": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "deprecated": "This package is no longer supported.", "devOptional": true, - "license": "ISC", "dependencies": { "are-we-there-yet": "^3.0.0", "console-control-strings": "^1.1.0", @@ -11309,8 +11197,9 @@ }, "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==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0" }, @@ -11319,31 +11208,10 @@ } }, "node_modules/object-inspect": { - "version": "1.12.2", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, "engines": { "node": ">= 0.4" }, @@ -11353,13 +11221,15 @@ }, "node_modules/obuf": { "version": "1.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true }, "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==", "dev": true, - "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -11369,23 +11239,26 @@ }, "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==", "dev": true, - "license": "MIT", "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==", "devOptional": true, - "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/onetime": { "version": "5.1.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -11398,8 +11271,9 @@ }, "node_modules/open": { "version": "8.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", + "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", "devOptional": true, - "license": "MIT", "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -11414,24 +11288,27 @@ }, "node_modules/opencollective-postinstall": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", + "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", "dev": true, - "license": "MIT", "bin": { "opencollective-postinstall": "index.js" } }, "node_modules/opener": { "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", "dev": true, - "license": "(WTFPL OR MIT)", "bin": { "opener": "bin/opener-bin.js" } }, "node_modules/optionator": { "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, - "license": "MIT", "dependencies": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.6", @@ -11446,7 +11323,8 @@ }, "node_modules/ora": { "version": "5.4.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", @@ -11467,7 +11345,8 @@ }, "node_modules/ora/node_modules/ansi-styles": { "version": "4.3.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, @@ -11480,7 +11359,8 @@ }, "node_modules/ora/node_modules/chalk": { "version": "4.1.2", - "license": "MIT", + "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" @@ -11494,7 +11374,8 @@ }, "node_modules/ora/node_modules/color-convert": { "version": "2.0.1", - "license": "MIT", + "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" }, @@ -11504,18 +11385,21 @@ }, "node_modules/ora/node_modules/color-name": { "version": "1.1.4", - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/ora/node_modules/has-flag": { "version": "4.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "engines": { "node": ">=8" } }, "node_modules/ora/node_modules/supports-color": { "version": "7.2.0", - "license": "MIT", + "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" }, @@ -11525,8 +11409,9 @@ }, "node_modules/os-name": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/os-name/-/os-name-4.0.1.tgz", + "integrity": "sha512-xl9MAoU97MH1Xt5K9ERft2YfCAoaO6msy1OBA0ozxEC0x0TmIoE6K3QvgJMMZA9yKGLmHXNY/YZoDbiGDj4zYw==", "dev": true, - "license": "MIT", "dependencies": { "macos-release": "^2.5.0", "windows-release": "^4.0.0" @@ -11540,15 +11425,17 @@ }, "node_modules/os-tmpdir": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/p-limit": { "version": "2.3.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dependencies": { "p-try": "^2.0.0" }, @@ -11561,7 +11448,8 @@ }, "node_modules/p-locate": { "version": "4.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dependencies": { "p-limit": "^2.2.0" }, @@ -11571,8 +11459,9 @@ }, "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==", "devOptional": true, - "license": "MIT", "dependencies": { "aggregate-error": "^3.0.0" }, @@ -11585,8 +11474,9 @@ }, "node_modules/p-retry": { "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/retry": "0.12.0", "retry": "^0.13.1" @@ -11597,23 +11487,26 @@ }, "node_modules/p-retry/node_modules/retry": { "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/p-try": { "version": "2.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "engines": { "node": ">=6" } }, "node_modules/pac-proxy-agent": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-5.0.0.tgz", + "integrity": "sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ==", "dev": true, - "license": "MIT", "dependencies": { "@tootallnate/once": "1", "agent-base": "6", @@ -11631,16 +11524,18 @@ }, "node_modules/pac-proxy-agent/node_modules/@tootallnate/once": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/pac-proxy-agent/node_modules/http-proxy-agent": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "dev": true, - "license": "MIT", "dependencies": { "@tootallnate/once": "1", "agent-base": "6", @@ -11652,8 +11547,9 @@ }, "node_modules/pac-proxy-agent/node_modules/socks-proxy-agent": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz", + "integrity": "sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==", "dev": true, - "license": "MIT", "dependencies": { "agent-base": "^6.0.2", "debug": "4", @@ -11665,8 +11561,9 @@ }, "node_modules/pac-resolver": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-5.0.1.tgz", + "integrity": "sha512-cy7u00ko2KVgBAjuhevqpPeHIkCIqPe1v24cydhWjmeuzaBfmUWFCZJ1iAh5TuVzVZoUzXIW7K8sMYOZ84uZ9Q==", "dev": true, - "license": "MIT", "dependencies": { "degenerator": "^3.0.2", "ip": "^1.1.5", @@ -11676,15 +11573,11 @@ "node": ">= 8" } }, - "node_modules/pac-resolver/node_modules/ip": { - "version": "1.1.8", - "dev": true, - "license": "MIT" - }, "node_modules/pacote": { "version": "13.6.2", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.6.2.tgz", + "integrity": "sha512-Gu8fU3GsvOPkak2CkbojR7vjs3k3P9cA6uazKTHdsdV0gpCEQq2opelnEv30KRQWgVzP5Vd/5umjcedma3MKtg==", "devOptional": true, - "license": "ISC", "dependencies": { "@npmcli/git": "^3.0.0", "@npmcli/installed-package-contents": "^1.0.7", @@ -11716,13 +11609,15 @@ } }, "node_modules/pako": { - "version": "2.0.4", - "license": "(MIT AND Zlib)" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" }, "node_modules/parent-module": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -11732,8 +11627,9 @@ }, "node_modules/parse-json": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -11749,19 +11645,22 @@ }, "node_modules/parse-node-version": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/parse5": { "version": "6.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" }, "node_modules/parse5-html-rewriting-stream": { "version": "6.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-6.0.1.tgz", + "integrity": "sha512-vwLQzynJVEfUlURxgnf51yAJDQTtVpNyGD8tKi2Za7m+akukNHxCcUQMAa/mUGLhCeicFdpy7Tlvj8ZNKadprg==", "dependencies": { "parse5": "^6.0.1", "parse5-sax-parser": "^6.0.1" @@ -11769,23 +11668,26 @@ }, "node_modules/parse5-htmlparser2-tree-adapter": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", "dev": true, - "license": "MIT", "dependencies": { "parse5": "^6.0.1" } }, "node_modules/parse5-sax-parser": { "version": "6.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-6.0.1.tgz", + "integrity": "sha512-kXX+5S81lgESA0LsDuGjAlBybImAChYRMT+/uKCEXFBFOeEhS52qUCydGhU3qLRD8D9DVjaUo821WK7DM4iCeg==", "dependencies": { "parse5": "^6.0.1" } }, "node_modules/parseurl": { "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.8" } @@ -11796,53 +11698,61 @@ }, "node_modules/path-browserify": { "version": "1.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", "optional": true }, "node_modules/path-exists": { "version": "4.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-key": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-parse": { "version": "1.0.7", - "devOptional": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "devOptional": true }, "node_modules/path-to-regexp": { "version": "0.1.7", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true }, "node_modules/path-type": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/pbkdf2": { "version": "3.1.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", "dependencies": { "create-hash": "^1.1.2", "create-hmac": "^1.1.4", @@ -11855,14 +11765,16 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "dev": true, - "license": "ISC" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=8.6" }, @@ -11872,8 +11784,9 @@ }, "node_modules/pidtree": { "version": "0.5.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.5.0.tgz", + "integrity": "sha512-9nxspIM7OpZuhBxPg73Zvyq7j1QMPMPsGKTqRc2XOaFQauDvoNz9fM1Wdkjmeo7l9GXOZiRs97sPkuayl39wjA==", "dev": true, - "license": "MIT", "bin": { "pidtree": "bin/pidtree.js" }, @@ -11883,16 +11796,18 @@ }, "node_modules/pify": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/piscina": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-3.2.0.tgz", + "integrity": "sha512-yn/jMdHRw+q2ZJhFhyqsmANcbF6V2QwmD84c6xRau+QpQOmtrBCoRGdvTfeuFDYXB5W2m6MfLkjkvQa9lUSmIA==", "dev": true, - "license": "MIT", "dependencies": { "eventemitter-asyncresource": "^1.0.0", "hdr-histogram-js": "^2.0.1", @@ -11904,8 +11819,9 @@ }, "node_modules/pkg-dir": { "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, - "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -11915,21 +11831,25 @@ }, "node_modules/please-upgrade-node": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", "dev": true, - "license": "MIT", "dependencies": { "semver-compare": "^1.0.0" } }, "node_modules/pngjs": { "version": "5.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", + "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", "engines": { "node": ">=10.13.0" } }, "node_modules/postcss": { - "version": "8.4.16", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "dev": true, "funding": [ { @@ -11939,11 +11859,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -11953,8 +11876,9 @@ }, "node_modules/postcss-attribute-case-insensitive": { "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", + "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", "dev": true, - "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -11971,8 +11895,9 @@ }, "node_modules/postcss-clamp": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", + "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", "dev": true, - "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -11985,8 +11910,9 @@ }, "node_modules/postcss-color-functional-notation": { "version": "4.2.4", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", + "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12003,8 +11929,9 @@ }, "node_modules/postcss-color-hex-alpha": { "version": "8.0.4", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", + "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", "dev": true, - "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12021,8 +11948,9 @@ }, "node_modules/postcss-color-rebeccapurple": { "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", + "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12039,8 +11967,9 @@ }, "node_modules/postcss-custom-media": { "version": "8.0.2", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", + "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", "dev": true, - "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12056,9 +11985,10 @@ } }, "node_modules/postcss-custom-properties": { - "version": "12.1.9", + "version": "12.1.11", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz", + "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==", "dev": true, - "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12075,8 +12005,9 @@ }, "node_modules/postcss-custom-selectors": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", + "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", "dev": true, - "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.4" }, @@ -12093,8 +12024,9 @@ }, "node_modules/postcss-dir-pseudo-class": { "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", + "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -12111,8 +12043,9 @@ }, "node_modules/postcss-double-position-gradients": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", + "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", "dev": true, - "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", "postcss-value-parser": "^4.2.0" @@ -12130,8 +12063,9 @@ }, "node_modules/postcss-env-function": { "version": "4.0.6", + "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz", + "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12144,8 +12078,9 @@ }, "node_modules/postcss-focus-visible": { "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", + "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.9" }, @@ -12158,8 +12093,9 @@ }, "node_modules/postcss-focus-within": { "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", + "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.9" }, @@ -12172,16 +12108,18 @@ }, "node_modules/postcss-font-variant": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", "dev": true, - "license": "MIT", "peerDependencies": { "postcss": "^8.1.0" } }, "node_modules/postcss-gap-properties": { "version": "3.0.5", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", + "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", "dev": true, - "license": "CC0-1.0", "engines": { "node": "^12 || ^14 || >=16" }, @@ -12195,8 +12133,9 @@ }, "node_modules/postcss-image-set-function": { "version": "4.0.7", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", + "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12213,8 +12152,9 @@ }, "node_modules/postcss-import": { "version": "15.0.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.0.0.tgz", + "integrity": "sha512-Y20shPQ07RitgBGv2zvkEAu9bqvrD77C9axhj/aA1BQj4czape2MdClCExvB27EwYEJdGgKZBpKanb0t1rK2Kg==", "dev": true, - "license": "MIT", "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", @@ -12229,16 +12169,18 @@ }, "node_modules/postcss-initial": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", + "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", "dev": true, - "license": "MIT", "peerDependencies": { "postcss": "^8.0.0" } }, "node_modules/postcss-lab-function": { "version": "4.2.1", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", + "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", "dev": true, - "license": "CC0-1.0", "dependencies": { "@csstools/postcss-progressive-custom-properties": "^1.1.0", "postcss-value-parser": "^4.2.0" @@ -12256,8 +12198,9 @@ }, "node_modules/postcss-loader": { "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.0.1.tgz", + "integrity": "sha512-VRviFEyYlLjctSM93gAZtcJJ/iSkPZ79zWbN/1fSH+NisBByEiVLqpdVDrPLVSi8DX0oJo12kL/GppTBdKVXiQ==", "dev": true, - "license": "MIT", "dependencies": { "cosmiconfig": "^7.0.0", "klona": "^2.0.5", @@ -12277,8 +12220,9 @@ }, "node_modules/postcss-logical": { "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", + "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", "dev": true, - "license": "CC0-1.0", "engines": { "node": "^12 || ^14 || >=16" }, @@ -12288,8 +12232,9 @@ }, "node_modules/postcss-media-minmax": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", + "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -12298,9 +12243,10 @@ } }, "node_modules/postcss-modules-extract-imports": { - "version": "3.0.0", + "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==", "dev": true, - "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" }, @@ -12309,9 +12255,10 @@ } }, "node_modules/postcss-modules-local-by-default": { - "version": "4.0.0", + "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==", "dev": true, - "license": "MIT", "dependencies": { "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", @@ -12325,9 +12272,10 @@ } }, "node_modules/postcss-modules-scope": { - "version": "3.0.0", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", + "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", "dev": true, - "license": "ISC", "dependencies": { "postcss-selector-parser": "^6.0.4" }, @@ -12340,8 +12288,9 @@ }, "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==", "dev": true, - "license": "ISC", "dependencies": { "icss-utils": "^5.0.0" }, @@ -12354,8 +12303,9 @@ }, "node_modules/postcss-nesting": { "version": "10.2.0", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", + "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", "dev": true, - "license": "CC0-1.0", "dependencies": { "@csstools/selector-specificity": "^2.0.0", "postcss-selector-parser": "^6.0.10" @@ -12372,7 +12322,9 @@ } }, "node_modules/postcss-opacity-percentage": { - "version": "1.1.2", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz", + "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==", "dev": true, "funding": [ { @@ -12384,15 +12336,18 @@ "url": "https://liberapay.com/mrcgrtz" } ], - "license": "MIT", "engines": { "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" } }, "node_modules/postcss-overflow-shorthand": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", + "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12409,16 +12364,18 @@ }, "node_modules/postcss-page-break": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", "dev": true, - "license": "MIT", "peerDependencies": { "postcss": "^8" } }, "node_modules/postcss-place": { "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz", + "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -12435,8 +12392,9 @@ }, "node_modules/postcss-preset-env": { "version": "7.8.0", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.0.tgz", + "integrity": "sha512-leqiqLOellpLKfbHkD06E04P6d9ZQ24mat6hu4NSqun7WG0UhspHR5Myiv/510qouCjoo4+YJtNOqg5xHaFnCA==", "dev": true, - "license": "CC0-1.0", "dependencies": { "@csstools/postcss-cascade-layers": "^1.0.5", "@csstools/postcss-color-function": "^1.1.1", @@ -12501,8 +12459,9 @@ }, "node_modules/postcss-pseudo-class-any-link": { "version": "7.1.6", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", + "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", "dev": true, - "license": "CC0-1.0", "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -12519,16 +12478,18 @@ }, "node_modules/postcss-replace-overflow-wrap": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", "dev": true, - "license": "MIT", "peerDependencies": { "postcss": "^8.0.3" } }, "node_modules/postcss-selector-not": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", + "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", "dev": true, - "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.10" }, @@ -12544,9 +12505,10 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.10", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", + "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", "dev": true, - "license": "MIT", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -12557,8 +12519,9 @@ }, "node_modules/postcss-url": { "version": "10.1.3", + "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-10.1.3.tgz", + "integrity": "sha512-FUzyxfI5l2tKmXdYc6VTu3TWZsInayEKPbiyW+P6vmmIrrb4I6CGX0BFoewgYHLK+oIL5FECEK02REYRpBvUCw==", "dev": true, - "license": "MIT", "dependencies": { "make-dir": "~3.1.0", "mime": "~2.5.2", @@ -12574,8 +12537,9 @@ }, "node_modules/postcss-url/node_modules/brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -12583,8 +12547,9 @@ }, "node_modules/postcss-url/node_modules/mime": { "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", "dev": true, - "license": "MIT", "bin": { "mime": "cli.js" }, @@ -12594,8 +12559,9 @@ }, "node_modules/postcss-url/node_modules/minimatch": { "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -12605,20 +12571,24 @@ }, "node_modules/postcss-value-parser": { "version": "4.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true }, "node_modules/prelude-ls": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { - "version": "2.7.1", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, - "license": "MIT", "bin": { "prettier": "bin-prettier.js" }, @@ -12631,8 +12601,9 @@ }, "node_modules/pretty-bytes": { "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" }, @@ -12642,33 +12613,38 @@ }, "node_modules/proc-log": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.1.tgz", + "integrity": "sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==", "devOptional": true, - "license": "ISC", "engines": { "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/process": { "version": "0.11.10", - "license": "MIT", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "engines": { "node": ">= 0.6.0" } }, "node_modules/process-nextick-args": { "version": "2.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true }, "node_modules/promise-inflight": { "version": "1.0.1", - "devOptional": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "devOptional": true }, "node_modules/promise-retry": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", "devOptional": true, - "license": "MIT", "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" @@ -12679,8 +12655,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -12691,16 +12668,18 @@ }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/proxy-agent": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-5.0.0.tgz", + "integrity": "sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g==", "dev": true, - "license": "MIT", "dependencies": { "agent-base": "^6.0.0", "debug": "4", @@ -12717,16 +12696,18 @@ }, "node_modules/proxy-agent/node_modules/@tootallnate/once": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/proxy-agent/node_modules/http-proxy-agent": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "dev": true, - "license": "MIT", "dependencies": { "@tootallnate/once": "1", "agent-base": "6", @@ -12736,18 +12717,11 @@ "node": ">= 6" } }, - "node_modules/proxy-agent/node_modules/lru-cache": { - "version": "5.1.1", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, "node_modules/proxy-agent/node_modules/socks-proxy-agent": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz", + "integrity": "sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==", "dev": true, - "license": "MIT", "dependencies": { "agent-base": "^6.0.2", "debug": "4", @@ -12757,41 +12731,41 @@ "node": ">= 6" } }, - "node_modules/proxy-agent/node_modules/yallist": { - "version": "3.1.1", - "dev": true, - "license": "ISC" - }, "node_modules/proxy-from-env": { "version": "1.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true }, "node_modules/prr": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "dev": true, - "license": "MIT", "optional": true }, "node_modules/pump": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, - "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "node_modules/punycode": { - "version": "2.1.1", - "license": "MIT", + "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/qrcode": { - "version": "1.5.1", - "license": "MIT", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.3.tgz", + "integrity": "sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==", "dependencies": { "dijkstrajs": "^1.0.1", "encode-utf8": "^1.0.3", @@ -12807,7 +12781,8 @@ }, "node_modules/qrcode/node_modules/ansi-styles": { "version": "4.3.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, @@ -12820,7 +12795,8 @@ }, "node_modules/qrcode/node_modules/cliui": { "version": "6.0.0", - "license": "ISC", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -12829,7 +12805,8 @@ }, "node_modules/qrcode/node_modules/color-convert": { "version": "2.0.1", - "license": "MIT", + "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" }, @@ -12839,11 +12816,13 @@ }, "node_modules/qrcode/node_modules/color-name": { "version": "1.1.4", - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/qrcode/node_modules/wrap-ansi": { "version": "6.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -12855,11 +12834,13 @@ }, "node_modules/qrcode/node_modules/y18n": { "version": "4.0.3", - "license": "ISC" + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" }, "node_modules/qrcode/node_modules/yargs": { "version": "15.4.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -12879,7 +12860,8 @@ }, "node_modules/qrcode/node_modules/yargs-parser": { "version": "18.1.3", - "license": "ISC", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -12889,11 +12871,12 @@ } }, "node_modules/qs": { - "version": "6.11.0", + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.2.tgz", + "integrity": "sha512-x+NLUpx9SYrcwXtX7ob1gnkSems4i/mGZX5SlYxwIau6RrUSODO89TR/XDGGpn5RPWSYIB+aSfuSlV5+CmbTBg==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -12904,6 +12887,8 @@ }, "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==", "devOptional": true, "funding": [ { @@ -12918,29 +12903,31 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/randombytes": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, - "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/raw-body": { - "version": "2.5.1", + "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==", "dev": true, - "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -12953,8 +12940,9 @@ }, "node_modules/raw-loader": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz", + "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==", "dev": true, - "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" @@ -12972,8 +12960,9 @@ }, "node_modules/raw-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==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -12987,21 +12976,24 @@ }, "node_modules/raw-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==", "dev": true, - "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } }, "node_modules/raw-loader/node_modules/json-schema-traverse": { "version": "0.4.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/raw-loader/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==", "dev": true, - "license": "MIT", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -13012,9 +13004,10 @@ } }, "node_modules/raw-loader/node_modules/schema-utils": { - "version": "3.1.1", + "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==", "dev": true, - "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -13030,16 +13023,19 @@ }, "node_modules/read-cache": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", "dev": true, - "license": "MIT", "dependencies": { "pify": "^2.3.0" } }, "node_modules/read-package-json": { "version": "5.0.2", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-5.0.2.tgz", + "integrity": "sha512-BSzugrt4kQ/Z0krro8zhTwV1Kd79ue25IhNN/VtHFy1mG/6Tluyi+msc0UpwaoQzxSHa28mntAjIZY6kEgfR9Q==", + "deprecated": "This package is no longer supported. Please use @npmcli/package-json instead.", "devOptional": true, - "license": "ISC", "dependencies": { "glob": "^8.0.1", "json-parse-even-better-errors": "^2.3.1", @@ -13052,8 +13048,9 @@ }, "node_modules/read-package-json-fast": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz", + "integrity": "sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ==", "devOptional": true, - "license": "ISC", "dependencies": { "json-parse-even-better-errors": "^2.3.0", "npm-normalize-package-bin": "^1.0.1" @@ -13064,15 +13061,17 @@ }, "node_modules/read-package-json/node_modules/npm-normalize-package-bin": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz", + "integrity": "sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==", "devOptional": true, - "license": "ISC", "engines": { "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/readable-stream": { - "version": "3.6.0", - "license": "MIT", + "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", @@ -13084,8 +13083,9 @@ }, "node_modules/readdirp": { "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "devOptional": true, - "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -13094,19 +13094,22 @@ } }, "node_modules/reflect-metadata": { - "version": "0.1.13", - "dev": true, - "license": "Apache-2.0" + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", + "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==", + "dev": true }, "node_modules/regenerate": { "version": "1.4.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true }, "node_modules/regenerate-unicode-properties": { - "version": "10.1.0", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", "dev": true, - "license": "MIT", "dependencies": { "regenerate": "^1.4.2" }, @@ -13116,47 +13119,47 @@ }, "node_modules/regenerator-runtime": { "version": "0.13.9", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "dev": true }, "node_modules/regenerator-transform": { - "version": "0.15.0", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/runtime": "^7.8.4" } }, "node_modules/regex-parser": { - "version": "2.2.11", - "dev": true, - "license": "MIT" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.0.tgz", + "integrity": "sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg==", + "dev": true }, "node_modules/regexpu-core": { - "version": "5.2.1", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", "dev": true, - "license": "MIT", "dependencies": { + "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.1.0", - "regjsgen": "^0.7.1", "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" + "unicode-match-property-value-ecmascript": "^2.1.0" }, "engines": { "node": ">=4" } }, - "node_modules/regjsgen": { - "version": "0.7.1", - "dev": true, - "license": "MIT" - }, "node_modules/regjsparser": { "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "jsesc": "~0.5.0" }, @@ -13166,6 +13169,8 @@ }, "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==", "dev": true, "bin": { "jsesc": "bin/jsesc" @@ -13173,31 +13178,36 @@ }, "node_modules/require-directory": { "version": "2.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "engines": { "node": ">=0.10.0" } }, "node_modules/require-from-string": { "version": "2.0.2", - "license": "MIT", + "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-main-filename": { "version": "2.0.0", - "license": "ISC" + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, "node_modules/requires-port": { "version": "1.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true }, "node_modules/resolve": { "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "devOptional": true, - "license": "MIT", "dependencies": { "is-core-module": "^2.9.0", "path-parse": "^1.0.7", @@ -13212,16 +13222,18 @@ }, "node_modules/resolve-from": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/resolve-url-loader": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", + "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", "dev": true, - "license": "MIT", "dependencies": { "adjust-sourcemap-loader": "^4.0.0", "convert-source-map": "^1.7.0", @@ -13235,8 +13247,9 @@ }, "node_modules/resolve-url-loader/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==", "dev": true, - "license": "MIT", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -13248,15 +13261,17 @@ }, "node_modules/resolve-url-loader/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==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/restore-cursor": { "version": "3.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -13267,30 +13282,35 @@ }, "node_modules/retry": { "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "devOptional": true, - "license": "MIT", "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==", "devOptional": true, - "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, "node_modules/rfdc": { - "version": "1.3.0", - "dev": true, - "license": "MIT" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true }, "node_modules/rimraf": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "devOptional": true, - "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -13303,8 +13323,9 @@ }, "node_modules/rimraf/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==", "devOptional": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -13312,8 +13333,10 @@ }, "node_modules/rimraf/node_modules/glob": { "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "devOptional": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -13331,8 +13354,9 @@ }, "node_modules/rimraf/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "devOptional": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -13342,16 +13366,18 @@ }, "node_modules/ripemd160": { "version": "2.0.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1" } }, "node_modules/rollup": { - "version": "2.79.0", + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "dev": true, - "license": "MIT", "bin": { "rollup": "dist/bin/rollup" }, @@ -13364,8 +13390,9 @@ }, "node_modules/rollup-plugin-sourcemaps": { "version": "0.6.3", + "resolved": "https://registry.npmjs.org/rollup-plugin-sourcemaps/-/rollup-plugin-sourcemaps-0.6.3.tgz", + "integrity": "sha512-paFu+nT1xvuO1tPFYXGe+XnQvg4Hjqv/eIhG8i5EspfYYPBKL57X7iVbfv55aNVASg3dzWvES9dmWsL2KhfByw==", "dev": true, - "license": "MIT", "dependencies": { "@rollup/pluginutils": "^3.0.9", "source-map-resolve": "^0.6.0" @@ -13385,22 +13412,26 @@ }, "node_modules/rsvp": { "version": "3.6.2", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz", + "integrity": "sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==", "dev": true, - "license": "MIT", "engines": { "node": "0.12.* || 4.* || 6.* || >= 7.*" } }, "node_modules/run-async": { "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=0.12.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==", "devOptional": true, "funding": [ { @@ -13416,7 +13447,6 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -13430,18 +13460,35 @@ } }, "node_modules/safe-buffer": { - "version": "5.1.2", - "license": "MIT" + "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", - "devOptional": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "devOptional": true }, "node_modules/sass": { "version": "1.54.4", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.4.tgz", + "integrity": "sha512-3tmF16yvnBwtlPrNBHw/H907j8MlOX8aTBnlNX1yrKx24RKcJGPyLhFUwkoKBKesR3unP93/2z14Ll8NicwQUA==", "dev": true, - "license": "MIT", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -13456,8 +13503,9 @@ }, "node_modules/sass-loader": { "version": "13.0.2", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.0.2.tgz", + "integrity": "sha512-BbiqbVmbfJaWVeOOAu2o7DhYWtcNmTfvroVgFXa6k2hHheMxNAeDHLNoDy/Q5aoaVlz0LH+MbMktKwm9vN/j8Q==", "dev": true, - "license": "MIT", "dependencies": { "klona": "^2.0.4", "neo-async": "^2.6.2" @@ -13493,13 +13541,15 @@ }, "node_modules/sax": { "version": "1.1.4", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.4.tgz", + "integrity": "sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==", + "dev": true }, "node_modules/schema-utils": { "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", "dev": true, - "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.5", "ajv": "^6.12.4", @@ -13515,8 +13565,9 @@ }, "node_modules/schema-utils/node_modules/ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -13530,27 +13581,32 @@ }, "node_modules/schema-utils/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==", "dev": true, - "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } }, "node_modules/schema-utils/node_modules/json-schema-traverse": { "version": "0.4.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/select-hose": { "version": "2.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true }, "node_modules/selfsigned": { - "version": "2.1.1", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", "dev": true, - "license": "MIT", "dependencies": { + "@types/node-forge": "^1.3.0", "node-forge": "^1" }, "engines": { @@ -13558,9 +13614,10 @@ } }, "node_modules/semver": { - "version": "7.3.7", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "devOptional": true, - "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -13573,13 +13630,15 @@ }, "node_modules/semver-compare": { "version": "1.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true }, "node_modules/semver-regex": { "version": "3.1.4", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.4.tgz", + "integrity": "sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, @@ -13589,8 +13648,9 @@ }, "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==", "devOptional": true, - "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -13598,10 +13658,17 @@ "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==", + "devOptional": true + }, "node_modules/send": { "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dev": true, - "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -13623,42 +13690,51 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, - "node_modules/send/node_modules/depd": { - "version": "2.0.0", + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, - "license": "MIT", + "bin": { + "mime": "cli.js" + }, "engines": { - "node": ">= 0.8" + "node": ">=4" } }, "node_modules/send/node_modules/ms": { "version": "2.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, "node_modules/serialize-javascript": { - "version": "6.0.0", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, "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==", "dev": true, - "license": "MIT", "dependencies": { "accepts": "~1.3.4", "batch": "0.6.1", @@ -13674,16 +13750,27 @@ }, "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==", "dev": true, - "license": "MIT", "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==", + "dev": true, + "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==", "dev": true, - "license": "MIT", "dependencies": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -13696,31 +13783,36 @@ }, "node_modules/serve-index/node_modules/inherits": { "version": "2.0.3", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true }, "node_modules/serve-index/node_modules/ms": { "version": "2.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, "node_modules/serve-index/node_modules/setprototypeof": { "version": "1.1.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true }, "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==", "dev": true, - "license": "MIT", "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==", "dev": true, - "license": "MIT", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -13733,16 +13825,36 @@ }, "node_modules/set-blocking": { "version": "2.0.0", - "license": "ISC" + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + }, + "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==", + "dev": true, + "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", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true }, "node_modules/sha.js": { "version": "2.4.11", - "license": "(MIT AND BSD-3-Clause)", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -13753,8 +13865,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "kind-of": "^6.0.2" }, @@ -13764,8 +13877,9 @@ }, "node_modules/shebang-command": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -13775,20 +13889,26 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/side-channel": { - "version": "1.0.4", + "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==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "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" @@ -13796,16 +13916,18 @@ }, "node_modules/signal-exit": { "version": "3.0.7", - "license": "ISC" + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/sirv": { - "version": "1.0.19", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", "dev": true, - "license": "MIT", "dependencies": { - "@polka/url": "^1.0.0-next.20", - "mrmime": "^1.0.0", - "totalist": "^1.0.0" + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" }, "engines": { "node": ">= 10" @@ -13813,8 +13935,9 @@ }, "node_modules/slash": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -13824,8 +13947,9 @@ }, "node_modules/slice-ansi": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -13840,8 +13964,9 @@ }, "node_modules/slice-ansi/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -13854,8 +13979,9 @@ }, "node_modules/slice-ansi/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -13865,13 +13991,15 @@ }, "node_modules/slice-ansi/node_modules/color-name": { "version": "1.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/smart-buffer": { "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "devOptional": true, - "license": "MIT", "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" @@ -13879,8 +14007,9 @@ }, "node_modules/sockjs": { "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", "dev": true, - "license": "MIT", "dependencies": { "faye-websocket": "^0.11.3", "uuid": "^8.3.2", @@ -13888,22 +14017,24 @@ } }, "node_modules/socks": { - "version": "2.7.0", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", "devOptional": true, - "license": "MIT", "dependencies": { - "ip": "^2.0.0", + "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" }, "engines": { - "node": ">= 10.13.0", + "node": ">= 10.0.0", "npm": ">= 3.0.0" } }, "node_modules/socks-proxy-agent": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", "devOptional": true, - "license": "MIT", "dependencies": { "agent-base": "^6.0.2", "debug": "^4.3.3", @@ -13915,23 +14046,26 @@ }, "node_modules/source-map": { "version": "0.7.4", - "license": "BSD-3-Clause", + "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.0.2", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-loader": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-4.0.0.tgz", + "integrity": "sha512-i3KVgM3+QPAHNbGavK+VBq03YoJl24m9JWNbLgsjTj8aJzXG9M61bantBTNBt7CNwY2FYf+RJRYJ3pzalKjIrw==", "dev": true, - "license": "MIT", "dependencies": { "abab": "^2.0.6", "iconv-lite": "^0.6.3", @@ -13950,8 +14084,9 @@ }, "node_modules/source-map-loader/node_modules/iconv-lite": { "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, - "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -13961,8 +14096,10 @@ }, "node_modules/source-map-resolve": { "version": "0.6.0", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", + "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", "dev": true, - "license": "MIT", "dependencies": { "atob": "^2.1.2", "decode-uri-component": "^0.2.0" @@ -13970,8 +14107,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -13979,48 +14117,56 @@ }, "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==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/sourcemap-codec": { "version": "1.4.8", - "license": "MIT" + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead" }, "node_modules/spdx-correct": { - "version": "3.1.1", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "devOptional": true, - "license": "Apache-2.0", "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-exceptions": { - "version": "2.3.0", - "devOptional": true, - "license": "CC-BY-3.0" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "devOptional": true }, "node_modules/spdx-expression-parse": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "devOptional": true, - "license": "MIT", "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-license-ids": { - "version": "3.0.12", - "devOptional": true, - "license": "CC0-1.0" + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", + "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "devOptional": true }, "node_modules/spdy": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.1.0", "handle-thing": "^2.0.0", @@ -14034,8 +14180,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.1.0", "detect-node": "^2.0.4", @@ -14047,30 +14194,35 @@ }, "node_modules/split2": { "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", "dev": true, - "license": "ISC", "dependencies": { "readable-stream": "^3.0.0" } }, "node_modules/sprintf-js": { - "version": "1.0.3", - "dev": true, - "license": "BSD-3-Clause" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "devOptional": true }, "node_modules/ssh-config": { "version": "1.1.6", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ssh-config/-/ssh-config-1.1.6.tgz", + "integrity": "sha512-ZPO9rECxzs5JIQ6G/2EfL1I9ho/BVZkx9HRKn8+0af7QgwAmumQ7XBFP1ggMyPMo+/tUbmv0HFdv4qifdO/9JA==", + "dev": true }, "node_modules/ssr-window": { "version": "4.0.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-4.0.2.tgz", + "integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ==" }, "node_modules/ssri": { "version": "9.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", + "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", "devOptional": true, - "license": "ISC", "dependencies": { "minipass": "^3.1.1" }, @@ -14080,25 +14232,28 @@ }, "node_modules/statuses": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/stream-combiner2": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", "dev": true, - "license": "MIT", "dependencies": { "duplexer2": "~0.1.0", "readable-stream": "^2.0.2" } }, "node_modules/stream-combiner2/node_modules/readable-stream": { - "version": "2.3.7", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -14109,50 +14264,42 @@ "util-deprecate": "~1.0.1" } }, + "node_modules/stream-combiner2/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==", + "dev": true + }, "node_modules/stream-combiner2/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==", "dev": true, - "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/string_decoder": { "version": "1.3.0", - "license": "MIT", + "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_decoder/node_modules/safe-buffer": { - "version": "5.2.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/string-argv": { - "version": "0.3.1", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.6.19" } }, "node_modules/string-width": { "version": "4.2.3", - "license": "MIT", + "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", @@ -14164,7 +14311,8 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -14174,16 +14322,18 @@ }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/stylus": { "version": "0.59.0", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.59.0.tgz", + "integrity": "sha512-lQ9w/XIOH5ZHVNuNbWW8D822r+/wBSO/d6XvtyHLF7LW4KaCIDeVbvn5DF8fGCJAUCwVhVi/h6J0NUcnylUEjg==", "dev": true, - "license": "MIT", "dependencies": { "@adobe/css-tools": "^4.0.1", "debug": "^4.3.2", @@ -14203,8 +14353,9 @@ }, "node_modules/stylus-loader": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-7.0.0.tgz", + "integrity": "sha512-WTbtLrNfOfLgzTaR9Lj/BPhQroKk/LC1hfTXSUbrxmxgfUo3Y3LpmKRVA2R1XbjvTAvOfaian9vOyfv1z99E+A==", "dev": true, - "license": "MIT", "dependencies": { "fast-glob": "^3.2.11", "klona": "^2.0.5", @@ -14224,8 +14375,9 @@ }, "node_modules/stylus/node_modules/brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -14233,8 +14385,10 @@ }, "node_modules/stylus/node_modules/glob": { "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -14252,8 +14406,9 @@ }, "node_modules/stylus/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -14263,13 +14418,16 @@ }, "node_modules/stylus/node_modules/sax": { "version": "1.2.4", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true }, "node_modules/superagent": { "version": "5.3.1", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-5.3.1.tgz", + "integrity": "sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ==", + "deprecated": "Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net", "dev": true, - "license": "MIT", "dependencies": { "component-emitter": "^1.3.0", "cookiejar": "^2.1.2", @@ -14289,8 +14447,9 @@ }, "node_modules/superagent-proxy": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/superagent-proxy/-/superagent-proxy-3.0.0.tgz", + "integrity": "sha512-wAlRInOeDFyd9pyonrkJspdRAxdLrcsZ6aSnS+8+nu4x1aXbz6FWSTT9M6Ibze+eG60szlL7JA8wEIV7bPWuyQ==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.3.2", "proxy-agent": "^5.0.0" @@ -14304,8 +14463,9 @@ }, "node_modules/superagent/node_modules/mime": { "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true, - "license": "MIT", "bin": { "mime": "cli.js" }, @@ -14315,8 +14475,9 @@ }, "node_modules/supports-color": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -14326,8 +14487,9 @@ }, "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==", "devOptional": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -14336,7 +14498,9 @@ } }, "node_modules/swiper": { - "version": "8.4.2", + "version": "8.4.7", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-8.4.7.tgz", + "integrity": "sha512-VwO/KU3i9IV2Sf+W2NqyzwWob4yX9Qdedq6vBtS0rFqJ6Fa5iLUJwxQkuD4I38w0WDJwmFl8ojkdcRFPHWD+2g==", "funding": [ { "type": "patreon", @@ -14348,7 +14512,6 @@ } ], "hasInstallScript": true, - "license": "MIT", "dependencies": { "dom7": "^4.0.4", "ssr-window": "^4.0.2" @@ -14359,40 +14522,59 @@ }, "node_modules/symbol-observable": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=0.10" } }, "node_modules/tapable": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/tar": { - "version": "6.1.11", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "devOptional": true, - "license": "ISC", "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", + "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" }, "engines": { - "node": ">= 10" + "node": ">=10" } }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "devOptional": true + }, "node_modules/terser": { "version": "5.14.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", + "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", @@ -14407,15 +14589,16 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.6", + "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==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.14", + "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "terser": "^5.14.1" + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" }, "engines": { "node": ">= 10.13.0" @@ -14441,8 +14624,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -14456,21 +14640,30 @@ }, "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==", "dev": true, - "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } }, + "node_modules/terser-webpack-plugin/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==", + "dev": true + }, "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { "version": "0.4.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.1.1", + "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==", "dev": true, - "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -14484,15 +14677,35 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/terser-webpack-plugin/node_modules/terser": { + "version": "5.31.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", + "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", + "dev": true, + "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/node_modules/commander": { "version": "2.20.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true }, "node_modules/test-exclude": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, - "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -14504,8 +14717,9 @@ }, "node_modules/test-exclude/node_modules/brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -14513,8 +14727,10 @@ }, "node_modules/test-exclude/node_modules/glob": { "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -14532,8 +14748,9 @@ }, "node_modules/test-exclude/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -14543,27 +14760,32 @@ }, "node_modules/text-mask-core": { "version": "5.1.2", - "license": "Unlicense" + "resolved": "https://registry.npmjs.org/text-mask-core/-/text-mask-core-5.1.2.tgz", + "integrity": "sha512-VfkCMdmRRZqXgQZFlDMiavm3hzsMzBM23CxHZsaeAYg66ZhXCNJWrFmnJwNy8KF9f74YvAUAuQenxsMCfuvhUw==" }, "node_modules/text-table": { "version": "0.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true }, "node_modules/through": { "version": "2.3.8", - "devOptional": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "devOptional": true }, "node_modules/thunky": { "version": "1.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true }, "node_modules/tmp": { "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "devOptional": true, - "license": "MIT", "dependencies": { "os-tmpdir": "~1.0.2" }, @@ -14573,16 +14795,18 @@ }, "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==", "dev": true, - "license": "MIT", "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==", "devOptional": true, - "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -14592,45 +14816,51 @@ }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.6" } }, "node_modules/totalist": { - "version": "1.1.0", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/tree-kill": { "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true, - "license": "MIT", "bin": { "tree-kill": "cli.js" } }, "node_modules/ts-matches": { - "version": "v5.2.1", - "license": "MIT" + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/ts-matches/-/ts-matches-5.5.1.tgz", + "integrity": "sha512-UFYaKgfqlg9FROK7bdpYqFwG1CJvP4kOJdjXuWoqxo9jCmANoDw1GxkSCpJgoTeIiSTaTH5Qr1klSspb8c+ydg==" }, "node_modules/ts-morph": { - "version": "10.0.2", - "license": "MIT", + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-21.0.1.tgz", + "integrity": "sha512-dbDtVdEAncKctzrVZ+Nr7kHpHkv+0JDJb2MjjpBaj8bFeCkePU9rHfMklmhuLFnpeq/EJZk2IhStY6NzqgjOkg==", "optional": true, "dependencies": { - "@ts-morph/common": "~0.9.0", - "code-block-writer": "^10.1.1" + "@ts-morph/common": "~0.22.0", + "code-block-writer": "^12.0.0" } }, "node_modules/ts-node": { - "version": "10.9.1", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, - "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -14670,13 +14900,16 @@ } }, "node_modules/tslib": { - "version": "2.4.0", - "license": "0BSD" + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/tslint": { "version": "6.1.3", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", + "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", + "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.", "dev": true, - "license": "Apache-2.0", "dependencies": { "@babel/code-frame": "^7.0.0", "builtin-modules": "^1.1.1", @@ -14704,16 +14937,18 @@ }, "node_modules/tslint/node_modules/argparse": { "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/tslint/node_modules/brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -14721,21 +14956,25 @@ }, "node_modules/tslint/node_modules/builtin-modules": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/tslint/node_modules/commander": { "version": "2.20.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true }, "node_modules/tslint/node_modules/glob": { "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -14753,8 +14992,9 @@ }, "node_modules/tslint/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==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -14765,8 +15005,9 @@ }, "node_modules/tslint/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -14776,8 +15017,9 @@ }, "node_modules/tslint/node_modules/mkdirp": { "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, - "license": "MIT", "dependencies": { "minimist": "^1.2.6" }, @@ -14786,22 +15028,31 @@ } }, "node_modules/tslint/node_modules/semver": { - "version": "5.7.1", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver" } }, + "node_modules/tslint/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, "node_modules/tslint/node_modules/tslib": { "version": "1.14.1", - "dev": true, - "license": "0BSD" + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true }, "node_modules/tsutils": { "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^1.8.1" }, @@ -14811,13 +15062,15 @@ }, "node_modules/tsutils/node_modules/tslib": { "version": "1.14.1", - "dev": true, - "license": "0BSD" + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true }, "node_modules/type-check": { "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", "dev": true, - "license": "MIT", "dependencies": { "prelude-ls": "~1.1.2" }, @@ -14827,8 +15080,9 @@ }, "node_modules/type-fest": { "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "devOptional": true, - "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -14838,8 +15092,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -14850,21 +15105,24 @@ }, "node_modules/typed-assert": { "version": "1.0.9", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz", + "integrity": "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==", + "dev": true }, "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==", "dev": true, - "license": "MIT", "dependencies": { "is-typedarray": "^1.0.0" } }, "node_modules/typescript": { "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", "dev": true, - "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -14875,16 +15133,18 @@ }, "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==", "dev": true, - "license": "MIT", "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==", "dev": true, - "license": "MIT", "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -14894,63 +15154,72 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.0.0", + "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==", "dev": true, - "license": "MIT", "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==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/unique-filename": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", "devOptional": true, - "license": "ISC", "dependencies": { "unique-slug": "^2.0.0" } }, "node_modules/unique-slug": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", "devOptional": true, - "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4" } }, "node_modules/universalify": { - "version": "2.0.0", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, - "license": "MIT", "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==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/untildify": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/update-browserslist-db": { - "version": "1.0.9", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "dev": true, "funding": [ { @@ -14960,15 +15229,18 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { - "browserslist-lint": "cli.js" + "update-browserslist-db": "cli.js" }, "peerDependencies": { "browserslist": ">= 4.21.0" @@ -14976,39 +15248,45 @@ }, "node_modules/uri-js": { "version": "4.4.1", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dependencies": { "punycode": "^2.1.0" } }, "node_modules/util-deprecate": { "version": "1.0.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4.0" } }, "node_modules/uuid": { "version": "8.3.2", - "license": "MIT", + "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/v8-compile-cache-lib": { "version": "3.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true }, "node_modules/validate-npm-package-license": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "devOptional": true, - "license": "Apache-2.0", "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -15016,8 +15294,9 @@ }, "node_modules/validate-npm-package-name": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz", + "integrity": "sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==", "devOptional": true, - "license": "ISC", "dependencies": { "builtins": "^5.0.0" }, @@ -15027,16 +15306,19 @@ }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/vm2": { - "version": "3.9.11", + "version": "3.9.19", + "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.19.tgz", + "integrity": "sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg==", + "deprecated": "The library contains critical security issues and should not be used for production! The maintenance of the project has been discontinued. Consider migrating your code to isolated-vm.", "dev": true, - "license": "MIT", "dependencies": { "acorn": "^8.7.0", "acorn-walk": "^8.2.0" @@ -15049,9 +15331,10 @@ } }, "node_modules/watchpack": { - "version": "2.4.0", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, - "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -15062,47 +15345,51 @@ }, "node_modules/wbuf": { "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "dev": true, - "license": "MIT", "dependencies": { "minimalistic-assert": "^1.0.0" } }, "node_modules/wcwidth": { "version": "1.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dependencies": { "defaults": "^1.0.3" } }, "node_modules/webpack": { - "version": "5.74.0", + "version": "5.92.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", + "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", + "@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-assertions": "^1.7.6", - "browserslist": "^4.14.5", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.17.0", + "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.9", + "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.1.0", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.4.0", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": { @@ -15122,19 +15409,22 @@ } }, "node_modules/webpack-bundle-analyzer": { - "version": "4.8.0", + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", + "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", "dev": true, - "license": "MIT", "dependencies": { "@discoveryjs/json-ext": "0.5.7", "acorn": "^8.0.4", "acorn-walk": "^8.0.0", - "chalk": "^4.1.0", "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", "gzip-size": "^6.0.0", - "lodash": "^4.17.20", + "html-escaper": "^2.0.2", "opener": "^1.5.2", - "sirv": "^1.0.7", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", "ws": "^7.3.1" }, "bin": { @@ -15144,102 +15434,32 @@ "node": ">= 10.13.0" } }, - "node_modules/webpack-bundle-analyzer/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/chalk": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "license": "MIT" - }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">= 10" } }, - "node_modules/webpack-bundle-analyzer/node_modules/has-flag": { + "node_modules/webpack-bundle-analyzer/node_modules/escape-string-regexp": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "license": "MIT", "engines": { - "node": ">=8" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" + "node": ">=10" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/ws": { - "version": "7.5.9", - "dev": true, - "license": "MIT", - "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 - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/webpack-dev-middleware": { "version": "5.3.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", + "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", "dev": true, - "license": "MIT", "dependencies": { "colorette": "^2.0.10", "memfs": "^3.4.3", @@ -15259,14 +15479,15 @@ } }, "node_modules/webpack-dev-middleware/node_modules/schema-utils": { - "version": "4.0.0", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, - "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", + "ajv": "^8.9.0", "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" + "ajv-keywords": "^5.1.0" }, "engines": { "node": ">= 12.13.0" @@ -15278,8 +15499,9 @@ }, "node_modules/webpack-dev-server": { "version": "4.11.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.11.0.tgz", + "integrity": "sha512-L5S4Q2zT57SK7tazgzjMiSMBdsw+rGYIX27MgPgx7LDhWO0lViPrHKoLS7jo5In06PWYAhlYu3PbyoC6yAThbw==", "dev": true, - "license": "MIT", "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -15331,14 +15553,15 @@ } }, "node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "4.0.0", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, - "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", + "ajv": "^8.9.0", "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" + "ajv-keywords": "^5.1.0" }, "engines": { "node": ">= 12.13.0" @@ -15348,10 +15571,32 @@ "url": "https://opencollective.com/webpack" } }, + "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==", + "dev": true, + "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.8.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", "dev": true, - "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", "wildcard": "^2.0.0" @@ -15362,16 +15607,18 @@ }, "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==", "dev": true, - "license": "MIT", "engines": { "node": ">=10.13.0" } }, "node_modules/webpack-subresource-integrity": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz", + "integrity": "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==", "dev": true, - "license": "MIT", "dependencies": { "typed-assert": "^1.0.8" }, @@ -15388,10 +15635,19 @@ } } }, + "node_modules/webpack/node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true, + "peer": true + }, "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -15405,21 +15661,27 @@ }, "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==", "dev": true, - "license": "MIT", + "peer": true, "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==", "dev": true, - "license": "MIT" + "peer": true }, "node_modules/webpack/node_modules/schema-utils": { - "version": "3.1.1", + "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==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -15435,8 +15697,9 @@ }, "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==", "dev": true, - "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", @@ -15448,16 +15711,18 @@ }, "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==", "dev": true, - "license": "Apache-2.0", "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==", "devOptional": true, - "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -15469,34 +15734,39 @@ } }, "node_modules/which-module": { - "version": "2.0.0", - "license": "ISC" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" }, "node_modules/which-pm-runs": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", + "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/wide-align": { "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", "devOptional": true, - "license": "ISC", "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } }, "node_modules/wildcard": { - "version": "2.0.0", - "dev": true, - "license": "MIT" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true }, "node_modules/windows-release": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-4.0.0.tgz", + "integrity": "sha512-OxmV4wzDKB1x7AZaZgXMVsdJ1qER1ed83ZrTYd5Bwq2HfJVg3DJS8nqlAG4sMoJ7mu8cuRmLEYyU13BKwctRAg==", "dev": true, - "license": "MIT", "dependencies": { "execa": "^4.0.2" }, @@ -15509,8 +15779,9 @@ }, "node_modules/windows-release/node_modules/execa": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "dev": true, - "license": "MIT", "dependencies": { "cross-spawn": "^7.0.0", "get-stream": "^5.0.0", @@ -15531,8 +15802,9 @@ }, "node_modules/windows-release/node_modules/get-stream": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, - "license": "MIT", "dependencies": { "pump": "^3.0.0" }, @@ -15545,24 +15817,27 @@ }, "node_modules/windows-release/node_modules/human-signals": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=8.12.0" } }, "node_modules/word-wrap": { - "version": "1.2.3", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/wrap-ansi": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "devOptional": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -15577,8 +15852,9 @@ }, "node_modules/wrap-ansi/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==", "devOptional": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -15591,8 +15867,9 @@ }, "node_modules/wrap-ansi/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==", "devOptional": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -15602,18 +15879,21 @@ }, "node_modules/wrap-ansi/node_modules/color-name": { "version": "1.1.4", - "devOptional": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true }, "node_modules/wrappy": { "version": "1.0.2", - "devOptional": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "devOptional": true }, "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==", "dev": true, - "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", @@ -15622,11 +15902,12 @@ } }, "node_modules/ws": { - "version": "8.8.1", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "dev": true, - "license": "MIT", "engines": { - "node": ">=10.0.0" + "node": ">=8.3.0" }, "peerDependencies": { "bufferutil": "^4.0.1", @@ -15643,42 +15924,51 @@ }, "node_modules/xregexp": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", + "integrity": "sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA==", "dev": true, - "license": "MIT" + "engines": { + "node": "*" + } }, "node_modules/xxhashjs": { "version": "0.2.2", + "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", + "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==", "dev": true, - "license": "MIT", "dependencies": { "cuint": "^0.2.2" } }, "node_modules/y18n": { "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "devOptional": true, - "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yallist": { - "version": "4.0.0", - "devOptional": true, - "license": "ISC" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true }, "node_modules/yaml": { "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true, - "license": "ISC", "engines": { "node": ">= 6" } }, "node_modules/yargs": { "version": "17.5.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", + "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", "devOptional": true, - "license": "MIT", "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -15694,24 +15984,27 @@ }, "node_modules/yargs-parser": { "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "devOptional": true, - "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/yn": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/yocto-queue": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -15721,7 +16014,8 @@ }, "node_modules/zone.js": { "version": "0.11.8", - "license": "MIT", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.11.8.tgz", + "integrity": "sha512-82bctBg2hKcEJ21humWIkXRlLBBmrc3nN7DFh5LGGhcyycO2S7FN8NmdvlcKaGFDNVL4/9kFLmwmInTavdJERA==", "dependencies": { "tslib": "^2.3.0" } diff --git a/web/package.json b/web/package.json index 6d7db5863..69c3585ce 100644 --- a/web/package.json +++ b/web/package.json @@ -43,21 +43,26 @@ "@angular/service-worker": "^14.2.2", "@ionic/angular": "^6.1.15", "@materia-ui/ngx-monaco-editor": "^6.0.0", - "@ng-web-apis/common": "^2.0.0", - "@ng-web-apis/mutation-observer": "^2.0.0", - "@ng-web-apis/resize-observer": "^2.0.0", + "@ng-web-apis/common": "^3.0.6", + "@ng-web-apis/mutation-observer": "^3.2.1", + "@ng-web-apis/resize-observer": "^3.2.1", + "@noble/curves": "^1.4.0", + "@noble/hashes": "^1.4.0", "@start9labs/argon2": "^0.2.2", "@start9labs/emver": "^0.1.5", "@start9labs/start-sdk": "file:../sdk/dist", - "@taiga-ui/addon-charts": "3.20.0", - "@taiga-ui/cdk": "3.20.0", - "@taiga-ui/core": "3.20.0", - "@taiga-ui/icons": "3.20.0", - "@taiga-ui/kit": "3.20.0", + "@taiga-ui/addon-charts": "3.84.0", + "@taiga-ui/cdk": "3.84.0", + "@taiga-ui/core": "3.84.0", + "@taiga-ui/experimental": "3.84.0", + "@taiga-ui/icons": "3.84.0", + "@taiga-ui/kit": "3.84.0", "@tinkoff/ng-dompurify": "4.0.0", + "@tinkoff/ng-event-plugins": "3.2.0", "angular-svg-round-progressbar": "^9.0.0", "ansi-to-html": "^0.7.2", "base64-js": "^1.5.1", + "buffer": "^6.0.3", "cbor": "npm:@jprochazk/cbor@^0.4.9", "cbor-web": "^8.1.0", "core-js": "^3.21.1", @@ -68,6 +73,7 @@ "jose": "^4.9.0", "js-yaml": "^4.1.0", "marked": "^4.0.0", + "mime": "^4.0.3", "monaco-editor": "^0.33.0", "mustache": "^4.2.0", "ng-qrcode": "^7.0.0", @@ -76,7 +82,7 @@ "pbkdf2": "^3.1.2", "rxjs": "^7.8.1", "swiper": "^8.2.4", - "ts-matches": "^5.2.1", + "ts-matches": "^5.5.1", "tslib": "^2.3.0", "uuid": "^8.3.2", "zone.js": "^0.11.5" diff --git a/web/projects/setup-wizard/src/app/app.component.ts b/web/projects/setup-wizard/src/app/app.component.ts index e10d672e5..e07df5870 100644 --- a/web/projects/setup-wizard/src/app/app.component.ts +++ b/web/projects/setup-wizard/src/app/app.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core' import { NavController } from '@ionic/angular' +import { ErrorService } from '@start9labs/shared' import { ApiService } from './services/api/api.service' -import { ErrorToastService } from '@start9labs/shared' @Component({ selector: 'app-root', @@ -11,7 +11,7 @@ import { ErrorToastService } from '@start9labs/shared' export class AppComponent { constructor( private readonly apiService: ApiService, - private readonly errorToastService: ErrorToastService, + private readonly errorService: ErrorService, private readonly navCtrl: NavController, ) {} @@ -26,7 +26,7 @@ export class AppComponent { await this.navCtrl.navigateForward(route) } catch (e: any) { - this.errorToastService.present(e) + this.errorService.handleError(e) } } } diff --git a/web/projects/setup-wizard/src/app/app.module.ts b/web/projects/setup-wizard/src/app/app.module.ts index f2ba59012..973ce35ee 100644 --- a/web/projects/setup-wizard/src/app/app.module.ts +++ b/web/projects/setup-wizard/src/app/app.module.ts @@ -2,7 +2,7 @@ import { NgModule } from '@angular/core' import { BrowserAnimationsModule } from '@angular/platform-browser/animations' import { RouteReuseStrategy } from '@angular/router' import { HttpClientModule } from '@angular/common/http' -import { TuiRootModule } from '@taiga-ui/core' +import { TuiAlertModule, TuiRootModule } from '@taiga-ui/core' import { ApiService } from './services/api/api.service' import { MockApiService } from './services/api/mock-api.service' import { LiveApiService } from './services/api/live-api.service' @@ -41,6 +41,7 @@ const { RecoverPageModule, TransferPageModule, TuiRootModule, + TuiAlertModule, ], providers: [ { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, diff --git a/web/projects/setup-wizard/src/app/pages/attach/attach.page.ts b/web/projects/setup-wizard/src/app/pages/attach/attach.page.ts index b4d6eb9f9..3b8323798 100644 --- a/web/projects/setup-wizard/src/app/pages/attach/attach.page.ts +++ b/web/projects/setup-wizard/src/app/pages/attach/attach.page.ts @@ -4,10 +4,10 @@ import { ModalController, NavController, } from '@ionic/angular' -import { ApiService } from 'src/app/services/api/api.service' -import { DiskInfo, ErrorToastService } from '@start9labs/shared' -import { StateService } from 'src/app/services/state.service' +import { DiskInfo, ErrorService } from '@start9labs/shared' import { PasswordPage } from 'src/app/modals/password/password.page' +import { ApiService } from 'src/app/services/api/api.service' +import { StateService } from 'src/app/services/state.service' @Component({ selector: 'app-attach', @@ -21,7 +21,7 @@ export class AttachPage { constructor( private readonly apiService: ApiService, private readonly navCtrl: NavController, - private readonly errToastService: ErrorToastService, + private readonly errorService: ErrorService, private readonly stateService: StateService, private readonly modalCtrl: ModalController, private readonly loadingCtrl: LoadingController, @@ -41,7 +41,7 @@ export class AttachPage { try { this.drives = await this.apiService.getDrives() } catch (e: any) { - this.errToastService.present(e) + this.errorService.handleError(e) } finally { this.loading = false } @@ -70,7 +70,7 @@ export class AttachPage { await this.stateService.importDrive(guid, password) await this.navCtrl.navigateForward(`/loading`) } catch (e: any) { - this.errToastService.present(e) + this.errorService.handleError(e) } finally { loader.dismiss() } diff --git a/web/projects/setup-wizard/src/app/pages/embassy/embassy.page.ts b/web/projects/setup-wizard/src/app/pages/embassy/embassy.page.ts index 7f7ee6241..110768be5 100644 --- a/web/projects/setup-wizard/src/app/pages/embassy/embassy.page.ts +++ b/web/projects/setup-wizard/src/app/pages/embassy/embassy.page.ts @@ -5,8 +5,8 @@ import { ModalController, NavController, } from '@ionic/angular' +import { DiskInfo, ErrorService, GuidPipe } from '@start9labs/shared' import { ApiService } from 'src/app/services/api/api.service' -import { DiskInfo, ErrorToastService, GuidPipe } from '@start9labs/shared' import { StateService } from 'src/app/services/state.service' import { PasswordPage } from '../../modals/password/password.page' @@ -27,7 +27,7 @@ export class EmbassyPage { private readonly alertCtrl: AlertController, private readonly stateService: StateService, private readonly loadingCtrl: LoadingController, - private readonly errorToastService: ErrorToastService, + private readonly errorService: ErrorService, private readonly guidPipe: GuidPipe, ) {} @@ -71,7 +71,7 @@ export class EmbassyPage { }) } } catch (e: any) { - this.errorToastService.present(e) + this.errorService.handleError(e) } finally { this.loading = false } @@ -148,7 +148,7 @@ export class EmbassyPage { await this.stateService.setupEmbassy(logicalname, password) await this.navCtrl.navigateForward(`/loading`) } catch (e: any) { - this.errorToastService.present(e) + this.errorService.handleError(e) } finally { loader.dismiss() } diff --git a/web/projects/setup-wizard/src/app/pages/home/home.page.ts b/web/projects/setup-wizard/src/app/pages/home/home.page.ts index c0e93d18a..f3d165940 100644 --- a/web/projects/setup-wizard/src/app/pages/home/home.page.ts +++ b/web/projects/setup-wizard/src/app/pages/home/home.page.ts @@ -1,9 +1,9 @@ import { Component } from '@angular/core' import { IonicSlides } from '@ionic/angular' +import { ErrorService } from '@start9labs/shared' import { ApiService } from 'src/app/services/api/api.service' -import SwiperCore, { Swiper } from 'swiper' -import { ErrorToastService } from '@start9labs/shared' import { StateService } from 'src/app/services/state.service' +import SwiperCore, { Swiper } from 'swiper' SwiperCore.use([IonicSlides]) @@ -19,7 +19,7 @@ export class HomePage { constructor( private readonly api: ApiService, - private readonly errToastService: ErrorToastService, + private readonly errorService: ErrorService, private readonly stateService: StateService, ) {} @@ -33,7 +33,7 @@ export class HomePage { await this.api.getPubKey() } catch (e: any) { this.error = true - this.errToastService.present(e) + this.errorService.handleError(e) } finally { this.loading = false } diff --git a/web/projects/setup-wizard/src/app/pages/loading/loading.module.ts b/web/projects/setup-wizard/src/app/pages/loading/loading.module.ts index 2f3507941..498620697 100644 --- a/web/projects/setup-wizard/src/app/pages/loading/loading.module.ts +++ b/web/projects/setup-wizard/src/app/pages/loading/loading.module.ts @@ -1,12 +1,17 @@ import { NgModule } from '@angular/core' import { CommonModule } from '@angular/common' -import { IonicModule } from '@ionic/angular' -import { FormsModule } from '@angular/forms' +import { TuiProgressModule } from '@taiga-ui/kit' import { LoadingPage } from './loading.page' import { LoadingPageRoutingModule } from './loading-routing.module' +import { IonicModule } from '@ionic/angular' @NgModule({ - imports: [CommonModule, FormsModule, IonicModule, LoadingPageRoutingModule], + imports: [ + CommonModule, + IonicModule, + TuiProgressModule, + LoadingPageRoutingModule, + ], declarations: [LoadingPage], }) export class LoadingPageModule {} diff --git a/web/projects/setup-wizard/src/app/pages/loading/loading.page.html b/web/projects/setup-wizard/src/app/pages/loading/loading.page.html index 6c9ca41ab..94a666223 100644 --- a/web/projects/setup-wizard/src/app/pages/loading/loading.page.html +++ b/web/projects/setup-wizard/src/app/pages/loading/loading.page.html @@ -1,17 +1,23 @@ -
-

- Setting up your server -

-
- Progress: {{ (progress.total * 100).toFixed(0) }}% -
- - -

{{ progress.message }}

-
+ + + + +
+

+ Setting up your server +

+
+ Progress: {{ (progress.total * 100).toFixed(0) }}% +
+ +

{{ progress.message }}

+
+
+
+
+
diff --git a/web/projects/setup-wizard/src/app/pages/loading/loading.page.scss b/web/projects/setup-wizard/src/app/pages/loading/loading.page.scss index e69de29bb..099f7084e 100644 --- a/web/projects/setup-wizard/src/app/pages/loading/loading.page.scss +++ b/web/projects/setup-wizard/src/app/pages/loading/loading.page.scss @@ -0,0 +1,9 @@ +section { + border-radius: 0.25rem; + padding: 3rem; + margin: 2rem; + text-align: center; + background: #e0e0e0; + color: #333; + --tui-clear-inverse: rgba(0, 0, 0, 0.1); +} \ No newline at end of file diff --git a/web/projects/setup-wizard/src/app/pages/loading/loading.page.ts b/web/projects/setup-wizard/src/app/pages/loading/loading.page.ts index 459be5c7a..2386c09ec 100644 --- a/web/projects/setup-wizard/src/app/pages/loading/loading.page.ts +++ b/web/projects/setup-wizard/src/app/pages/loading/loading.page.ts @@ -1,14 +1,15 @@ import { Component } from '@angular/core' import { NavController } from '@ionic/angular' -import { Pipe, PipeTransform } from '@angular/core' +import { ErrorService } from '@start9labs/shared' +import { T } from '@start9labs/start-sdk' import { - EMPTY, - Observable, catchError, + EMPTY, filter, from, interval, map, + Observable, of, startWith, switchMap, @@ -16,8 +17,6 @@ import { tap, } from 'rxjs' import { ApiService } from 'src/app/services/api/api.service' -import { ErrorToastService } from '@start9labs/shared' -import { T } from '@start9labs/start-sdk' @Component({ selector: 'app-loading', @@ -69,7 +68,7 @@ export class LoadingPage { constructor( private readonly navCtrl: NavController, private readonly api: ApiService, - private readonly errorToastService: ErrorToastService, + private readonly errorService: ErrorService, ) {} private async getStatus(): Promise<{ @@ -96,7 +95,7 @@ export class LoadingPage { return from(this.getStatus()).pipe( filter(Boolean), catchError(e => { - this.errorToastService.present(e) + this.errorService.handleError(e) return of(e) }), take(1), diff --git a/web/projects/setup-wizard/src/app/pages/recover/recover.page.ts b/web/projects/setup-wizard/src/app/pages/recover/recover.page.ts index f9e5adbb1..d47105f24 100644 --- a/web/projects/setup-wizard/src/app/pages/recover/recover.page.ts +++ b/web/projects/setup-wizard/src/app/pages/recover/recover.page.ts @@ -1,8 +1,8 @@ import { Component, Input } from '@angular/core' import { ModalController, NavController } from '@ionic/angular' +import { ErrorService } from '@start9labs/shared' import { CifsModal } from 'src/app/modals/cifs-modal/cifs-modal.page' import { ApiService, DiskBackupTarget } from 'src/app/services/api/api.service' -import { ErrorToastService } from '@start9labs/shared' import { StateService } from 'src/app/services/state.service' import { PasswordPage } from '../../modals/password/password.page' @@ -20,7 +20,7 @@ export class RecoverPage { private readonly navCtrl: NavController, private readonly modalCtrl: ModalController, private readonly modalController: ModalController, - private readonly errToastService: ErrorToastService, + private readonly errorService: ErrorService, private readonly stateService: StateService, ) {} @@ -62,7 +62,7 @@ export class RecoverPage { }) }) } catch (e: any) { - this.errToastService.present(e) + this.errorService.handleError(e) } finally { this.loading = false } diff --git a/web/projects/setup-wizard/src/app/pages/success/success.page.ts b/web/projects/setup-wizard/src/app/pages/success/success.page.ts index 71566580a..88262bdf2 100644 --- a/web/projects/setup-wizard/src/app/pages/success/success.page.ts +++ b/web/projects/setup-wizard/src/app/pages/success/success.page.ts @@ -1,6 +1,6 @@ import { DOCUMENT } from '@angular/common' import { Component, ElementRef, Inject, NgZone, ViewChild } from '@angular/core' -import { DownloadHTMLService, ErrorToastService } from '@start9labs/shared' +import { DownloadHTMLService, ErrorService } from '@start9labs/shared' import { ApiService } from 'src/app/services/api/api.service' import { StateService } from 'src/app/services/state.service' @@ -12,7 +12,8 @@ import { StateService } from 'src/app/services/state.service' }) export class SuccessPage { @ViewChild('canvas', { static: true }) - private canvas: ElementRef = {} as ElementRef + private canvas: ElementRef = + {} as ElementRef private ctx: CanvasRenderingContext2D = {} as CanvasRenderingContext2D torAddress?: string @@ -28,7 +29,7 @@ export class SuccessPage { constructor( @Inject(DOCUMENT) private readonly document: Document, - private readonly errCtrl: ErrorToastService, + private readonly errorService: ErrorService, private readonly stateService: StateService, private readonly api: ApiService, private readonly downloadHtml: DownloadHTMLService, @@ -83,7 +84,7 @@ export class SuccessPage { await this.api.exit() } } catch (e: any) { - await this.errCtrl.present(e) + await this.errorService.handleError(e) } } diff --git a/web/projects/setup-wizard/src/app/pages/transfer/transfer.page.ts b/web/projects/setup-wizard/src/app/pages/transfer/transfer.page.ts index 5de21a289..5034a2272 100644 --- a/web/projects/setup-wizard/src/app/pages/transfer/transfer.page.ts +++ b/web/projects/setup-wizard/src/app/pages/transfer/transfer.page.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core' import { AlertController, NavController } from '@ionic/angular' +import { DiskInfo, ErrorService } from '@start9labs/shared' import { ApiService } from 'src/app/services/api/api.service' -import { DiskInfo, ErrorToastService } from '@start9labs/shared' import { StateService } from 'src/app/services/state.service' @Component({ @@ -17,7 +17,7 @@ export class TransferPage { private readonly apiService: ApiService, private readonly navCtrl: NavController, private readonly alertCtrl: AlertController, - private readonly errToastService: ErrorToastService, + private readonly errorService: ErrorService, private readonly stateService: StateService, ) {} @@ -35,7 +35,7 @@ export class TransferPage { try { this.drives = await this.apiService.getDrives() } catch (e: any) { - this.errToastService.present(e) + this.errorService.handleError(e) } finally { this.loading = false } diff --git a/web/projects/shared/assets/img/icon_transparent.png b/web/projects/shared/assets/img/icon_transparent.png new file mode 100644 index 000000000..f0aafd15d Binary files /dev/null and b/web/projects/shared/assets/img/icon_transparent.png differ diff --git a/web/projects/shared/assets/img/storefront-outline.png b/web/projects/shared/assets/img/storefront-outline.png new file mode 100644 index 000000000..aa7bd4404 Binary files /dev/null and b/web/projects/shared/assets/img/storefront-outline.png differ diff --git a/web/projects/shared/assets/taiga-ui/icons/tuiIconPaintOutline.svg b/web/projects/shared/assets/taiga-ui/icons/tuiIconPaintOutline.svg new file mode 100644 index 000000000..55450c05c --- /dev/null +++ b/web/projects/shared/assets/taiga-ui/icons/tuiIconPaintOutline.svg @@ -0,0 +1,10 @@ + + + diff --git a/web/projects/shared/src/components/loading/loading.component.scss b/web/projects/shared/src/components/loading/loading.component.scss new file mode 100644 index 000000000..9a7d10100 --- /dev/null +++ b/web/projects/shared/src/components/loading/loading.component.scss @@ -0,0 +1,20 @@ +@import '@taiga-ui/core/styles/taiga-ui-local'; + +:host { + @include shadow(3); + + display: flex; + align-items: center; + max-width: 80%; + margin: auto; + padding: 1.5rem; + background: var(--tui-elevation-01); + border-radius: var(--tui-radius-m); + + --tui-primary: var(--tui-warning-fill); +} + +tui-loader { + flex-shrink: 0; + min-width: 2rem; +} diff --git a/web/projects/shared/src/components/loading/loading.component.ts b/web/projects/shared/src/components/loading/loading.component.ts new file mode 100644 index 000000000..373f013a1 --- /dev/null +++ b/web/projects/shared/src/components/loading/loading.component.ts @@ -0,0 +1,17 @@ +import { ChangeDetectionStrategy, Component, inject } from '@angular/core' +import { + POLYMORPHEUS_CONTEXT, + PolymorpheusContent, +} from '@tinkoff/ng-polymorpheus' + +@Component({ + template: ` + + `, + styleUrls: ['./loading.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class LoadingComponent { + readonly content: PolymorpheusContent = + inject(POLYMORPHEUS_CONTEXT)['content'] +} diff --git a/web/projects/shared/src/components/loading/loading.module.ts b/web/projects/shared/src/components/loading/loading.module.ts new file mode 100644 index 000000000..4a3798041 --- /dev/null +++ b/web/projects/shared/src/components/loading/loading.module.ts @@ -0,0 +1,13 @@ +import { NgModule } from '@angular/core' +import { TuiLoaderModule } from '@taiga-ui/core' +import { tuiAsDialog } from '@taiga-ui/cdk' +import { LoadingComponent } from './loading.component' +import { LoadingService } from './loading.service' + +@NgModule({ + imports: [TuiLoaderModule], + declarations: [LoadingComponent], + exports: [LoadingComponent], + providers: [tuiAsDialog(LoadingService)], +}) +export class LoadingModule {} diff --git a/web/projects/shared/src/components/loading/loading.service.ts b/web/projects/shared/src/components/loading/loading.service.ts new file mode 100644 index 000000000..96ab4301f --- /dev/null +++ b/web/projects/shared/src/components/loading/loading.service.ts @@ -0,0 +1,10 @@ +import { Injectable } from '@angular/core' +import { AbstractTuiDialogService } from '@taiga-ui/cdk' +import { PolymorpheusComponent } from '@tinkoff/ng-polymorpheus' +import { LoadingComponent } from './loading.component' + +@Injectable({ providedIn: `root` }) +export class LoadingService extends AbstractTuiDialogService { + protected readonly component = new PolymorpheusComponent(LoadingComponent) + protected readonly defaultOptions = {} +} diff --git a/web/projects/shared/src/components/markdown/markdown.component.ts b/web/projects/shared/src/components/markdown/markdown.component.ts index d560f7537..e3f350e4a 100644 --- a/web/projects/shared/src/components/markdown/markdown.component.ts +++ b/web/projects/shared/src/components/markdown/markdown.component.ts @@ -3,7 +3,7 @@ import { ModalController } from '@ionic/angular' import { defer, isObservable, Observable, of } from 'rxjs' import { catchError, ignoreElements, share } from 'rxjs/operators' -import { getErrorMessage } from '../../services/error-toast.service' +import { getErrorMessage } from '../../services/error.service' @Component({ selector: 'markdown', diff --git a/web/projects/shared/src/public-api.ts b/web/projects/shared/src/public-api.ts index 7b1cd71b8..c83fef860 100644 --- a/web/projects/shared/src/public-api.ts +++ b/web/projects/shared/src/public-api.ts @@ -9,6 +9,9 @@ export * from './components/alert/alert.component' export * from './components/alert/alert.module' export * from './components/alert/alert-button.directive' export * from './components/alert/alert-input.directive' +export * from './components/loading/loading.component' +export * from './components/loading/loading.module' +export * from './components/loading/loading.service' export * from './components/markdown/markdown.component' export * from './components/markdown/markdown.component.module' export * from './components/text-spinner/text-spinner.component' @@ -42,7 +45,7 @@ export * from './pipes/unit-conversion/unit-conversion.pipe' export * from './services/download-html.service' export * from './services/emver.service' -export * from './services/error-toast.service' +export * from './services/error.service' export * from './services/http.service' export * from './themes/dark-theme/dark-theme.component' @@ -63,6 +66,7 @@ export * from './util/base-64' export * from './util/copy-to-clipboard' export * from './util/get-new-entries' export * from './util/get-pkg-id' +export * from './util/invert' export * from './util/misc.util' export * from './util/rpc.util' export * from './util/to-local-iso-string' diff --git a/web/projects/shared/src/services/error-toast.service.ts b/web/projects/shared/src/services/error-toast.service.ts deleted file mode 100644 index fe6607995..000000000 --- a/web/projects/shared/src/services/error-toast.service.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Injectable } from '@angular/core' -import { IonicSafeString, ToastController } from '@ionic/angular' -import { HttpError } from '../classes/http-error' - -@Injectable({ - providedIn: 'root', -}) -export class ErrorToastService { - private toast?: HTMLIonToastElement - - constructor(private readonly toastCtrl: ToastController) {} - - async present(e: HttpError | string, link?: string): Promise { - console.error(e) - - if (this.toast) return - - this.toast = await this.toastCtrl.create({ - header: 'Error', - message: getErrorMessage(e, link), - duration: 0, - position: 'top', - cssClass: 'error-toast', - buttons: [ - { - side: 'end', - icon: 'close', - handler: () => { - this.dismiss() - }, - }, - ], - }) - await this.toast.present() - } - - async dismiss(): Promise { - if (this.toast) { - await this.toast.dismiss() - this.toast = undefined - } - } -} - -export function getErrorMessage( - e: HttpError | string, - link?: string, -): string | IonicSafeString { - let message = '' - - if (typeof e === 'string') { - message = e - } else if (e.code === 0) { - message = - 'Request Error. Your browser blocked the request. This is usually caused by a corrupt browser cache or an overly aggressive ad blocker. Please clear your browser cache and/or adjust your ad blocker and try again' - link = 'https://docs.start9.com/0.3.5.x/support/common-issues#request-error' - } else if (!e.message) { - message = 'Unknown Error' - } else { - message = e.message - } - - if (link) { - return new IonicSafeString( - `${message}

Get Help`, - ) - } - - return message -} diff --git a/web/projects/shared/src/services/error.service.ts b/web/projects/shared/src/services/error.service.ts new file mode 100644 index 000000000..45891e0f4 --- /dev/null +++ b/web/projects/shared/src/services/error.service.ts @@ -0,0 +1,43 @@ +import { ErrorHandler, inject, Injectable } from '@angular/core' +import { TuiAlertService, TuiNotification } from '@taiga-ui/core' +import { HttpError } from '../classes/http-error' + +// TODO: Enable this as ErrorHandler +@Injectable({ + providedIn: 'root', +}) +export class ErrorService extends ErrorHandler { + private readonly alerts = inject(TuiAlertService) + + override handleError(error: HttpError | string, link?: string) { + console.error(error) + + this.alerts + .open(getErrorMessage(error, link), { + label: 'Error', + autoClose: false, + status: TuiNotification.Error, + }) + .subscribe() + } +} + +export function getErrorMessage(e: HttpError | string, link?: string): string { + let message = '' + + if (typeof e === 'string') { + message = e + } else if (e.code === 0) { + message = + 'Request Error. Your browser blocked the request. This is usually caused by a corrupt browser cache or an overly aggressive ad blocker. Please clear your browser cache and/or adjust your ad blocker and try again' + } else if (!e.message) { + message = 'Unknown Error' + link = 'https://docs.start9.com/latest/support/faq' + } else { + message = e.message + } + + return link + ? `${message}

Get Help` + : message +} diff --git a/web/projects/shared/src/util/invert.ts b/web/projects/shared/src/util/invert.ts new file mode 100644 index 000000000..6931b3660 --- /dev/null +++ b/web/projects/shared/src/util/invert.ts @@ -0,0 +1,12 @@ +export function invert< + T extends string | number | symbol, + D extends string | number | symbol, +>(obj: Record): Record { + const result = {} as Record + + for (const key in obj) { + result[obj[key]] = key + } + + return result +} diff --git a/web/projects/ui/src/app/app.module.ts b/web/projects/ui/src/app/app.module.ts index c0264f064..048d81fe0 100644 --- a/web/projects/ui/src/app/app.module.ts +++ b/web/projects/ui/src/app/app.module.ts @@ -14,6 +14,7 @@ import { DarkThemeModule, EnterModule, LightThemeModule, + LoadingModule, MarkdownModule, ResponsiveColModule, SharedPipesModule, @@ -22,13 +23,11 @@ import { import { AppComponent } from './app.component' import { AppRoutingModule } from './app-routing.module' import { OSWelcomePageModule } from './modals/os-welcome/os-welcome.module' -import { GenericInputComponentModule } from './modals/generic-input/generic-input.component.module' import { MarketplaceModule } from './marketplace.module' import { PreloaderModule } from './app/preloader/preloader.module' import { FooterModule } from './app/footer/footer.module' import { MenuModule } from './app/menu/menu.module' import { APP_PROVIDERS } from './app.providers' -import { PatchDbModule } from './services/patch-db/patch-db.module' import { ToastContainerModule } from './components/toast-container/toast-container.module' import { ConnectionBarComponentModule } from './components/connection-bar/connection-bar.component.module' import { WidgetsPageModule } from './pages/widgets/widgets.module' @@ -50,11 +49,10 @@ import { environment } from '../environments/environment' EnterModule, OSWelcomePageModule, MarkdownModule, - GenericInputComponentModule, + LoadingModule, MonacoEditorModule, SharedPipesModule, MarketplaceModule, - PatchDbModule, ToastContainerModule, ConnectionBarComponentModule, TuiRootModule, diff --git a/web/projects/ui/src/app/app.providers.ts b/web/projects/ui/src/app/app.providers.ts index bf26a8cb9..00ff64690 100644 --- a/web/projects/ui/src/app/app.providers.ts +++ b/web/projects/ui/src/app/app.providers.ts @@ -3,6 +3,12 @@ import { UntypedFormBuilder } from '@angular/forms' import { Router, RouteReuseStrategy } from '@angular/router' import { IonicRouteStrategy, IonNav } from '@ionic/angular' import { RELATIVE_URL, THEME, WorkspaceConfig } from '@start9labs/shared' +import { TUI_ICONS_PATH } from '@taiga-ui/core' +import { PatchDB } from 'patch-db-client' +import { + PATCH_CACHE, + PatchDbSource, +} from 'src/app/services/patch-db/patch-db-source' import { ApiService } from './services/api/embassy-api.service' import { MockApiService } from './services/api/embassy-mock-api.service' import { LiveApiService } from './services/api/embassy-live-api.service' @@ -29,6 +35,11 @@ export const APP_PROVIDERS: Provider[] = [ provide: ApiService, useClass: useMocks ? MockApiService : LiveApiService, }, + { + provide: PatchDB, + deps: [PatchDbSource, PATCH_CACHE], + useClass: PatchDB, + }, { provide: APP_INITIALIZER, deps: [StorageService, AuthService, ClientStorageService, Router], @@ -43,6 +54,10 @@ export const APP_PROVIDERS: Provider[] = [ provide: THEME, useExisting: ThemeSwitcherService, }, + { + provide: TUI_ICONS_PATH, + useValue: (name: string) => `/assets/taiga-ui/icons/${name}.svg#${name}`, + }, ] export function appInitializer( @@ -54,7 +69,7 @@ export function appInitializer( return () => { storage.migrate036() auth.init() - localStorage.init() // @TODO pretty sure we can navigate before this step + localStorage.init() router.initialNavigation() } } diff --git a/web/projects/ui/src/app/app/preloader/preloader.component.html b/web/projects/ui/src/app/app/preloader/preloader.component.html index 94d6d7107..82923250e 100644 --- a/web/projects/ui/src/app/app/preloader/preloader.component.html +++ b/web/projects/ui/src/app/app/preloader/preloader.component.html @@ -8,8 +8,6 @@ - - @@ -19,14 +17,11 @@ - - - - - - - - - load bold font - - @@ -66,10 +53,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-

a

a

a

diff --git a/web/projects/ui/src/app/app/preloader/preloader.component.ts b/web/projects/ui/src/app/app/preloader/preloader.component.ts index 0b387ac45..f7184008e 100644 --- a/web/projects/ui/src/app/app/preloader/preloader.component.ts +++ b/web/projects/ui/src/app/app/preloader/preloader.component.ts @@ -1,4 +1,10 @@ import { ChangeDetectionStrategy, Component } from '@angular/core' +import { + ActionSheetController, + AlertController, + ModalController, + ToastController, +} from '@ionic/angular' // TODO: Turn into DI token if this is needed someplace else too const ICONS = [ @@ -88,6 +94,26 @@ const ICONS = [ 'wifi', ] +const TAIGA = [ + 'tuiIconPaintOutline', + 'tuiIconTrash', + 'tuiIconTrashOutline', + 'tuiIconChevronDown', + 'tuiIconChevronDownOutline', + 'tuiIconRefreshCcw', + 'tuiIconRefreshCcwOutline', + 'tuiIconEye', + 'tuiIconEyeOutline', + 'tuiIconEyeOff', + 'tuiIconEyeOffOutline', + 'tuiIconPlus', + 'tuiIconMinus', + 'tuiIconCheck', + 'tuiIconClose', + 'tuiIconCalendarLarge', + 'tuiIconHelpCircle', +] + @Component({ selector: 'section[appPreloader]', templateUrl: 'preloader.component.html', @@ -95,4 +121,12 @@ const ICONS = [ }) export class PreloaderComponent { readonly icons = ICONS + readonly taiga = TAIGA + + constructor( + _modals: ModalController, + _alerts: AlertController, + _toasts: ToastController, + _actions: ActionSheetController, + ) {} } diff --git a/web/projects/ui/src/app/app/preloader/preloader.module.ts b/web/projects/ui/src/app/app/preloader/preloader.module.ts index b1496e638..380b70f3a 100644 --- a/web/projects/ui/src/app/app/preloader/preloader.module.ts +++ b/web/projects/ui/src/app/app/preloader/preloader.module.ts @@ -1,11 +1,65 @@ import { CommonModule } from '@angular/common' import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core' import { IonicModule } from '@ionic/angular' +import { + TuiErrorModule, + TuiExpandModule, + TuiLinkModule, + TuiScrollbarModule, + TuiSvgModule, + TuiTooltipModule, +} from '@taiga-ui/core' +import { + TuiButtonModule, + TuiCellModule, + TuiIconModule, +} from '@taiga-ui/experimental' +import { + TuiElasticContainerModule, + TuiInputDateModule, + TuiInputDateTimeModule, + TuiInputFilesModule, + TuiInputModule, + TuiInputNumberModule, + TuiInputTimeModule, + TuiMultiSelectModule, + TuiProgressModule, + TuiRadioListModule, + TuiSelectModule, + TuiTextAreaModule, + TuiToggleModule, +} from '@taiga-ui/kit' import { QrCodeModule } from 'ng-qrcode' import { PreloaderComponent } from './preloader.component' @NgModule({ - imports: [CommonModule, IonicModule, QrCodeModule], + imports: [ + CommonModule, + IonicModule, + QrCodeModule, + TuiTooltipModule, + TuiErrorModule, + TuiInputModule, + TuiSvgModule, + TuiIconModule, + TuiButtonModule, + TuiLinkModule, + TuiInputTimeModule, + TuiInputDateModule, + TuiInputDateTimeModule, + TuiInputFilesModule, + TuiMultiSelectModule, + TuiInputNumberModule, + TuiExpandModule, + TuiSelectModule, + TuiTextAreaModule, + TuiToggleModule, + TuiElasticContainerModule, + TuiCellModule, + TuiProgressModule, + TuiScrollbarModule, + TuiRadioListModule, + ], declarations: [PreloaderComponent], exports: [PreloaderComponent], schemas: [CUSTOM_ELEMENTS_SCHEMA], diff --git a/web/projects/ui/src/app/app/snek/snek.directive.ts b/web/projects/ui/src/app/app/snek/snek.directive.ts index 255926792..3e3ad5dc3 100644 --- a/web/projects/ui/src/app/app/snek/snek.directive.ts +++ b/web/projects/ui/src/app/app/snek/snek.directive.ts @@ -1,6 +1,6 @@ import { Directive, HostListener, Input } from '@angular/core' -import { LoadingController, ModalController } from '@ionic/angular' -import { ErrorToastService } from '@start9labs/shared' +import { ModalController } from '@ionic/angular' +import { ErrorService, LoadingService } from '@start9labs/shared' import { SnakePage } from '../../modals/snake/snake.page' import { ApiService } from '../../services/api/embassy-api.service' @@ -13,8 +13,8 @@ export class SnekDirective { constructor( private readonly modalCtrl: ModalController, - private readonly loadingCtrl: LoadingController, - private readonly errToast: ErrorToastService, + private readonly loader: LoadingService, + private readonly errorService: ErrorService, private readonly embassyApi: ApiService, ) {} @@ -30,22 +30,17 @@ export class SnekDirective { modal.onDidDismiss().then(async ({ data }) => { if (data?.highScore <= (this.appSnekHighScore || 0)) return - const loader = await this.loadingCtrl.create({ - message: 'Saving high score...', - backdropDismiss: true, - }) - - await loader.present() + const loader = this.loader.open('Saving high score...').subscribe() try { await this.embassyApi.setDbValue( - ['gaming', 'snake', 'high-score'], + ['gaming', 'snake', 'highScore'], data.highScore, ) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - this.loadingCtrl.dismiss() + this.loader.subscribe() } }) diff --git a/web/projects/ui/src/app/components/backup-drives/backup-drives.component.module.ts b/web/projects/ui/src/app/components/backup-drives/backup-drives.component.module.ts index bf7f844e3..60c37d08d 100644 --- a/web/projects/ui/src/app/components/backup-drives/backup-drives.component.module.ts +++ b/web/projects/ui/src/app/components/backup-drives/backup-drives.component.module.ts @@ -10,7 +10,6 @@ import { UnitConversionPipesModule, TextSpinnerComponentModule, } from '@start9labs/shared' -import { GenericFormPageModule } from 'src/app/modals/generic-form/generic-form.module' @NgModule({ declarations: [ @@ -23,7 +22,6 @@ import { GenericFormPageModule } from 'src/app/modals/generic-form/generic-form. IonicModule, UnitConversionPipesModule, TextSpinnerComponentModule, - GenericFormPageModule, ], exports: [ BackupDrivesComponent, diff --git a/web/projects/ui/src/app/components/backup-drives/backup-drives.component.ts b/web/projects/ui/src/app/components/backup-drives/backup-drives.component.ts index fa73b8452..5613ae153 100644 --- a/web/projects/ui/src/app/components/backup-drives/backup-drives.component.ts +++ b/web/projects/ui/src/app/components/backup-drives/backup-drives.component.ts @@ -1,21 +1,18 @@ import { Component, EventEmitter, Input, Output } from '@angular/core' -import { BackupService } from './backup.service' +import { ActionSheetController, AlertController } from '@ionic/angular' +import { ErrorService, LoadingService } from '@start9labs/shared' +import { CB } from '@start9labs/start-sdk' import { CifsBackupTarget, DiskBackupTarget, RR, } from 'src/app/services/api/api.types' -import { - ActionSheetController, - AlertController, - LoadingController, - ModalController, -} from '@ionic/angular' -import { GenericFormPage } from 'src/app/modals/generic-form/generic-form.page' -import { ConfigSpec } from 'src/app/pkg-config/config-types' import { ApiService } from 'src/app/services/api/embassy-api.service' -import { ErrorToastService } from '@start9labs/shared' +import { FormDialogService } from 'src/app/services/form-dialog.service' import { MappedBackupTarget } from 'src/app/types/mapped-backup-target' +import { configBuilderToSpec } from 'src/app/util/configBuilderToSpec' +import { FormComponent } from '../form.component' +import { BackupService } from './backup.service' type BackupType = 'create' | 'restore' @@ -32,13 +29,13 @@ export class BackupDrivesComponent { loadingText = '' constructor( - private readonly loadingCtrl: LoadingController, + private readonly loader: LoadingService, private readonly actionCtrl: ActionSheetController, private readonly alertCtrl: AlertController, - private readonly modalCtrl: ModalController, private readonly embassyApi: ApiService, - private readonly errToast: ErrorToastService, + private readonly errorService: ErrorService, private readonly backupService: BackupService, + private readonly formDialog: FormDialogService, ) {} get loading() { @@ -87,23 +84,19 @@ export class BackupDrivesComponent { } async presentModalAddCifs(): Promise { - const modal = await this.modalCtrl.create({ - component: GenericFormPage, - componentProps: { - title: 'New Network Folder', - spec: CifsSpec, + this.formDialog.open(FormComponent, { + label: 'New Network Folder', + data: { + spec: await configBuilderToSpec(cifsSpec), buttons: [ { - text: 'Connect', - handler: (value: RR.AddBackupTargetReq) => { - return this.addCifs(value) - }, - isSubmit: true, + text: 'Execute', + handler: async (value: RR.AddBackupTargetReq) => + this.addCifs(value), }, ], }, }) - await modal.present() } async presentActionCifs( @@ -151,10 +144,9 @@ export class BackupDrivesComponent { } private async addCifs(value: RR.AddBackupTargetReq): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Testing connectivity to shared folder...', - }) - await loader.present() + const loader = this.loader + .open('Testing connectivity to shared folder...') + .subscribe() try { const res = await this.embassyApi.addBackupTarget(value) @@ -166,10 +158,10 @@ export class BackupDrivesComponent { }) return true } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) return false } finally { - loader.dismiss() + loader.unsubscribe() } } @@ -180,62 +172,57 @@ export class BackupDrivesComponent { ): Promise { const { hostname, path, username } = entry - const modal = await this.modalCtrl.create({ - component: GenericFormPage, - componentProps: { - title: 'Update Shared Folder', - spec: CifsSpec, + this.formDialog.open(FormComponent, { + label: 'Update Network Folder', + data: { + spec: await configBuilderToSpec(cifsSpec), buttons: [ { - text: 'Save', - handler: (value: RR.AddBackupTargetReq) => { - return this.editCifs({ id, ...value }, index) - }, - isSubmit: true, + text: 'Execute', + handler: async (value: RR.AddBackupTargetReq) => + this.editCifs({ id, ...value }, index), }, ], - initialValue: { + value: { hostname, path, username, }, }, }) - await modal.present() } private async editCifs( value: RR.UpdateBackupTargetReq, index: number, - ): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Testing connectivity to shared folder...', - }) - await loader.present() + ): Promise { + const loader = this.loader + .open('Testing connectivity to shared folder...') + .subscribe() try { const res = await this.embassyApi.updateBackupTarget(value) this.backupService.cifs[index].entry = Object.values(res)[0] + + return true } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) + return false } finally { - loader.dismiss() + loader.unsubscribe() } } private async deleteCifs(id: string, index: number): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Removing...', - }) - await loader.present() + const loader = this.loader.open('Removing...').subscribe() try { await this.embassyApi.removeBackupTarget({ id }) this.backupService.cifs.splice(index, 1) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } @@ -274,40 +261,33 @@ export class BackupDrivesStatusComponent { @Input() hasValidBackup!: boolean } -const CifsSpec: ConfigSpec = { - hostname: { - type: 'string', - name: 'Hostname/IP', +const cifsSpec = CB.Config.of({ + hostname: CB.Value.text({ + name: 'Hostname', description: - 'The hostname or IP address of the target device on your Local Area Network.', - placeholder: `e.g. 'MyComputer.local' OR '192.168.1.4'`, - nullable: false, - masked: false, - copyable: false, - }, - path: { - type: 'string', + 'The hostname of your target device on the Local Area Network.', + warning: null, + placeholder: `e.g. 'My Computer' OR 'my-computer.local'`, + required: { default: null }, + patterns: [], + }), + path: CB.Value.text({ name: 'Path', description: `On Windows, this is the fully qualified path to the shared folder, (e.g. /Desktop/my-folder).\n\n On Linux and Mac, this is the literal name of the shared folder (e.g. my-shared-folder).`, placeholder: 'e.g. my-shared-folder or /Desktop/my-folder', - nullable: false, - masked: false, - copyable: false, - }, - username: { - type: 'string', + required: { default: null }, + }), + username: CB.Value.text({ name: 'Username', description: `On Linux, this is the samba username you created when sharing the folder.\n\n On Mac and Windows, this is the username of the user who is sharing the folder.`, - nullable: false, - masked: false, - copyable: false, - }, - password: { - type: 'string', + required: { default: null }, + placeholder: 'My Network Folder', + }), + password: CB.Value.text({ name: 'Password', description: `On Linux, this is the samba password you created when sharing the folder.\n\n On Mac and Windows, this is the password of the user who is sharing the folder.`, - nullable: true, + required: false, masked: true, - copyable: false, - }, -} + placeholder: 'My Network Folder', + }), +}) diff --git a/web/projects/ui/src/app/components/form-object/form-label.component.html b/web/projects/ui/src/app/components/form-object/form-label.component.html deleted file mode 100644 index 69c29f99d..000000000 --- a/web/projects/ui/src/app/components/form-object/form-label.component.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - -{{ data.name }} - - (New) - (New Options) - (Edited) - - * diff --git a/web/projects/ui/src/app/components/form-object/form-object.component.html b/web/projects/ui/src/app/components/form-object/form-object.component.html deleted file mode 100644 index 8bbfc5c78..000000000 --- a/web/projects/ui/src/app/components/form-object/form-object.component.html +++ /dev/null @@ -1,372 +0,0 @@ - -
-
- - - -

- -

- - - - - - - - - - {{ spec.units }} - - -

- - {{ errors | getError: $any(spec)['pattern-description'] }} - -

-
- - - - - - - - {{ spec.name }} - - (New) - - - (Edited) - - - - - - - - - - {{ spec['value-names'][option] }} - - - - - - - - - - - - -
- -
-
-
- - - - - - - - - - - Add - - -

- - {{ errors | getError }} - -

- -
-
- - - - - - - - - - - -
- - - Delete - -
-
-
- -
- - - - - - -

- - {{ errors | getError: $any(spec)['pattern-description'] }} - -

-
-
-
-
-
- - - - -

- -

- - - -

{{ formArr.value | toEnumListDisplay: $any(spec.spec) }}

-
- - - -
-

- - {{ errors | getError }} - -

-
-
-
-
-
diff --git a/web/projects/ui/src/app/components/form-object/form-object.component.module.ts b/web/projects/ui/src/app/components/form-object/form-object.component.module.ts deleted file mode 100644 index 06af388c0..000000000 --- a/web/projects/ui/src/app/components/form-object/form-object.component.module.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { NgModule } from '@angular/core' -import { CommonModule } from '@angular/common' -import { - FormObjectComponent, - FormUnionComponent, - FormLabelComponent, -} from './form-object.component' -import { - GetErrorPipe, - ToWarningTextPipe, - ToElementIdPipe, - GetControlPipe, - ToEnumListDisplayPipe, - ToRangePipe, -} from './form-object.pipes' -import { IonicModule } from '@ionic/angular' -import { FormsModule, ReactiveFormsModule } from '@angular/forms' -import { SharedPipesModule } from '@start9labs/shared' -import { TuiElasticContainerModule } from '@taiga-ui/kit' -import { EnumListPageModule } from 'src/app/modals/enum-list/enum-list.module' -import { TuiExpandModule } from '@taiga-ui/core' - -@NgModule({ - declarations: [ - FormObjectComponent, - FormUnionComponent, - FormLabelComponent, - ToWarningTextPipe, - GetErrorPipe, - ToEnumListDisplayPipe, - ToElementIdPipe, - GetControlPipe, - ToRangePipe, - ], - imports: [ - CommonModule, - IonicModule, - FormsModule, - ReactiveFormsModule, - SharedPipesModule, - EnumListPageModule, - TuiElasticContainerModule, - TuiExpandModule, - ], - exports: [FormObjectComponent, FormLabelComponent], -}) -export class FormObjectComponentModule {} diff --git a/web/projects/ui/src/app/components/form-object/form-object.component.scss b/web/projects/ui/src/app/components/form-object/form-object.component.scss deleted file mode 100644 index a98a0ff72..000000000 --- a/web/projects/ui/src/app/components/form-object/form-object.component.scss +++ /dev/null @@ -1,42 +0,0 @@ -.slot-start { - display: inline-block; - vertical-align: middle; - --padding-start: 0; - --padding-end: 7px; -} - -.error-border { - border-color: var(--ion-color-danger-shade); - --border-color: var(--ion-color-danger-shade); -} - -.redacted { - font-family: 'Redacted' -} - -ion-input { - font-family: 'Courier New'; - font-weight: bold; - --placeholder-font-weight: 400; -} - -ion-item-divider { - text-transform: unset; - --padding-top: 18px; - --padding-start: 0; - border-bottom: 1px solid var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, rgba(0, 0, 0, 0.13)))) -} - -.nested-wrapper { - padding: 0 0 16px 24px; -} - -.error-message { - margin-top: 2px; - font-size: small; - color: var(--ion-color-danger); -} - -.indent { - margin-left: 24px; -} \ No newline at end of file diff --git a/web/projects/ui/src/app/components/form-object/form-object.component.ts b/web/projects/ui/src/app/components/form-object/form-object.component.ts deleted file mode 100644 index fcc6a0c61..000000000 --- a/web/projects/ui/src/app/components/form-object/form-object.component.ts +++ /dev/null @@ -1,425 +0,0 @@ -import { - Component, - Input, - Output, - EventEmitter, - ChangeDetectionStrategy, - Inject, - inject, - SimpleChanges, -} from '@angular/core' -import { FormArray, UntypedFormArray, UntypedFormGroup } from '@angular/forms' -import { AlertButton, AlertController, ModalController } from '@ionic/angular' -import { - ConfigSpec, - ListValueSpecOf, - ValueSpec, - ValueSpecBoolean, - ValueSpecEnum, - ValueSpecList, - ValueSpecListOf, - ValueSpecUnion, -} from 'src/app/pkg-config/config-types' -import { FormService } from 'src/app/services/form.service' -import { EnumListPage } from 'src/app/modals/enum-list/enum-list.page' -import { THEME, pauseFor } from '@start9labs/shared' -import { v4 } from 'uuid' -import { DOCUMENT } from '@angular/common' - -const Mustache = require('mustache') - -interface Config { - [key: string]: any -} -@Component({ - selector: 'form-object', - templateUrl: './form-object.component.html', - styleUrls: ['./form-object.component.scss'], -}) -export class FormObjectComponent { - @Input() objectSpec!: ConfigSpec - @Input() formGroup!: UntypedFormGroup - @Input() current?: Config - @Input() original?: Config - @Output() onInputChange = new EventEmitter() - @Output() hasNewOptions = new EventEmitter() - warningAck: { [key: string]: boolean } = {} - unmasked: { [key: string]: boolean } = {} - objectDisplay: { - [key: string]: { expanded: boolean; hasNewOptions: boolean } - } = {} - objectListDisplay: { - [key: string]: { expanded: boolean; displayAs: string }[] - } = {} - objectId = v4() - - readonly theme$ = inject(THEME) - - constructor( - private readonly alertCtrl: AlertController, - private readonly modalCtrl: ModalController, - private readonly formService: FormService, - @Inject(DOCUMENT) private readonly document: Document, - ) {} - - ngOnInit() { - this.setDisplays() - - // setTimeout hack to avoid ExpressionChangedAfterItHasBeenCheckedError - setTimeout(() => { - if ( - this.original && - Object.keys(this.current || {}).some( - key => this.original![key] === undefined, - ) - ) - this.hasNewOptions.emit() - }) - } - - ngOnChanges(changes: SimpleChanges) { - const specChanges = changes['objectSpec'] - - if (!specChanges) return - - if ( - !specChanges.firstChange && - Object.keys({ - ...specChanges.previousValue, - ...specChanges.currentValue, - }).length !== Object.keys(specChanges.previousValue).length - ) { - this.setDisplays() - } - } - - private setDisplays() { - Object.keys(this.objectSpec).forEach(key => { - const spec = this.objectSpec[key] - - if (spec.type === 'list' && ['object', 'union'].includes(spec.subtype)) { - this.objectListDisplay[key] = [] - this.formGroup.get(key)?.value.forEach((obj: any, index: number) => { - const displayAs = (spec.spec as ListValueSpecOf<'object'>)[ - 'display-as' - ] - this.objectListDisplay[key][index] = { - expanded: false, - displayAs: displayAs - ? (Mustache as any).render(displayAs, obj) - : '', - } - }) - } else if (spec.type === 'object') { - this.objectDisplay[key] = { - expanded: false, - hasNewOptions: false, - } - } - }) - } - - addListItemWrapper( - key: string, - spec: T extends ValueSpecUnion ? never : T, - ) { - this.presentAlertChangeWarning(key, spec, () => this.addListItem(key)) - } - - toggleExpandObject(key: string) { - this.objectDisplay[key].expanded = !this.objectDisplay[key].expanded - } - - toggleExpandListObject(key: string, i: number) { - this.objectListDisplay[key][i].expanded = - !this.objectListDisplay[key][i].expanded - } - - updateLabel(key: string, i: number, displayAs: string) { - this.objectListDisplay[key][i].displayAs = displayAs - ? Mustache.render(displayAs, this.formGroup.get(key)?.value[i]) - : '' - } - - handleInputChange() { - this.onInputChange.emit() - } - - setHasNew(key: string) { - this.hasNewOptions.emit() - setTimeout(() => { - this.objectDisplay[key].hasNewOptions = true - }, 100) - } - - handleBooleanChange(key: string, spec: ValueSpecBoolean) { - if (spec.warning) { - const current = this.formGroup.get(key)?.value - const cancelFn = () => this.formGroup.get(key)?.setValue(!current) - this.presentAlertChangeWarning(key, spec, undefined, cancelFn) - } - } - - async presentModalEnumList( - key: string, - spec: ValueSpecListOf<'enum'>, - current: string[], - ) { - const modal = await this.modalCtrl.create({ - componentProps: { - key, - spec, - current, - }, - component: EnumListPage, - }) - - modal.onWillDismiss().then(({ data }) => { - if (!data) return - this.updateEnumList(key, current, data) - }) - - await modal.present() - } - - async presentAlertChangeWarning( - key: string, - spec: T extends ValueSpecUnion ? never : T, - okFn?: Function, - cancelFn?: Function, - ) { - if (!spec.warning || this.warningAck[key]) return okFn ? okFn() : null - this.warningAck[key] = true - - const buttons: AlertButton[] = [ - { - text: 'Ok', - handler: () => { - if (okFn) okFn() - }, - cssClass: 'enter-click', - }, - ] - - if (okFn || cancelFn) { - buttons.unshift({ - text: 'Cancel', - handler: () => { - if (cancelFn) cancelFn() - }, - }) - } - - const alert = await this.alertCtrl.create({ - header: 'Warning', - subHeader: `Editing ${spec.name} has consequences:`, - message: spec.warning, - buttons, - }) - await alert.present() - } - - async presentAlertDelete(key: string, index: number) { - const alert = await this.alertCtrl.create({ - header: 'Confirm', - message: 'Are you sure you want to delete this entry?', - buttons: [ - { - text: 'Cancel', - role: 'cancel', - }, - { - text: 'Delete', - handler: () => { - this.deleteListItem(key, index) - }, - cssClass: 'enter-click', - }, - ], - }) - await alert.present() - } - - async presentAlertBoolEnumDescription( - event: Event, - spec: ValueSpecBoolean | ValueSpecEnum, - ) { - event.stopPropagation() - const { name, description } = spec - - const alert = await this.alertCtrl.create({ - header: name, - message: description, - buttons: [ - { - text: 'OK', - cssClass: 'enter-click', - }, - ], - }) - await alert.present() - } - - private addListItem(key: string): void { - const arr = this.formGroup.get(key) as UntypedFormArray - const listSpec = this.objectSpec[key] as ValueSpecList - const newItem = this.formService.getListItem(listSpec, undefined)! - - const index = arr.length - arr.insert(index, newItem) - - if (['object', 'union'].includes(listSpec.subtype)) { - const displayAs = (listSpec.spec as ListValueSpecOf<'object'>)[ - 'display-as' - ] - this.objectListDisplay[key].push({ - expanded: false, - displayAs: displayAs ? Mustache.render(displayAs, newItem.value) : '', - }) - } - - setTimeout(() => { - const element = this.document.getElementById( - getElementId(this.objectId, key, index), - ) - element?.parentElement?.scrollIntoView({ behavior: 'smooth' }) - - if (['object', 'union'].includes(listSpec.subtype)) { - pauseFor(250).then(() => this.toggleExpandListObject(key, index)) - } - }, 100) - - arr.markAsDirty() - } - - private deleteListItem(key: string, index: number, markDirty = true): void { - // if (this.objectListDisplay[key]) - // this.objectListDisplay[key][index].height = '0px' - const arr = this.formGroup.get(key) as UntypedFormArray - if (markDirty) arr.markAsDirty() - pauseFor(250).then(() => { - if (this.objectListDisplay[key]) - this.objectListDisplay[key].splice(index, 1) - arr.removeAt(index) - }) - } - - private updateEnumList(key: string, current: string[], updated: string[]) { - const arr = this.formGroup.get(key) as FormArray - - for (let i = current.length - 1; i >= 0; i--) { - if (!updated.includes(current[i])) { - arr.removeAt(i) - } - } - - const listSpec = this.objectSpec[key] as ValueSpecList - - updated.forEach(val => { - if (!current.includes(val)) { - const newItem = this.formService.getListItem(listSpec, val)! - arr.insert(arr.length, newItem) - } - }) - - arr.markAsDirty() - } - - asIsOrder() { - return 0 - } -} - -@Component({ - selector: 'form-union', - templateUrl: './form-union.component.html', - styleUrls: ['./form-object.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class FormUnionComponent { - @Input() formGroup!: UntypedFormGroup - @Input() spec!: ValueSpecUnion - @Input() current?: Config - @Input() original?: Config - - get unionValue() { - return this.formGroup.get(this.spec.tag.id)?.value - } - - get isNew() { - return !this.original - } - - get hasNewOptions() { - const tagId = this.spec.tag.id - return ( - this.original?.[tagId] === this.current?.[tagId] && - !!Object.keys(this.current || {}).find( - key => this.original![key] === undefined, - ) - ) - } - - objectId = v4() - - constructor(private readonly formService: FormService) {} - - updateUnion(e: any): void { - const tagId = this.spec.tag.id - - Object.keys(this.formGroup.controls).forEach(control => { - if (control === tagId) return - this.formGroup.removeControl(control) - }) - - const unionGroup = this.formService.getUnionObject( - this.spec as ValueSpecUnion, - e.detail.value, - ) - - Object.keys(unionGroup.controls).forEach(control => { - if (control === tagId) return - this.formGroup.addControl(control, unionGroup.controls[control]) - }) - } -} - -@Component({ - selector: 'form-label', - templateUrl: './form-label.component.html', - styleUrls: ['./form-object.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class FormLabelComponent { - @Input() data!: { - name: string - new: boolean - edited: boolean - description?: string - required?: boolean - newOptions?: boolean - } - - constructor(private readonly alertCtrl: AlertController) {} - - async presentAlertDescription(event: Event) { - event.stopPropagation() - const { name, description } = this.data - - const alert = await this.alertCtrl.create({ - header: name, - message: description, - buttons: [ - { - text: 'OK', - cssClass: 'enter-click', - }, - ], - }) - await alert.present() - } -} - -export function getElementId(objectId: string, key: string, index = 0): string { - return `${key}-${index}-${objectId}` -} diff --git a/web/projects/ui/src/app/components/form-object/form-object.pipes.ts b/web/projects/ui/src/app/components/form-object/form-object.pipes.ts deleted file mode 100644 index 1dc5a18f2..000000000 --- a/web/projects/ui/src/app/components/form-object/form-object.pipes.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { Pipe, PipeTransform } from '@angular/core' -import { - AbstractControl, - FormGroup, - UntypedFormArray, - ValidationErrors, -} from '@angular/forms' -import { IonicSafeString } from '@ionic/angular' -import { ListValueSpecOf } from 'src/app/pkg-config/config-types' -import { Range } from 'src/app/pkg-config/config-utilities' -import { getElementId } from './form-object.component' - -@Pipe({ - name: 'getError', -}) -export class GetErrorPipe implements PipeTransform { - transform(errors: ValidationErrors, patternDesc?: string): string { - if (errors['required']) { - return 'Required' - } else if (errors['pattern']) { - return patternDesc || 'Invalid pattern' - } else if (errors['notNumber']) { - return 'Must be a number' - } else if (errors['numberNotInteger']) { - return 'Must be an integer' - } else if (errors['numberNotInRange']) { - return errors['numberNotInRange'].value - } else if (errors['listNotUnique']) { - return errors['listNotUnique'].value - } else if (errors['listNotInRange']) { - return errors['listNotInRange'].value - } else if (errors['listItemIssue']) { - return errors['listItemIssue'].value - } else { - return 'Unknown error' - } - } -} - -@Pipe({ - name: 'toEnumListDisplay', -}) -export class ToEnumListDisplayPipe implements PipeTransform { - transform(arr: string[], spec: ListValueSpecOf<'enum'>): string { - return arr.map((v: string) => spec['value-names'][v]).join(', ') - } -} - -@Pipe({ - name: 'toWarningText', -}) -export class ToWarningTextPipe implements PipeTransform { - transform(text?: string): IonicSafeString | string { - return text - ? new IonicSafeString(`${text}`) - : '' - } -} - -@Pipe({ - name: 'toRange', -}) -export class ToRangePipe implements PipeTransform { - transform(range: string): Range { - return Range.from(range) - } -} - -@Pipe({ - name: 'toElementId', -}) -export class ToElementIdPipe implements PipeTransform { - transform(objectId: string, key: string, index = 0): string { - return getElementId(objectId, key, index) - } -} - -@Pipe({ - name: 'getControl', -}) -export class GetControlPipe implements PipeTransform { - transform( - formGroup: FormGroup, - key: string, - index?: number, - ): AbstractControl { - const abstractControl = formGroup.get(key)! - if (index !== undefined) - return (abstractControl as UntypedFormArray).at(index) - return abstractControl - } -} diff --git a/web/projects/ui/src/app/components/form-object/form-union.component.html b/web/projects/ui/src/app/components/form-object/form-union.component.html deleted file mode 100644 index ed9fc31be..000000000 --- a/web/projects/ui/src/app/components/form-object/form-union.component.html +++ /dev/null @@ -1,42 +0,0 @@ -
- - - - - - - {{ spec.tag['variant-names'][option.key] }} - - - - - - - -
diff --git a/web/projects/ui/src/app/components/form.component.ts b/web/projects/ui/src/app/components/form.component.ts new file mode 100644 index 000000000..830e8de1e --- /dev/null +++ b/web/projects/ui/src/app/components/form.component.ts @@ -0,0 +1,167 @@ +import { CommonModule } from '@angular/common' +import { + ChangeDetectionStrategy, + Component, + inject, + Input, + OnInit, +} from '@angular/core' +import { FormGroup, ReactiveFormsModule } from '@angular/forms' +import { RouterModule } from '@angular/router' +import { CT } from '@start9labs/start-sdk' + +import { + tuiMarkControlAsTouchedAndValidate, + TuiValueChangesModule, +} from '@taiga-ui/cdk' +import { TuiDialogContext, TuiModeModule } from '@taiga-ui/core' +import { TuiButtonModule } from '@taiga-ui/experimental' +import { TuiDialogFormService } from '@taiga-ui/kit' +import { POLYMORPHEUS_CONTEXT } from '@tinkoff/ng-polymorpheus' +import { compare, Operation } from 'fast-json-patch' +import { FormModule } from 'src/app/components/form/form.module' +import { InvalidService } from 'src/app/components/form/invalid.service' +import { FormService } from 'src/app/services/form.service' + +export interface ActionButton { + text: string + handler?: (value: T) => Promise | void + link?: string +} + +export interface FormContext { + spec: CT.InputSpec + buttons: ActionButton[] + value?: T + patch?: Operation[] +} + +@Component({ + standalone: true, + selector: 'app-form', + template: ` +
+ + +
+ `, + styles: [ + ` + footer { + position: sticky; + bottom: 0; + z-index: 10; + display: flex; + justify-content: flex-end; + padding: 1rem 0; + margin: 1rem 0 -1rem; + gap: 1rem; + background: var(--tui-elevation-01); + border-top: 1px solid var(--tui-base-02); + } + `, + ], + imports: [ + CommonModule, + ReactiveFormsModule, + RouterModule, + TuiValueChangesModule, + TuiButtonModule, + TuiModeModule, + FormModule, + ], + providers: [InvalidService], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class FormComponent> implements OnInit { + private readonly dialogFormService = inject(TuiDialogFormService) + private readonly formService = inject(FormService) + private readonly invalidService = inject(InvalidService) + private readonly context = inject>>( + POLYMORPHEUS_CONTEXT, + { optional: true }, + ) + + @Input() spec = this.context?.data.spec || {} + @Input() buttons = this.context?.data.buttons || [] + @Input() patch = this.context?.data.patch || [] + @Input() value?: T = this.context?.data.value + + form = new FormGroup({}) + + ngOnInit() { + this.dialogFormService.markAsPristine() + this.form = this.formService.createForm(this.spec, this.value) + this.process(this.patch) + } + + onReset() { + const { value } = this.form + + this.form = this.formService.createForm(this.spec) + this.process(compare(this.form.value, value)) + tuiMarkControlAsTouchedAndValidate(this.form) + this.markAsDirty() + } + + async onClick(handler: Required>['handler']) { + tuiMarkControlAsTouchedAndValidate(this.form) + this.invalidService.scrollIntoView() + + if (this.form.valid && (await handler(this.form.value as T))) { + this.close() + } + } + + markAsDirty() { + this.dialogFormService.markAsDirty() + } + + close() { + this.context?.$implicit.complete() + } + + private process(patch: Operation[]) { + patch.forEach(({ op, path }) => { + const control = this.form.get(path.substring(1).split('/')) + + if (!control || !control.parent) return + + if (op !== 'remove') { + control.markAsDirty() + control.markAsTouched() + } + + control.parent.markAsDirty() + control.parent.markAsTouched() + }) + } +} diff --git a/web/projects/ui/src/app/components/form/control.directive.ts b/web/projects/ui/src/app/components/form/control.directive.ts new file mode 100644 index 000000000..327eb8255 --- /dev/null +++ b/web/projects/ui/src/app/components/form/control.directive.ts @@ -0,0 +1,30 @@ +import { Directive, ElementRef, inject, OnDestroy, OnInit } from '@angular/core' +import { ControlContainer, NgControl } from '@angular/forms' +import { InvalidService } from './invalid.service' + +@Directive({ + selector: 'form-control, form-array, form-object', +}) +export class ControlDirective implements OnInit, OnDestroy { + private readonly invalidService = inject(InvalidService, { optional: true }) + private readonly element: ElementRef = inject(ElementRef) + private readonly control = + inject(NgControl, { optional: true }) || + inject(ControlContainer, { optional: true }) + + get invalid(): boolean { + return !!this.control?.invalid + } + + scrollIntoView() { + this.element.nativeElement.scrollIntoView({ behavior: 'smooth' }) + } + + ngOnInit() { + this.invalidService?.add(this) + } + + ngOnDestroy() { + this.invalidService?.remove(this) + } +} diff --git a/web/projects/ui/src/app/components/form/control.ts b/web/projects/ui/src/app/components/form/control.ts new file mode 100644 index 000000000..476826194 --- /dev/null +++ b/web/projects/ui/src/app/components/form/control.ts @@ -0,0 +1,35 @@ +import { inject } from '@angular/core' +import { FormControlComponent } from './form-control/form-control.component' +import { CT } from '@start9labs/start-sdk' + +export abstract class Control { + private readonly control: FormControlComponent = + inject(FormControlComponent) + + get invalid(): boolean { + return this.control.touched && this.control.invalid + } + + get spec(): Spec { + return this.control.spec + } + + // TODO: Properly handle already set immutable value + get readOnly(): boolean { + return ( + !!this.value && !!this.control.control?.pristine && this.control.immutable + ) + } + + get value(): Value | null { + return this.control.value + } + + set value(value: Value | null) { + this.control.onInput(value) + } + + onFocus(focused: boolean) { + this.control.onFocus(focused) + } +} diff --git a/web/projects/ui/src/app/components/form/form-array/form-array.component.html b/web/projects/ui/src/app/components/form/form-array/form-array.component.html new file mode 100644 index 000000000..76c67f837 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-array/form-array.component.html @@ -0,0 +1,58 @@ +
+ {{ spec.name }} + + +
+ + + + + {{ item.value | mustache: $any(spec.spec).displayAs }} + + + + + + + + + diff --git a/web/projects/ui/src/app/components/form/form-array/form-array.component.scss b/web/projects/ui/src/app/components/form/form-array/form-array.component.scss new file mode 100644 index 000000000..9b6415ff7 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-array/form-array.component.scss @@ -0,0 +1,50 @@ +@import '@taiga-ui/core/styles/taiga-ui-local'; + +:host { + display: block; + margin: 2rem 0; +} + +.label { + display: flex; + font-size: 1.25rem; + font-weight: bold; +} + +.add { + font-size: 1rem; + padding: 0 1rem; + margin-left: auto; +} + +.object { + display: block; + position: relative; + + &_open::after, + &:last-child::after { + opacity: 0; + } + + &:after { + @include transition(opacity); + + content: ''; + position: absolute; + bottom: -0.5rem; + height: 1px; + left: 3rem; + right: 1rem; + background: var(--tui-clear); + } +} + +.remove { + margin-left: auto; + pointer-events: auto; +} + +.control { + display: block; + margin: 0.5rem 0; +} diff --git a/web/projects/ui/src/app/components/form/form-array/form-array.component.ts b/web/projects/ui/src/app/components/form/form-array/form-array.component.ts new file mode 100644 index 000000000..11495d510 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-array/form-array.component.ts @@ -0,0 +1,91 @@ +import { Component, HostBinding, inject, Input } from '@angular/core' +import { AbstractControl, FormArrayName } from '@angular/forms' +import { TUI_PARENT_ANIMATION, TuiDestroyService } from '@taiga-ui/cdk' +import { + TUI_ANIMATION_OPTIONS, + TuiDialogService, + tuiFadeIn, + tuiHeightCollapse, +} from '@taiga-ui/core' +import { TUI_PROMPT } from '@taiga-ui/kit' +import { CT } from '@start9labs/start-sdk' +import { filter, takeUntil } from 'rxjs' +import { FormService } from 'src/app/services/form.service' +import { ERRORS } from '../form-group/form-group.component' + +@Component({ + selector: 'form-array', + templateUrl: './form-array.component.html', + styleUrls: ['./form-array.component.scss'], + animations: [tuiFadeIn, tuiHeightCollapse, TUI_PARENT_ANIMATION], + providers: [TuiDestroyService], +}) +export class FormArrayComponent { + @Input() + spec!: CT.ValueSpecList + + @HostBinding('@tuiParentAnimation') + readonly animation = { value: '', ...inject(TUI_ANIMATION_OPTIONS) } + readonly order = ERRORS + readonly array = inject(FormArrayName) + readonly open = new Map() + + private warned = false + private readonly formService = inject(FormService) + private readonly dialogs = inject(TuiDialogService) + private readonly destroy$ = inject(TuiDestroyService) + + get canAdd(): boolean { + return ( + !this.spec.disabled && + (!this.spec.maxLength || + this.spec.maxLength >= this.array.control.controls.length) + ) + } + + add() { + if (!this.warned && this.spec.warning) { + this.dialogs + .open(TUI_PROMPT, { + label: 'Warning', + size: 's', + data: { content: this.spec.warning, yes: 'Ok', no: 'Cancel' }, + }) + .pipe(filter(Boolean), takeUntil(this.destroy$)) + .subscribe(() => { + this.addItem() + }) + } else { + this.addItem() + } + + this.warned = true + } + + removeAt(index: number) { + this.dialogs + .open(TUI_PROMPT, { + label: 'Confirm', + size: 's', + data: { + content: 'Are you sure you want to delete this entry?', + yes: 'Delete', + no: 'Cancel', + }, + }) + .pipe(filter(Boolean), takeUntil(this.destroy$)) + .subscribe(() => { + this.removeItem(index) + }) + } + + private removeItem(index: number) { + this.open.delete(this.array.control.at(index)) + this.array.control.removeAt(index) + } + + private addItem() { + this.array.control.insert(0, this.formService.getListItem(this.spec)) + this.open.set(this.array.control.at(0), true) + } +} diff --git a/web/projects/ui/src/app/components/form/form-color/form-color.component.html b/web/projects/ui/src/app/components/form/form-color/form-color.component.html new file mode 100644 index 000000000..19cf4051d --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-color/form-color.component.html @@ -0,0 +1,31 @@ + + {{ spec.name }} + * + + +
+ + +
+
diff --git a/web/projects/ui/src/app/components/form/form-color/form-color.component.scss b/web/projects/ui/src/app/components/form/form-color/form-color.component.scss new file mode 100644 index 000000000..49496946e --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-color/form-color.component.scss @@ -0,0 +1,33 @@ +@import '@taiga-ui/core/styles/taiga-ui-local'; + +.wrapper { + position: relative; + width: 1.5rem; + height: 1.5rem; + pointer-events: auto; + + &::after { + content: ''; + position: absolute; + height: 0.3rem; + width: 1.4rem; + bottom: 0.125rem; + background: currentColor; + border-radius: 0.125rem; + pointer-events: none; + } +} + +.color { + @include fullsize(); + opacity: 0; +} + +.icon { + @include fullsize(); + pointer-events: none; + + input:hover + & { + opacity: 1; + } +} diff --git a/web/projects/ui/src/app/components/form/form-color/form-color.component.ts b/web/projects/ui/src/app/components/form/form-color/form-color.component.ts new file mode 100644 index 000000000..32a7c1c04 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-color/form-color.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core' +import { CT } from '@start9labs/start-sdk' +import { Control } from '../control' +import { MaskitoOptions } from '@maskito/core' + +@Component({ + selector: 'form-color', + templateUrl: './form-color.component.html', + styleUrls: ['./form-color.component.scss'], +}) +export class FormColorComponent extends Control { + readonly mask: MaskitoOptions = { + mask: ['#', ...Array(6).fill(/[0-9a-f]/i)], + } +} diff --git a/web/projects/ui/src/app/components/form/form-control/form-control.component.html b/web/projects/ui/src/app/components/form/form-control/form-control.component.html new file mode 100644 index 000000000..614aae05c --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-control/form-control.component.html @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + {{ spec.warning }} +

This value cannot be changed once set!

+
+ + +
+
diff --git a/web/projects/ui/src/app/components/form/form-control/form-control.component.scss b/web/projects/ui/src/app/components/form/form-control/form-control.component.scss new file mode 100644 index 000000000..844651118 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-control/form-control.component.scss @@ -0,0 +1,11 @@ +:host { + display: block; +} + +.buttons { + margin-top: 0.5rem; + + :first-child { + margin-right: 0.5rem; + } +} diff --git a/web/projects/ui/src/app/components/form/form-control/form-control.component.ts b/web/projects/ui/src/app/components/form/form-control/form-control.component.ts new file mode 100644 index 000000000..ec49bd084 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-control/form-control.component.ts @@ -0,0 +1,71 @@ +import { + ChangeDetectionStrategy, + Component, + inject, + Input, + TemplateRef, + ViewChild, +} from '@angular/core' +import { AbstractTuiNullableControl } from '@taiga-ui/cdk' +import { + TuiAlertService, + TuiDialogContext, + TuiNotification, +} from '@taiga-ui/core' +import { filter, takeUntil } from 'rxjs' +import { CT } from '@start9labs/start-sdk' +import { ERRORS } from '../form-group/form-group.component' +import { FORM_CONTROL_PROVIDERS } from './form-control.providers' + +@Component({ + selector: 'form-control', + templateUrl: './form-control.component.html', + styleUrls: ['./form-control.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + providers: FORM_CONTROL_PROVIDERS, +}) +export class FormControlComponent< + T extends CT.ValueSpec, + V, +> extends AbstractTuiNullableControl { + @Input() + spec!: T + + @ViewChild('warning') + warning?: TemplateRef> + + warned = false + focused = false + readonly order = ERRORS + private readonly alerts = inject(TuiAlertService) + + get immutable(): boolean { + return 'immutable' in this.spec && this.spec.immutable + } + + onFocus(focused: boolean) { + this.focused = focused + this.updateFocused(focused) + } + + onInput(value: V | null) { + const previous = this.value + + if (!this.warned && this.warning) { + this.alerts + .open(this.warning, { + label: 'Warning', + status: TuiNotification.Warning, + hasCloseButton: false, + autoClose: false, + }) + .pipe(filter(Boolean), takeUntil(this.destroy$)) + .subscribe(() => { + this.value = previous + }) + } + + this.warned = true + this.value = value === '' ? null : value + } +} diff --git a/web/projects/ui/src/app/components/form/form-control/form-control.providers.ts b/web/projects/ui/src/app/components/form/form-control/form-control.providers.ts new file mode 100644 index 000000000..f065f86cb --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-control/form-control.providers.ts @@ -0,0 +1,25 @@ +import { forwardRef, Provider } from '@angular/core' +import { TUI_VALIDATION_ERRORS } from '@taiga-ui/kit' +import { CT } from '@start9labs/start-sdk' +import { FormControlComponent } from './form-control.component' + +interface ValidatorsPatternError { + actualValue: string + requiredPattern: string | RegExp +} + +export const FORM_CONTROL_PROVIDERS: Provider[] = [ + { + provide: TUI_VALIDATION_ERRORS, + deps: [forwardRef(() => FormControlComponent)], + useFactory: (control: FormControlComponent) => ({ + required: 'Required', + pattern: ({ requiredPattern }: ValidatorsPatternError) => + ('patterns' in control.spec && + control.spec.patterns.find( + ({ regex }) => String(regex) === String(requiredPattern), + )?.description) || + 'Invalid format', + }), + }, +] diff --git a/web/projects/ui/src/app/components/form/form-datetime/form-datetime.component.html b/web/projects/ui/src/app/components/form/form-datetime/form-datetime.component.html new file mode 100644 index 000000000..05ffa69f3 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-datetime/form-datetime.component.html @@ -0,0 +1,43 @@ + + + {{ spec.name }} + * + + + {{ spec.name }} + * + + + {{ spec.name }} + * + + diff --git a/web/projects/ui/src/app/components/form/form-datetime/form-datetime.component.ts b/web/projects/ui/src/app/components/form/form-datetime/form-datetime.component.ts new file mode 100644 index 000000000..e09b22d24 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-datetime/form-datetime.component.ts @@ -0,0 +1,36 @@ +import { Component } from '@angular/core' +import { + TUI_FIRST_DAY, + TUI_LAST_DAY, + TuiDay, + tuiPure, + TuiTime, +} from '@taiga-ui/cdk' +import { CT } from '@start9labs/start-sdk' +import { Control } from '../control' + +@Component({ + selector: 'form-datetime', + templateUrl: './form-datetime.component.html', +}) +export class FormDatetimeComponent extends Control< + CT.ValueSpecDatetime, + string +> { + readonly min = TUI_FIRST_DAY + readonly max = TUI_LAST_DAY + + @tuiPure + getTime(value: string | null) { + return value ? TuiTime.fromString(value) : null + } + + getLimit(limit: string): [TuiDay, TuiTime] { + return [ + TuiDay.jsonParse(limit.slice(0, 10)), + limit.length === 10 + ? new TuiTime(0, 0) + : TuiTime.fromString(limit.slice(-5)), + ] + } +} diff --git a/web/projects/ui/src/app/components/form/form-file/form-file.component.html b/web/projects/ui/src/app/components/form/form-file/form-file.component.html new file mode 100644 index 000000000..9e9c16613 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-file/form-file.component.html @@ -0,0 +1,31 @@ + + + +
+
+ {{ spec.name }} + * + +
+ + + Click or drop file here + +
+
Drop file here
+
+
diff --git a/web/projects/ui/src/app/components/form/form-file/form-file.component.scss b/web/projects/ui/src/app/components/form/form-file/form-file.component.scss new file mode 100644 index 000000000..2e314972d --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-file/form-file.component.scss @@ -0,0 +1,46 @@ +@import '@taiga-ui/core/styles/taiga-ui-local'; + +.template { + @include transition(opacity); + + width: 100%; + display: flex; + align-items: center; + padding: 0 0.5rem; + font: var(--tui-font-text-m); + font-weight: bold; + + &_hidden { + opacity: 0; + } +} + +.drop { + @include fullsize(); + @include transition(opacity); + display: flex; + align-items: center; + justify-content: space-around; + + &_hidden { + opacity: 0; + } +} + +.label { + display: flex; + align-items: center; + max-width: 50%; +} + +small { + max-width: 50%; + font-weight: normal; + color: var(--tui-text-02); + margin-left: auto; +} + +tui-tag { + z-index: 1; + margin: -0.25rem -0.25rem -0.25rem auto; +} diff --git a/web/projects/ui/src/app/components/form/form-file/form-file.component.ts b/web/projects/ui/src/app/components/form/form-file/form-file.component.ts new file mode 100644 index 000000000..52d340fa6 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-file/form-file.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core' +import { TuiFileLike } from '@taiga-ui/kit' +import { CT } from '@start9labs/start-sdk' +import { Control } from '../control' + +@Component({ + selector: 'form-file', + templateUrl: './form-file.component.html', + styleUrls: ['./form-file.component.scss'], +}) +export class FormFileComponent extends Control {} diff --git a/web/projects/ui/src/app/components/form/form-group/form-group.component.html b/web/projects/ui/src/app/components/form/form-group/form-group.component.html new file mode 100644 index 000000000..d3c769b98 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-group/form-group.component.html @@ -0,0 +1,30 @@ + + + + + + diff --git a/web/projects/ui/src/app/components/form/form-group/form-group.component.scss b/web/projects/ui/src/app/components/form/form-group/form-group.component.scss new file mode 100644 index 000000000..ce5665fc0 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-group/form-group.component.scss @@ -0,0 +1,35 @@ +form-group .g-form-control:not(:first-child) { + margin-top: 1rem; +} + +form-group .g-form-group { + position: relative; + padding-left: var(--tui-height-m); + + &::before, + &::after { + content: ''; + position: absolute; + background: var(--tui-clear); + } + + &::before { + top: 0; + left: calc(1rem - 1px); + bottom: 0.5rem; + width: 2px; + } + + &::after { + left: 0.75rem; + bottom: 0; + width: 0.5rem; + height: 0.5rem; + border-radius: 100%; + } +} + +form-group tui-tooltip { + z-index: 1; + margin-left: 0.25rem; +} diff --git a/web/projects/ui/src/app/components/form/form-group/form-group.component.ts b/web/projects/ui/src/app/components/form/form-group/form-group.component.ts new file mode 100644 index 000000000..d9d28c8df --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-group/form-group.component.ts @@ -0,0 +1,35 @@ +import { + ChangeDetectionStrategy, + Component, + Input, + ViewEncapsulation, +} from '@angular/core' +import { CT } from '@start9labs/start-sdk' +import { FORM_GROUP_PROVIDERS } from './form-group.providers' + +export const ERRORS = [ + 'required', + 'pattern', + 'notNumber', + 'numberNotInteger', + 'numberNotInRange', + 'listNotUnique', + 'listNotInRange', + 'listItemIssue', +] + +@Component({ + selector: 'form-group', + templateUrl: './form-group.component.html', + styleUrls: ['./form-group.component.scss'], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, + viewProviders: [FORM_GROUP_PROVIDERS], +}) +export class FormGroupComponent { + @Input() spec: CT.InputSpec = {} + + asIsOrder() { + return 0 + } +} diff --git a/web/projects/ui/src/app/components/form/form-group/form-group.providers.ts b/web/projects/ui/src/app/components/form/form-group/form-group.providers.ts new file mode 100644 index 000000000..5c9039f40 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-group/form-group.providers.ts @@ -0,0 +1,34 @@ +import { Provider, SkipSelf } from '@angular/core' +import { + TUI_ARROW_MODE, + tuiInputDateOptionsProvider, + tuiInputTimeOptionsProvider, +} from '@taiga-ui/kit' +import { TUI_DEFAULT_ERROR_MESSAGE } from '@taiga-ui/core' +import { ControlContainer } from '@angular/forms' +import { identity, of } from 'rxjs' + +export const FORM_GROUP_PROVIDERS: Provider[] = [ + { + provide: TUI_DEFAULT_ERROR_MESSAGE, + useValue: of('Unknown error'), + }, + { + provide: ControlContainer, + deps: [[new SkipSelf(), ControlContainer]], + useFactory: identity, + }, + { + provide: TUI_ARROW_MODE, + useValue: { + interactive: null, + disabled: null, + }, + }, + tuiInputDateOptionsProvider({ + nativePicker: true, + }), + tuiInputTimeOptionsProvider({ + nativePicker: true, + }), +] diff --git a/web/projects/ui/src/app/components/form/form-multiselect/form-multiselect.component.html b/web/projects/ui/src/app/components/form/form-multiselect/form-multiselect.component.html new file mode 100644 index 000000000..0e2a47cc2 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-multiselect/form-multiselect.component.html @@ -0,0 +1,18 @@ + + {{ spec.name }} + + diff --git a/web/projects/ui/src/app/components/form/form-multiselect/form-multiselect.component.ts b/web/projects/ui/src/app/components/form/form-multiselect/form-multiselect.component.ts new file mode 100644 index 000000000..7134eb1f6 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-multiselect/form-multiselect.component.ts @@ -0,0 +1,49 @@ +import { Component } from '@angular/core' +import { CT } from '@start9labs/start-sdk' +import { Control } from '../control' +import { tuiPure } from '@taiga-ui/cdk' +import { invert } from '@start9labs/shared' + +@Component({ + selector: 'form-multiselect', + templateUrl: './form-multiselect.component.html', +}) +export class FormMultiselectComponent extends Control< + CT.ValueSpecMultiselect, + readonly string[] +> { + private readonly inverted = invert(this.spec.values) + + private readonly isDisabled = (item: string) => + Array.isArray(this.spec.disabled) && + this.spec.disabled.includes(this.inverted[item]) + + private readonly isExceedingLimit = (item: string) => + !!this.spec.maxLength && + this.selected.length >= this.spec.maxLength && + !this.selected.includes(item) + + readonly disabledItemHandler = (item: string): boolean => + this.isDisabled(item) || this.isExceedingLimit(item) + + readonly items = Object.values(this.spec.values) + + get disabled(): boolean { + return typeof this.spec.disabled === 'string' + } + + get selected(): string[] { + return this.memoize(this.value) + } + + set selected(value: string[]) { + this.value = Object.entries(this.spec.values) + .filter(([_, v]) => value.includes(v)) + .map(([k]) => k) + } + + @tuiPure + private memoize(value: null | readonly string[]): string[] { + return value?.map(key => this.spec.values[key]) || [] + } +} diff --git a/web/projects/ui/src/app/components/form/form-number/form-number.component.html b/web/projects/ui/src/app/components/form/form-number/form-number.component.html new file mode 100644 index 000000000..c205b2bb8 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-number/form-number.component.html @@ -0,0 +1,18 @@ + + {{ spec.name }} + * + + diff --git a/web/projects/ui/src/app/components/form/form-number/form-number.component.ts b/web/projects/ui/src/app/components/form/form-number/form-number.component.ts new file mode 100644 index 000000000..a930b1614 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-number/form-number.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core' +import { CT } from '@start9labs/start-sdk' +import { Control } from '../control' + +@Component({ + selector: 'form-number', + templateUrl: './form-number.component.html', +}) +export class FormNumberComponent extends Control { + protected readonly Infinity = Infinity +} diff --git a/web/projects/ui/src/app/components/form/form-object/form-object.component.html b/web/projects/ui/src/app/components/form/form-object/form-object.component.html new file mode 100644 index 000000000..589019c15 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-object/form-object.component.html @@ -0,0 +1,25 @@ +

+ + + {{ spec.name }} + +

+ + +
+ +
+
diff --git a/web/projects/ui/src/app/components/form/form-object/form-object.component.scss b/web/projects/ui/src/app/components/form/form-object/form-object.component.scss new file mode 100644 index 000000000..c167c89fa --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-object/form-object.component.scss @@ -0,0 +1,41 @@ +@import '@taiga-ui/core/styles/taiga-ui-local'; + +:host { + display: flex; + flex-direction: column; + align-items: flex-start; +} + +.title { + position: relative; + height: var(--tui-height-l); + display: flex; + align-items: center; + cursor: pointer; + font: var(--tui-font-text-l); + font-weight: bold; + margin: 0 0 -0.75rem; +} + +.button { + @include transition(transform); + + margin-right: 1rem; + + &_open { + transform: rotate(180deg); + } +} + +.expand { + align-self: stretch; +} + +.g-form-group { + padding-top: 0.75rem; + + &_invalid::before, + &_invalid::after { + background: var(--tui-error-bg); + } +} diff --git a/web/projects/ui/src/app/components/form/form-object/form-object.component.ts b/web/projects/ui/src/app/components/form/form-object/form-object.component.ts new file mode 100644 index 000000000..b1aa507cf --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-object/form-object.component.ts @@ -0,0 +1,38 @@ +import { + ChangeDetectionStrategy, + Component, + EventEmitter, + inject, + Input, + Output, +} from '@angular/core' +import { ControlContainer } from '@angular/forms' +import { CT } from '@start9labs/start-sdk' + +@Component({ + selector: 'form-object', + templateUrl: './form-object.component.html', + styleUrls: ['./form-object.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class FormObjectComponent { + @Input() + spec!: CT.ValueSpecObject + + @Input() + open = false + + @Output() + readonly openChange = new EventEmitter() + + private readonly container = inject(ControlContainer) + + get invalid() { + return !this.container.valid && this.container.touched + } + + toggle() { + this.open = !this.open + this.openChange.emit(this.open) + } +} diff --git a/web/projects/ui/src/app/components/form/form-select/form-select.component.html b/web/projects/ui/src/app/components/form/form-select/form-select.component.html new file mode 100644 index 000000000..c10e62018 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-select/form-select.component.html @@ -0,0 +1,17 @@ + + {{ spec.name }} + * + + diff --git a/web/projects/ui/src/app/components/form/form-select/form-select.component.ts b/web/projects/ui/src/app/components/form/form-select/form-select.component.ts new file mode 100644 index 000000000..ccbbccae8 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-select/form-select.component.ts @@ -0,0 +1,30 @@ +import { Component } from '@angular/core' +import { CT } from '@start9labs/start-sdk' +import { invert } from '@start9labs/shared' +import { Control } from '../control' + +@Component({ + selector: 'form-select', + templateUrl: './form-select.component.html', +}) +export class FormSelectComponent extends Control { + private readonly inverted = invert(this.spec.values) + + readonly items = Object.values(this.spec.values) + + readonly disabledItemHandler = (item: string) => + Array.isArray(this.spec.disabled) && + this.spec.disabled.includes(this.inverted[item]) + + get disabled(): boolean { + return typeof this.spec.disabled === 'string' + } + + get selected(): string | null { + return (this.value && this.spec.values[this.value]) || null + } + + set selected(value: string | null) { + this.value = (value && this.inverted[value]) || null + } +} diff --git a/web/projects/ui/src/app/components/form/form-text/form-text.component.html b/web/projects/ui/src/app/components/form/form-text/form-text.component.html new file mode 100644 index 000000000..0db900238 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-text/form-text.component.html @@ -0,0 +1,44 @@ + + {{ spec.name }} + * + + + + + + diff --git a/web/projects/ui/src/app/components/form/form-text/form-text.component.scss b/web/projects/ui/src/app/components/form/form-text/form-text.component.scss new file mode 100644 index 000000000..05e47885b --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-text/form-text.component.scss @@ -0,0 +1,8 @@ +.button { + pointer-events: auto; + margin-left: 0.25rem; +} + +.masked { + -webkit-text-security: disc; +} diff --git a/web/projects/ui/src/app/components/form/form-text/form-text.component.ts b/web/projects/ui/src/app/components/form/form-text/form-text.component.ts new file mode 100644 index 000000000..8a5ac86f0 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-text/form-text.component.ts @@ -0,0 +1,16 @@ +import { Component } from '@angular/core' +import { CT, utils } from '@start9labs/start-sdk' +import { Control } from '../control' + +@Component({ + selector: 'form-text', + templateUrl: './form-text.component.html', + styleUrls: ['./form-text.component.scss'], +}) +export class FormTextComponent extends Control { + masked = true + + generate() { + this.value = utils.getDefaultString(this.spec.generate || '') + } +} diff --git a/web/projects/ui/src/app/components/form/form-textarea/form-textarea.component.html b/web/projects/ui/src/app/components/form/form-textarea/form-textarea.component.html new file mode 100644 index 000000000..7a2bf5149 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-textarea/form-textarea.component.html @@ -0,0 +1,15 @@ + + {{ spec.name }} + * + + diff --git a/web/projects/ui/src/app/components/form/form-textarea/form-textarea.component.ts b/web/projects/ui/src/app/components/form/form-textarea/form-textarea.component.ts new file mode 100644 index 000000000..b32685c21 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-textarea/form-textarea.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core' +import { CT } from '@start9labs/start-sdk' +import { Control } from '../control' + +@Component({ + selector: 'form-textarea', + templateUrl: './form-textarea.component.html', +}) +export class FormTextareaComponent extends Control< + CT.ValueSpecTextarea, + string +> {} diff --git a/web/projects/ui/src/app/components/form/form-toggle/form-toggle.component.html b/web/projects/ui/src/app/components/form/form-toggle/form-toggle.component.html new file mode 100644 index 000000000..73d116f92 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-toggle/form-toggle.component.html @@ -0,0 +1,11 @@ +{{ spec.name }} + + diff --git a/web/projects/ui/src/app/components/form/form-toggle/form-toggle.component.ts b/web/projects/ui/src/app/components/form/form-toggle/form-toggle.component.ts new file mode 100644 index 000000000..6a3c0196f --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-toggle/form-toggle.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core' +import { CT } from '@start9labs/start-sdk' +import { Control } from '../control' + +@Component({ + selector: 'form-toggle', + templateUrl: './form-toggle.component.html', + host: { class: 'g-toggle' }, +}) +export class FormToggleComponent extends Control {} diff --git a/web/projects/ui/src/app/components/form/form-union/form-union.component.html b/web/projects/ui/src/app/components/form/form-union/form-union.component.html new file mode 100644 index 000000000..1cb5bfe57 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-union/form-union.component.html @@ -0,0 +1,11 @@ + + + + diff --git a/web/projects/ui/src/app/components/form/form-union/form-union.component.scss b/web/projects/ui/src/app/components/form/form-union/form-union.component.scss new file mode 100644 index 000000000..cfb2f95e8 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-union/form-union.component.scss @@ -0,0 +1,8 @@ +:host { + display: block; +} + +.group { + display: block; + margin-top: 1rem; +} diff --git a/web/projects/ui/src/app/components/form/form-union/form-union.component.ts b/web/projects/ui/src/app/components/form/form-union/form-union.component.ts new file mode 100644 index 000000000..2c164be48 --- /dev/null +++ b/web/projects/ui/src/app/components/form/form-union/form-union.component.ts @@ -0,0 +1,55 @@ +import { + ChangeDetectionStrategy, + Component, + inject, + Input, + OnChanges, +} from '@angular/core' +import { ControlContainer, FormGroupName } from '@angular/forms' +import { CT } from '@start9labs/start-sdk' +import { FormService } from 'src/app/services/form.service' +import { tuiPure } from '@taiga-ui/cdk' + +@Component({ + selector: 'form-union', + templateUrl: './form-union.component.html', + styleUrls: ['./form-union.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + viewProviders: [ + { + provide: ControlContainer, + useExisting: FormGroupName, + }, + ], +}) +export class FormUnionComponent implements OnChanges { + @Input() + spec!: CT.ValueSpecUnion + + selectSpec!: CT.ValueSpecSelect + + private readonly form = inject(FormGroupName) + private readonly formService = inject(FormService) + + get union(): string { + return this.form.value.selection + } + + @tuiPure + onUnion(union: string) { + this.form.control.setControl( + 'value', + this.formService.getFormGroup( + union ? this.spec.variants[union].spec : {}, + ), + { + emitEvent: false, + }, + ) + } + + ngOnChanges() { + this.selectSpec = this.formService.getUnionSelectSpec(this.spec, this.union) + if (this.union) this.onUnion(this.union) + } +} diff --git a/web/projects/ui/src/app/components/form/form.module.ts b/web/projects/ui/src/app/components/form/form.module.ts new file mode 100644 index 000000000..fe16b229f --- /dev/null +++ b/web/projects/ui/src/app/components/form/form.module.ts @@ -0,0 +1,109 @@ +import { NgModule } from '@angular/core' +import { CommonModule } from '@angular/common' +import { FormsModule, ReactiveFormsModule } from '@angular/forms' +import { MaskitoModule } from '@maskito/angular' +import { TuiMapperPipeModule, TuiValueChangesModule } from '@taiga-ui/cdk' +import { + TuiErrorModule, + TuiExpandModule, + TuiHintModule, + TuiLinkModule, + TuiModeModule, + TuiTextfieldControllerModule, + TuiTooltipModule, +} from '@taiga-ui/core' +import { + TuiAppearanceModule, + TuiButtonModule, + TuiIconModule, +} from '@taiga-ui/experimental' +import { + TuiElasticContainerModule, + TuiFieldErrorPipeModule, + TuiInputDateModule, + TuiInputDateTimeModule, + TuiInputFilesModule, + TuiInputModule, + TuiInputNumberModule, + TuiInputTimeModule, + TuiMultiSelectModule, + TuiPromptModule, + TuiSelectModule, + TuiTagModule, + TuiTextAreaModule, + TuiToggleModule, +} from '@taiga-ui/kit' + +import { FormGroupComponent } from './form-group/form-group.component' +import { FormTextComponent } from './form-text/form-text.component' +import { FormToggleComponent } from './form-toggle/form-toggle.component' +import { FormTextareaComponent } from './form-textarea/form-textarea.component' +import { FormNumberComponent } from './form-number/form-number.component' +import { FormSelectComponent } from './form-select/form-select.component' +import { FormFileComponent } from './form-file/form-file.component' +import { FormMultiselectComponent } from './form-multiselect/form-multiselect.component' +import { FormUnionComponent } from './form-union/form-union.component' +import { FormObjectComponent } from './form-object/form-object.component' +import { FormArrayComponent } from './form-array/form-array.component' +import { FormControlComponent } from './form-control/form-control.component' +import { MustachePipe } from './mustache.pipe' +import { ControlDirective } from './control.directive' +import { FormColorComponent } from './form-color/form-color.component' +import { FormDatetimeComponent } from './form-datetime/form-datetime.component' +import { HintPipe } from './hint.pipe' + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + ReactiveFormsModule, + TuiInputModule, + TuiInputNumberModule, + TuiInputFilesModule, + TuiTextAreaModule, + TuiSelectModule, + TuiMultiSelectModule, + TuiToggleModule, + TuiTooltipModule, + TuiHintModule, + TuiModeModule, + TuiTagModule, + TuiButtonModule, + TuiExpandModule, + TuiTextfieldControllerModule, + TuiLinkModule, + TuiPromptModule, + TuiErrorModule, + TuiFieldErrorPipeModule, + TuiValueChangesModule, + TuiElasticContainerModule, + MaskitoModule, + TuiIconModule, + TuiAppearanceModule, + TuiInputDateModule, + TuiInputTimeModule, + TuiInputDateTimeModule, + TuiMapperPipeModule, + ], + declarations: [ + FormGroupComponent, + FormControlComponent, + FormColorComponent, + FormDatetimeComponent, + FormTextComponent, + FormToggleComponent, + FormTextareaComponent, + FormNumberComponent, + FormSelectComponent, + FormMultiselectComponent, + FormFileComponent, + FormUnionComponent, + FormObjectComponent, + FormArrayComponent, + MustachePipe, + HintPipe, + ControlDirective, + ], + exports: [FormGroupComponent], +}) +export class FormModule {} diff --git a/web/projects/ui/src/app/components/form/hint.pipe.ts b/web/projects/ui/src/app/components/form/hint.pipe.ts new file mode 100644 index 000000000..b5a730661 --- /dev/null +++ b/web/projects/ui/src/app/components/form/hint.pipe.ts @@ -0,0 +1,21 @@ +import { Pipe, PipeTransform } from '@angular/core' +import { CT } from '@start9labs/start-sdk' + +@Pipe({ + name: 'hint', +}) +export class HintPipe implements PipeTransform { + transform(spec: CT.ValueSpec): string { + const hint = [] + + if (spec.description) { + hint.push(spec.description) + } + + if ('disabled' in spec && typeof spec.disabled === 'string') { + hint.push(`Disabled: ${spec.disabled}`) + } + + return hint.join('\n\n') + } +} diff --git a/web/projects/ui/src/app/components/form/invalid.service.ts b/web/projects/ui/src/app/components/form/invalid.service.ts new file mode 100644 index 000000000..9f474e853 --- /dev/null +++ b/web/projects/ui/src/app/components/form/invalid.service.ts @@ -0,0 +1,19 @@ +import { Injectable } from '@angular/core' +import { ControlDirective } from './control.directive' + +@Injectable() +export class InvalidService { + private readonly controls: ControlDirective[] = [] + + scrollIntoView() { + this.controls.find(({ invalid }) => invalid)?.scrollIntoView() + } + + add(control: ControlDirective) { + this.controls.push(control) + } + + remove(control: ControlDirective) { + this.controls.splice(this.controls.indexOf(control), 1) + } +} diff --git a/web/projects/ui/src/app/components/form/mustache.pipe.ts b/web/projects/ui/src/app/components/form/mustache.pipe.ts new file mode 100644 index 000000000..ec04b0104 --- /dev/null +++ b/web/projects/ui/src/app/components/form/mustache.pipe.ts @@ -0,0 +1,12 @@ +import { Pipe, PipeTransform } from '@angular/core' + +const Mustache = require('mustache') + +@Pipe({ + name: 'mustache', +}) +export class MustachePipe implements PipeTransform { + transform(value: any, displayAs: string): string { + return displayAs && Mustache.render(displayAs, value) + } +} diff --git a/web/projects/ui/src/app/components/logs/logs.component.ts b/web/projects/ui/src/app/components/logs/logs.component.ts index 8ce328f91..c1ed61f09 100644 --- a/web/projects/ui/src/app/components/logs/logs.component.ts +++ b/web/projects/ui/src/app/components/logs/logs.component.ts @@ -1,5 +1,15 @@ import { Component, Input, ViewChild } from '@angular/core' -import { IonContent, LoadingController } from '@ionic/angular' +import { IonContent } from '@ionic/angular' +import { + DownloadHTMLService, + ErrorService, + LoadingService, + Log, + LogsRes, + ServerLogsReq, + toLocalIsoString, +} from '@start9labs/shared' +import { TuiDestroyService } from '@taiga-ui/cdk' import { bufferTime, catchError, @@ -11,15 +21,6 @@ import { takeUntil, tap, } from 'rxjs' -import { - LogsRes, - ServerLogsReq, - ErrorToastService, - toLocalIsoString, - Log, - DownloadHTMLService, -} from '@start9labs/shared' -import { TuiDestroyService } from '@taiga-ui/cdk' import { RR } from 'src/app/services/api/api.types' import { ApiService } from 'src/app/services/api/embassy-api.service' import { ConnectionService } from 'src/app/services/connection.service' @@ -66,10 +67,10 @@ export class LogsComponent { count = 0 constructor( - private readonly errToast: ErrorToastService, + private readonly errorService: ErrorService, private readonly destroy$: TuiDestroyService, private readonly api: ApiService, - private readonly loadingCtrl: LoadingController, + private readonly loader: LoadingService, private readonly downloadHtml: DownloadHTMLService, private readonly connection$: ConnectionService, ) {} @@ -97,7 +98,7 @@ export class LogsComponent { this.processRes(res) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { e.target.complete() } @@ -119,10 +120,7 @@ export class LogsComponent { } async download() { - const loader = await this.loadingCtrl.create({ - message: 'Processing 10,000 logs...', - }) - await loader.present() + const loader = this.loader.open('Processing 10,000 logs...').subscribe() try { const { entries } = await this.fetchLogs({ @@ -139,9 +137,9 @@ export class LogsComponent { this.downloadHtml.download(`${this.context}-logs.html`, html, styles) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } diff --git a/web/projects/ui/src/app/components/toast-container/refresh-alert/refresh-alert.component.ts b/web/projects/ui/src/app/components/toast-container/refresh-alert/refresh-alert.component.ts index f039841d3..04943eb1a 100644 --- a/web/projects/ui/src/app/components/toast-container/refresh-alert/refresh-alert.component.ts +++ b/web/projects/ui/src/app/components/toast-container/refresh-alert/refresh-alert.component.ts @@ -1,9 +1,9 @@ import { ChangeDetectionStrategy, Component, Inject } from '@angular/core' +import { SwUpdate } from '@angular/service-worker' +import { LoadingService } from '@start9labs/shared' import { merge, Observable, Subject } from 'rxjs' import { RefreshAlertService } from './refresh-alert.service' -import { SwUpdate } from '@angular/service-worker' -import { LoadingController } from '@ionic/angular' @Component({ selector: 'refresh-alert', @@ -18,7 +18,7 @@ export class RefreshAlertComponent { constructor( @Inject(RefreshAlertService) private readonly refresh$: Observable, private readonly updates: SwUpdate, - private readonly loadingCtrl: LoadingController, + private readonly loader: LoadingService, ) {} ngOnInit() { @@ -26,17 +26,14 @@ export class RefreshAlertComponent { } async pwaReload() { - const loader = await this.loadingCtrl.create({ - message: 'Reloading PWA...', - }) - await loader.present() + const loader = this.loader.open('Reloading PWA...').subscribe() try { // attempt to update to the latest client version available await this.updates.activateUpdate() } catch (e) { console.error('Error activating update from service worker: ', e) } finally { - loader.dismiss() + loader.unsubscribe() // always reload, as this resolves most out of sync cases window.location.reload() } diff --git a/web/projects/ui/src/app/components/toast-container/update-toast/update-toast.component.ts b/web/projects/ui/src/app/components/toast-container/update-toast/update-toast.component.ts index 72b6956ee..276260ba8 100644 --- a/web/projects/ui/src/app/components/toast-container/update-toast/update-toast.component.ts +++ b/web/projects/ui/src/app/components/toast-container/update-toast/update-toast.component.ts @@ -1,10 +1,9 @@ import { ChangeDetectionStrategy, Component, Inject } from '@angular/core' -import { LoadingController } from '@ionic/angular' -import { ErrorToastService } from '@start9labs/shared' -import { Observable, Subject, merge } from 'rxjs' +import { ErrorService, LoadingService } from '@start9labs/shared' +import { merge, Observable, Subject } from 'rxjs' +import { ApiService } from '../../../services/api/embassy-api.service' import { UpdateToastService } from './update-toast.service' -import { ApiService } from '../../../services/api/embassy-api.service' @Component({ selector: 'update-toast', @@ -19,8 +18,8 @@ export class UpdateToastComponent { constructor( @Inject(UpdateToastService) private readonly update$: Observable, private readonly embassyApi: ApiService, - private readonly errToast: ErrorToastService, - private readonly loadingCtrl: LoadingController, + private readonly errorService: ErrorService, + private readonly loader: LoadingService, ) {} onDismiss() { @@ -30,18 +29,14 @@ export class UpdateToastComponent { async restart(): Promise { this.onDismiss() - const loader = await this.loadingCtrl.create({ - message: 'Restarting...', - }) - - await loader.present() + const loader = this.loader.open('Restarting...').subscribe() try { await this.embassyApi.restartServer({}) } catch (e: any) { - await this.errToast.present(e) + await this.errorService.handleError(e) } finally { - await loader.dismiss() + await loader.unsubscribe() } } } diff --git a/web/projects/ui/src/app/modals/app-config/app-config.module.ts b/web/projects/ui/src/app/modals/app-config/app-config.module.ts deleted file mode 100644 index fde422826..000000000 --- a/web/projects/ui/src/app/modals/app-config/app-config.module.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { NgModule } from '@angular/core' -import { CommonModule } from '@angular/common' -import { FormsModule, ReactiveFormsModule } from '@angular/forms' -import { IonicModule } from '@ionic/angular' -import { AppConfigPage } from './app-config.page' -import { TextSpinnerComponentModule } from '@start9labs/shared' -import { FormObjectComponentModule } from 'src/app/components/form-object/form-object.component.module' - -@NgModule({ - declarations: [AppConfigPage], - imports: [ - CommonModule, - FormsModule, - IonicModule, - TextSpinnerComponentModule, - FormObjectComponentModule, - ReactiveFormsModule, - ], - exports: [AppConfigPage], -}) -export class AppConfigPageModule {} diff --git a/web/projects/ui/src/app/modals/app-config/app-config.page.html b/web/projects/ui/src/app/modals/app-config/app-config.page.html deleted file mode 100644 index 42eb6cf39..000000000 --- a/web/projects/ui/src/app/modals/app-config/app-config.page.html +++ /dev/null @@ -1,144 +0,0 @@ - - - Config - - - - - - - - - - - - - - - - - {{ loadingError }} - - - - - - -

- - {{ manifest.title }} has been automatically configured with - recommended defaults. Make whatever changes you want, then click - "Save". - -

-
- -

- - New config options! To accept the default values, click "Save". - You may also customize these new options below. - -

-
-
- - - - -

- - - {{ manifest.title }} - -

-

- - The following modifications have been made to {{ manifest.title }} - to satisfy {{ dependentInfo.title }}: -

    -
  • -
- To accept these modifications, click "Save". - -

-
-
- - - - -

- No config options for {{ manifest.title }} {{ manifest.version }}. -

-
-
- - -
- -
-
-
-
- - - - - - - - Reset Defaults - - - - - Save - - - Close - - - - - diff --git a/web/projects/ui/src/app/modals/app-config/app-config.page.scss b/web/projects/ui/src/app/modals/app-config/app-config.page.scss deleted file mode 100644 index e568528a8..000000000 --- a/web/projects/ui/src/app/modals/app-config/app-config.page.scss +++ /dev/null @@ -1,12 +0,0 @@ -.notifier-item { - margin: 12px; - margin-top: 0px; - border-radius: 12px; - // kills the lines - --border-width: 0; - --inner-border-width: 0; -} - -.header-details { - font-size: 20px; -} \ No newline at end of file diff --git a/web/projects/ui/src/app/modals/app-config/app-config.page.ts b/web/projects/ui/src/app/modals/app-config/app-config.page.ts deleted file mode 100644 index 4bba83acb..000000000 --- a/web/projects/ui/src/app/modals/app-config/app-config.page.ts +++ /dev/null @@ -1,349 +0,0 @@ -import { Component, Input } from '@angular/core' -import { - AlertController, - ModalController, - LoadingController, - IonicSafeString, -} from '@ionic/angular' -import { ApiService } from 'src/app/services/api/embassy-api.service' -import { - ErrorToastService, - getErrorMessage, - isEmptyObject, - isObject, -} from '@start9labs/shared' -import { DependentInfo } from 'src/app/types/dependent-info' -import { ConfigSpec } from 'src/app/pkg-config/config-types' -import { - DataModel, - InstalledState, - PackageDataEntry, -} from 'src/app/services/patch-db/data-model' -import { PatchDB } from 'patch-db-client' -import { UntypedFormGroup } from '@angular/forms' -import { - convertValuesRecursive, - FormService, -} from 'src/app/services/form.service' -import { compare, Operation, getValueByPointer } from 'fast-json-patch' -import { hasCurrentDeps } from 'src/app/util/has-deps' -import { - getAllPackages, - getManifest, - getPackage, - isInstalled, -} from 'src/app/util/get-package-data' -import { Breakages } from 'src/app/services/api/api.types' - -@Component({ - selector: 'app-config', - templateUrl: './app-config.page.html', - styleUrls: ['./app-config.page.scss'], -}) -export class AppConfigPage { - @Input() pkgId!: string - - @Input() dependentInfo?: DependentInfo - - pkg!: PackageDataEntry - loadingText = '' - - configSpec?: ConfigSpec - configForm?: UntypedFormGroup - - original?: object // only if existing config - diff?: string[] // only if dependent info - - loading = true - hasNewOptions = false - saving = false - loadingError: string | IonicSafeString = '' - - constructor( - private readonly embassyApi: ApiService, - private readonly errToast: ErrorToastService, - private readonly loadingCtrl: LoadingController, - private readonly alertCtrl: AlertController, - private readonly modalCtrl: ModalController, - private readonly formService: FormService, - private readonly patch: PatchDB, - ) {} - - get hasConfig() { - return this.pkg.stateInfo.manifest.hasConfig - } - - async ngOnInit() { - try { - const pkg = await getPackage(this.patch, this.pkgId) - if (!pkg || !isInstalled(pkg)) return - - this.pkg = pkg - - if (!this.hasConfig) return - - let newConfig: object | undefined - let patch: Operation[] | undefined - - if (this.dependentInfo) { - this.loadingText = `Setting properties to accommodate ${this.dependentInfo.title}` - const { - oldConfig: oc, - newConfig: nc, - spec: s, - } = await this.embassyApi.dryConfigureDependency({ - dependencyId: this.pkgId, - dependentId: this.dependentInfo.id, - }) - this.original = oc - newConfig = nc - this.configSpec = s - patch = compare(this.original, newConfig) - } else { - this.loadingText = 'Loading Config' - const { config: c, spec: s } = await this.embassyApi.getPackageConfig({ - id: this.pkgId, - }) - this.original = c - this.configSpec = s - } - - this.configForm = this.formService.createForm( - this.configSpec, - newConfig || this.original, - ) - - if (patch) { - this.diff = this.getDiff(patch) - this.markDirty(patch) - } - } catch (e: any) { - this.loadingError = getErrorMessage(e) - } finally { - this.loading = false - } - } - - resetDefaults() { - this.configForm = this.formService.createForm(this.configSpec!) - const patch = compare(this.original || {}, this.configForm.value) - this.markDirty(patch) - } - - async dismiss() { - if (this.configForm?.dirty) { - this.presentAlertUnsaved() - } else { - this.modalCtrl.dismiss() - } - } - - async tryConfigure() { - convertValuesRecursive(this.configSpec!, this.configForm!) - - if (this.configForm!.invalid) { - document - .getElementsByClassName('validation-error')[0] - ?.scrollIntoView({ behavior: 'smooth' }) - return - } - - this.saving = true - - if (hasCurrentDeps(this.pkgId, await getAllPackages(this.patch))) { - this.dryConfigure() - } else { - this.configure() - } - } - - private async dryConfigure() { - const loader = await this.loadingCtrl.create({ - message: 'Checking dependent services...', - }) - await loader.present() - - try { - const breakages = await this.embassyApi.drySetPackageConfig({ - id: this.pkgId, - config: this.configForm!.value, - }) - - if (isEmptyObject(breakages)) { - this.configure(loader) - } else { - await loader.dismiss() - const proceed = await this.presentAlertBreakages(breakages) - if (proceed) { - this.configure() - } else { - this.saving = false - } - } - } catch (e: any) { - this.errToast.present(e) - this.saving = false - loader.dismiss() - } - } - - private async configure(loader?: HTMLIonLoadingElement) { - const message = 'Saving...' - if (loader) { - loader.message = message - } else { - loader = await this.loadingCtrl.create({ message }) - await loader.present() - } - - try { - await this.embassyApi.setPackageConfig({ - id: this.pkgId, - config: this.configForm!.value, - }) - this.modalCtrl.dismiss() - } catch (e: any) { - this.errToast.present(e) - } finally { - this.saving = false - loader.dismiss() - } - } - - private async presentAlertBreakages(breakages: Breakages): Promise { - let message: string = - 'As a result of this change, the following services will no longer work properly and may crash:
    ' - const localPkgs = await getAllPackages(this.patch) - const bullets = Object.keys(breakages).map(id => { - const title = getManifest(localPkgs[id]).title - return `
  • ${title}
  • ` - }) - message = `${message}${bullets}
` - - return new Promise(async resolve => { - const alert = await this.alertCtrl.create({ - header: 'Warning', - message, - buttons: [ - { - text: 'Cancel', - role: 'cancel', - handler: () => { - resolve(false) - }, - }, - { - text: 'Continue', - handler: () => { - resolve(true) - }, - cssClass: 'enter-click', - }, - ], - cssClass: 'alert-warning-message', - }) - - await alert.present() - }) - } - - private getDiff(patch: Operation[]): string[] { - return patch.map(op => { - let message: string - switch (op.op) { - case 'add': - message = `Added ${this.getNewValue(op.value)}` - break - case 'remove': - message = `Removed ${this.getOldValue(op.path)}` - break - case 'replace': - message = `Changed from ${this.getOldValue( - op.path, - )} to ${this.getNewValue(op.value)}` - break - default: - message = `Unknown operation` - } - - let displayPath: string - - const arrPath = op.path - .substring(1) - .split('/') - .map(node => { - const num = Number(node) - return isNaN(num) ? node : num - }) - - if (typeof arrPath[arrPath.length - 1] === 'number') { - arrPath.pop() - } - - displayPath = arrPath.join(' → ') - - return `${displayPath}: ${message}` - }) - } - - private getOldValue(path: any): string { - const val = getValueByPointer(this.original, path) - if (['string', 'number', 'boolean'].includes(typeof val)) { - return val - } else if (isObject(val)) { - return 'entry' - } else { - return 'list' - } - } - - private getNewValue(val: any): string { - if (['string', 'number', 'boolean'].includes(typeof val)) { - return val - } else if (isObject(val)) { - return 'new entry' - } else { - return 'new list' - } - } - - private markDirty(patch: Operation[]) { - patch.forEach(op => { - const arrPath = op.path - .substring(1) - .split('/') - .map(node => { - const num = Number(node) - return isNaN(num) ? node : num - }) - - if (op.op !== 'remove') this.configForm!.get(arrPath)?.markAsDirty() - - if (typeof arrPath[arrPath.length - 1] === 'number') { - const prevPath = arrPath.slice(0, arrPath.length - 1) - this.configForm!.get(prevPath)?.markAsDirty() - } - }) - } - - private async presentAlertUnsaved() { - const alert = await this.alertCtrl.create({ - header: 'Unsaved Changes', - message: 'You have unsaved changes. Are you sure you want to leave?', - buttons: [ - { - text: 'Cancel', - role: 'cancel', - }, - { - text: `Leave`, - handler: () => { - this.modalCtrl.dismiss() - }, - cssClass: 'enter-click', - }, - ], - }) - await alert.present() - } -} diff --git a/web/projects/ui/src/app/modals/app-recover-select/app-recover-select.page.ts b/web/projects/ui/src/app/modals/app-recover-select/app-recover-select.page.ts index 15bec3d4f..e1d637ecf 100644 --- a/web/projects/ui/src/app/modals/app-recover-select/app-recover-select.page.ts +++ b/web/projects/ui/src/app/modals/app-recover-select/app-recover-select.page.ts @@ -1,16 +1,12 @@ import { Component, Input } from '@angular/core' -import { - LoadingController, - ModalController, - IonicSafeString, -} from '@ionic/angular' -import { getErrorMessage } from '@start9labs/shared' +import { IonicSafeString, ModalController } from '@ionic/angular' +import { getErrorMessage, LoadingService } from '@start9labs/shared' +import { PatchDB } from 'patch-db-client' +import { take } from 'rxjs' import { BackupInfo } from 'src/app/services/api/api.types' import { ApiService } from 'src/app/services/api/embassy-api.service' -import { PatchDB } from 'patch-db-client' -import { AppRecoverOption } from './to-options.pipe' import { DataModel } from 'src/app/services/patch-db/data-model' -import { take } from 'rxjs' +import { AppRecoverOption } from './to-options.pipe' @Component({ selector: 'app-recover-select', @@ -30,7 +26,7 @@ export class AppRecoverSelectPage { constructor( private readonly modalCtrl: ModalController, - private readonly loadingCtrl: LoadingController, + private readonly loader: LoadingService, private readonly embassyApi: ApiService, private readonly patch: PatchDB, ) {} @@ -45,10 +41,7 @@ export class AppRecoverSelectPage { async restore(options: AppRecoverOption[]): Promise { const ids = options.filter(({ checked }) => !!checked).map(({ id }) => id) - const loader = await this.loadingCtrl.create({ - message: 'Initializing...', - }) - await loader.present() + const loader = this.loader.open('Initializing...').subscribe() try { await this.embassyApi.restorePackages({ @@ -61,7 +54,7 @@ export class AppRecoverSelectPage { } catch (e: any) { this.error = getErrorMessage(e) } finally { - loader.dismiss() + loader.unsubscribe() } } } diff --git a/web/projects/ui/src/app/modals/config-dep.component.ts b/web/projects/ui/src/app/modals/config-dep.component.ts new file mode 100644 index 000000000..14becf2e8 --- /dev/null +++ b/web/projects/ui/src/app/modals/config-dep.component.ts @@ -0,0 +1,104 @@ +import { + ChangeDetectionStrategy, + Component, + Input, + OnChanges, +} from '@angular/core' +import { compare, getValueByPointer, Operation } from 'fast-json-patch' +import { isObject } from '@start9labs/shared' +import { tuiIsNumber } from '@taiga-ui/cdk' +import { CommonModule } from '@angular/common' +import { TuiNotificationModule } from '@taiga-ui/core' + +@Component({ + selector: 'config-dep', + template: ` + +

+ {{ package }} +

+ The following modifications have been made to {{ package }} to satisfy + {{ dep }}: +
    +
  • +
+ To accept these modifications, click "Save". +
+ `, + standalone: true, + imports: [CommonModule, TuiNotificationModule], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ConfigDepComponent implements OnChanges { + @Input() + package = '' + + @Input() + dep = '' + + @Input() + original: object = {} + + @Input() + value: object = {} + + diff: string[] = [] + + ngOnChanges() { + this.diff = compare(this.original, this.value).map( + op => `${this.getPath(op)}: ${this.getMessage(op)}`, + ) + } + + private getPath(operation: Operation): string { + const path = operation.path + .substring(1) + .split('/') + .map(node => { + const num = Number(node) + return isNaN(num) ? node : num + }) + + if (tuiIsNumber(path[path.length - 1])) { + path.pop() + } + + return path.join(' → ') + } + + private getMessage(operation: Operation): string { + switch (operation.op) { + case 'add': + return `Added ${this.getNewValue(operation.value)}` + case 'remove': + return `Removed ${this.getOldValue(operation.path)}` + case 'replace': + return `Changed from ${this.getOldValue( + operation.path, + )} to ${this.getNewValue(operation.value)}` + default: + return `Unknown operation` + } + } + + private getOldValue(path: any): string { + const val = getValueByPointer(this.original, path) + if (['string', 'number', 'boolean'].includes(typeof val)) { + return val + } else if (isObject(val)) { + return 'entry' + } else { + return 'list' + } + } + + private getNewValue(val: any): string { + if (['string', 'number', 'boolean'].includes(typeof val)) { + return val + } else if (isObject(val)) { + return 'new entry' + } else { + return 'new list' + } + } +} diff --git a/web/projects/ui/src/app/modals/config.component.ts b/web/projects/ui/src/app/modals/config.component.ts new file mode 100644 index 000000000..194302f5f --- /dev/null +++ b/web/projects/ui/src/app/modals/config.component.ts @@ -0,0 +1,281 @@ +import { CommonModule } from '@angular/common' +import { Component, Inject, ViewChild } from '@angular/core' +import { + ErrorService, + getErrorMessage, + isEmptyObject, + LoadingService, +} from '@start9labs/shared' +import { CT } from '@start9labs/start-sdk' +import { TuiButtonModule } from '@taiga-ui/experimental' +import { + TuiDialogContext, + TuiDialogService, + TuiLoaderModule, + TuiModeModule, + TuiNotificationModule, +} from '@taiga-ui/core' +import { TUI_PROMPT, TuiPromptData } from '@taiga-ui/kit' +import { POLYMORPHEUS_CONTEXT } from '@tinkoff/ng-polymorpheus' +import { compare, Operation } from 'fast-json-patch' +import { PatchDB } from 'patch-db-client' +import { endWith, firstValueFrom, Subscription } from 'rxjs' +import { ActionButton, FormComponent } from 'src/app/components/form.component' +import { InvalidService } from 'src/app/components/form/invalid.service' +import { ConfigDepComponent } from 'src/app/modals/config-dep.component' +import { UiPipeModule } from 'src/app/pipes/ui/ui.module' +import { ApiService } from 'src/app/services/api/embassy-api.service' +import { + DataModel, + PackageDataEntry, +} from 'src/app/services/patch-db/data-model' +import { + getAllPackages, + getManifest, + getPackage, +} from 'src/app/util/get-package-data' +import { hasCurrentDeps } from 'src/app/util/has-deps' +import { Breakages } from 'src/app/services/api/api.types' +import { DependentInfo } from 'src/app/types/dependent-info' + +export interface PackageConfigData { + readonly pkgId: string + readonly dependentInfo?: DependentInfo +} + +@Component({ + template: ` + + + +
+
+ + + + {{ manifest.title }} has been automatically configured with recommended + defaults. Make whatever changes you want, then click "Save". + + + + + + No config options for {{ manifest.title }} {{ manifest.version }}. + + + + + + + `, + styles: [ + ` + tui-notification { + font-size: 1rem; + margin-bottom: 1rem; + } + `, + ], + standalone: true, + imports: [ + CommonModule, + FormComponent, + TuiLoaderModule, + TuiNotificationModule, + TuiButtonModule, + TuiModeModule, + ConfigDepComponent, + UiPipeModule, + ], + providers: [InvalidService], +}) +export class ConfigModal { + @ViewChild(FormComponent) + private readonly form?: FormComponent> + + readonly pkgId = this.context.data.pkgId + readonly dependentInfo = this.context.data.dependentInfo + + loadingError = '' + loadingText = this.dependentInfo + ? `Setting properties to accommodate ${this.dependentInfo.title}` + : 'Loading Config' + + pkg?: PackageDataEntry + spec: CT.InputSpec = {} + patch: Operation[] = [] + buttons: ActionButton[] = [ + { + text: 'Save', + handler: value => this.save(value), + }, + ] + + original: object | null = null + value: object | null = null + + constructor( + @Inject(POLYMORPHEUS_CONTEXT) + private readonly context: TuiDialogContext, + private readonly dialogs: TuiDialogService, + private readonly errorService: ErrorService, + private readonly loader: LoadingService, + private readonly embassyApi: ApiService, + private readonly patchDb: PatchDB, + ) {} + + get success(): boolean { + return ( + !!this.form && + !this.form.form.dirty && + !this.original && + !this.pkg?.status?.configured + ) + } + + async ngOnInit() { + try { + this.pkg = await getPackage(this.patchDb, this.pkgId) + + if (!this.pkg) { + this.loadingError = 'This service does not exist' + + return + } + + if (this.dependentInfo) { + const depConfig = await this.embassyApi.dryConfigureDependency({ + dependencyId: this.pkgId, + dependentId: this.dependentInfo.id, + }) + + this.original = depConfig.oldConfig + this.value = depConfig.newConfig || this.original + this.spec = depConfig.spec + this.patch = compare(this.original, this.value) + } else { + const { config, spec } = await this.embassyApi.getPackageConfig({ + id: this.pkgId, + }) + + this.original = config + this.value = config + this.spec = spec + } + } catch (e: any) { + this.loadingError = String(getErrorMessage(e)) + } finally { + this.loadingText = '' + } + } + + private async save(config: any) { + const loader = new Subscription() + + try { + await this.uploadFiles(config, loader) + + if (hasCurrentDeps(this.pkgId, await getAllPackages(this.patchDb))) { + await this.configureDeps(config, loader) + } else { + await this.configure(config, loader) + } + } catch (e: any) { + this.errorService.handleError(e) + } finally { + loader.unsubscribe() + } + } + + private async uploadFiles(config: Record, loader: Subscription) { + loader.unsubscribe() + loader.closed = false + + // TODO: Could be nested files + const keys = Object.keys(config).filter(key => config[key] instanceof File) + const message = `Uploading File${keys.length > 1 ? 's' : ''}...` + + if (!keys.length) return + + loader.add(this.loader.open(message).subscribe()) + + const hashes = await Promise.all( + keys.map(key => this.embassyApi.uploadFile(config[key])), + ) + keys.forEach((key, i) => (config[key] = hashes[i])) + } + + private async configureDeps( + config: Record, + loader: Subscription, + ) { + loader.unsubscribe() + loader.closed = false + loader.add(this.loader.open('Checking dependent services...').subscribe()) + + const breakages = await this.embassyApi.drySetPackageConfig({ + id: this.pkgId, + config, + }) + + loader.unsubscribe() + loader.closed = false + + if (isEmptyObject(breakages) || (await this.approveBreakages(breakages))) { + await this.configure(config, loader) + } + } + + private async configure(config: Record, loader: Subscription) { + loader.unsubscribe() + loader.closed = false + loader.add(this.loader.open('Saving...').subscribe()) + + await this.embassyApi.setPackageConfig({ id: this.pkgId, config }) + this.context.$implicit.complete() + } + + private async approveBreakages(breakages: Breakages): Promise { + const packages = await getAllPackages(this.patchDb) + const message = + 'As a result of this change, the following services will no longer work properly and may crash:
    ' + const content = `${message}${Object.keys(breakages).map( + id => `
  • ${getManifest(packages[id]).title}
  • `, + )}
` + const data: TuiPromptData = { content, yes: 'Continue', no: 'Cancel' } + + return firstValueFrom( + this.dialogs.open(TUI_PROMPT, { data }).pipe(endWith(false)), + ) + } +} diff --git a/web/projects/ui/src/app/modals/enum-list/enum-list.module.ts b/web/projects/ui/src/app/modals/enum-list/enum-list.module.ts deleted file mode 100644 index a0acb46d5..000000000 --- a/web/projects/ui/src/app/modals/enum-list/enum-list.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { NgModule } from '@angular/core' -import { CommonModule } from '@angular/common' -import { IonicModule } from '@ionic/angular' -import { EnumListPage } from './enum-list.page' -import { FormsModule } from '@angular/forms' - -@NgModule({ - declarations: [EnumListPage], - imports: [CommonModule, IonicModule, FormsModule], - exports: [EnumListPage], -}) -export class EnumListPageModule {} diff --git a/web/projects/ui/src/app/modals/enum-list/enum-list.page.html b/web/projects/ui/src/app/modals/enum-list/enum-list.page.html deleted file mode 100644 index 5cc74ba21..000000000 --- a/web/projects/ui/src/app/modals/enum-list/enum-list.page.html +++ /dev/null @@ -1,45 +0,0 @@ - - - {{ spec.name }} - - - - - - - - - - - - - - {{ selectAll ? 'Select All' : 'Deselect All' }} - - - - - {{ spec.spec['value-names'][option.key] }} - - - - - - - - - - Done - - - - diff --git a/web/projects/ui/src/app/modals/enum-list/enum-list.page.scss b/web/projects/ui/src/app/modals/enum-list/enum-list.page.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/web/projects/ui/src/app/modals/enum-list/enum-list.page.ts b/web/projects/ui/src/app/modals/enum-list/enum-list.page.ts deleted file mode 100644 index e5ddc8ed3..000000000 --- a/web/projects/ui/src/app/modals/enum-list/enum-list.page.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Component, Input } from '@angular/core' -import { ModalController } from '@ionic/angular' -import { ValueSpecListOf } from 'src/app/pkg-config/config-types' - -@Component({ - selector: 'enum-list', - templateUrl: './enum-list.page.html', - styleUrls: ['./enum-list.page.scss'], -}) -export class EnumListPage { - @Input() key!: string - @Input() spec!: ValueSpecListOf<'enum'> - @Input() current: string[] = [] - - options: { [option: string]: boolean } = {} - selectAll = false - - constructor(private readonly modalCtrl: ModalController) {} - - ngOnInit() { - for (let val of this.spec.spec.values || []) { - this.options[val] = this.current.includes(val) - } - // if none are selected, set selectAll to true - this.selectAll = Object.values(this.options).some(k => !k) - } - - dismiss() { - this.modalCtrl.dismiss() - } - - save() { - this.modalCtrl.dismiss( - Object.keys(this.options).filter(key => this.options[key]), - ) - } - - toggleSelectAll() { - Object.keys(this.options).forEach(k => (this.options[k] = this.selectAll)) - this.selectAll = !this.selectAll - } - - toggleSelected(key: string) { - this.options[key] = !this.options[key] - } - - asIsOrder() { - return 0 - } -} diff --git a/web/projects/ui/src/app/modals/generic-form/generic-form.module.ts b/web/projects/ui/src/app/modals/generic-form/generic-form.module.ts deleted file mode 100644 index f278f652b..000000000 --- a/web/projects/ui/src/app/modals/generic-form/generic-form.module.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { NgModule } from '@angular/core' -import { CommonModule } from '@angular/common' -import { IonicModule } from '@ionic/angular' -import { GenericFormPage } from './generic-form.page' -import { FormsModule, ReactiveFormsModule } from '@angular/forms' -import { FormObjectComponentModule } from 'src/app/components/form-object/form-object.component.module' - -@NgModule({ - declarations: [GenericFormPage], - imports: [ - CommonModule, - IonicModule, - FormsModule, - ReactiveFormsModule, - FormObjectComponentModule, - ], - exports: [GenericFormPage], -}) -export class GenericFormPageModule {} diff --git a/web/projects/ui/src/app/modals/generic-form/generic-form.page.html b/web/projects/ui/src/app/modals/generic-form/generic-form.page.html deleted file mode 100644 index 706c8487d..000000000 --- a/web/projects/ui/src/app/modals/generic-form/generic-form.page.html +++ /dev/null @@ -1,35 +0,0 @@ - - - {{ title }} - - - - - - - - - -
- - -
-
- - - - - - {{ button.text }} - - - - diff --git a/web/projects/ui/src/app/modals/generic-form/generic-form.page.scss b/web/projects/ui/src/app/modals/generic-form/generic-form.page.scss deleted file mode 100644 index 0353411b3..000000000 --- a/web/projects/ui/src/app/modals/generic-form/generic-form.page.scss +++ /dev/null @@ -1,9 +0,0 @@ -button:disabled, -button[disabled]{ - border: 1px solid #999999; - background-color: #cccccc; - color: #666666; -} -button { - color: var(--ion-color-primary); -} \ No newline at end of file diff --git a/web/projects/ui/src/app/modals/generic-form/generic-form.page.ts b/web/projects/ui/src/app/modals/generic-form/generic-form.page.ts deleted file mode 100644 index eb690a787..000000000 --- a/web/projects/ui/src/app/modals/generic-form/generic-form.page.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Component, Input } from '@angular/core' -import { UntypedFormGroup } from '@angular/forms' -import { ModalController } from '@ionic/angular' -import { - convertValuesRecursive, - FormService, -} from 'src/app/services/form.service' -import { ConfigSpec } from 'src/app/pkg-config/config-types' - -export interface ActionButton { - text: string - handler: (value: any) => Promise - isSubmit?: boolean -} - -@Component({ - selector: 'generic-form', - templateUrl: './generic-form.page.html', - styleUrls: ['./generic-form.page.scss'], -}) -export class GenericFormPage { - @Input() title!: string - @Input() spec!: ConfigSpec - @Input() buttons!: ActionButton[] - @Input() initialValue: object = {} - - submitBtn!: ActionButton - formGroup!: UntypedFormGroup - - constructor( - private readonly modalCtrl: ModalController, - private readonly formService: FormService, - ) {} - - ngOnInit() { - this.formGroup = this.formService.createForm(this.spec, this.initialValue) - this.submitBtn = this.buttons.find(btn => btn.isSubmit) || { - text: '', - handler: () => Promise.resolve(true), - } - } - - async dismiss(): Promise { - this.modalCtrl.dismiss() - } - - async handleClick(handler: ActionButton['handler']): Promise { - convertValuesRecursive(this.spec, this.formGroup) - - if (this.formGroup.invalid) { - document - .getElementsByClassName('validation-error')[0] - ?.scrollIntoView({ behavior: 'smooth' }) - return - } - - // @TODO make this more like generic input component dismissal - const success = await handler(this.formGroup.value) - if (success !== false) this.modalCtrl.dismiss() - } -} diff --git a/web/projects/ui/src/app/modals/generic-input/generic-input.component.html b/web/projects/ui/src/app/modals/generic-input/generic-input.component.html deleted file mode 100644 index 8ff7e795f..000000000 --- a/web/projects/ui/src/app/modals/generic-input/generic-input.component.html +++ /dev/null @@ -1,67 +0,0 @@ - -
- - -

{{ options.title }}

-
-

{{ options.message }}

- -
-

- {{ options.warning }} -

-
-
-
- -
-
-

{{ options.label }}

- - - - - - - -

- {{ error }} -

-
- -
- Cancel - - {{ options.buttonText }} - -
-
-
-
diff --git a/web/projects/ui/src/app/modals/generic-input/generic-input.component.module.ts b/web/projects/ui/src/app/modals/generic-input/generic-input.component.module.ts deleted file mode 100644 index d2b1faab4..000000000 --- a/web/projects/ui/src/app/modals/generic-input/generic-input.component.module.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { NgModule } from '@angular/core' -import { CommonModule } from '@angular/common' -import { GenericInputComponent } from './generic-input.component' -import { IonicModule } from '@ionic/angular' -import { RouterModule } from '@angular/router' -import { SharedPipesModule } from '@start9labs/shared' -import { FormsModule } from '@angular/forms' - -@NgModule({ - declarations: [GenericInputComponent], - imports: [ - CommonModule, - IonicModule, - FormsModule, - RouterModule.forChild([]), - SharedPipesModule, - ], - exports: [GenericInputComponent], -}) -export class GenericInputComponentModule {} diff --git a/web/projects/ui/src/app/modals/generic-input/generic-input.component.scss b/web/projects/ui/src/app/modals/generic-input/generic-input.component.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/web/projects/ui/src/app/modals/generic-input/generic-input.component.ts b/web/projects/ui/src/app/modals/generic-input/generic-input.component.ts deleted file mode 100644 index 59ebb8c3d..000000000 --- a/web/projects/ui/src/app/modals/generic-input/generic-input.component.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { Component, inject, Input, ViewChild } from '@angular/core' -import { ModalController, IonicSafeString, IonInput } from '@ionic/angular' -import { getErrorMessage, THEME } from '@start9labs/shared' -import { MaskPipe } from 'src/app/pipes/mask/mask.pipe' - -@Component({ - selector: 'generic-input', - templateUrl: './generic-input.component.html', - styleUrls: ['./generic-input.component.scss'], - providers: [MaskPipe], -}) -export class GenericInputComponent { - @ViewChild('mainInput') elem?: IonInput - - @Input() options!: GenericInputOptions - - value!: string - masked!: boolean - - maskedValue?: string - - error: string | IonicSafeString = '' - - readonly theme$ = inject(THEME) - - constructor( - private readonly modalCtrl: ModalController, - private readonly mask: MaskPipe, - ) {} - - ngOnInit() { - const defaultOptions: Partial = { - buttonText: 'Submit', - placeholder: 'Enter value', - nullable: false, - useMask: false, - initialValue: '', - } - this.options = { - ...defaultOptions, - ...this.options, - } - - this.masked = !!this.options.useMask - this.value = this.options.initialValue || '' - } - - ngAfterViewInit() { - setTimeout(() => this.elem?.setFocus(), 400) - } - - toggleMask() { - this.masked = !this.masked - } - - cancel() { - this.modalCtrl.dismiss() - } - - transformInput(newValue: string) { - let i = 0 - this.value = newValue - .split('') - .map(x => (x === '●' ? this.value[i++] : x)) - .join('') - this.maskedValue = this.mask.transform(this.value) - } - - async submit() { - const value = this.value.trim() - - if (!value && !this.options.nullable) return - - try { - await this.options.submitFn(value) - this.modalCtrl.dismiss(undefined, 'success') - } catch (e: any) { - this.error = getErrorMessage(e) - } - } -} - -export interface GenericInputOptions { - // required - title: string - message: string - label: string - submitFn: (value: string) => Promise - // optional - warning?: string - buttonText?: string - placeholder?: string - nullable?: boolean - useMask?: boolean - initialValue?: string -} diff --git a/web/projects/ui/src/app/modals/marketplace-settings/marketplace-settings.module.ts b/web/projects/ui/src/app/modals/marketplace-settings/marketplace-settings.module.ts deleted file mode 100644 index 096e06add..000000000 --- a/web/projects/ui/src/app/modals/marketplace-settings/marketplace-settings.module.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { NgModule } from '@angular/core' -import { CommonModule } from '@angular/common' -import { IonicModule } from '@ionic/angular' -import { MarketplaceSettingsPage } from './marketplace-settings.page' -import { SharedPipesModule } from '@start9labs/shared' -import { StoreIconComponentModule } from 'src/app/components/store-icon/store-icon.component.module' - -@NgModule({ - imports: [ - CommonModule, - IonicModule, - SharedPipesModule, - StoreIconComponentModule, - ], - declarations: [MarketplaceSettingsPage], -}) -export class MarketplaceSettingsPageModule {} diff --git a/web/projects/ui/src/app/modals/marketplace-settings/marketplace-settings.page.html b/web/projects/ui/src/app/modals/marketplace-settings/marketplace-settings.page.html index 663b022cd..ab3bf8b34 100644 --- a/web/projects/ui/src/app/modals/marketplace-settings/marketplace-settings.page.html +++ b/web/projects/ui/src/app/modals/marketplace-settings/marketplace-settings.page.html @@ -1,67 +1,30 @@ - - - Change Registry - - - - - - - - - - - Default Registries - +

Default Registries

+ +

Custom Registries

+ +
+ + +
+ diff --git a/web/projects/ui/src/app/modals/marketplace-settings/marketplace-settings.page.scss b/web/projects/ui/src/app/modals/marketplace-settings/marketplace-settings.page.scss index e69de29bb..310b9ab30 100644 --- a/web/projects/ui/src/app/modals/marketplace-settings/marketplace-settings.page.scss +++ b/web/projects/ui/src/app/modals/marketplace-settings/marketplace-settings.page.scss @@ -0,0 +1,5 @@ +.connect-container { + display: flex; + flex-direction: row; + align-items: center; +} diff --git a/web/projects/ui/src/app/modals/marketplace-settings/marketplace-settings.page.ts b/web/projects/ui/src/app/modals/marketplace-settings/marketplace-settings.page.ts index f62331819..dd8fe73eb 100644 --- a/web/projects/ui/src/app/modals/marketplace-settings/marketplace-settings.page.ts +++ b/web/projects/ui/src/app/modals/marketplace-settings/marketplace-settings.page.ts @@ -1,276 +1,230 @@ -import { - ChangeDetectionStrategy, - Component, - Inject, - ViewChild, -} from '@angular/core' -import { - ActionSheetController, - AlertController, - LoadingController, - ModalController, -} from '@ionic/angular' -import { ActionSheetButton } from '@ionic/core' -import { ErrorToastService, sameUrl, toUrl } from '@start9labs/shared' +import { CommonModule } from '@angular/common' +import { ChangeDetectionStrategy, Component, inject } from '@angular/core' import { AbstractMarketplaceService } from '@start9labs/marketplace' -import { ApiService } from 'src/app/services/api/embassy-api.service' -import { ValueSpecObject } from 'src/app/pkg-config/config-types' -import { GenericFormPage } from 'src/app/modals/generic-form/generic-form.page' +import { + ErrorService, + LoadingService, + sameUrl, + toUrl, +} from '@start9labs/shared' +import { CT } from '@start9labs/start-sdk' +import { TuiDialogOptions, TuiDialogService } from '@taiga-ui/core' +import { + TuiButtonModule, + TuiCellModule, + TuiIconModule, + TuiTitleModule, +} from '@taiga-ui/experimental' +import { TUI_PROMPT, TuiPromptData } from '@taiga-ui/kit' +import { PolymorpheusComponent } from '@tinkoff/ng-polymorpheus' import { PatchDB } from 'patch-db-client' -import { DataModel, UIStore } from 'src/app/services/patch-db/data-model' -import { MarketplaceService } from 'src/app/services/marketplace.service' +import { combineLatest, filter, firstValueFrom, Subscription } from 'rxjs' import { map } from 'rxjs/operators' -import { combineLatest, firstValueFrom } from 'rxjs' +import { FormComponent } from 'src/app/components/form.component' +import { ApiService } from 'src/app/services/api/embassy-api.service' +import { FormDialogService } from 'src/app/services/form-dialog.service' +import { MarketplaceService } from 'src/app/services/marketplace.service' +import { DataModel, UIStore } from 'src/app/services/patch-db/data-model' + +import { MarketplaceRegistryComponent } from './registry.component' @Component({ + standalone: true, + imports: [ + CommonModule, + TuiCellModule, + TuiIconModule, + TuiTitleModule, + TuiButtonModule, + MarketplaceRegistryComponent, + ], selector: 'marketplace-settings', templateUrl: 'marketplace-settings.page.html', styleUrls: ['marketplace-settings.page.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) export class MarketplaceSettingsPage { - stores$ = combineLatest([ - this.marketplaceService.getKnownHosts$(), - this.marketplaceService.getSelectedHost$(), - ]).pipe( - map(([stores, selected]) => { - const toSlice = stores.map(s => ({ - ...s, - selected: sameUrl(s.url, selected.url), - })) - // 0 and 1 are prod and community - const standard = toSlice.slice(0, 2) - // 2 and beyond are alts - const alt = toSlice.slice(2) - - return { standard, alt } - }), + private readonly api = inject(ApiService) + private readonly loader = inject(LoadingService) + private readonly errorService = inject(ErrorService) + private readonly formDialog = inject(FormDialogService) + private readonly dialogs = inject(TuiDialogService) + private readonly marketplace = inject( + AbstractMarketplaceService, + ) as MarketplaceService + private readonly hosts$ = inject(PatchDB).watch$( + 'ui', + 'marketplace', + 'knownHosts', ) - constructor( - private readonly api: ApiService, - private readonly loadingCtrl: LoadingController, - private readonly modalCtrl: ModalController, - private readonly errToast: ErrorToastService, - private readonly actionCtrl: ActionSheetController, - @Inject(AbstractMarketplaceService) - private readonly marketplaceService: MarketplaceService, - private readonly patch: PatchDB, - private readonly alertCtrl: AlertController, - ) {} + readonly stores$ = combineLatest([ + this.marketplace.getKnownHosts$(), + this.marketplace.getSelectedHost$(), + ]).pipe( + map(([stores, selected]) => + stores.map(s => ({ + ...s, + selected: sameUrl(s.url, selected.url), + })), + ), + // 0 and 1 are prod and community, 2 and beyond are alts + map(stores => ({ standard: stores.slice(0, 2), alt: stores.slice(2) })), + ) - async dismiss() { - this.modalCtrl.dismiss() - } - - async presentModalAdd() { + async add() { const { name, spec } = getMarketplaceValueSpec() - const modal = await this.modalCtrl.create({ - component: GenericFormPage, - componentProps: { - title: name, + + this.formDialog.open(FormComponent, { + label: name, + data: { spec, buttons: [ { text: 'Save for Later', - handler: (value: { url: string }) => { - this.saveOnly(value.url) - }, + handler: async ({ url }: { url: string }) => this.save(url), }, { text: 'Save and Connect', - handler: (value: { url: string }) => { - this.saveAndConnect(value.url) - }, + handler: async ({ url }: { url: string }) => this.save(url, true), isSubmit: true, }, ], }, - cssClass: 'alertlike-modal', }) - - await modal.present() } + delete(url: string, name: string = '') { + this.dialogs + .open(TUI_PROMPT, getPromptOptions(name)) + .pipe(filter(Boolean)) + .subscribe(async () => { + const loader = this.loader.open('Deleting...').subscribe() + const hosts = await firstValueFrom(this.hosts$) + const filtered: { [url: string]: UIStore } = Object.keys(hosts) + .filter(key => !sameUrl(key, url)) + .reduce( + (prev, curr) => ({ + ...prev, + [curr]: hosts[curr], + }), + {}, + ) - async presentAction( - { url, name }: { url: string; name?: string }, - canDelete = false, - ) { - const buttons: ActionSheetButton[] = [ - { - text: 'Connect', - handler: () => { - this.connect(url) - }, - }, - ] - - if (canDelete) { - buttons.unshift({ - text: 'Delete', - role: 'destructive', - handler: () => { - this.presentAlertDelete(url, name!) - }, + try { + await this.api.setDbValue(['marketplace', 'knownHosts'], filtered) + } catch (e: any) { + this.errorService.handleError(e) + } finally { + loader.unsubscribe() + } }) - } - - const action = await this.actionCtrl.create({ - header: name, - mode: 'ios', - buttons, - }) - - await action.present() } - private async presentAlertDelete(url: string, name: string) { - const alert = await this.alertCtrl.create({ - header: 'Confirm', - message: `Are you sure you want to delete ${name}?`, - buttons: [ - { - text: 'Cancel', - role: 'cancel', - }, - { - text: 'Delete', - handler: () => this.delete(url), - cssClass: 'enter-click', - }, - ], - }) - - await alert.present() - } - - private async connect( + async connect( url: string, - loader?: HTMLIonLoadingElement, + loader: Subscription = new Subscription(), ): Promise { - const message = 'Changing Registry...' - if (!loader) { - loader = await this.loadingCtrl.create({ message }) - await loader.present() - } else { - loader.message = message - } + loader.unsubscribe() + loader.closed = false + loader.add(this.loader.open('Changing Registry...').subscribe()) try { - await this.api.setDbValue(['marketplace', 'selected-url'], url) + await this.api.setDbValue(['marketplace', 'selectedUrl'], url) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() - this.dismiss() + loader.unsubscribe() } } - private async saveOnly(rawUrl: string): Promise { - const loader = await this.loadingCtrl.create() + private async save(rawUrl: string, connect = false): Promise { + const loader = this.loader.open('Loading').subscribe() + const url = new URL(rawUrl).toString() try { - const url = new URL(rawUrl).toString() await this.validateAndSave(url, loader) + if (connect) await this.connect(url, loader) + return true } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) + return false } finally { - loader.dismiss() - } - } - - private async saveAndConnect(rawUrl: string): Promise { - const loader = await this.loadingCtrl.create() - - try { - const url = new URL(rawUrl).toString() - await this.validateAndSave(url, loader) - await this.connect(url, loader) - } catch (e: any) { - this.errToast.present(e) - } finally { - loader.dismiss() - this.dismiss() + loader.unsubscribe() } } private async validateAndSave( url: string, - loader: HTMLIonLoadingElement, + loader: Subscription, ): Promise { // Error on duplicates - const hosts = await firstValueFrom( - this.patch.watch$('ui', 'marketplace', 'knownHosts'), - ) + const hosts = await firstValueFrom(this.hosts$) const currentUrls = Object.keys(hosts).map(toUrl) - if (currentUrls.includes(url)) throw new Error('marketplace already added') + if (currentUrls.includes(url)) throw new Error('Marketplace already added') // Validate - loader.message = 'Validating marketplace...' - await loader.present() + loader.unsubscribe() + loader.closed = false + loader.add(this.loader.open('Validating marketplace...').subscribe()) - const { name } = await firstValueFrom( - this.marketplaceService.fetchInfo$(url), - ) + const { name } = await firstValueFrom(this.marketplace.fetchInfo$(url)) // Save - loader.message = 'Saving...' + loader.unsubscribe() + loader.closed = false + loader.add(this.loader.open('Saving...').subscribe()) - await this.api.setDbValue<{ name: string }>( - ['marketplace', 'knownHosts', url], - { name }, - ) - } - - private async delete(url: string): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Deleting...', - }) - await loader.present() - - const hosts = await firstValueFrom( - this.patch.watch$('ui', 'marketplace', 'knownHosts'), - ) - - const filtered: { [url: string]: UIStore } = Object.keys(hosts) - .filter(key => !sameUrl(key, url)) - .reduce((prev, curr) => { - const name = hosts[curr] - return { - ...prev, - [curr]: name, - } - }, {}) - - try { - await this.api.setDbValue<{ [url: string]: UIStore }>( - ['marketplace', 'knownHosts'], - filtered, - ) - } catch (e: any) { - this.errToast.present(e) - } finally { - loader.dismiss() - } + await this.api.setDbValue(['marketplace', 'knownHosts', url], { name }) } } -function getMarketplaceValueSpec(): ValueSpecObject { +export const MARKETPLACE_REGISTRY = new PolymorpheusComponent( + MarketplaceSettingsPage, +) + +function getMarketplaceValueSpec(): CT.ValueSpecObject { return { type: 'object', name: 'Add Custom Registry', + description: null, + warning: null, spec: { url: { - type: 'string', + type: 'text', name: 'URL', description: 'A fully-qualified URL of the custom registry', - nullable: false, + inputmode: 'url', + required: true, masked: false, - copyable: false, - pattern: `https?:\/\/[a-zA-Z0-9][a-zA-Z0-9-\.]+[a-zA-Z0-9]\.[^\s]{2,}`, - 'pattern-description': 'Must be a valid URL', + minLength: null, + maxLength: null, + patterns: [ + { + regex: `https?:\/\/[a-zA-Z0-9][a-zA-Z0-9-\.]+[a-zA-Z0-9]\.[^\s]{2,}`, + description: 'Must be a valid URL', + }, + ], placeholder: 'e.g. https://example.org', + default: null, + warning: null, + disabled: false, + immutable: false, + generate: null, }, }, } } + +function getPromptOptions( + name: string, +): Partial> { + return { + label: 'Confirm', + size: 's', + data: { + content: `Are you sure you want to delete ${name}?`, + yes: 'Delete', + no: 'Cancel', + }, + } +} diff --git a/web/projects/ui/src/app/modals/marketplace-settings/registry.component.ts b/web/projects/ui/src/app/modals/marketplace-settings/registry.component.ts new file mode 100644 index 000000000..0441ae18f --- /dev/null +++ b/web/projects/ui/src/app/modals/marketplace-settings/registry.component.ts @@ -0,0 +1,42 @@ +import { NgIf } from '@angular/common' +import { + ChangeDetectionStrategy, + Component, + inject, + Input, +} from '@angular/core' +import { TuiIconModule, TuiTitleModule } from '@taiga-ui/experimental' +import { ConfigService } from 'src/app/services/config.service' + +import { StoreIconComponent } from './store-icon.component' + +@Component({ + standalone: true, + selector: '[registry]', + template: ` + +
+ {{ registry.name }} +
{{ registry.url }}
+
+ + + `, + styles: [':host { border-radius: 0.25rem; width: stretch; }'], + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [NgIf, StoreIconComponent, TuiIconModule, TuiTitleModule], +}) +export class MarketplaceRegistryComponent { + readonly marketplace = inject(ConfigService).marketplace + + @Input() + registry!: { url: string; selected: boolean; name?: string } +} diff --git a/web/projects/ui/src/app/modals/marketplace-settings/store-icon.component.ts b/web/projects/ui/src/app/modals/marketplace-settings/store-icon.component.ts new file mode 100644 index 000000000..dcdfe3b2f --- /dev/null +++ b/web/projects/ui/src/app/modals/marketplace-settings/store-icon.component.ts @@ -0,0 +1,46 @@ +import { NgIf } from '@angular/common' +import { ChangeDetectionStrategy, Component, Input } from '@angular/core' +import { sameUrl } from '@start9labs/shared' + +@Component({ + standalone: true, + selector: 'store-icon', + template: ` + Marketplace Icon + + Marketplace Icon + + `, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [NgIf], +}) +export class StoreIconComponent { + @Input() + url = '' + @Input() + size?: string + @Input() + marketplace!: any + + get icon() { + const { start9, community } = this.marketplace + + if (sameUrl(this.url, start9)) { + return 'assets/img/icon_transparent.png' + } else if (sameUrl(this.url, community)) { + return 'assets/img/community-store.png' + } + return null + } +} diff --git a/web/projects/ui/src/app/modals/os-update/os-update.page.ts b/web/projects/ui/src/app/modals/os-update/os-update.page.ts index 9900bbb47..45b9cb009 100644 --- a/web/projects/ui/src/app/modals/os-update/os-update.page.ts +++ b/web/projects/ui/src/app/modals/os-update/os-update.page.ts @@ -1,8 +1,8 @@ import { ChangeDetectionStrategy, Component } from '@angular/core' -import { LoadingController, ModalController } from '@ionic/angular' -import { ApiService } from '../../services/api/embassy-api.service' -import { ErrorToastService } from '@start9labs/shared' +import { ModalController } from '@ionic/angular' +import { ErrorService, LoadingService } from '@start9labs/shared' import { EOSService } from 'src/app/services/eos.service' +import { ApiService } from '../../services/api/embassy-api.service' @Component({ selector: 'os-update', @@ -15,8 +15,8 @@ export class OSUpdatePage { constructor( private readonly modalCtrl: ModalController, - private readonly loadingCtrl: LoadingController, - private readonly errToast: ErrorToastService, + private readonly loader: LoadingService, + private readonly errorService: ErrorService, private readonly embassyApi: ApiService, private readonly eosService: EOSService, ) {} @@ -39,18 +39,15 @@ export class OSUpdatePage { } async updateEOS() { - const loader = await this.loadingCtrl.create({ - message: 'Beginning update...', - }) - await loader.present() + const loader = this.loader.open('Beginning update...').subscribe() try { await this.embassyApi.updateServer() this.dismiss() } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } diff --git a/web/projects/ui/src/app/modals/prompt.component.ts b/web/projects/ui/src/app/modals/prompt.component.ts new file mode 100644 index 000000000..e2a2765f5 --- /dev/null +++ b/web/projects/ui/src/app/modals/prompt.component.ts @@ -0,0 +1,123 @@ +import { CommonModule } from '@angular/common' +import { ChangeDetectionStrategy, Component, Inject } from '@angular/core' +import { FormsModule } from '@angular/forms' +import { TuiAutoFocusModule } from '@taiga-ui/cdk' +import { TuiDialogContext, TuiTextfieldControllerModule } from '@taiga-ui/core' +import { TuiButtonModule } from '@taiga-ui/experimental' +import { TuiInputModule } from '@taiga-ui/kit' +import { + POLYMORPHEUS_CONTEXT, + PolymorpheusComponent, +} from '@tinkoff/ng-polymorpheus' + +@Component({ + standalone: true, + template: ` +

{{ options.message }}

+

{{ options.warning }}

+
+ + {{ options.label }} + * + + +
+ + +
+
+ + + + + `, + styles: [ + ` + .warning { + color: var(--tui-warning-fill); + } + + .button { + pointer-events: auto; + margin-left: 0.25rem; + } + + .masked { + -webkit-text-security: disc; + } + `, + ], + imports: [ + CommonModule, + FormsModule, + TuiInputModule, + TuiButtonModule, + TuiTextfieldControllerModule, + TuiAutoFocusModule, + ], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class PromptModal { + masked = this.options.useMask + value = this.options.initialValue || '' + + constructor( + @Inject(POLYMORPHEUS_CONTEXT) + private readonly context: TuiDialogContext, + ) {} + + get options(): PromptOptions { + return this.context.data + } + + cancel() { + this.context.$implicit.complete() + } + + submit(value: string) { + if (value || !this.options.required) { + this.context.$implicit.next(value) + } + } +} + +export const PROMPT = new PolymorpheusComponent(PromptModal) + +export interface PromptOptions { + message: string + label?: string + warning?: string + buttonText?: string + placeholder?: string + required?: boolean + useMask?: boolean + initialValue?: string | null +} diff --git a/web/projects/ui/src/app/pages/apps-routes/app-actions/app-actions.module.ts b/web/projects/ui/src/app/pages/apps-routes/app-actions/app-actions.module.ts index 5f30abc0e..84e52d15f 100644 --- a/web/projects/ui/src/app/pages/apps-routes/app-actions/app-actions.module.ts +++ b/web/projects/ui/src/app/pages/apps-routes/app-actions/app-actions.module.ts @@ -5,7 +5,6 @@ import { IonicModule } from '@ionic/angular' import { AppActionsPage, AppActionsItemComponent } from './app-actions.page' import { QRComponentModule } from 'src/app/components/qr/qr.component.module' import { SharedPipesModule } from '@start9labs/shared' -import { GenericFormPageModule } from 'src/app/modals/generic-form/generic-form.module' import { ActionSuccessPageModule } from 'src/app/modals/action-success/action-success.module' const routes: Routes = [ @@ -22,7 +21,6 @@ const routes: Routes = [ RouterModule.forChild(routes), QRComponentModule, SharedPipesModule, - GenericFormPageModule, ActionSuccessPageModule, ], declarations: [AppActionsPage, AppActionsItemComponent], diff --git a/web/projects/ui/src/app/pages/apps-routes/app-actions/app-actions.page.ts b/web/projects/ui/src/app/pages/apps-routes/app-actions/app-actions.page.ts index a48ac8185..dd4e4b36e 100644 --- a/web/projects/ui/src/app/pages/apps-routes/app-actions/app-actions.page.ts +++ b/web/projects/ui/src/app/pages/apps-routes/app-actions/app-actions.page.ts @@ -1,23 +1,24 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core' import { ActivatedRoute } from '@angular/router' -import { ApiService } from 'src/app/services/api/embassy-api.service' +import { AlertController, ModalController, NavController } from '@ionic/angular' import { - AlertController, - LoadingController, - ModalController, - NavController, -} from '@ionic/angular' + ErrorService, + getPkgId, + isEmptyObject, + LoadingService, +} from '@start9labs/shared' +import { T } from '@start9labs/start-sdk' import { PatchDB } from 'patch-db-client' +import { FormComponent } from 'src/app/components/form.component' +import { ActionSuccessPage } from 'src/app/modals/action-success/action-success.page' +import { ApiService } from 'src/app/services/api/embassy-api.service' +import { FormDialogService } from 'src/app/services/form-dialog.service' import { DataModel, PackageDataEntry, } from 'src/app/services/patch-db/data-model' -import { GenericFormPage } from 'src/app/modals/generic-form/generic-form.page' -import { isEmptyObject, ErrorToastService, getPkgId } from '@start9labs/shared' -import { ActionSuccessPage } from 'src/app/modals/action-success/action-success.page' -import { hasCurrentDeps } from 'src/app/util/has-deps' import { getAllPackages, getManifest } from 'src/app/util/get-package-data' -import { T } from '@start9labs/start-sdk' +import { hasCurrentDeps } from 'src/app/util/has-deps' @Component({ selector: 'app-actions', @@ -34,40 +35,32 @@ export class AppActionsPage { private readonly embassyApi: ApiService, private readonly modalCtrl: ModalController, private readonly alertCtrl: AlertController, - private readonly errToast: ErrorToastService, - private readonly loadingCtrl: LoadingController, + private readonly errorService: ErrorService, + private readonly loader: LoadingService, private readonly navCtrl: NavController, private readonly patch: PatchDB, + private readonly formDialog: FormDialogService, ) {} async handleAction( status: T.Status, action: { key: string; value: T.ActionMetadata }, ) { - if ( - status && - action.value.allowedStatuses.includes( - status.main.status, // @TODO - ) - ) { + if (status && action.value.allowedStatuses.includes(status.main.status)) { if (!isEmptyObject(action.value.input || {})) { - const modal = await this.modalCtrl.create({ - component: GenericFormPage, - componentProps: { - title: action.value.name, + this.formDialog.open(FormComponent, { + label: action.value.name, + data: { spec: action.value.input, buttons: [ { text: 'Execute', - handler: (value: any) => { - return this.executeAction(action.key, value) - }, - isSubmit: true, + handler: async (value: any) => + this.executeAction(action.key, value), }, ], }, }) - await modal.present() } else { const alert = await this.alertCtrl.create({ header: 'Confirm', @@ -91,7 +84,7 @@ export class AppActionsPage { await alert.present() } } else { - const statuses = [...action.value.allowedStatuses] // @TODO + const statuses = [...action.value.allowedStatuses] const last = statuses.pop() let statusesStr = statuses.join(', ') let error = '' @@ -152,10 +145,7 @@ export class AppActionsPage { } private async uninstall() { - const loader = await this.loadingCtrl.create({ - message: `Beginning uninstall...`, - }) - await loader.present() + const loader = this.loader.open(`Beginning uninstall...`).subscribe() try { await this.embassyApi.uninstallPackage({ id: this.pkgId }) @@ -164,9 +154,9 @@ export class AppActionsPage { .catch(e => console.error('Failed to mark instructions as unseen', e)) this.navCtrl.navigateRoot('/services') } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } @@ -174,10 +164,7 @@ export class AppActionsPage { actionId: string, input?: object, ): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Executing action...', - }) - await loader.present() + const loader = this.loader.open('Executing action...').subscribe() try { const res = await this.embassyApi.executePackageAction({ @@ -196,10 +183,10 @@ export class AppActionsPage { setTimeout(() => successModal.present(), 500) return true // needed to dismiss original modal/alert } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) return false // don't dismiss original modal/alert } finally { - loader.dismiss() + loader.unsubscribe() } } diff --git a/web/projects/ui/src/app/pages/apps-routes/app-interfaces/app-interfaces.page.html b/web/projects/ui/src/app/pages/apps-routes/app-interfaces/app-interfaces.page.html index 79b1a1fde..ab7940a06 100644 --- a/web/projects/ui/src/app/pages/apps-routes/app-interfaces/app-interfaces.page.html +++ b/web/projects/ui/src/app/pages/apps-routes/app-interfaces/app-interfaces.page.html @@ -8,7 +8,9 @@ - + User Interfaces { - const sorted = Object.values(interfaces) - .sort(iface => - iface.name.toLowerCase() > iface.name.toLowerCase() ? -1 : 1, - ) - .map(iface => { - // TODO @Matt - const host = {} as any - return { - ...iface, - addresses: getAddresses(iface, host), - } - }) + private readonly serviceInterfaces$ = this.patch.watch$( + 'packageData', + this.pkgId, + 'serviceInterfaces', + ) + private readonly hosts$ = this.patch.watch$( + 'packageData', + this.pkgId, + 'hosts', + ) - return { - ui: sorted.filter(val => val.type === 'ui'), - api: sorted.filter(val => val.type === 'api'), - p2p: sorted.filter(val => val.type === 'p2p'), - } - }), - ) + readonly serviceInterfacesWithHostInfo$ = combineLatest([ + this.serviceInterfaces$, + this.hosts$, + ]).pipe( + map(([interfaces, hosts]) => { + const sorted = Object.values(interfaces) + .sort(iface => + iface.name.toLowerCase() > iface.name.toLowerCase() ? -1 : 1, + ) + .map(iface => { + return { + ...iface, + addresses: getAddresses( + iface, + hosts[iface.addressInfo.hostId] || {}, + ), + } + }) + + return { + ui: sorted.filter(val => val.type === 'ui'), + api: sorted.filter(val => val.type === 'api'), + p2p: sorted.filter(val => val.type === 'p2p'), + } + }), + ) constructor( private readonly route: ActivatedRoute, @@ -108,20 +120,15 @@ function getAddresses( host: T.Host, ): MappedAddress[] { const addressInfo = serviceInterface.addressInfo - const username = addressInfo.username ? addressInfo.username + '@' : '' - const suffix = addressInfo.suffix || '' const hostnames = - host.kind === 'multi' ? host.hostnameInfo[addressInfo.internalPort] : [] // TODO: non-multi - /* host.hostname - ? [host.hostname] - : [] */ + host.kind === 'multi' ? host.hostnameInfo[addressInfo.internalPort] : [] - return hostnames.flatMap(h => { + const addressesWithNames = hostnames.flatMap(h => { let name = '' if (h.kind === 'onion') { - name = 'Tor' + name = `Tor` } else { const hostnameKind = h.hostname.kind @@ -135,9 +142,23 @@ function getAddresses( } } - return addressHostToUrl(addressInfo, h).map(url => ({ - name, - url, - })) + const addresses = utils.addressHostToUrl(addressInfo, h) + if (addresses.length > 1) { + return utils.addressHostToUrl(addressInfo, h).map(url => ({ + name: `${name} (${new URL(url).protocol + .replace(':', '') + .toUpperCase()})`, + url, + })) + } else { + return utils.addressHostToUrl(addressInfo, h).map(url => ({ + name, + url, + })) + } }) + + return addressesWithNames.filter( + (value, index, self) => index === self.findIndex(t => t.url === value.url), + ) } diff --git a/web/projects/ui/src/app/pages/apps-routes/app-metrics/app-metrics.page.ts b/web/projects/ui/src/app/pages/apps-routes/app-metrics/app-metrics.page.ts index 8cf576bd7..61b17b669 100644 --- a/web/projects/ui/src/app/pages/apps-routes/app-metrics/app-metrics.page.ts +++ b/web/projects/ui/src/app/pages/apps-routes/app-metrics/app-metrics.page.ts @@ -1,8 +1,8 @@ import { Component } from '@angular/core' import { ActivatedRoute } from '@angular/router' +import { ErrorService, getPkgId, pauseFor } from '@start9labs/shared' import { Metric } from 'src/app/services/api/api.types' import { ApiService } from 'src/app/services/api/embassy-api.service' -import { pauseFor, ErrorToastService, getPkgId } from '@start9labs/shared' @Component({ selector: 'app-metrics', @@ -17,7 +17,7 @@ export class AppMetricsPage { constructor( private readonly route: ActivatedRoute, - private readonly errToast: ErrorToastService, + private readonly errorService: ErrorService, private readonly embassyApi: ApiService, ) {} @@ -46,7 +46,7 @@ export class AppMetricsPage { try { this.metrics = await this.embassyApi.getPkgMetrics({ id: this.pkgId }) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) this.stopDaemon() } finally { this.loading = false diff --git a/web/projects/ui/src/app/pages/apps-routes/app-properties/app-properties.page.ts b/web/projects/ui/src/app/pages/apps-routes/app-properties/app-properties.page.ts index d9b6bbc3e..af659c32b 100644 --- a/web/projects/ui/src/app/pages/apps-routes/app-properties/app-properties.page.ts +++ b/web/projects/ui/src/app/pages/apps-routes/app-properties/app-properties.page.ts @@ -1,6 +1,5 @@ import { Component, ViewChild } from '@angular/core' import { ActivatedRoute } from '@angular/router' -import { ApiService } from 'src/app/services/api/embassy-api.service' import { AlertController, IonBackButtonDelegate, @@ -8,18 +7,15 @@ import { NavController, ToastController, } from '@ionic/angular' -import { PackageProperties } from 'src/app/util/properties.util' -import { QRComponent } from 'src/app/components/qr/qr.component' -import { PatchDB } from 'patch-db-client' -import { DataModel } from 'src/app/services/patch-db/data-model' -import { - ErrorToastService, - getPkgId, - copyToClipboard, -} from '@start9labs/shared' +import { copyToClipboard, ErrorService, getPkgId } from '@start9labs/shared' import { TuiDestroyService } from '@taiga-ui/cdk' import { getValueByPointer } from 'fast-json-patch' +import { PatchDB } from 'patch-db-client' import { map, takeUntil } from 'rxjs/operators' +import { QRComponent } from 'src/app/components/qr/qr.component' +import { ApiService } from 'src/app/services/api/embassy-api.service' +import { DataModel } from 'src/app/services/patch-db/data-model' +import { PackageProperties } from 'src/app/util/properties.util' @Component({ selector: 'app-properties', @@ -47,7 +43,7 @@ export class AppPropertiesPage { constructor( private readonly route: ActivatedRoute, private readonly embassyApi: ApiService, - private readonly errToast: ErrorToastService, + private readonly errorService: ErrorService, private readonly alertCtrl: AlertController, private readonly toastCtrl: ToastController, private readonly modalCtrl: ModalController, @@ -139,7 +135,7 @@ export class AppPropertiesPage { }) this.node = getValueByPointer(this.properties, this.pointer) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { this.loading = false } diff --git a/web/projects/ui/src/app/pages/apps-routes/app-show/app-show.module.ts b/web/projects/ui/src/app/pages/apps-routes/app-show/app-show.module.ts index 0b2d82763..86744cc91 100644 --- a/web/projects/ui/src/app/pages/apps-routes/app-show/app-show.module.ts +++ b/web/projects/ui/src/app/pages/apps-routes/app-show/app-show.module.ts @@ -4,13 +4,11 @@ import { Routes, RouterModule } from '@angular/router' import { IonicModule } from '@ionic/angular' import { AppShowPage } from './app-show.page' import { - EmptyPipe, EmverPipesModule, ResponsiveColModule, SharedPipesModule, } from '@start9labs/shared' import { StatusComponentModule } from 'src/app/components/status/status.component.module' -import { AppConfigPageModule } from 'src/app/modals/app-config/app-config.module' import { LaunchablePipeModule } from 'src/app/pipes/launchable/launchable.module' import { UiPipeModule } from 'src/app/pipes/ui/ui.module' import { AppShowHeaderComponent } from './components/app-show-header/app-show-header.component' @@ -51,7 +49,6 @@ const routes: Routes = [ InstallingProgressPipeModule, IonicModule, RouterModule.forChild(routes), - AppConfigPageModule, EmverPipesModule, LaunchablePipeModule, UiPipeModule, diff --git a/web/projects/ui/src/app/pages/apps-routes/app-show/app-show.page.ts b/web/projects/ui/src/app/pages/apps-routes/app-show/app-show.page.ts index 010a7473c..cb1f6f5f9 100644 --- a/web/projects/ui/src/app/pages/apps-routes/app-show/app-show.page.ts +++ b/web/projects/ui/src/app/pages/apps-routes/app-show/app-show.page.ts @@ -11,7 +11,6 @@ import { renderPkgStatus } from 'src/app/services/pkg-status-rendering.service' import { map, tap } from 'rxjs/operators' import { ActivatedRoute, NavigationExtras } from '@angular/router' import { getPkgId } from '@start9labs/shared' -import { ModalService } from 'src/app/services/modal.service' import { DependentInfo } from 'src/app/types/dependent-info' import { DepErrorService, @@ -26,6 +25,8 @@ import { isUpdating, } from 'src/app/util/get-package-data' import { T } from '@start9labs/start-sdk' +import { FormDialogService } from 'src/app/services/form-dialog.service' +import { ConfigModal, PackageConfigData } from 'src/app/modals/config.component' export interface DependencyInfo { id: string @@ -68,8 +69,8 @@ export class AppShowPage { private readonly route: ActivatedRoute, private readonly navCtrl: NavController, private readonly patch: PatchDB, - private readonly modalService: ModalService, private readonly depErrorService: DepErrorService, + private readonly formDialog: FormDialogService, ) {} showProgress( @@ -171,7 +172,13 @@ export class AppShowPage { case 'update': return this.installDep(pkg, pkgManifest, id) case 'configure': - return this.configureDep(pkgManifest, id) + return this.formDialog.open(ConfigModal, { + label: `${pkgManifest.title} config`, + data: { + pkgId: id, + dependentInfo: pkgManifest, + }, + }) } } @@ -194,19 +201,4 @@ export class AppShowPage { navigationExtras, ) } - - private async configureDep( - pkgManifest: T.Manifest, - dependencyId: string, - ): Promise { - const dependentInfo: DependentInfo = { - id: pkgManifest.id, - title: pkgManifest.title, - } - - await this.modalService.presentModalConfig({ - pkgId: dependencyId, - dependentInfo, - }) - } } diff --git a/web/projects/ui/src/app/pages/apps-routes/app-show/components/app-show-health-checks/app-show-health-checks.component.html b/web/projects/ui/src/app/pages/apps-routes/app-show/components/app-show-health-checks/app-show-health-checks.component.html index 8e4bb760d..b0d65b5fd 100644 --- a/web/projects/ui/src/app/pages/apps-routes/app-show/components/app-show-health-checks/app-show-health-checks.component.html +++ b/web/projects/ui/src/app/pages/apps-routes/app-show/components/app-show-health-checks/app-show-health-checks.component.html @@ -68,7 +68,7 @@ - + diff --git a/web/projects/ui/src/app/pages/apps-routes/app-show/components/app-show-status/app-show-status.component.ts b/web/projects/ui/src/app/pages/apps-routes/app-show/components/app-show-status/app-show-status.component.ts index ba60c331d..30657ae01 100644 --- a/web/projects/ui/src/app/pages/apps-routes/app-show/components/app-show-status/app-show-status.component.ts +++ b/web/projects/ui/src/app/pages/apps-routes/app-show/components/app-show-status/app-show-status.component.ts @@ -1,26 +1,27 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core' -import { UiLauncherService } from 'src/app/services/ui-launcher.service' -import { - PackageStatus, - PrimaryRendering, -} from 'src/app/services/pkg-status-rendering.service' +import { AlertController } from '@ionic/angular' +import { ErrorService, LoadingService } from '@start9labs/shared' +import { T } from '@start9labs/start-sdk' +import { PatchDB } from 'patch-db-client' +import { ConfigModal, PackageConfigData } from 'src/app/modals/config.component' +import { ApiService } from 'src/app/services/api/embassy-api.service' +import { ConnectionService } from 'src/app/services/connection.service' +import { FormDialogService } from 'src/app/services/form-dialog.service' import { DataModel, PackageDataEntry, } from 'src/app/services/patch-db/data-model' -import { ErrorToastService } from '@start9labs/shared' -import { AlertController, LoadingController } from '@ionic/angular' -import { ApiService } from 'src/app/services/api/embassy-api.service' -import { ModalService } from 'src/app/services/modal.service' -import { hasCurrentDeps } from 'src/app/util/has-deps' -import { ConnectionService } from 'src/app/services/connection.service' import { - isInstalled, - getManifest, + PackageStatus, + PrimaryRendering, +} from 'src/app/services/pkg-status-rendering.service' +import { UiLauncherService } from 'src/app/services/ui-launcher.service' +import { getAllPackages, + getManifest, + isInstalled, } from 'src/app/util/get-package-data' -import { PatchDB } from 'patch-db-client' -import { T } from '@start9labs/start-sdk' +import { hasCurrentDeps } from 'src/app/util/has-deps' @Component({ selector: 'app-show-status', @@ -41,11 +42,11 @@ export class AppShowStatusComponent { constructor( private readonly alertCtrl: AlertController, - private readonly errToast: ErrorToastService, - private readonly loadingCtrl: LoadingController, + private readonly errorService: ErrorService, + private readonly loader: LoadingService, private readonly embassyApi: ApiService, private readonly launcherService: UiLauncherService, - private readonly modalService: ModalService, + private readonly formDialog: FormDialogService, readonly connection$: ConnectionService, private readonly patch: PatchDB, ) {} @@ -85,8 +86,8 @@ export class AppShowStatusComponent { } async presentModalConfig(): Promise { - return this.modalService.presentModalConfig({ - pkgId: this.manifest.id, + return this.formDialog.open(ConfigModal, { + data: { pkgId: this.manifest.id }, }) } @@ -172,47 +173,38 @@ export class AppShowStatusComponent { } private async start(): Promise { - const loader = await this.loadingCtrl.create({ - message: `Starting...`, - }) - await loader.present() + const loader = this.loader.open(`Starting...`).subscribe() try { await this.embassyApi.startPackage({ id: this.manifest.id }) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } private async stop(): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Stopping...', - }) - await loader.present() + const loader = this.loader.open('Stopping...').subscribe() try { await this.embassyApi.stopPackage({ id: this.manifest.id }) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } private async restart(): Promise { - const loader = await this.loadingCtrl.create({ - message: `Restarting...`, - }) - await loader.present() + const loader = this.loader.open(`Restarting...`).subscribe() try { await this.embassyApi.restartPackage({ id: this.manifest.id }) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } private async presentAlertStart(message: string): Promise { diff --git a/web/projects/ui/src/app/pages/apps-routes/app-show/pipes/to-buttons.pipe.ts b/web/projects/ui/src/app/pages/apps-routes/app-show/pipes/to-buttons.pipe.ts index 692d5d55f..e2a03ecf8 100644 --- a/web/projects/ui/src/app/pages/apps-routes/app-show/pipes/to-buttons.pipe.ts +++ b/web/projects/ui/src/app/pages/apps-routes/app-show/pipes/to-buttons.pipe.ts @@ -7,11 +7,12 @@ import { InstalledState, PackageDataEntry, } from 'src/app/services/patch-db/data-model' -import { ModalService } from 'src/app/services/modal.service' import { ApiService } from 'src/app/services/api/embassy-api.service' import { from, map, Observable } from 'rxjs' import { PatchDB } from 'patch-db-client' import { T } from '@start9labs/start-sdk' +import { FormDialogService } from 'src/app/services/form-dialog.service' +import { ConfigModal, PackageConfigData } from 'src/app/modals/config.component' export interface Button { title: string @@ -30,9 +31,9 @@ export class ToButtonsPipe implements PipeTransform { private readonly route: ActivatedRoute, private readonly navCtrl: NavController, private readonly modalCtrl: ModalController, - private readonly modalService: ModalService, private readonly apiService: ApiService, private readonly patch: PatchDB, + private readonly formDialog: FormDialogService, ) {} transform(pkg: PackageDataEntry): Button[] { @@ -52,7 +53,10 @@ export class ToButtonsPipe implements PipeTransform { // config { action: async () => - this.modalService.presentModalConfig({ pkgId: manifest.id }), + this.formDialog.open(ConfigModal, { + label: `${manifest.title} configuration`, + data: { pkgId: manifest.id }, + }), title: 'Config', description: `Customize ${manifest.title}`, icon: 'options-outline', diff --git a/web/projects/ui/src/app/pages/diagnostic-routes/home/home.page.ts b/web/projects/ui/src/app/pages/diagnostic-routes/home/home.page.ts index 9bb7376bc..00ee305bc 100644 --- a/web/projects/ui/src/app/pages/diagnostic-routes/home/home.page.ts +++ b/web/projects/ui/src/app/pages/diagnostic-routes/home/home.page.ts @@ -1,5 +1,6 @@ import { Component } from '@angular/core' -import { AlertController, LoadingController } from '@ionic/angular' +import { AlertController } from '@ionic/angular' +import { LoadingService } from '@start9labs/shared' import { ApiService } from 'src/app/services/api/embassy-api.service' @Component({ @@ -18,7 +19,7 @@ export class HomePage { restarted = false constructor( - private readonly loadingCtrl: LoadingController, + private readonly loader: LoadingService, private readonly api: ApiService, private readonly alertCtrl: AlertController, ) {} @@ -86,10 +87,7 @@ export class HomePage { } async restart(): Promise { - const loader = await this.loadingCtrl.create({ - cssClass: 'loader', - }) - await loader.present() + const loader = this.loader.open('Loading...').subscribe() try { await this.api.diagnosticRestart() @@ -97,15 +95,12 @@ export class HomePage { } catch (e) { console.error(e) } finally { - loader.dismiss() + loader.unsubscribe() } } async forgetDrive(): Promise { - const loader = await this.loadingCtrl.create({ - cssClass: 'loader', - }) - await loader.present() + const loader = this.loader.open('Loading...').subscribe() try { await this.api.diagnosticForgetDrive() @@ -114,7 +109,7 @@ export class HomePage { } catch (e) { console.error(e) } finally { - loader.dismiss() + loader.unsubscribe() } } @@ -149,10 +144,7 @@ export class HomePage { } private async repairDisk(): Promise { - const loader = await this.loadingCtrl.create({ - cssClass: 'loader', - }) - await loader.present() + const loader = this.loader.open('Loading...').subscribe() try { await this.api.diagnosticRepairDisk() @@ -161,7 +153,7 @@ export class HomePage { } catch (e) { console.error(e) } finally { - loader.dismiss() + loader.unsubscribe() } } } diff --git a/web/projects/ui/src/app/pages/diagnostic-routes/logs/logs.page.ts b/web/projects/ui/src/app/pages/diagnostic-routes/logs/logs.page.ts index 976abc2a0..1a6cf6a4f 100644 --- a/web/projects/ui/src/app/pages/diagnostic-routes/logs/logs.page.ts +++ b/web/projects/ui/src/app/pages/diagnostic-routes/logs/logs.page.ts @@ -1,7 +1,7 @@ import { Component, ViewChild } from '@angular/core' import { IonContent } from '@ionic/angular' +import { ErrorService, toLocalIsoString } from '@start9labs/shared' import { ApiService } from 'src/app/services/api/embassy-api.service' -import { ErrorToastService, toLocalIsoString } from '@start9labs/shared' var Convert = require('ansi-to-html') var convert = new Convert({ @@ -23,7 +23,7 @@ export class LogsPage { constructor( private readonly api: ApiService, - private readonly errToast: ErrorToastService, + private readonly errorService: ErrorService, ) {} async ngOnInit() { @@ -89,7 +89,7 @@ export class LogsPage { this.needInfinite = false } } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } } } diff --git a/web/projects/ui/src/app/pages/init/init.page.html b/web/projects/ui/src/app/pages/init/init.page.html index bd3467bbb..5cd21bb07 100644 --- a/web/projects/ui/src/app/pages/init/init.page.html +++ b/web/projects/ui/src/app/pages/init/init.page.html @@ -2,7 +2,7 @@

Initializing StartOS

-
+
Progress: {{ (progress.total * 100).toFixed(0) }}%
diff --git a/web/projects/ui/src/app/pages/init/init.service.ts b/web/projects/ui/src/app/pages/init/init.service.ts index 3cca42a58..245e1ae24 100644 --- a/web/projects/ui/src/app/pages/init/init.service.ts +++ b/web/projects/ui/src/app/pages/init/init.service.ts @@ -1,5 +1,5 @@ import { inject, Injectable } from '@angular/core' -import { ErrorToastService } from '@start9labs/shared' +import { ErrorService } from '@start9labs/shared' import { T } from '@start9labs/start-sdk' import { catchError, @@ -24,7 +24,7 @@ interface MappedProgress { export class InitService extends Observable { private readonly state = inject(StateService) private readonly api = inject(ApiService) - private readonly errorService = inject(ErrorToastService) + private readonly errorService = inject(ErrorService) private readonly progress$ = defer(() => from(this.api.initGetProgress()), ).pipe( @@ -58,7 +58,8 @@ export class InitService extends Observable { } }), catchError(e => { - this.errorService.present(e) + // @TODO this toast is presenting when we navigate away from init page. It seems other websockets exhibit the same behavior, but we never noticed because the error were not being caught and presented in this manner + this.errorService.handleError(e) return EMPTY }), diff --git a/web/projects/ui/src/app/pages/login/ca-wizard/ca-wizard.component.ts b/web/projects/ui/src/app/pages/login/ca-wizard/ca-wizard.component.ts index 2c0e9c7fe..fde1c968f 100644 --- a/web/projects/ui/src/app/pages/login/ca-wizard/ca-wizard.component.ts +++ b/web/projects/ui/src/app/pages/login/ca-wizard/ca-wizard.component.ts @@ -42,7 +42,7 @@ export class CAWizardComponent { private async testHttps() { const url = `https://${this.document.location.host}${this.relativeUrl}` - await this.api.getState().then(() => { + await this.api.echo({ message: 'ping' }, url).then(() => { this.caTrusted = true }) } diff --git a/web/projects/ui/src/app/pages/login/login.page.ts b/web/projects/ui/src/app/pages/login/login.page.ts index db0d1c2c4..065a4cc7f 100644 --- a/web/projects/ui/src/app/pages/login/login.page.ts +++ b/web/projects/ui/src/app/pages/login/login.page.ts @@ -1,10 +1,11 @@ +import { DOCUMENT } from '@angular/common' import { Component, Inject } from '@angular/core' -import { getPlatforms, LoadingController } from '@ionic/angular' +import { Router } from '@angular/router' +import { getPlatforms } from '@ionic/angular' +import { LoadingService } from '@start9labs/shared' import { ApiService } from 'src/app/services/api/embassy-api.service' import { AuthService } from 'src/app/services/auth.service' -import { Router } from '@angular/router' import { ConfigService } from 'src/app/services/config.service' -import { DOCUMENT } from '@angular/common' @Component({ selector: 'login', @@ -19,7 +20,7 @@ export class LoginPage { constructor( private readonly router: Router, private readonly authService: AuthService, - private readonly loadingCtrl: LoadingController, + private readonly loader: LoadingService, private readonly api: ApiService, public readonly config: ConfigService, @Inject(DOCUMENT) public readonly document: Document, @@ -28,10 +29,7 @@ export class LoginPage { async submit() { this.error = '' - const loader = await this.loadingCtrl.create({ - message: 'Logging in...', - }) - await loader.present() + const loader = this.loader.open('Logging in...').subscribe() try { document.cookie = '' @@ -51,7 +49,7 @@ export class LoginPage { // code 7 is for incorrect password this.error = e.code === 7 ? 'Invalid Password' : e.message } finally { - loader.dismiss() + loader.unsubscribe() } } } diff --git a/web/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.module.ts b/web/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.module.ts index ea1952578..c10ce42aa 100644 --- a/web/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.module.ts +++ b/web/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.module.ts @@ -18,7 +18,6 @@ import { import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module' import { MarketplaceStatusModule } from '../marketplace-status/marketplace-status.module' import { MarketplaceListPage } from './marketplace-list.page' -import { MarketplaceSettingsPageModule } from 'src/app/modals/marketplace-settings/marketplace-settings.module' import { StoreIconComponentModule } from 'src/app/components/store-icon/store-icon.component.module' const routes: Routes = [ @@ -43,7 +42,6 @@ const routes: Routes = [ CategoriesModule, SearchModule, SkeletonModule, - MarketplaceSettingsPageModule, StoreIconComponentModule, ResponsiveColModule, ], diff --git a/web/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.ts b/web/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.ts index 6792b917a..e1f13883a 100644 --- a/web/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.ts +++ b/web/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.ts @@ -1,10 +1,10 @@ import { ChangeDetectionStrategy, Component, Inject } from '@angular/core' import { ActivatedRoute } from '@angular/router' -import { ModalController } from '@ionic/angular' import { AbstractMarketplaceService } from '@start9labs/marketplace' +import { TuiDialogService } from '@taiga-ui/core' import { PatchDB } from 'patch-db-client' import { map } from 'rxjs' -import { MarketplaceSettingsPage } from 'src/app/modals/marketplace-settings/marketplace-settings.page' +import { MARKETPLACE_REGISTRY } from 'src/app/modals/marketplace-settings/marketplace-settings.page' import { ConfigService } from 'src/app/services/config.service' import { MarketplaceService } from 'src/app/services/marketplace.service' import { DataModel } from 'src/app/services/patch-db/data-model' @@ -73,7 +73,7 @@ export class MarketplaceListPage { private readonly patch: PatchDB, @Inject(AbstractMarketplaceService) private readonly marketplaceService: MarketplaceService, - private readonly modalCtrl: ModalController, + private readonly dialogs: TuiDialogService, private readonly config: ConfigService, private readonly route: ActivatedRoute, ) {} @@ -82,10 +82,11 @@ export class MarketplaceListPage { query = '' async presentModalMarketplaceSettings() { - const modal = await this.modalCtrl.create({ - component: MarketplaceSettingsPage, - }) - await modal.present() + this.dialogs + .open(MARKETPLACE_REGISTRY, { + label: 'Change Registry', + }) + .subscribe() } onCategoryChange(category: string): void { diff --git a/web/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show-controls/marketplace-show-controls.component.ts b/web/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show-controls/marketplace-show-controls.component.ts index 4e44e2af3..5c83c536f 100644 --- a/web/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show-controls/marketplace-show-controls.component.ts +++ b/web/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show-controls/marketplace-show-controls.component.ts @@ -4,28 +4,29 @@ import { Inject, Input, } from '@angular/core' -import { AlertController, LoadingController } from '@ionic/angular' +import { AlertController } from '@ionic/angular' import { AbstractMarketplaceService, MarketplacePkg, } from '@start9labs/marketplace' import { Emver, - ErrorToastService, + ErrorService, isEmptyObject, + LoadingService, sameUrl, } from '@start9labs/shared' +import { PatchDB } from 'patch-db-client' +import { firstValueFrom } from 'rxjs' +import { ClientStorageService } from 'src/app/services/client-storage.service' +import { MarketplaceService } from 'src/app/services/marketplace.service' import { DataModel, PackageDataEntry, } from 'src/app/services/patch-db/data-model' -import { ClientStorageService } from 'src/app/services/client-storage.service' -import { MarketplaceService } from 'src/app/services/marketplace.service' -import { hasCurrentDeps } from 'src/app/util/has-deps' -import { PatchDB } from 'patch-db-client' -import { getAllPackages, getManifest } from 'src/app/util/get-package-data' -import { firstValueFrom } from 'rxjs' import { dryUpdate } from 'src/app/util/dry-update' +import { getAllPackages, getManifest } from 'src/app/util/get-package-data' +import { hasCurrentDeps } from 'src/app/util/has-deps' @Component({ selector: 'marketplace-show-controls', @@ -50,9 +51,9 @@ export class MarketplaceShowControlsComponent { private readonly ClientStorageService: ClientStorageService, @Inject(AbstractMarketplaceService) private readonly marketplaceService: MarketplaceService, - private readonly loadingCtrl: LoadingController, + private readonly loader: LoadingService, private readonly emver: Emver, - private readonly errToast: ErrorToastService, + private readonly errorService: ErrorService, private readonly patch: PatchDB, ) {} @@ -176,19 +177,16 @@ export class MarketplaceShowControlsComponent { } private async install(url: string) { - const loader = await this.loadingCtrl.create({ - message: 'Beginning Install...', - }) - await loader.present() + const loader = this.loader.open('Beginning Install...').subscribe() const { id, version } = this.pkg.manifest try { await this.marketplaceService.installPackage(id, version, url) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } diff --git a/web/projects/ui/src/app/pages/notifications/notifications.page.ts b/web/projects/ui/src/app/pages/notifications/notifications.page.ts index 933c50e67..69bad6c29 100644 --- a/web/projects/ui/src/app/pages/notifications/notifications.page.ts +++ b/web/projects/ui/src/app/pages/notifications/notifications.page.ts @@ -1,21 +1,17 @@ import { Component } from '@angular/core' -import { ApiService } from 'src/app/services/api/embassy-api.service' +import { ActivatedRoute } from '@angular/router' +import { AlertController, ModalController } from '@ionic/angular' +import { ErrorService, LoadingService } from '@start9labs/shared' +import { PatchDB } from 'patch-db-client' +import { first } from 'rxjs' +import { BackupReportPage } from 'src/app/modals/backup-report/backup-report.page' import { - ServerNotifications, NotificationLevel, ServerNotification, + ServerNotifications, } from 'src/app/services/api/api.types' -import { - AlertController, - LoadingController, - ModalController, -} from '@ionic/angular' -import { ActivatedRoute } from '@angular/router' -import { ErrorToastService } from '@start9labs/shared' -import { BackupReportPage } from 'src/app/modals/backup-report/backup-report.page' -import { PatchDB } from 'patch-db-client' +import { ApiService } from 'src/app/services/api/embassy-api.service' import { DataModel } from 'src/app/services/patch-db/data-model' -import { first } from 'rxjs' @Component({ selector: 'notifications', @@ -34,9 +30,9 @@ export class NotificationsPage { constructor( private readonly embassyApi: ApiService, private readonly alertCtrl: AlertController, - private readonly loadingCtrl: LoadingController, + private readonly loader: LoadingService, private readonly modalCtrl: ModalController, - private readonly errToast: ErrorToastService, + private readonly errorService: ErrorService, private readonly route: ActivatedRoute, private readonly patch: PatchDB, ) {} @@ -66,26 +62,23 @@ export class NotificationsPage { return notifications } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } return [] } async delete(id: number, index: number): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Deleting...', - }) - await loader.present() + const loader = this.loader.open('Deleting...').subscribe() try { await this.embassyApi.deleteNotification({ id }) this.notifications.splice(index, 1) this.beforeCursor = this.notifications[this.notifications.length - 1]?.id } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } @@ -160,10 +153,7 @@ export class NotificationsPage { } private async deleteAll(): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Deleting...', - }) - await loader.present() + const loader = this.loader.open('Deleting...').subscribe() try { await this.embassyApi.deleteAllNotifications({ @@ -172,9 +162,9 @@ export class NotificationsPage { this.notifications = [] this.beforeCursor = undefined } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } } diff --git a/web/projects/ui/src/app/pages/server-routes/restore/restore.component.ts b/web/projects/ui/src/app/pages/server-routes/restore/restore.component.ts index 88e9cb4a8..ae644399f 100644 --- a/web/projects/ui/src/app/pages/server-routes/restore/restore.component.ts +++ b/web/projects/ui/src/app/pages/server-routes/restore/restore.component.ts @@ -1,14 +1,10 @@ import { Component } from '@angular/core' -import { - LoadingController, - ModalController, - NavController, -} from '@ionic/angular' +import { ModalController, NavController } from '@ionic/angular' +import { LoadingService } from '@start9labs/shared' +import { TuiDialogService } from '@taiga-ui/core' +import { take } from 'rxjs/operators' +import { PROMPT, PromptOptions } from 'src/app/modals/prompt.component' import { ApiService } from 'src/app/services/api/embassy-api.service' -import { - GenericInputComponent, - GenericInputOptions, -} from 'src/app/modals/generic-input/generic-input.component' import { MappedBackupTarget } from 'src/app/types/mapped-backup-target' import { BackupInfo, @@ -26,37 +22,35 @@ import * as argon2 from '@start9labs/argon2' export class RestorePage { constructor( private readonly modalCtrl: ModalController, + private readonly dialogs: TuiDialogService, private readonly navCtrl: NavController, private readonly embassyApi: ApiService, - private readonly loadingCtrl: LoadingController, + private readonly loader: LoadingService, ) {} async presentModalPassword( target: MappedBackupTarget, ): Promise { - const options: GenericInputOptions = { - title: 'Password Required', + const options: PromptOptions = { message: 'Enter the master password that was used to encrypt this backup. On the next screen, you will select the individual services you want to restore.', label: 'Master Password', placeholder: 'Enter master password', useMask: true, buttonText: 'Next', - submitFn: async (password: string) => { + } + + this.dialogs + .open(PROMPT, { + label: 'Password Required', + data: options, + }) + .pipe(take(1)) + .subscribe(async (password: string) => { const passwordHash = target.entry.startOs?.passwordHash || '' argon2.verify(passwordHash, password) await this.restoreFromBackup(target, password) - }, - } - - const modal = await this.modalCtrl.create({ - componentProps: { options }, - cssClass: 'alertlike-modal', - presentingElement: await this.modalCtrl.getTop(), - component: GenericInputComponent, - }) - - await modal.present() + }) } private async restoreFromBackup( @@ -64,10 +58,7 @@ export class RestorePage { password: string, oldPassword?: string, ): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Decrypting drive...', - }) - await loader.present() + const loader = this.loader.open('Decrypting drive...').subscribe() try { const backupInfo = await this.embassyApi.getBackupInfo({ @@ -76,7 +67,7 @@ export class RestorePage { }) this.presentModalSelect(target.id, backupInfo, password, oldPassword) } finally { - loader.dismiss() + loader.unsubscribe() } } diff --git a/web/projects/ui/src/app/pages/server-routes/server-backup/server-backup.page.ts b/web/projects/ui/src/app/pages/server-routes/server-backup/server-backup.page.ts index 0467df102..804a88fab 100644 --- a/web/projects/ui/src/app/pages/server-routes/server-backup/server-backup.page.ts +++ b/web/projects/ui/src/app/pages/server-routes/server-backup/server-backup.page.ts @@ -1,16 +1,11 @@ import { Component } from '@angular/core' -import { - LoadingController, - ModalController, - NavController, -} from '@ionic/angular' +import { ModalController, NavController } from '@ionic/angular' +import { LoadingService } from '@start9labs/shared' +import { TuiDialogService } from '@taiga-ui/core' +import { PROMPT, PromptOptions } from 'src/app/modals/prompt.component' import { ApiService } from 'src/app/services/api/embassy-api.service' -import { - GenericInputComponent, - GenericInputOptions, -} from 'src/app/modals/generic-input/generic-input.component' import { PatchDB } from 'patch-db-client' -import { skip, takeUntil } from 'rxjs/operators' +import { skip, take, takeUntil } from 'rxjs/operators' import { MappedBackupTarget } from 'src/app/types/mapped-backup-target' import * as argon2 from '@start9labs/argon2' import { TuiDestroyService } from '@taiga-ui/cdk' @@ -35,7 +30,8 @@ export class ServerBackupPage { readonly backingUp$ = this.eosService.backingUp$ constructor( - private readonly loadingCtrl: LoadingController, + private readonly loader: LoadingService, + private readonly dialogs: TuiDialogService, private readonly modalCtrl: ModalController, private readonly embassyApi: ApiService, private readonly navCtrl: NavController, @@ -75,14 +71,21 @@ export class ServerBackupPage { private async presentModalPassword( target: MappedBackupTarget, ): Promise { - const options: GenericInputOptions = { - title: 'Master Password Needed', + const options: PromptOptions = { message: 'Enter your master password to encrypt this backup.', label: 'Master Password', placeholder: 'Enter master password', useMask: true, buttonText: 'Create Backup', - submitFn: async (password: string) => { + } + + this.dialogs + .open(PROMPT, { + label: 'Master Password Needed', + data: options, + }) + .pipe(take(1)) + .subscribe(async (password: string) => { // confirm password matches current master password const { passwordHash } = await getServerInfo(this.patch) argon2.verify(passwordHash, password) @@ -105,45 +108,34 @@ export class ServerBackupPage { } await this.createBackup(target, password) } - }, - } - - const m = await this.modalCtrl.create({ - component: GenericInputComponent, - componentProps: { options }, - cssClass: 'alertlike-modal', - }) - - await m.present() + }) } private async presentModalOldPassword( target: MappedBackupTarget, password: string, ): Promise { - const options: GenericInputOptions = { - title: 'Original Password Needed', + const options: PromptOptions = { message: 'This backup was created with a different password. Enter the ORIGINAL password that was used to encrypt this backup.', label: 'Original Password', placeholder: 'Enter original password', useMask: true, buttonText: 'Create Backup', - submitFn: async (oldPassword: string) => { + } + + this.dialogs + .open(PROMPT, { + label: 'Original Password Needed', + data: options, + }) + .pipe(take(1)) + .subscribe(async (oldPassword: string) => { const passwordHash = target.entry.startOs?.passwordHash || '' argon2.verify(passwordHash, oldPassword) await this.createBackup(target, password, oldPassword) - }, - } - - const m = await this.modalCtrl.create({ - component: GenericInputComponent, - componentProps: { options }, - cssClass: 'alertlike-modal', - }) - - await m.present() + }) } private async createBackup( @@ -151,10 +143,7 @@ export class ServerBackupPage { password: string, oldPassword?: string, ): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Beginning backup...', - }) - await loader.present() + const loader = this.loader.open('Beginning backup...').subscribe() try { await this.embassyApi.createBackup({ @@ -164,7 +153,7 @@ export class ServerBackupPage { password, }) } finally { - loader.dismiss() + loader.unsubscribe() } } } diff --git a/web/projects/ui/src/app/pages/server-routes/server-metrics/server-metrics.page.ts b/web/projects/ui/src/app/pages/server-routes/server-metrics/server-metrics.page.ts index 569d34a45..4678fe3ea 100644 --- a/web/projects/ui/src/app/pages/server-routes/server-metrics/server-metrics.page.ts +++ b/web/projects/ui/src/app/pages/server-routes/server-metrics/server-metrics.page.ts @@ -1,9 +1,9 @@ import { Component } from '@angular/core' +import { ErrorService, pauseFor } from '@start9labs/shared' +import { Subject } from 'rxjs' import { Metrics } from 'src/app/services/api/api.types' import { ApiService } from 'src/app/services/api/embassy-api.service' import { TimeService } from 'src/app/services/time-service' -import { pauseFor, ErrorToastService } from '@start9labs/shared' -import { Subject } from 'rxjs' @Component({ selector: 'server-metrics', @@ -18,7 +18,7 @@ export class ServerMetricsPage { readonly uptime$ = this.timeService.uptime$ constructor( - private readonly errToast: ErrorToastService, + private readonly errorService: ErrorService, private readonly embassyApi: ApiService, private readonly timeService: TimeService, ) {} @@ -50,7 +50,7 @@ export class ServerMetricsPage { const metrics = await this.embassyApi.getServerMetrics({}) this.metrics$.next(metrics) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) this.stopDaemon() } } diff --git a/web/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts b/web/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts index f375b0e86..5ade9c666 100644 --- a/web/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts +++ b/web/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts @@ -1,32 +1,32 @@ import { Component, Inject } from '@angular/core' +import { ActivatedRoute } from '@angular/router' import { AlertController, - LoadingController, ModalController, NavController, ToastController, } from '@ionic/angular' -import { ApiService } from 'src/app/services/api/embassy-api.service' -import { ActivatedRoute } from '@angular/router' -import { PatchDB } from 'patch-db-client' -import { firstValueFrom, Observable, of } from 'rxjs' -import { ErrorToastService } from '@start9labs/shared' -import { EOSService } from 'src/app/services/eos.service' -import { ClientStorageService } from 'src/app/services/client-storage.service' -import { OSUpdatePage } from 'src/app/modals/os-update/os-update.page' -import { getAllPackages } from '../../../util/get-package-data' -import { AuthService } from 'src/app/services/auth.service' -import { DataModel } from 'src/app/services/patch-db/data-model' -import { - GenericInputComponent, - GenericInputOptions, -} from 'src/app/modals/generic-input/generic-input.component' -import { ConfigService } from 'src/app/services/config.service' import { WINDOW } from '@ng-web-apis/common' -import { getServerInfo } from 'src/app/util/get-server-info' -import { GenericFormPage } from 'src/app/modals/generic-form/generic-form.page' -import { ConfigSpec } from 'src/app/pkg-config/config-types' import * as argon2 from '@start9labs/argon2' +import { ErrorService, LoadingService } from '@start9labs/shared' +import { CB } from '@start9labs/start-sdk' +import { TuiAlertService, TuiDialogService } from '@taiga-ui/core' +import { TUI_PROMPT } from '@taiga-ui/kit' +import { PatchDB } from 'patch-db-client' +import { filter, from, Observable, of, switchMap } from 'rxjs' +import { take } from 'rxjs/operators' +import { FormComponent } from 'src/app/components/form.component' +import { OSUpdatePage } from 'src/app/modals/os-update/os-update.page' +import { PROMPT } from 'src/app/modals/prompt.component' +import { ApiService } from 'src/app/services/api/embassy-api.service' +import { AuthService } from 'src/app/services/auth.service' +import { ClientStorageService } from 'src/app/services/client-storage.service' +import { ConfigService } from 'src/app/services/config.service' +import { EOSService } from 'src/app/services/eos.service' +import { FormDialogService } from 'src/app/services/form-dialog.service' +import { DataModel } from 'src/app/services/patch-db/data-model' +import { configBuilderToSpec } from 'src/app/util/configBuilderToSpec' +import { getServerInfo } from 'src/app/util/get-server-info' @Component({ selector: 'server-show', @@ -45,8 +45,11 @@ export class ServerShowPage { constructor( private readonly alertCtrl: AlertController, private readonly modalCtrl: ModalController, - private readonly loadingCtrl: LoadingController, - private readonly errToast: ErrorToastService, + private readonly alerts: TuiAlertService, + private readonly dialogs: TuiDialogService, + private readonly formDialog: FormDialogService, + private readonly loader: LoadingService, + private readonly errorService: ErrorService, private readonly embassyApi: ApiService, private readonly navCtrl: NavController, private readonly route: ActivatedRoute, @@ -60,123 +63,110 @@ export class ServerShowPage { ) {} async setBrowserTab(): Promise { - const chosenName = await firstValueFrom(this.patch.watch$('ui', 'name')) + this.patch + .watch$('ui', 'name') + .pipe( + switchMap(initialValue => + this.dialogs.open(PROMPT, { + label: 'Browser Tab Title', + data: { + message: `This value will be displayed as the title of your browser tab.`, + label: 'Device Name', + placeholder: 'StartOS', + required: false, + buttonText: 'Save', + initialValue, + }, + }), + ), + take(1), + ) + .subscribe(async name => { + const loader = this.loader.open('Saving...').subscribe() - const options: GenericInputOptions = { - title: 'Browser Tab Title', - message: `This value will be displayed as the title of your browser tab.`, - label: 'Device Name', - useMask: false, - placeholder: 'StartOS', - nullable: true, - initialValue: chosenName, - buttonText: 'Save', - submitFn: (name: string) => this.setName(name || null), - } - - const modal = await this.modalCtrl.create({ - componentProps: { options }, - cssClass: 'alertlike-modal', - presentingElement: await this.modalCtrl.getTop(), - component: GenericInputComponent, - }) - - await modal.present() + try { + await this.embassyApi.setDbValue( + ['name'], + name || null, + ) + } finally { + loader.unsubscribe() + } + }) } async presentAlertResetPassword() { - const alert = await this.alertCtrl.create({ - header: 'Warning', - message: - 'You will still need your current password to decrypt existing backups!', - buttons: [ - { - text: 'Cancel', - role: 'cancel', + this.dialogs + .open(TUI_PROMPT, { + label: 'Warning', + size: 's', + data: { + content: + 'You will still need your current password to decrypt existing backups!', + yes: 'Continue', + no: 'Cancel', }, - { - text: 'Continue', - handler: () => this.presentModalResetPassword(), - cssClass: 'enter-click', - }, - ], - cssClass: 'alert-warning-message', - }) - - await alert.present() - } - - async presentModalResetPassword(): Promise { - const modal = await this.modalCtrl.create({ - component: GenericFormPage, - componentProps: { - title: 'Change Master Password', - spec: PasswordSpec, - buttons: [ - { - text: 'Save', - handler: (value: any) => { - return this.resetPassword(value) - }, - isSubmit: true, + }) + .pipe( + filter(Boolean), + switchMap(() => from(configBuilderToSpec(passwordSpec))), + ) + .subscribe(spec => { + this.formDialog.open(FormComponent, { + label: 'Change Master Password', + data: { + spec, + buttons: [ + { + text: 'Save', + handler: (value: PasswordSpec) => this.resetPassword(value), + }, + ], }, - ], - }, - }) - await modal.present() + }) + }) } - private async resetPassword(value: { - currPass: string - newPass: string - newPass2: string - }): Promise { + private async resetPassword(value: PasswordSpec): Promise { let err = '' - if (value.newPass !== value.newPass2) { + if (value.newPassword1 !== value.newPassword2) { err = 'New passwords do not match' - } else if (value.newPass.length < 12) { + } else if (value.newPassword1.length < 12) { err = 'New password must be 12 characters or greater' - } else if (value.newPass.length > 64) { + } else if (value.newPassword1.length > 64) { err = 'New password must be less than 65 characters' } // confirm current password is correct const { passwordHash } = await getServerInfo(this.patch) try { - argon2.verify(passwordHash, value.currPass) + argon2.verify(passwordHash, value.currentPassword) } catch (e) { err = 'Current password is invalid' } if (err) { - this.errToast.present(err) + this.errorService.handleError(err) return false } - const loader = await this.loadingCtrl.create({ - message: 'Changing master password...', - }) - await loader.present() + const loader = this.loader.open('Saving...').subscribe() try { await this.embassyApi.resetPassword({ - oldPassword: value.currPass, - newPassword: value.newPass, - }) - const toast = await this.toastCtrl.create({ - header: 'Password changed!', - position: 'bottom', - duration: 2000, + oldPassword: value.currentPassword, + newPassword: value.newPassword1, }) - toast.present() + this.alerts.open('Password changed!').subscribe() + return true } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) return false } finally { - loader.dismiss() + loader.unsubscribe() } } @@ -187,7 +177,7 @@ export class ServerShowPage { const alert = await this.alertCtrl.create({ header: isTor ? 'Warning' : 'Confirm', message: isTor - ? `You are currently connected over Tor. If you reset the Tor daemon, you will loose connectivity until it comes back online.

${shared}` + ? `You are currently connected over Tor. If you reset the Tor daemon, you will lose connectivity until it comes back online.

${shared}` : `Reset Tor?

${shared}`, inputs: [ { @@ -215,10 +205,7 @@ export class ServerShowPage { } private async resetTor(wipeState: boolean) { - const loader = await this.loadingCtrl.create({ - message: 'Resetting Tor...', - }) - await loader.present() + const loader = this.loader.open('Resetting Tor...').subscribe() try { await this.embassyApi.resetTor({ @@ -241,9 +228,9 @@ export class ServerShowPage { }) await toast.present() } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } @@ -336,7 +323,7 @@ export class ServerShowPage { this.restart() }) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } }, cssClass: 'enter-click', @@ -360,19 +347,6 @@ export class ServerShowPage { } } - private async setName(value: string | null): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Saving...', - }) - await loader.present() - - try { - await this.embassyApi.setDbValue(['name'], value) - } finally { - loader.dismiss() - } - } - // should wipe cache independent of actual BE logout private logout() { this.embassyApi.logout({}).catch(e => console.error('Failed to log out', e)) @@ -381,48 +355,37 @@ export class ServerShowPage { private async restart() { const action = 'Restart' - - const loader = await this.loadingCtrl.create({ - message: `Beginning ${action}...`, - }) - await loader.present() + const loader = this.loader.open(`Beginning ${action}...`).subscribe() try { await this.embassyApi.restartServer({}) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } private async shutdown() { const action = 'Shutdown' - - const loader = await this.loadingCtrl.create({ - message: `Beginning ${action}...`, - }) - await loader.present() + const loader = this.loader.open(`Beginning ${action}...`).subscribe() try { await this.embassyApi.shutdownServer({}) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } private async checkForEosUpdate(): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Checking for updates', - }) - await loader.present() + const loader = this.loader.open('Checking for updates').subscribe() try { await this.eosService.loadEos() - await loader.dismiss() + await loader.unsubscribe() if (this.eosService.updateAvailable$.value) { this.updateEos() @@ -430,8 +393,8 @@ export class ServerShowPage { this.presentAlertLatest() } } catch (e: any) { - await loader.dismiss() - this.errToast.present(e) + await loader.unsubscribe() + this.errorService.handleError(e) } } @@ -729,29 +692,28 @@ interface SettingBtn { disabled$: Observable } -const PasswordSpec: ConfigSpec = { - currPass: { - type: 'string', +const passwordSpec = CB.Config.of({ + currentPassword: CB.Value.text({ name: 'Current Password', - placeholder: 'CurrentPass', - nullable: false, + required: { + default: null, + }, masked: true, - copyable: false, - }, - newPass: { - type: 'string', + }), + newPassword1: CB.Value.text({ name: 'New Password', - placeholder: 'NewPass', - nullable: false, + required: { + default: null, + }, masked: true, - copyable: false, - }, - newPass2: { - type: 'string', + }), + newPassword2: CB.Value.text({ name: 'Retype New Password', - placeholder: 'NewPass', - nullable: false, + required: { + default: null, + }, masked: true, - copyable: false, - }, -} + }), +}) + +export type PasswordSpec = typeof passwordSpec.validator._TYPE diff --git a/web/projects/ui/src/app/pages/server-routes/sessions/sessions.page.ts b/web/projects/ui/src/app/pages/server-routes/sessions/sessions.page.ts index d6a1a42e5..9dfdccb66 100644 --- a/web/projects/ui/src/app/pages/server-routes/sessions/sessions.page.ts +++ b/web/projects/ui/src/app/pages/server-routes/sessions/sessions.page.ts @@ -1,8 +1,8 @@ import { Component } from '@angular/core' -import { AlertController, LoadingController } from '@ionic/angular' -import { ErrorToastService } from '@start9labs/shared' -import { ApiService } from 'src/app/services/api/embassy-api.service' +import { AlertController } from '@ionic/angular' +import { ErrorService, LoadingService } from '@start9labs/shared' import { PlatformType, Session } from 'src/app/services/api/api.types' +import { ApiService } from 'src/app/services/api/embassy-api.service' @Component({ selector: 'sessions', @@ -15,8 +15,8 @@ export class SessionsPage { otherSessions: SessionWithId[] = [] constructor( - private readonly loadingCtrl: LoadingController, - private readonly errToast: ErrorToastService, + private readonly loader: LoadingService, + private readonly errorService: ErrorService, private readonly alertCtrl: AlertController, private readonly embassyApi: ApiService, ) {} @@ -39,7 +39,7 @@ export class SessionsPage { ) }) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { this.loading = false } @@ -67,18 +67,17 @@ export class SessionsPage { } async kill(ids: string[]): Promise { - const loader = await this.loadingCtrl.create({ - message: `Terminating session${ids.length > 1 ? 's' : ''}...`, - }) - await loader.present() + const loader = this.loader + .open(`Terminating session${ids.length > 1 ? 's' : ''}...`) + .subscribe() try { await this.embassyApi.killSessions({ ids }) this.otherSessions = this.otherSessions.filter(s => !ids.includes(s.id)) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } diff --git a/web/projects/ui/src/app/pages/server-routes/sideload/sideload.page.ts b/web/projects/ui/src/app/pages/server-routes/sideload/sideload.page.ts index 4026d5183..a0da8609d 100644 --- a/web/projects/ui/src/app/pages/server-routes/sideload/sideload.page.ts +++ b/web/projects/ui/src/app/pages/server-routes/sideload/sideload.page.ts @@ -1,17 +1,18 @@ import { Component } from '@angular/core' -import { isPlatform, LoadingController, NavController } from '@ionic/angular' +import { isPlatform, NavController } from '@ionic/angular' +import { ErrorService, LoadingService } from '@start9labs/shared' +import { S9pk, T } from '@start9labs/start-sdk' +import cbor from 'cbor' import { ApiService } from 'src/app/services/api/embassy-api.service' import { ConfigService } from 'src/app/services/config.service' -import cbor from 'cbor' -import { ErrorToastService } from '@start9labs/shared' -import { T } from '@start9labs/start-sdk' interface Positions { [key: string]: [bigint, bigint] // [position, length] } const MAGIC = new Uint8Array([59, 59]) -const VERSION = new Uint8Array([1]) +const VERSION_1 = new Uint8Array([1]) +const VERSION_2 = new Uint8Array([2]) @Component({ selector: 'sideload', @@ -36,10 +37,10 @@ export class SideloadPage { } constructor( - private readonly loadingCtrl: LoadingController, + private readonly loader: LoadingService, private readonly api: ApiService, private readonly navCtrl: NavController, - private readonly errToast: ErrorToastService, + private readonly errorService: ErrorService, private readonly config: ConfigService, ) {} @@ -64,11 +65,36 @@ export class SideloadPage { async validateS9pk(file: File) { const magic = new Uint8Array(await blobToBuffer(file.slice(0, 2))) const version = new Uint8Array(await blobToBuffer(file.slice(2, 3))) - if (compare(magic, MAGIC) && compare(version, VERSION)) { - await this.parseS9pk(file) - return { - invalid: false, - message: 'A valid package file has been detected!', + if (compare(magic, MAGIC)) { + try { + if (compare(version, VERSION_1)) { + await this.parseS9pkV1(file) + return { + invalid: false, + message: 'A valid package file has been detected!', + } + } else if (compare(version, VERSION_2)) { + await this.parseS9pkV2(file) + return { + invalid: false, + message: 'A valid package file has been detected!', + } + } else { + console.error(version) + return { + invalid: true, + message: 'Invalid package file', + } + } + } catch (e) { + console.error(e) + return { + invalid: true, + message: + e instanceof Error + ? `Invalid package file: ${e.message}` + : 'Invalid package file', + } } } else { return { @@ -85,30 +111,24 @@ export class SideloadPage { } async handleUpload() { - const loader = await this.loadingCtrl.create({ - message: 'Uploading package', - cssClass: 'loader', - }) - await loader.present() + const loader = this.loader.open('Uploading package').subscribe() + try { - const guid = await this.api.sideloadPackage({ - manifest: this.toUpload.manifest!, - icon: this.toUpload.icon!, - }) + const res = await this.api.sideloadPackage() this.api - .uploadPackage(guid, this.toUpload.file!) + .uploadPackage(res.upload, this.toUpload.file!) .catch(e => console.error(e)) this.navCtrl.navigateRoot('/services') } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() this.clearToUpload() } } - async parseS9pk(file: File) { + async parseS9pkV1(file: File) { const positions: Positions = {} // magic=2bytes, version=1bytes, pubkey=32bytes, signature=64bytes, toc_length=4bytes = 103byte is starting point let start = 103 @@ -122,6 +142,12 @@ export class SideloadPage { await this.getIcon(positions, file) } + async parseS9pkV2(file: File) { + const s9pk = await S9pk.deserialize(file, null) + this.toUpload.manifest = s9pk.manifest + this.toUpload.icon = await s9pk.icon() + } + async getManifest(positions: Positions, file: Blob) { const data = await blobToBuffer( file.slice( @@ -225,6 +251,7 @@ async function readBlobToArrayBuffer( } function compare(a: Uint8Array, b: Uint8Array) { + if (a.length !== b.length) return false for (let i = 0; i < a.length; i++) { if (a[i] !== b[i]) return false } diff --git a/web/projects/ui/src/app/pages/server-routes/ssh-keys/ssh-keys.page.html b/web/projects/ui/src/app/pages/server-routes/ssh-keys/ssh-keys.page.html index 61737639b..4dd44dfd1 100644 --- a/web/projects/ui/src/app/pages/server-routes/ssh-keys/ssh-keys.page.html +++ b/web/projects/ui/src/app/pages/server-routes/ssh-keys/ssh-keys.page.html @@ -24,7 +24,7 @@ Saved Keys - + Add New Key @@ -62,7 +62,7 @@ - +

{{ ssh.hostname }}

@@ -73,7 +73,7 @@ slot="end" fill="clear" color="danger" - (click)="presentAlertDelete(i)" + (click)="delete(ssh)" > Remove diff --git a/web/projects/ui/src/app/pages/server-routes/ssh-keys/ssh-keys.page.ts b/web/projects/ui/src/app/pages/server-routes/ssh-keys/ssh-keys.page.ts index 476835566..5e474db0f 100644 --- a/web/projects/ui/src/app/pages/server-routes/ssh-keys/ssh-keys.page.ts +++ b/web/projects/ui/src/app/pages/server-routes/ssh-keys/ssh-keys.page.ts @@ -1,16 +1,12 @@ -import { Component } from '@angular/core' -import { - AlertController, - LoadingController, - ModalController, -} from '@ionic/angular' +import { ChangeDetectorRef, Component } from '@angular/core' +import { ErrorService, LoadingService } from '@start9labs/shared' +import { TuiDialogOptions, TuiDialogService } from '@taiga-ui/core' +import { TUI_PROMPT, TuiPromptData } from '@taiga-ui/kit' +import { filter } from 'rxjs' +import { take } from 'rxjs/operators' +import { PROMPT } from 'src/app/modals/prompt.component' import { SSHKey } from 'src/app/services/api/api.types' -import { ErrorToastService } from '@start9labs/shared' import { ApiService } from 'src/app/services/api/embassy-api.service' -import { - GenericInputComponent, - GenericInputOptions, -} from 'src/app/modals/generic-input/generic-input.component' @Component({ selector: 'ssh-keys', @@ -23,10 +19,10 @@ export class SSHKeysPage { readonly docsUrl = 'https://docs.start9.com/0.3.5.x/user-manual/ssh' constructor( - private readonly loadingCtrl: LoadingController, - private readonly modalCtrl: ModalController, - private readonly errToast: ErrorToastService, - private readonly alertCtrl: AlertController, + private readonly cdr: ChangeDetectorRef, + private readonly loader: LoadingService, + private readonly dialogs: TuiDialogService, + private readonly errorService: ErrorService, private readonly embassyApi: ApiService, ) {} @@ -38,89 +34,62 @@ export class SSHKeysPage { try { this.sshKeys = await this.embassyApi.getSshKeys({}) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { this.loading = false } } - async presentModalAdd() { - const { name, description } = sshSpec + add() { + this.dialogs + .open(PROMPT, ADD_OPTIONS) + .pipe(take(1)) + .subscribe(async key => { + const loader = this.loader.open('Saving...').subscribe() - const options: GenericInputOptions = { - title: name, - message: description, - label: name, - submitFn: (pk: string) => this.add(pk), - } - - const modal = await this.modalCtrl.create({ - component: GenericInputComponent, - componentProps: { options }, - cssClass: 'alertlike-modal', - }) - await modal.present() + try { + this.sshKeys?.push(await this.embassyApi.addSshKey({ key })) + } finally { + loader.unsubscribe() + this.cdr.markForCheck() + } + }) } - async add(pubkey: string): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Saving...', - }) - await loader.present() + delete(key: SSHKey) { + this.dialogs + .open(TUI_PROMPT, DELETE_OPTIONS) + .pipe(filter(Boolean)) + .subscribe(async () => { + const loader = this.loader.open('Deleting...').subscribe() - try { - const key = await this.embassyApi.addSshKey({ key: pubkey }) - this.sshKeys.push(key) - } finally { - loader.dismiss() - } - } - - async presentAlertDelete(i: number) { - const alert = await this.alertCtrl.create({ - header: 'Caution', - message: `Are you sure you want to delete this key?`, - buttons: [ - { - text: 'Cancel', - role: 'cancel', - }, - { - text: 'Delete', - handler: () => { - this.delete(i) - }, - cssClass: 'enter-click', - }, - ], - }) - await alert.present() - } - - async delete(i: number): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Deleting...', - }) - await loader.present() - - try { - const entry = this.sshKeys[i] - await this.embassyApi.deleteSshKey({ fingerprint: entry.fingerprint }) - this.sshKeys.splice(i, 1) - } catch (e: any) { - this.errToast.present(e) - } finally { - loader.dismiss() - } + try { + await this.embassyApi.deleteSshKey({ fingerprint: key.fingerprint }) + this.sshKeys?.splice(this.sshKeys?.indexOf(key), 1) + } catch (e: any) { + this.errorService.handleError(e) + } finally { + loader.unsubscribe() + this.cdr.markForCheck() + } + }) } } -const sshSpec = { - type: 'string', - name: 'SSH Key', - description: - 'Enter the SSH public key you would like to authorize for root access to your server.', - nullable: false, - masked: false, - copyable: false, +const ADD_OPTIONS: Partial> = { + label: 'SSH Key', + data: { + message: + 'Enter the SSH public key you would like to authorize for root access to your Embassy.', + }, +} + +const DELETE_OPTIONS: Partial> = { + label: 'Confirm', + size: 's', + data: { + content: 'Delete key? This action cannot be undone.', + yes: 'Delete', + no: 'Cancel', + }, } diff --git a/web/projects/ui/src/app/pages/server-routes/wifi/wifi.page.ts b/web/projects/ui/src/app/pages/server-routes/wifi/wifi.page.ts index e6d5da252..0a1f6a7d9 100644 --- a/web/projects/ui/src/app/pages/server-routes/wifi/wifi.page.ts +++ b/web/projects/ui/src/app/pages/server-routes/wifi/wifi.page.ts @@ -2,19 +2,23 @@ import { Component, Inject } from '@angular/core' import { ActionSheetController, AlertController, - LoadingController, - ModalController, ToastController, } from '@ionic/angular' -import { AlertInput } from '@ionic/core' -import { ApiService } from 'src/app/services/api/embassy-api.service' -import { ActionSheetButton } from '@ionic/core' -import { ValueSpecObject } from 'src/app/pkg-config/config-types' -import { RR } from 'src/app/services/api/api.types' -import { pauseFor, ErrorToastService } from '@start9labs/shared' -import { GenericFormPage } from 'src/app/modals/generic-form/generic-form.page' -import { ConfigService } from 'src/app/services/config.service' +import { ActionSheetButton, AlertInput } from '@ionic/core' import { WINDOW } from '@ng-web-apis/common' +import { ErrorService, LoadingService, pauseFor } from '@start9labs/shared' +import { CT } from '@start9labs/start-sdk' +import { TuiDialogOptions } from '@taiga-ui/core' +import { FormComponent, FormContext } from 'src/app/components/form.component' +import { RR } from 'src/app/services/api/api.types' +import { ApiService } from 'src/app/services/api/embassy-api.service' +import { ConfigService } from 'src/app/services/config.service' +import { FormDialogService } from 'src/app/services/form-dialog.service' + +export interface WiFiForm { + ssid: string + password: string +} @Component({ selector: 'wifi', @@ -32,9 +36,9 @@ export class WifiPage { private readonly api: ApiService, private readonly toastCtrl: ToastController, private readonly alertCtrl: AlertController, - private readonly loadingCtrl: LoadingController, - private readonly modalCtrl: ModalController, - private readonly errToast: ErrorToastService, + private readonly loader: LoadingService, + private readonly formDialog: FormDialogService, + private readonly errorService: ErrorService, private readonly actionCtrl: ActionSheetController, private readonly config: ConfigService, @Inject(WINDOW) private readonly windowRef: Window, @@ -60,7 +64,7 @@ export class WifiPage { await this.presentAlertCountry() } } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { this.loading = false } @@ -120,30 +124,25 @@ export class WifiPage { async presentModalAdd(ssid?: string, needsPW: boolean = true) { const wifiSpec = getWifiValueSpec(ssid, needsPW) - const modal = await this.modalCtrl.create({ - component: GenericFormPage, - componentProps: { - title: wifiSpec.name, + const options: Partial>> = { + label: wifiSpec.name, + data: { spec: wifiSpec.spec, buttons: [ { text: 'Save for Later', - handler: async (value: { ssid: string; password: string }) => { - await this.save(value.ssid, value.password) - }, + handler: async ({ ssid, password }) => this.save(ssid, password), }, { text: 'Save and Connect', - handler: async (value: { ssid: string; password: string }) => { - await this.saveAndConnect(value.ssid, value.password) - }, - isSubmit: true, + handler: async ({ ssid, password }) => + this.saveAndConnect(ssid, password), }, ], }, - }) + } - await modal.present() + this.formDialog.open(FormComponent, options) } async presentAction(ssid: string) { @@ -179,19 +178,16 @@ export class WifiPage { } private async setCountry(country: string): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Setting country...', - }) - await loader.present() + const loader = this.loader.open('Setting country...').subscribe() try { await this.api.setWifiCountry({ country }) await this.getWifi() this.wifi.country = country } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } @@ -270,43 +266,36 @@ export class WifiPage { } private async connect(ssid: string): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Connecting. This could take a while...', - }) - await loader.present() + const loader = this.loader + .open('Connecting. This could take a while...') + .subscribe() try { await this.api.connectWifi({ ssid }) await this.confirmWifi(ssid) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } private async delete(ssid: string): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Deleting...', - }) - await loader.present() + const loader = this.loader.open('Deleting...').subscribe() try { await this.api.deleteWifi({ ssid }) await this.getWifi() delete this.wifi.ssids[ssid] } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } private async save(ssid: string, password: string): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Saving...', - }) - await loader.present() + const loader = this.loader.open('Saving...').subscribe() try { await this.api.addWifi({ @@ -317,17 +306,16 @@ export class WifiPage { }) await this.getWifi() } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } private async saveAndConnect(ssid: string, password: string): Promise { - const loader = await this.loadingCtrl.create({ - message: 'Connecting. This could take a while...', - }) - await loader.present() + const loader = this.loader + .open('Connecting. This could take a while...') + .subscribe() try { await this.api.addWifi({ @@ -339,39 +327,62 @@ export class WifiPage { await this.confirmWifi(ssid, true) } catch (e: any) { - this.errToast.present(e) + this.errorService.handleError(e) } finally { - loader.dismiss() + loader.unsubscribe() } } } function getWifiValueSpec( - ssid?: string, + ssid: string | null = null, needsPW: boolean = true, -): ValueSpecObject { +): CT.ValueSpecObject { return { + warning: null, type: 'object', name: 'WiFi Credentials', description: 'Enter the network SSID and password. You can connect now or save the network for later.', spec: { ssid: { - type: 'string', + type: 'text', + minLength: null, + maxLength: null, + patterns: [], name: 'Network SSID', - nullable: false, + description: null, + inputmode: 'text', + placeholder: null, + required: true, masked: false, - copyable: false, default: ssid, + warning: null, + disabled: false, + immutable: false, + generate: null, }, password: { - type: 'string', + type: 'text', + minLength: null, + maxLength: null, + patterns: [ + { + regex: '^.{8,}$', + description: 'Must be longer than 8 characters', + }, + ], name: 'Password', - nullable: !needsPW, + description: null, + inputmode: 'text', + placeholder: null, + required: needsPW, masked: true, - copyable: false, - pattern: '^.{8,}$', - 'pattern-description': 'Must be longer than 8 characters', + default: null, + warning: null, + disabled: false, + immutable: false, + generate: null, }, }, } diff --git a/web/projects/ui/src/app/pkg-config/config-types.ts b/web/projects/ui/src/app/pkg-config/config-types.ts deleted file mode 100644 index f73dbc0a4..000000000 --- a/web/projects/ui/src/app/pkg-config/config-types.ts +++ /dev/null @@ -1,159 +0,0 @@ -export type ConfigSpec = Record - -export type ValueType = - | 'string' - | 'number' - | 'boolean' - | 'enum' - | 'list' - | 'object' - | 'pointer' - | 'union' -export type ValueSpec = ValueSpecOf - -// core spec types. These types provide the metadata for performing validations -export type ValueSpecOf = T extends 'string' - ? ValueSpecString - : T extends 'number' - ? ValueSpecNumber - : T extends 'boolean' - ? ValueSpecBoolean - : T extends 'enum' - ? ValueSpecEnum - : T extends 'list' - ? ValueSpecList - : T extends 'object' - ? ValueSpecObject - : T extends 'union' - ? ValueSpecUnion - : never - -export interface ValueSpecString extends ListValueSpecString, WithStandalone { - type: 'string' - default?: DefaultString - nullable: boolean - textarea?: boolean -} - -export interface ValueSpecNumber extends ListValueSpecNumber, WithStandalone { - type: 'number' - nullable: boolean - default?: number -} - -export interface ValueSpecEnum extends ListValueSpecEnum, WithStandalone { - type: 'enum' - default: string -} - -export interface ValueSpecBoolean extends WithStandalone { - type: 'boolean' - default: boolean -} - -export interface ValueSpecUnion { - type: 'union' - tag: UnionTagSpec - variants: { [key: string]: ConfigSpec } - default: string -} - -export interface ValueSpecObject extends WithStandalone { - type: 'object' - spec: ConfigSpec -} - -export interface WithStandalone { - name: string - description?: string - warning?: string -} - -// no lists of booleans, lists, pointers -export type ListValueSpecType = - | 'string' - | 'number' - | 'enum' - | 'object' - | 'union' - -// represents a spec for the values of a list -export type ListValueSpecOf = T extends 'string' - ? ListValueSpecString - : T extends 'number' - ? ListValueSpecNumber - : T extends 'enum' - ? ListValueSpecEnum - : T extends 'object' - ? ListValueSpecObject - : T extends 'union' - ? ListValueSpecUnion - : never - -// represents a spec for a list -export type ValueSpecList = ValueSpecListOf -export interface ValueSpecListOf - extends WithStandalone { - type: 'list' - subtype: T - spec: ListValueSpecOf - range: string // '[0,1]' (inclusive) OR '[0,*)' (right unbounded), normal math rules - default: string[] | number[] | DefaultString[] | object[] -} - -// sometimes the type checker needs just a little bit of help -export function isValueSpecListOf( - t: ValueSpecList, - s: S, -): t is ValueSpecListOf { - return t.subtype === s -} - -export interface ListValueSpecString { - pattern?: string - 'pattern-description'?: string - masked: boolean - copyable: boolean - placeholder?: string -} - -export interface ListValueSpecNumber { - range: string - integral: boolean - units?: string - placeholder?: string -} - -export interface ListValueSpecEnum { - values: string[] - 'value-names': { [value: string]: string } -} - -export interface ListValueSpecObject { - spec: ConfigSpec // this is a mapped type of the config object at this level, replacing the object's values with specs on those values - 'unique-by': UniqueBy // indicates whether duplicates can be permitted in the list - 'display-as'?: string // this should be a handlebars template which can make use of the entire config which corresponds to 'spec' -} - -export type UniqueBy = null | string | { any: UniqueBy[] } | { all: UniqueBy[] } - -export interface ListValueSpecUnion { - tag: UnionTagSpec - variants: { [key: string]: ConfigSpec } - 'display-as'?: string // this may be a handlebars template which can conditionally (on tag.id) make use of each union's entries, or if left blank will display as tag.id - 'unique-by': UniqueBy - default: string // this should be the variantName which one prefers a user to start with by default when creating a new union instance in a list -} - -export interface UnionTagSpec { - id: string // The name of the field containing one of the union variants - 'variant-names': { - // the name of each variant - [variant: string]: string - } - name: string - description?: string - warning?: string -} - -export type DefaultString = string | { charset: string; len: number } diff --git a/web/projects/ui/src/app/pkg-config/config-utilities.ts b/web/projects/ui/src/app/pkg-config/config-utilities.ts deleted file mode 100644 index 431bc1c5d..000000000 --- a/web/projects/ui/src/app/pkg-config/config-utilities.ts +++ /dev/null @@ -1,235 +0,0 @@ -import { ValueSpec, DefaultString } from './config-types' - -export class Range { - min?: number - max?: number - minInclusive!: boolean - maxInclusive!: boolean - - static from(s: string): Range { - const r = new Range() - r.minInclusive = s.startsWith('[') - r.maxInclusive = s.endsWith(']') - const [minStr, maxStr] = s.split(',').map(a => a.trim()) - r.min = minStr === '(*' ? undefined : Number(minStr.slice(1)) - r.max = maxStr === '*)' ? undefined : Number(maxStr.slice(0, -1)) - return r - } - - checkIncludes(n: number) { - if ( - this.hasMin() && - (this.min > n || (!this.minInclusive && this.min == n)) - ) { - throw new Error(this.minMessage()) - } - if ( - this.hasMax() && - (this.max < n || (!this.maxInclusive && this.max == n)) - ) { - throw new Error(this.maxMessage()) - } - } - - hasMin(): this is Range & { min: number } { - return this.min !== undefined - } - - hasMax(): this is Range & { max: number } { - return this.max !== undefined - } - - minMessage(): string { - return `greater than${this.minInclusive ? ' or equal to' : ''} ${this.min}` - } - - maxMessage(): string { - return `less than${this.maxInclusive ? ' or equal to' : ''} ${this.max}` - } - - description(): string { - let message = 'Value can be any number.' - - if (this.hasMin() || this.hasMax()) { - message = 'Value must be' - } - - if (this.hasMin() && this.hasMax()) { - message = `${message} ${this.minMessage()} AND ${this.maxMessage()}.` - } else if (this.hasMin() && !this.hasMax()) { - message = `${message} ${this.minMessage()}.` - } else if (!this.hasMin() && this.hasMax()) { - message = `${message} ${this.maxMessage()}.` - } - - return message - } - - integralMin(): number | undefined { - if (this.min) { - const ceil = Math.ceil(this.min) - if (this.minInclusive) { - return ceil - } else { - if (ceil === this.min) { - return ceil + 1 - } else { - return ceil - } - } - } - } - - integralMax(): number | undefined { - if (this.max) { - const floor = Math.floor(this.max) - if (this.maxInclusive) { - return floor - } else { - if (floor === this.max) { - return floor - 1 - } else { - return floor - } - } - } - } -} - -export function getDefaultDescription(spec: ValueSpec): string { - let toReturn: string | undefined - switch (spec.type) { - case 'string': - if (typeof spec.default === 'string') { - toReturn = spec.default - } else if (typeof spec.default === 'object') { - toReturn = 'random' - } - break - case 'number': - if (typeof spec.default === 'number') { - toReturn = String(spec.default) - } - break - case 'boolean': - toReturn = spec.default === true ? 'True' : 'False' - break - case 'enum': - toReturn = spec['value-names'][spec.default] - break - } - - return toReturn || '' -} - -export function getDefaultString(defaultSpec: DefaultString): string { - if (typeof defaultSpec === 'string') { - return defaultSpec - } else { - let s = '' - for (let i = 0; i < defaultSpec.len; i++) { - s = s + getRandomCharInSet(defaultSpec.charset) - } - - return s - } -} - -// a,g,h,A-Z,,,,- -export function getRandomCharInSet(charset: string): string { - const set = stringToCharSet(charset) - let charIdx = Math.floor(Math.random() * set.len) - for (let range of set.ranges) { - if (range.len > charIdx) { - return String.fromCharCode(range.start.charCodeAt(0) + charIdx) - } - charIdx -= range.len - } - throw new Error('unreachable') -} - -function stringToCharSet(charset: string): CharSet { - let set: CharSet = { ranges: [], len: 0 } - let start: string | null = null - let end: string | null = null - let in_range = false - for (let char of charset) { - switch (char) { - case ',': - if (start !== null && end !== null) { - if (start!.charCodeAt(0) > end!.charCodeAt(0)) { - throw new Error('start > end of charset') - } - const len = end.charCodeAt(0) - start.charCodeAt(0) + 1 - set.ranges.push({ - start, - end, - len, - }) - set.len += len - start = null - end = null - in_range = false - } else if (start !== null && !in_range) { - set.len += 1 - set.ranges.push({ start, end: start, len: 1 }) - start = null - } else if (start !== null && in_range) { - end = ',' - } else if (start === null && end === null && !in_range) { - start = ',' - } else { - throw new Error('unexpected ","') - } - break - case '-': - if (start === null) { - start = '-' - } else if (!in_range) { - in_range = true - } else if (in_range && end === null) { - end = '-' - } else { - throw new Error('unexpected "-"') - } - break - default: - if (start === null) { - start = char - } else if (in_range && end === null) { - end = char - } else { - throw new Error(`unexpected "${char}"`) - } - } - } - if (start !== null && end !== null) { - if (start!.charCodeAt(0) > end!.charCodeAt(0)) { - throw new Error('start > end of charset') - } - const len = end.charCodeAt(0) - start.charCodeAt(0) + 1 - set.ranges.push({ - start, - end, - len, - }) - set.len += len - } else if (start !== null) { - set.len += 1 - set.ranges.push({ - start, - end: start, - len: 1, - }) - } - return set -} - -interface CharSet { - ranges: { - start: string - end: string - len: number - }[] - len: number -} diff --git a/web/projects/ui/src/app/services/api/api.fixures.ts b/web/projects/ui/src/app/services/api/api.fixures.ts index 8c0f447a0..abddbcf90 100644 --- a/web/projects/ui/src/app/services/api/api.fixures.ts +++ b/web/projects/ui/src/app/services/api/api.fixures.ts @@ -6,7 +6,8 @@ import { Metric, NotificationLevel, RR, ServerNotifications } from './api.types' import { BTC_ICON, LND_ICON, PROXY_ICON } from './api-icons' import { DependencyMetadata, MarketplacePkg } from '@start9labs/marketplace' import { Log } from '@start9labs/shared' -import { T } from '@start9labs/start-sdk' +import { configBuilderToSpec } from 'src/app/util/configBuilderToSpec' +import { T, CB } from '@start9labs/start-sdk' export module Mock { export const ServerUpdated: T.ServerStatus = { @@ -714,653 +715,514 @@ export module Mock { value: 'https://guessagain.com', }, }, - } as any // @TODO why is this necessary? + } - export const ConfigSpec: RR.GetPackageConfigRes['spec'] = { - bitcoin: { - type: 'object', - name: 'Bitcoin Settings', - description: - 'RPC and P2P interface configuration options for Bitcoin Core', - spec: { - 'bitcoind-p2p': { - type: 'union', - tag: { - id: 'type', - name: 'Bitcoin Core P2P', + export const getInputSpec = async (): Promise< + RR.GetPackageConfigRes['spec'] + > => + configBuilderToSpec( + CB.Config.of({ + bitcoin: CB.Value.object( + { + name: 'Bitcoin Settings', description: - '

The Bitcoin Core node to connect to over the peer-to-peer (P2P) interface:

  • Bitcoin Core: The Bitcoin Core service installed on this device
  • External Node: A Bitcoin node running on a different device
', - 'variant-names': { - internal: 'Bitcoin Core', - external: 'External Node', - }, + 'RPC and P2P interface configuration options for Bitcoin Core', }, - default: 'internal', - variants: { - internal: {}, - external: { - 'p2p-host': { - type: 'string', - name: 'Public Address', - description: 'The public address of your Bitcoin Core server', - nullable: false, - masked: false, - copyable: false, - }, - 'p2p-port': { - type: 'number', - name: 'P2P Port', + CB.Config.of({ + 'bitcoind-p2p': CB.Value.union( + { + name: 'P2P Settings', description: - 'The port that your Bitcoin Core P2P server is bound to', - nullable: false, - range: '[0,65535]', - integral: true, - default: 8333, + '

The Bitcoin Core node to connect to over the peer-to-peer (P2P) interface:

  • Bitcoin Core: The Bitcoin Core service installed on this device
  • External Node: A Bitcoin node running on a different device
', + required: { default: 'internal' }, }, - }, - }, - }, - }, - }, - advanced: { - name: 'Advanced', - type: 'object', - description: 'Advanced settings', - spec: { - rpcsettings: { - name: 'RPC Settings', - type: 'object', - description: 'rpc username and password', - warning: - 'Adding RPC users gives them special permissions on your node.', - spec: { - rpcuser2: { - name: 'RPC Username', - type: 'string', - description: 'rpc username', - nullable: false, - default: 'defaultrpcusername', - pattern: '^[a-zA-Z]+$', - 'pattern-description': 'must contain only letters.', - masked: false, - copyable: true, - }, - rpcuser: { - name: 'RPC Username', - type: 'string', - description: 'rpc username', - nullable: false, - default: 'defaultrpcusername', - pattern: '^[a-zA-Z]+$', - 'pattern-description': 'must contain only letters.', - masked: false, - copyable: true, - }, - rpcpass: { - name: 'RPC User Password', - type: 'string', - description: 'rpc password', - nullable: false, - default: { - charset: 'a-z,A-Z,2-9', - len: 20, - }, - masked: true, - copyable: true, - }, - rpcpass2: { - name: 'RPC User Password', - type: 'string', - description: 'rpc password', - nullable: false, - default: { - charset: 'a-z,A-Z,2-9', - len: 20, - }, - masked: true, - copyable: true, - }, - }, - }, - }, - }, - testnet: { - name: 'Testnet', - type: 'boolean', - description: - '
  • determines whether your node is running on testnet or mainnet
', - warning: 'Chain will have to resync!', - default: true, - }, - 'object-list': { - name: 'Object List', - type: 'list', - subtype: 'object', - description: 'This is a list of objects, like users or something', - range: '[0,4]', - default: [ - { - 'first-name': 'Admin', - 'last-name': 'User', - age: 40, - }, - { - 'first-name': 'Admin2', - 'last-name': 'User', - age: 40, - }, - ], - // the outer spec here, at the list level, says that what's inside (the inner spec) pertains to its inner elements. - // it just so happens that ValueSpecObject's have the field { spec: ConfigSpec } - // see 'union-list' below for a different example. - spec: { - 'unique-by': 'last-name', - 'display-as': `I'm {{last-name}}, {{first-name}} {{last-name}}`, - spec: { - 'first-name': { - name: 'First Name', - type: 'string', - description: 'User first name', - nullable: true, - masked: false, - copyable: false, - }, - 'last-name': { - name: 'Last Name', - type: 'string', - description: 'User first name', - nullable: true, - default: { - charset: 'a-g,2-9', - len: 12, - }, - pattern: '^[a-zA-Z]+$', - 'pattern-description': 'must contain only letters.', - masked: false, - copyable: true, - }, - age: { - name: 'Age', - type: 'number', - description: 'The age of the user', - nullable: true, - integral: false, - warning: 'User must be at least 18.', - range: '[18,*)', - }, - }, - }, - }, - 'union-list': { - name: 'Union List', - type: 'list', - subtype: 'union', - description: 'This is a sample list of unions', - warning: 'If you change this, things may work.', - // a list of union selections. e.g. 'summer', 'winter',... - default: ['summer'], - range: '[0, 2]', - spec: { - tag: { - id: 'preference', - 'variant-names': { - summer: 'Summer', - winter: 'Winter', - other: 'Other', - }, - name: 'Preference', - }, - // this default is used to make a union selection when a new list element is first created - default: 'summer', - variants: { - summer: { - 'favorite-tree': { - name: 'Favorite Tree', - type: 'string', - nullable: false, - description: 'What is your favorite tree?', - default: 'Maple', - masked: false, - copyable: false, - }, - 'favorite-flower': { - name: 'Favorite Flower', - type: 'enum', - description: 'Select your favorite flower', - 'value-names': { - none: 'Hate Flowers', - red: 'Red', - blue: 'Blue', - purple: 'Purple', - }, - values: ['none', 'red', 'blue', 'purple'], - default: 'none', - }, - }, - winter: { - 'like-snow': { - name: 'Like Snow?', - type: 'boolean', - description: 'Do you like snow or not?', - default: true, - }, - }, - }, - 'unique-by': 'preference', - }, - }, - 'random-enum': { - name: 'Random Enum', - type: 'enum', - 'value-names': { - null: 'Null', - option1: 'One 1', - option2: 'Two 2', - option3: 'Three 3', - }, - default: 'null', - description: 'This is not even real.', - warning: 'Be careful changing this!', - values: ['null', 'option1', 'option2', 'option3'], - }, - 'favorite-number': { - name: 'Favorite Number', - type: 'number', - integral: false, - description: 'Your favorite number of all time', - warning: - 'Once you set this number, it can never be changed without severe consequences.', - nullable: true, - default: 7, - range: '(-100,100]', - units: 'BTC', - }, - 'unlucky-numbers': { - name: 'Unlucky Numbers', - type: 'list', - subtype: 'number', - description: 'Numbers that you like but are not your top favorite.', - spec: { - integral: false, - range: '[-100,200)', - }, - range: '[0,10]', - default: [2, 3], - }, - rpcsettings: { - name: 'RPC Settings', - type: 'object', - description: 'rpc username and password', - warning: 'Adding RPC users gives them special permissions on your node.', - spec: { - laws: { - name: 'Laws', - type: 'object', - description: 'the law of the realm', - spec: { - law1: { - name: 'First Law', - type: 'string', - description: 'the first law', - nullable: true, - masked: false, - copyable: true, - }, - law2: { - name: 'Second Law', - type: 'string', - description: 'the second law', - nullable: true, - masked: false, - copyable: true, - }, - }, - }, - rulemakers: { - name: 'Rule Makers', - type: 'list', - subtype: 'object', - description: 'the people who make the rules', - range: '[0,2]', + CB.Variants.of({ + internal: { name: 'Bitcoin Core', spec: CB.Config.of({}) }, + external: { + name: 'External Node', + spec: CB.Config.of({ + 'p2p-host': CB.Value.text({ + name: 'Public Address', + required: { + default: null, + }, + description: + 'The public address of your Bitcoin Core server', + }), + 'p2p-port': CB.Value.number({ + name: 'P2P Port', + description: + 'The port that your Bitcoin Core P2P server is bound to', + required: { + default: 8333, + }, + min: 0, + max: 65535, + integer: true, + }), + }), + }, + }), + ), + }), + ), + color: CB.Value.color({ + name: 'Color', + required: false, + }), + datetime: CB.Value.datetime({ + name: 'Datetime', + required: false, + }), + file: CB.Value.file({ + name: 'File', + required: false, + extensions: ['png', 'pdf'], + }), + users: CB.Value.multiselect({ + name: 'Users', default: [], - spec: { - 'unique-by': null, - spec: { - rulemakername: { - name: 'Rulemaker Name', - type: 'string', - description: 'the name of the rule maker', - nullable: false, - default: { - charset: 'a-g,2-9', - len: 12, - }, - masked: false, - copyable: false, + maxLength: 2, + disabled: ['matt'], + values: { + matt: 'Matt Hill', + alex: 'Alex Inkin', + blue: 'Blue J', + lucy: 'Lucy', + }, + }), + advanced: CB.Value.object( + { + name: 'Advanced', + description: 'Advanced settings', + }, + CB.Config.of({ + rpcsettings: CB.Value.object( + { + name: 'RPC Settings', + description: 'rpc username and password', + warning: + 'Adding RPC users gives them special permissions on your node.', }, - rulemakerip: { - name: 'Rulemaker IP', - type: 'string', - description: 'the ip of the rule maker', - nullable: false, - default: '192.168.1.0', - pattern: - '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$', - 'pattern-description': 'may only contain numbers and periods', - masked: false, - copyable: true, - }, - }, - }, - }, - rpcuser: { - name: 'RPC Username', - type: 'string', - description: 'rpc username', - nullable: false, - default: 'defaultrpcusername', - pattern: '^[a-zA-Z]+$', - 'pattern-description': 'must contain only letters.', - masked: false, - copyable: true, - }, - rpcpass: { - name: 'RPC User Password', - type: 'string', - description: 'rpc password', - nullable: false, - default: { - charset: 'a-z,A-Z,2-9', - len: 20, - }, - masked: true, - copyable: true, - }, - }, - }, - 'bitcoin-node': { - type: 'union', - default: 'internal', - tag: { - id: 'type', - 'variant-names': { - internal: 'Internal', - external: 'External', - }, - name: 'Bitcoin Node Settings', - description: 'Options
  • Item 1
  • Item 2
', - warning: 'Careful changing this', - }, - variants: { - internal: {}, - external: { - 'emergency-contact': { - name: 'Emergency Contact', - type: 'object', - description: 'The person to contact in case of emergency.', - spec: { - name: { - type: 'string', - name: 'Name', - nullable: false, - masked: false, - copyable: false, - pattern: '^[a-zA-Z]+$', - 'pattern-description': 'Must contain only letters.', - }, - email: { - type: 'string', - name: 'Email', - nullable: false, - masked: false, - copyable: true, - }, - }, - }, - 'public-domain': { - name: 'Public Domain', - type: 'string', - description: 'the public address of the node', - nullable: false, - default: 'bitcoinnode.com', - pattern: '.*', - 'pattern-description': 'anything', - masked: false, - copyable: true, - }, - 'private-domain': { - name: 'Private Domain', - type: 'string', - description: 'the private address of the node', - nullable: false, - masked: true, - copyable: true, - }, - }, - }, - }, - port: { - name: 'Port', - type: 'number', - integral: true, - description: - 'the default port for your Bitcoin node. default: 8333, testnet: 18333, regtest: 18444', - nullable: false, - default: 8333, - range: '(0, 9998]', - }, - 'favorite-slogan': { - name: 'Favorite Slogan', - type: 'string', - description: - 'You most favorite slogan in the whole world, used for paying you.', - nullable: true, - masked: true, - copyable: true, - }, - rpcallowip: { - name: 'RPC Allowed IPs', - type: 'list', - subtype: 'string', - description: - 'external ip addresses that are authorized to access your Bitcoin node', - warning: - 'Any IP you allow here will have RPC access to your Bitcoin node.', - range: '[1,10]', - default: ['192.168.1.1'], - spec: { - masked: false, - copyable: false, - pattern: - '((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|((^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$)|(^[a-z2-7]{16}\\.onion$)|(^([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]$))', - 'pattern-description': 'must be a valid ipv4, ipv6, or domain name', - }, - }, - rpcauth: { - name: 'RPC Auth', - type: 'list', - subtype: 'string', - description: 'api keys that are authorized to access your Bitcoin node.', - range: '[0,*)', - default: [], - spec: { - masked: false, - copyable: false, - }, - }, - 'more-advanced': { - name: 'More Advanced', - type: 'object', - description: 'Advanced settings', - spec: { - notifications: { - name: 'Notification Preferences', - type: 'list', - subtype: 'enum', - description: 'how you want to be notified', - range: '[1,3]', - default: ['email'], - spec: { - 'value-names': { - email: 'EEEEmail', - text: 'Texxxt', - call: 'Ccccall', - push: 'PuuuusH', - webhook: 'WebHooookkeee', - }, - values: ['email', 'text', 'call', 'push', 'webhook'], - }, - }, - rpcsettings: { - name: 'RPC Settings', - type: 'object', - description: 'rpc username and password', - warning: - 'Adding RPC users gives them special permissions on your node.', - spec: { - laws: { - name: 'Laws', - type: 'object', - description: 'the law of the realm', - spec: { - law1: { - name: 'First Law', - type: 'string', - description: 'the first law', - nullable: true, - masked: false, - copyable: true, - }, - law2: { - name: 'Second Law', - type: 'string', - description: 'the second law', - nullable: true, - masked: false, - copyable: true, - }, - law4: { - name: 'Fourth Law', - type: 'string', - description: 'the fourth law', - nullable: true, - masked: false, - copyable: true, - }, - law3: { - name: 'Third Law', - type: 'list', - subtype: 'object', - description: 'the third law', - range: '[0,2]', - default: [], - spec: { - 'unique-by': null, - spec: { - lawname: { - name: 'Law Name', - type: 'string', - description: 'the name of the law maker', - nullable: false, - default: { - charset: 'a-g,2-9', - len: 12, - }, - masked: false, - copyable: false, - }, - lawagency: { - name: 'Law agency', - type: 'string', - description: 'the ip of the law maker', - nullable: false, - default: '192.168.1.0', - pattern: - '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$', - 'pattern-description': - 'may only contain numbers and periods', - masked: false, - copyable: true, - }, + CB.Config.of({ + rpcuser2: CB.Value.text({ + name: 'RPC Username', + required: { + default: 'defaultrpcusername', + }, + description: 'rpc username', + patterns: [ + { + regex: '^[a-zA-Z]+$', + description: 'must contain only letters.', + }, + ], + }), + rpcuser: CB.Value.text({ + name: 'RPC Username', + required: { + default: 'defaultrpcusername', + }, + description: 'rpc username', + patterns: [ + { + regex: '^[a-zA-Z]+$', + description: 'must contain only letters.', + }, + ], + }), + rpcpass: CB.Value.text({ + name: 'RPC User Password', + required: { + default: { + charset: 'a-z,A-Z,2-9', + len: 20, }, }, - }, - law5: { - name: 'Fifth Law', - type: 'string', - description: 'the fifth law', - nullable: true, - masked: false, - copyable: true, - }, - }, + description: 'rpc password', + }), + rpcpass2: CB.Value.text({ + name: 'RPC User Password', + required: { + default: { + charset: 'a-z,A-Z,2-9', + len: 20, + }, + }, + description: 'rpc password', + }), + }), + ), + }), + ), + testnet: CB.Value.toggle({ + name: 'Testnet', + default: true, + description: + '
  • determines whether your node is running on testnet or mainnet
', + warning: 'Chain will have to resync!', + }), + 'object-list': CB.Value.list( + CB.List.obj( + { + name: 'Object List', + minLength: 0, + maxLength: 4, + default: [ + // { 'first-name': 'Admin', 'last-name': 'User', age: 40 }, + // { 'first-name': 'Admin2', 'last-name': 'User', age: 40 }, + ], + description: 'This is a list of objects, like users or something', }, - rulemakers: { - name: 'Rule Makers', - type: 'list', - subtype: 'object', - description: 'the people who make the rules', - range: '[0,2]', - default: [], - spec: { - 'unique-by': null, - spec: { - rulemakername: { - name: 'Rulemaker Name', - type: 'string', - description: 'the name of the rule maker', - nullable: false, + { + spec: CB.Config.of({ + 'first-name': CB.Value.text({ + name: 'First Name', + required: false, + description: 'User first name', + }), + 'last-name': CB.Value.text({ + name: 'Last Name', + required: { default: { charset: 'a-g,2-9', len: 12, }, - masked: false, - copyable: false, }, - rulemakerip: { - name: 'Rulemaker IP', - type: 'string', - description: 'the ip of the rule maker', - nullable: false, - default: '192.168.1.0', - pattern: - '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$', - 'pattern-description': - 'may only contain numbers and periods', - masked: false, - copyable: true, + description: 'User first name', + patterns: [ + { + regex: '^[a-zA-Z]+$', + description: 'must contain only letters.', + }, + ], + }), + age: CB.Value.number({ + name: 'Age', + description: 'The age of the user', + warning: 'User must be at least 18.', + required: false, + min: 18, + integer: false, + }), + }), + displayAs: `I'm {{last-name}}, {{first-name}} {{last-name}}`, + uniqueBy: 'last-name', + }, + ), + ), + 'union-list': CB.Value.list( + CB.List.obj( + { + name: 'Union List', + minLength: 0, + maxLength: 2, + default: [], + description: 'This is a sample list of unions', + warning: 'If you change this, things may work.', + }, + { + spec: CB.Config.of({ + /* TODO: Convert range for this value ([0, 2])*/ + union: CB.Value.union( + { + name: 'Preference', + description: null, + warning: null, + required: { default: 'summer' }, }, + CB.Variants.of({ + summer: { + name: 'summer', + spec: CB.Config.of({ + 'favorite-tree': CB.Value.text({ + name: 'Favorite Tree', + required: { + default: 'Maple', + }, + description: 'What is your favorite tree?', + }), + 'favorite-flower': CB.Value.select({ + name: 'Favorite Flower', + description: 'Select your favorite flower', + required: { + default: 'none', + }, + values: { + none: 'none', + red: 'red', + blue: 'blue', + purple: 'purple', + }, + }), + }), + }, + winter: { + name: 'winter', + spec: CB.Config.of({ + 'like-snow': CB.Value.toggle({ + name: 'Like Snow?', + default: true, + description: 'Do you like snow or not?', + }), + }), + }, + }), + ), + }), + uniqueBy: 'preference', + }, + ), + ), + 'random-select': CB.Value.select({ + name: 'Random select', + description: 'This is not even real.', + warning: 'Be careful changing this!', + required: { + default: null, + }, + values: { + option1: 'option1', + option2: 'option2', + option3: 'option3', + }, + disabled: ['option2'], + }), + 'favorite-number': + /* TODO: Convert range for this value ((-100,100])*/ CB.Value.number({ + name: 'Favorite Number', + description: 'Your favorite number of all time', + warning: + 'Once you set this number, it can never be changed without severe consequences.', + required: { + default: 7, + }, + integer: false, + units: 'BTC', + }), + rpcsettings: CB.Value.object( + { + name: 'RPC Settings', + description: 'rpc username and password', + warning: + 'Adding RPC users gives them special permissions on your node.', + }, + CB.Config.of({ + laws: CB.Value.object( + { + name: 'Laws', + description: 'the law of the realm', + }, + CB.Config.of({ + law1: CB.Value.text({ + name: 'First Law', + required: false, + description: 'the first law', + }), + law2: CB.Value.text({ + name: 'Second Law', + required: false, + description: 'the second law', + }), + }), + ), + rulemakers: CB.Value.list( + CB.List.obj( + { + name: 'Rule Makers', + minLength: 0, + maxLength: 2, + description: 'the people who make the rules', + }, + { + spec: CB.Config.of({ + rulemakername: CB.Value.text({ + name: 'Rulemaker Name', + required: { + default: { + charset: 'a-g,2-9', + len: 12, + }, + }, + description: 'the name of the rule maker', + }), + rulemakerip: CB.Value.text({ + name: 'Rulemaker IP', + required: { + default: '192.168.1.0', + }, + description: 'the ip of the rule maker', + patterns: [ + { + regex: + '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$', + description: 'may only contain numbers and periods', + }, + ], + }), + }), + }, + ), + ), + rpcuser: CB.Value.text({ + name: 'RPC Username', + required: { + default: 'defaultrpcusername', + }, + description: 'rpc username', + patterns: [ + { + regex: '^[a-zA-Z]+$', + description: 'must contain only letters.', + }, + ], + }), + rpcpass: CB.Value.text({ + name: 'RPC User Password', + required: { + default: { + charset: 'a-z,A-Z,2-9', + len: 20, }, }, - }, - rpcuser: { - name: 'RPC Username', - type: 'string', - description: 'rpc username', - nullable: false, - default: 'defaultrpcusername', - pattern: '^[a-zA-Z]+$', - 'pattern-description': 'must contain only letters.', - masked: false, - copyable: true, - }, - rpcpass: { - name: 'RPC User Password', - type: 'string', description: 'rpc password', - nullable: false, - default: { - charset: 'a-z,A-Z,2-9', - len: 20, - }, masked: true, - copyable: true, - }, + }), + }), + ), + 'bitcoin-node': CB.Value.union( + { + name: 'Bitcoin Node', + description: 'Options
  • Item 1
  • Item 2
', + warning: 'Careful changing this', + required: { default: 'internal' }, + disabled: ['fake'], }, - }, - }, - }, - } + CB.Variants.of({ + fake: { + name: 'Fake', + spec: CB.Config.of({}), + }, + internal: { + name: 'Internal', + spec: CB.Config.of({}), + }, + external: { + name: 'External', + spec: CB.Config.of({ + 'emergency-contact': CB.Value.object( + { + name: 'Emergency Contact', + description: 'The person to contact in case of emergency.', + }, + CB.Config.of({ + name: CB.Value.text({ + name: 'Name', + required: { + default: null, + }, + patterns: [ + { + regex: '^[a-zA-Z]+$', + description: 'Must contain only letters.', + }, + ], + }), + email: CB.Value.text({ + name: 'Email', + inputmode: 'email', + required: { + default: null, + }, + }), + }), + ), + 'public-domain': CB.Value.text({ + name: 'Public Domain', + required: { + default: 'bitcoinnode.com', + }, + description: 'the public address of the node', + patterns: [ + { + regex: '.*', + description: 'anything', + }, + ], + }), + 'private-domain': CB.Value.text({ + name: 'Private Domain', + required: { + default: null, + }, + description: 'the private address of the node', + masked: true, + inputmode: 'url', + }), + }), + }, + }), + ), + port: CB.Value.number({ + name: 'Port', + description: + 'the default port for your Bitcoin node. default: 8333, testnet: 18333, regtest: 18444', + required: { + default: 8333, + }, + min: 1, + max: 9998, + step: 1, + integer: true, + }), + 'favorite-slogan': CB.Value.text({ + name: 'Favorite Slogan', + generate: { + charset: 'a-z,A-Z,2-9', + len: 20, + }, + required: false, + description: + 'You most favorite slogan in the whole world, used for paying you.', + masked: true, + }), + rpcallowip: CB.Value.list( + CB.List.text( + { + name: 'RPC Allowed IPs', + minLength: 1, + maxLength: 10, + default: ['192.168.1.1'], + description: + 'external ip addresses that are authorized to access your Bitcoin node', + warning: + 'Any IP you allow here will have RPC access to your Bitcoin node.', + }, + { + patterns: [ + { + regex: + '((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|((^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$)|(^[a-z2-7]{16}\\.onion$)|(^([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]$))', + description: 'must be a valid ipv4, ipv6, or domain name', + }, + ], + }, + ), + ), + rpcauth: CB.Value.list( + CB.List.text( + { + name: 'RPC Auth', + description: + 'api keys that are authorized to access your Bitcoin node.', + }, + { + patterns: [], + }, + ), + ), + }), + ) export const MockConfig = { testnet: undefined, @@ -1381,8 +1243,7 @@ export module Mock { age: 60, }, ], - 'union-list': undefined, - 'random-enum': 'option2', + 'random-select': ['goodbye'], 'favorite-number': 0, rpcsettings: { laws: { @@ -1394,7 +1255,7 @@ export module Mock { rulemakers: [], }, 'bitcoin-node': { - type: 'internal', + selection: 'internal', }, port: 20, rpcallowip: undefined, @@ -1419,7 +1280,7 @@ export module Mock { health: {}, }, }, - actions: {}, // @TODO need mocks + actions: {}, serviceInterfaces: { ui: { id: 'ui', @@ -1477,7 +1338,107 @@ export module Mock { }, }, currentDependencies: {}, - hosts: {}, + hosts: { + abcdefg: { + kind: 'multi', + bindings: [], + addresses: [], + hostnameInfo: { + 80: [ + { + kind: 'ip', + networkInterfaceId: 'eth0', + public: false, + hostname: { + kind: 'local', + value: 'adjective-noun.local', + port: null, + sslPort: 1234, + }, + }, + { + kind: 'ip', + networkInterfaceId: 'wlan0', + public: false, + hostname: { + kind: 'local', + value: 'adjective-noun.local', + port: null, + sslPort: 1234, + }, + }, + { + kind: 'ip', + networkInterfaceId: 'eth0', + public: false, + hostname: { + kind: 'ipv4', + value: '192.168.10.11', + port: null, + sslPort: 1234, + }, + }, + { + kind: 'ip', + networkInterfaceId: 'wlan0', + public: false, + hostname: { + kind: 'ipv4', + value: '10.0.0.2', + port: null, + sslPort: 1234, + }, + }, + { + kind: 'ip', + networkInterfaceId: 'eth0', + public: false, + hostname: { + kind: 'ipv6', + value: '[FE80:CD00:0000:0CDE:1257:0000:211E:729CD]', + port: null, + sslPort: 1234, + }, + }, + { + kind: 'ip', + networkInterfaceId: 'wlan0', + public: false, + hostname: { + kind: 'ipv6', + value: '[FE80:CD00:0000:0CDE:1257:0000:211E:1234]', + port: null, + sslPort: 1234, + }, + }, + { + kind: 'onion', + hostname: { + value: 'bitcoin-p2p.onion', + port: 80, + sslPort: 443, + }, + }, + ], + }, + }, + bcdefgh: { + kind: 'multi', + bindings: [], + addresses: [], + hostnameInfo: { + 8332: [], + }, + }, + cdefghi: { + kind: 'multi', + bindings: [], + addresses: [], + hostnameInfo: { + 8333: [], + }, + }, + }, storeExposedDependents: [], registry: 'https://registry.start9.com/', developerKey: 'developer-key', @@ -1618,7 +1579,7 @@ export module Mock { icon: 'assets/img/service-icons/btc-rpc-proxy.png', kind: 'exists', registryUrl: 'https://community-registry.start9.com', - versionSpec: '>2.0.0', // @TODO + versionSpec: '>2.0.0', configSatisfied: false, }, }, diff --git a/web/projects/ui/src/app/services/api/api.types.ts b/web/projects/ui/src/app/services/api/api.types.ts index 256f6848b..7ca97db53 100644 --- a/web/projects/ui/src/app/services/api/api.types.ts +++ b/web/projects/ui/src/app/services/api/api.types.ts @@ -1,10 +1,9 @@ import { Dump } from 'patch-db-client' import { MarketplacePkg, StoreInfo } from '@start9labs/marketplace' import { PackagePropertiesVersioned } from 'src/app/util/properties.util' -import { ConfigSpec } from 'src/app/pkg-config/config-types' import { DataModel } from 'src/app/services/patch-db/data-model' import { StartOSDiskInfo, LogsRes, ServerLogsReq } from '@start9labs/shared' -import { T } from '@start9labs/start-sdk' +import { CT, T } from '@start9labs/start-sdk' import { WebSocketSubjectConfig } from 'rxjs/webSocket' export module RR { @@ -12,7 +11,10 @@ export module RR { export type WebsocketConfig = Omit, 'url'> - // server state + // state + + export type EchoReq = { message: string } // server.echo + export type EchoRes = string export type ServerState = 'initializing' | 'error' | 'running' @@ -225,7 +227,7 @@ export module RR { export type InstallPackageRes = null export type GetPackageConfigReq = { id: string } // package.config.get - export type GetPackageConfigRes = { spec: ConfigSpec; config: object } + export type GetPackageConfigRes = { spec: CT.InputSpec; config: object } export type DrySetPackageConfigReq = { id: string; config: object } // package.config.set.dry export type DrySetPackageConfigRes = Breakages @@ -268,14 +270,17 @@ export module RR { export type DryConfigureDependencyRes = { oldConfig: object newConfig: object - spec: ConfigSpec + spec: CT.InputSpec } export type SideloadPackageReq = { manifest: T.Manifest icon: string // base64 } - export type SideloadPacakgeRes = string //guid + export type SideloadPackageRes = { + upload: string // guid + progress: string // guid + } // marketplace diff --git a/web/projects/ui/src/app/services/api/embassy-api.service.ts b/web/projects/ui/src/app/services/api/embassy-api.service.ts index d6bb11632..a5bce8c62 100644 --- a/web/projects/ui/src/app/services/api/embassy-api.service.ts +++ b/web/projects/ui/src/app/services/api/embassy-api.service.ts @@ -10,6 +10,8 @@ export abstract class ApiService { // for sideloading packages abstract uploadPackage(guid: string, body: Blob): Promise + abstract uploadFile(body: Blob): Promise + // websocket abstract openWebsocket$( @@ -17,7 +19,9 @@ export abstract class ApiService { config: RR.WebsocketConfig, ): Observable - // server state + // state + + abstract echo(params: RR.EchoReq, url: string): Promise abstract getState(): Promise @@ -241,7 +245,5 @@ export abstract class ApiService { params: RR.DryConfigureDependencyReq, ): Promise - abstract sideloadPackage( - params: RR.SideloadPackageReq, - ): Promise + abstract sideloadPackage(): Promise } diff --git a/web/projects/ui/src/app/services/api/embassy-live-api.service.ts b/web/projects/ui/src/app/services/api/embassy-live-api.service.ts index b460e00ff..cef2c13ff 100644 --- a/web/projects/ui/src/app/services/api/embassy-live-api.service.ts +++ b/web/projects/ui/src/app/services/api/embassy-live-api.service.ts @@ -7,6 +7,7 @@ import { RpcError, RPCOptions, } from '@start9labs/shared' +import { PATCH_CACHE } from 'src/app/services/patch-db/patch-db-source' import { ApiService } from './embassy-api.service' import { RR } from './api.types' import { parsePropertiesPermissive } from 'src/app/util/properties.util' @@ -16,7 +17,7 @@ import { Observable, filter, firstValueFrom } from 'rxjs' import { AuthService } from '../auth.service' import { DOCUMENT } from '@angular/common' import { DataModel } from '../patch-db/data-model' -import { PatchDB, pathFromArray } from 'patch-db-client' +import { Dump, pathFromArray } from 'patch-db-client' @Injectable() export class LiveApiService extends ApiService { @@ -25,7 +26,7 @@ export class LiveApiService extends ApiService { private readonly http: HttpService, private readonly config: ConfigService, private readonly auth: AuthService, - private readonly patch: PatchDB, + @Inject(PATCH_CACHE) private readonly cache$: Observable>, ) { super() ; (window as any).rpcClient = this @@ -52,6 +53,15 @@ export class LiveApiService extends ApiService { }) } + async uploadFile(body: Blob): Promise { + return this.httpRequest({ + method: Method.POST, + body, + url: `/rest/upload`, + responseType: 'text', + }) + } + // websocket openWebsocket$( @@ -70,6 +80,10 @@ export class LiveApiService extends ApiService { // state + async echo(params: RR.EchoReq, url: string): Promise { + return this.rpcRequest({ method: 'echo', params }, url) + } + async getState(): Promise { return this.rpcRequest({ method: 'state', params: {} }) } @@ -457,12 +471,10 @@ export class LiveApiService extends ApiService { }) } - async sideloadPackage( - params: RR.SideloadPackageReq, - ): Promise { + async sideloadPackage(): Promise { return this.rpcRequest({ method: 'package.sideload', - params, + params: {}, }) } @@ -484,7 +496,7 @@ export class LiveApiService extends ApiService { const patchSequence = res.headers.get('x-patch-sequence') if (patchSequence) await firstValueFrom( - this.patch.cache$.pipe(filter(({ id }) => id >= Number(patchSequence))), + this.cache$.pipe(filter(({ id }) => id >= Number(patchSequence))), ) return body.result diff --git a/web/projects/ui/src/app/services/api/embassy-mock-api.service.ts b/web/projects/ui/src/app/services/api/embassy-mock-api.service.ts index 728b4ff35..284e3bab8 100644 --- a/web/projects/ui/src/app/services/api/embassy-mock-api.service.ts +++ b/web/projects/ui/src/app/services/api/embassy-mock-api.service.ts @@ -118,7 +118,17 @@ export class MockApiService extends ApiService { } } - // server state + // state + + async echo(params: RR.EchoReq, url: string): Promise { + if (url) { + const num = Math.floor(Math.random() * 10) + 1 + if (num > 8) return params.message + throw new Error() + } + await pauseFor(2000) + return params.message + } private stateIndex = 0 async getState(): Promise { @@ -758,7 +768,7 @@ export class MockApiService extends ApiService { await pauseFor(2000) return { config: Mock.MockConfig, - spec: Mock.ConfigSpec, + spec: await Mock.getInputSpec(), } } @@ -1048,15 +1058,21 @@ export class MockApiService extends ApiService { return { oldConfig: Mock.MockConfig, newConfig: Mock.MockDependencyConfig, - spec: Mock.ConfigSpec, + spec: await Mock.getInputSpec(), } } - async sideloadPackage( - params: RR.SideloadPackageReq, - ): Promise { + async sideloadPackage(): Promise { await pauseFor(2000) - return '4120e092-05ab-4de2-9fbd-c3f1f4b1df9e' // no significance, randomly generated + return { + upload: '4120e092-05ab-4de2-9fbd-c3f1f4b1df9e', // no significance, randomly generated + progress: '5120e092-05ab-4de2-9fbd-c3f1f4b1df9e', // no significance, randomly generated + } + } + + async uploadFile(body: Blob): Promise { + await pauseFor(2000) + return 'returnedhash' } private async initProgress(): Promise { diff --git a/web/projects/ui/src/app/services/api/mock-patch.ts b/web/projects/ui/src/app/services/api/mock-patch.ts index 14fdaa724..92fd979ef 100644 --- a/web/projects/ui/src/app/services/api/mock-patch.ts +++ b/web/projects/ui/src/app/services/api/mock-patch.ts @@ -127,7 +127,7 @@ export const mockPatchData: DataModel = { }, }, }, - actions: {}, // @TODO + actions: {}, serviceInterfaces: { ui: { id: 'ui', @@ -185,7 +185,107 @@ export const mockPatchData: DataModel = { }, }, currentDependencies: {}, - hosts: {}, + hosts: { + abcdefg: { + kind: 'multi', + bindings: [], + addresses: [], + hostnameInfo: { + 80: [ + { + kind: 'ip', + networkInterfaceId: 'eth0', + public: false, + hostname: { + kind: 'local', + value: 'adjective-noun.local', + port: null, + sslPort: 1234, + }, + }, + { + kind: 'ip', + networkInterfaceId: 'wlan0', + public: false, + hostname: { + kind: 'local', + value: 'adjective-noun.local', + port: null, + sslPort: 1234, + }, + }, + { + kind: 'ip', + networkInterfaceId: 'eth0', + public: false, + hostname: { + kind: 'ipv4', + value: '10.0.0.1', + port: null, + sslPort: 1234, + }, + }, + { + kind: 'ip', + networkInterfaceId: 'wlan0', + public: false, + hostname: { + kind: 'ipv4', + value: '10.0.0.2', + port: null, + sslPort: 1234, + }, + }, + { + kind: 'ip', + networkInterfaceId: 'eth0', + public: false, + hostname: { + kind: 'ipv6', + value: '[FE80:CD00:0000:0CDE:1257:0000:211E:729CD]', + port: null, + sslPort: 1234, + }, + }, + { + kind: 'ip', + networkInterfaceId: 'wlan0', + public: false, + hostname: { + kind: 'ipv6', + value: '[FE80:CD00:0000:0CDE:1257:0000:211E:1234]', + port: null, + sslPort: 1234, + }, + }, + { + kind: 'onion', + hostname: { + value: 'bitcoin-p2p.onion', + port: 80, + sslPort: 443, + }, + }, + ], + }, + }, + bcdefgh: { + kind: 'multi', + bindings: [], + addresses: [], + hostnameInfo: { + 8332: [], + }, + }, + cdefghi: { + kind: 'multi', + bindings: [], + addresses: [], + hostnameInfo: { + 8333: [], + }, + }, + }, storeExposedDependents: [], registry: 'https://registry.start9.com/', developerKey: 'developer-key', diff --git a/web/projects/ui/src/app/services/form-dialog.service.ts b/web/projects/ui/src/app/services/form-dialog.service.ts new file mode 100644 index 000000000..69df946bb --- /dev/null +++ b/web/projects/ui/src/app/services/form-dialog.service.ts @@ -0,0 +1,41 @@ +import { inject, Injectable, Injector, Type } from '@angular/core' +import { TuiDialogOptions, TuiDialogService } from '@taiga-ui/core' +import { TuiDialogFormService, TuiPromptData } from '@taiga-ui/kit' +import { PolymorpheusComponent } from '@tinkoff/ng-polymorpheus' + +const PROMPT: Partial> = { + label: 'Unsaved Changes', + data: { + content: 'You have unsaved changes. Are you sure you want to leave?', + yes: 'Leave', + no: 'Cancel', + }, +} + +@Injectable({ providedIn: 'root' }) +export class FormDialogService { + private readonly dialogs = inject(TuiDialogService) + private readonly formService = new TuiDialogFormService(this.dialogs) + private readonly prompt = this.formService.withPrompt(PROMPT) + private readonly injector = Injector.create({ + parent: inject(Injector), + providers: [ + { + provide: TuiDialogFormService, + useValue: this.formService, + }, + ], + }) + + open(component: Type, options: Partial> = {}) { + this.dialogs + .open(new PolymorpheusComponent(component, this.injector), { + closeable: this.prompt, + dismissible: this.prompt, + ...options, + }) + .subscribe({ + complete: () => this.formService.markAsPristine(), + }) + } +} diff --git a/web/projects/ui/src/app/services/form.service.ts b/web/projects/ui/src/app/services/form.service.ts index ee8f0f136..3cd0ee591 100644 --- a/web/projects/ui/src/app/services/form.service.ts +++ b/web/projects/ui/src/app/services/form.service.ts @@ -7,24 +7,7 @@ import { ValidatorFn, Validators, } from '@angular/forms' -import { - ConfigSpec, - isValueSpecListOf, - ListValueSpecNumber, - ListValueSpecObject, - ListValueSpecOf, - ListValueSpecString, - ListValueSpecUnion, - UniqueBy, - ValueSpec, - ValueSpecEnum, - ValueSpecList, - ValueSpecNumber, - ValueSpecObject, - ValueSpecString, - ValueSpecUnion, -} from 'src/app/pkg-config/config-types' -import { getDefaultString, Range } from '../pkg-config/config-utilities' +import { CT, utils } from '@start9labs/start-sdk' const Mustache = require('mustache') @Injectable({ @@ -34,55 +17,54 @@ export class FormService { constructor(private readonly formBuilder: UntypedFormBuilder) {} createForm( - spec: ConfigSpec, - current: { [key: string]: any } = {}, + spec: CT.InputSpec, + current: Record = {}, ): UntypedFormGroup { return this.getFormGroup(spec, [], current) } - getUnionObject( - spec: ValueSpecUnion | ListValueSpecUnion, - selection: string, - current?: { [key: string]: any } | null, - ): UntypedFormGroup { - const { variants, tag } = spec - const { name, description, warning, 'variant-names': variantNames } = tag - - const enumSpec: ValueSpecEnum = { - type: 'enum', - name, - description, - warning, + getUnionSelectSpec( + spec: CT.ValueSpecUnion, + selection: string | null, + ): CT.ValueSpecSelect { + return { + ...spec, + type: 'select', default: selection, - values: Object.keys(variants), - 'value-names': variantNames, + values: Object.fromEntries( + Object.entries(spec.variants).map(([key, { name }]) => [key, name]), + ), } - return this.getFormGroup( - { [spec.tag.id]: enumSpec, ...spec.variants[selection] }, - [], - current, + } + + getUnionObject( + spec: CT.ValueSpecUnion, + selected: string | null, + ): UntypedFormGroup { + const group = this.getFormGroup({ + selection: this.getUnionSelectSpec(spec, selected), + }) + + group.setControl( + 'value', + this.getFormGroup(selected ? spec.variants[selected].spec : {}), ) + + return group } - getListItem(spec: ValueSpecList, entry: any) { - const listItemValidators = getListItemValidators(spec) - if (isValueSpecListOf(spec, 'string')) { - return this.formBuilder.control(entry, listItemValidators) - } else if (isValueSpecListOf(spec, 'number')) { - return this.formBuilder.control(entry, listItemValidators) - } else if (isValueSpecListOf(spec, 'enum')) { - return this.formBuilder.control(entry) - } else if (isValueSpecListOf(spec, 'object')) { - return this.getFormGroup(spec.spec.spec, listItemValidators, entry) - } else if (isValueSpecListOf(spec, 'union')) { - return this.getUnionObject(spec.spec, spec.spec.default, entry) + getListItem(spec: CT.ValueSpecList, entry?: any) { + if (CT.isValueSpecListOf(spec, 'text')) { + return this.formBuilder.control(entry, stringValidators(spec.spec)) + } else if (CT.isValueSpecListOf(spec, 'object')) { + return this.getFormGroup(spec.spec.spec, [], entry) } } - private getFormGroup( - config: ConfigSpec, + getFormGroup( + config: CT.InputSpec, validators: ValidatorFn[] = [], - current?: { [key: string]: any } | null, + current?: Record | null, ): UntypedFormGroup { let group: Record< string, @@ -95,150 +77,281 @@ export class FormService { } private getFormEntry( - spec: ValueSpec, + spec: CT.ValueSpec, currentValue?: any, ): UntypedFormGroup | UntypedFormArray | UntypedFormControl { - let validators: ValidatorFn[] let value: any switch (spec.type) { - case 'string': - validators = stringValidators(spec) + case 'text': if (currentValue !== undefined) { value = currentValue } else { - value = spec.default ? getDefaultString(spec.default) : null + value = spec.default ? utils.getDefaultString(spec.default) : null } - return this.formBuilder.control(value, validators) + return this.formBuilder.control(value, stringValidators(spec)) + case 'textarea': + value = currentValue || null + return this.formBuilder.control(value, textareaValidators(spec)) case 'number': - validators = numberValidators(spec) if (currentValue !== undefined) { value = currentValue } else { value = spec.default || null } - return this.formBuilder.control(value, validators) + return this.formBuilder.control(value, numberValidators(spec)) + case 'color': + if (currentValue !== undefined) { + value = currentValue + } else { + value = spec.default || null + } + return this.formBuilder.control(value, colorValidators(spec)) + case 'datetime': + if (currentValue !== undefined) { + value = currentValue + } else { + value = spec.default || null + } + return this.formBuilder.control(value, datetimeValidators(spec)) case 'object': return this.getFormGroup(spec.spec, [], currentValue) case 'list': - validators = listValidators(spec) const mapped = ( Array.isArray(currentValue) ? currentValue : (spec.default as any[]) ).map(entry => { return this.getListItem(spec, entry) }) - return this.formBuilder.array(mapped, validators) + return this.formBuilder.array(mapped, listValidators(spec)) + case 'file': + return this.formBuilder.control( + currentValue || null, + fileValidators(spec), + ) case 'union': - const currentSelection = currentValue?.[spec.tag.id] + const currentSelection = currentValue?.selection const isValid = !!spec.variants[currentSelection] return this.getUnionObject( spec, isValid ? currentSelection : spec.default, - isValid ? currentValue : undefined, ) - case 'boolean': - case 'enum': + case 'toggle': value = currentValue === undefined ? spec.default : currentValue return this.formBuilder.control(value) + case 'select': + value = currentValue === undefined ? spec.default : currentValue + return this.formBuilder.control(value, selectValidators(spec)) + case 'multiselect': + value = currentValue === undefined ? spec.default : currentValue + return this.formBuilder.control(value, multiselectValidators(spec)) default: return this.formBuilder.control(null) } } } -function getListItemValidators(spec: ValueSpecList) { - if (isValueSpecListOf(spec, 'string')) { - return stringValidators(spec.spec) - } else if (isValueSpecListOf(spec, 'number')) { - return numberValidators(spec.spec) - } -} +// function getListItemValidators(spec: CT.ValueSpecList) { +// if (CT.isValueSpecListOf(spec, 'text')) { +// return stringValidators(spec.spec) +// } +// } function stringValidators( - spec: ValueSpecString | ListValueSpecString, + spec: CT.ValueSpecText | CT.ListValueSpecText, ): ValidatorFn[] { const validators: ValidatorFn[] = [] - if (!(spec as ValueSpecString).nullable) { + if ((spec as CT.ValueSpecText).required) { validators.push(Validators.required) } - if (spec.pattern) { - validators.push(Validators.pattern(spec.pattern)) + validators.push(textLengthInRange(spec.minLength, spec.maxLength)) + + if (spec.patterns.length) { + spec.patterns.forEach(p => validators.push(Validators.pattern(p.regex))) } return validators } -function numberValidators( - spec: ValueSpecNumber | ListValueSpecNumber, -): ValidatorFn[] { +function textareaValidators(spec: CT.ValueSpecTextarea): ValidatorFn[] { + const validators: ValidatorFn[] = [] + + if (spec.required) { + validators.push(Validators.required) + } + + validators.push(textLengthInRange(spec.minLength, spec.maxLength)) + + return validators +} + +function colorValidators({ required }: CT.ValueSpecColor): ValidatorFn[] { + const validators: ValidatorFn[] = [Validators.pattern(/^#[0-9a-f]{6}$/i)] + + if (required) { + validators.push(Validators.required) + } + + return validators +} + +function datetimeValidators({ + required, + min, + max, +}: CT.ValueSpecDatetime): ValidatorFn[] { + const validators: ValidatorFn[] = [] + + if (required) { + validators.push(Validators.required) + } + + if (min) { + validators.push(datetimeMin(min)) + } + + if (max) { + validators.push(datetimeMax(max)) + } + + return validators +} + +function numberValidators(spec: CT.ValueSpecNumber): ValidatorFn[] { const validators: ValidatorFn[] = [] validators.push(isNumber()) - if (!(spec as ValueSpecNumber).nullable) { + if ((spec as CT.ValueSpecNumber).required) { validators.push(Validators.required) } - if (spec.integral) { + if (spec.integer) { validators.push(isInteger()) } - validators.push(numberInRange(spec.range)) + validators.push(numberInRange(spec.min, spec.max)) return validators } -function listValidators(spec: ValueSpecList): ValidatorFn[] { +function selectValidators(spec: CT.ValueSpecSelect): ValidatorFn[] { const validators: ValidatorFn[] = [] - validators.push(listInRange(spec.range)) - - validators.push(listItemIssue()) - - if (!isValueSpecListOf(spec, 'enum')) { - validators.push(listUnique(spec)) + if (spec.required) { + validators.push(Validators.required) } return validators } -export function numberInRange(stringRange: string): ValidatorFn { +function multiselectValidators(spec: CT.ValueSpecMultiselect): ValidatorFn[] { + const validators: ValidatorFn[] = [] + validators.push(listInRange(spec.minLength, spec.maxLength)) + return validators +} + +function listValidators(spec: CT.ValueSpecList): ValidatorFn[] { + const validators: ValidatorFn[] = [] + validators.push(listInRange(spec.minLength, spec.maxLength)) + validators.push(listItemIssue()) + return validators +} + +function fileValidators(spec: CT.ValueSpecFile): ValidatorFn[] { + const validators: ValidatorFn[] = [] + + if (spec.required) { + validators.push(Validators.required) + } + + return validators +} + +export function numberInRange( + min: number | null, + max: number | null, +): ValidatorFn { return control => { const value = control.value - if (!value) return null - try { - Range.from(stringRange).checkIncludes(value) - return null - } catch (e: any) { - return { numberNotInRange: { value: `Number must be ${e.message}` } } - } + if (typeof value !== 'number') return null + if (min && value < min) + return { + numberNotInRange: `Number must be greater than or equal to ${min}`, + } + if (max && value > max) + return { numberNotInRange: `Number must be less than or equal to ${max}` } + return null } } export function isNumber(): ValidatorFn { - return control => - !control.value || control.value == Number(control.value) - ? null - : { notNumber: { value: control.value } } + return ({ value }) => + !value || value == Number(value) ? null : { notNumber: 'Must be a number' } } export function isInteger(): ValidatorFn { - return control => - !control.value || control.value == Math.trunc(control.value) + return ({ value }) => + !value || value == Math.trunc(value) ? null - : { numberNotInteger: { value: control.value } } + : { numberNotInteger: 'Must be an integer' } } -export function listInRange(stringRange: string): ValidatorFn { +export function listInRange( + minLength: number | null, + maxLength: number | null, +): ValidatorFn { return control => { - try { - Range.from(stringRange).checkIncludes(control.value.length) - return null - } catch (e: any) { - return { listNotInRange: { value: `List must be ${e.message}` } } - } + const length = control.value.length + if (minLength && length < minLength) + return { + listNotInRange: `List must contain at least ${minLength} entries`, + } + if (maxLength && length > maxLength) + return { + listNotInRange: `List cannot contain more than ${maxLength} entries`, + } + return null + } +} + +export function datetimeMin(min: string): ValidatorFn { + return ({ value }) => { + if (!value) return null + + const date = new Date(value.length === 5 ? `2000-01-01T${value}` : value) + const minDate = new Date(min.length === 5 ? `2000-01-01T${min}` : min) + + return date < minDate ? { datetimeMin: `Minimum is ${min}` } : null + } +} + +export function datetimeMax(max: string): ValidatorFn { + return ({ value }) => { + if (!value) return null + + const date = new Date(value.length === 5 ? `2000-01-01T${value}` : value) + const maxDate = new Date(max.length === 5 ? `2000-01-01T${max}` : max) + + return date > maxDate ? { datetimeMin: `Maximum is ${max}` } : null + } +} + +export function textLengthInRange( + minLength: number | null, + maxLength: number | null, +): ValidatorFn { + return control => { + const value = control.value + if (value === null || value === undefined) return null + + const length = value.length + if (minLength && length < minLength) + return { listNotInRange: `Must be at least ${minLength} characters` } + if (maxLength && length > maxLength) + return { listNotInRange: `Cannot be great than ${maxLength} characters` } + return null } } @@ -247,36 +360,33 @@ export function listItemIssue(): ValidatorFn { const { controls } = parentControl as UntypedFormArray const problemChild = controls.find(c => c.invalid) if (problemChild) { - return { listItemIssue: { value: 'Invalid entries' } } + return { listItemIssue: 'Invalid entries' } } else { return null } } } -export function listUnique(spec: ValueSpecList): ValidatorFn { +export function listUnique(spec: CT.ValueSpecList): ValidatorFn { return control => { const list = control.value for (let idx = 0; idx < list.length; idx++) { for (let idx2 = idx + 1; idx2 < list.length; idx2++) { if (listItemEquals(spec, list[idx], list[idx2])) { + const objSpec = spec.spec let display1: string let display2: string - let uniqueMessage = isObjectOrUnion(spec.spec) - ? uniqueByMessageWrapper( - spec.spec['unique-by'], - spec.spec, - list[idx], - ) + let uniqueMessage = isObject(objSpec) + ? uniqueByMessageWrapper(objSpec.uniqueBy, objSpec) : '' - if (isObjectOrUnion(spec.spec) && spec.spec['display-as']) { + if (isObject(objSpec) && objSpec.displayAs) { display1 = `"${(Mustache as any).render( - spec.spec['display-as'], + objSpec.displayAs, list[idx], )}"` display2 = `"${(Mustache as any).render( - spec.spec['display-as'], + objSpec.displayAs, list[idx2], )}"` } else { @@ -285,9 +395,7 @@ export function listUnique(spec: ValueSpecList): ValidatorFn { } return { - listNotUnique: { - value: `${display1} and ${display2} are not unique.${uniqueMessage}`, - }, + listNotUnique: `${display1} and ${display2} are not unique.${uniqueMessage}`, } } } @@ -296,46 +404,40 @@ export function listUnique(spec: ValueSpecList): ValidatorFn { } } -function listItemEquals(spec: ValueSpecList, val1: any, val2: any): boolean { +function listItemEquals(spec: CT.ValueSpecList, val1: any, val2: any): boolean { // TODO: fix types - switch (spec.subtype) { - case 'string': - case 'number': - case 'enum': + switch (spec.spec.type) { + case 'text': return val1 == val2 case 'object': - const obj: ListValueSpecObject = spec.spec as any - - return listObjEquals(obj['unique-by'], obj, val1, val2) - case 'union': - const union: ListValueSpecUnion = spec.spec as any - - return unionEquals(union['unique-by'], union, val1, val2) + const obj = spec.spec + return listObjEquals(obj.uniqueBy, obj, val1, val2) default: return false } } -function itemEquals(spec: ValueSpec, val1: any, val2: any): boolean { +function itemEquals(spec: CT.ValueSpec, val1: any, val2: any): boolean { switch (spec.type) { - case 'string': + case 'text': + case 'textarea': case 'number': - case 'boolean': - case 'enum': + case 'toggle': + case 'select': return val1 == val2 case 'object': // TODO: 'unique-by' does not exist on ValueSpecObject, fix types return objEquals( (spec as any)['unique-by'], - spec as ValueSpecObject, + spec as CT.ValueSpecObject, val1, val2, ) case 'union': - // TODO: 'unique-by' does not exist on ValueSpecUnion, fix types + // TODO: 'unique-by' does not exist on CT.ValueSpecUnion, fix types return unionEquals( (spec as any)['unique-by'], - spec as ValueSpecUnion, + spec as CT.ValueSpecUnion, val1, val2, ) @@ -355,12 +457,12 @@ function itemEquals(spec: ValueSpec, val1: any, val2: any): boolean { } function listObjEquals( - uniqueBy: UniqueBy, - spec: ListValueSpecObject, + uniqueBy: CT.UniqueBy, + spec: CT.ListValueSpecObject, val1: any, val2: any, ): boolean { - if (uniqueBy === null) { + if (!uniqueBy) { return false } else if (typeof uniqueBy === 'string') { return itemEquals(spec.spec[uniqueBy], val1[uniqueBy], val2[uniqueBy]) @@ -383,12 +485,12 @@ function listObjEquals( } function objEquals( - uniqueBy: UniqueBy, - spec: ValueSpecObject, + uniqueBy: CT.UniqueBy, + spec: CT.ValueSpecObject, val1: any, val2: any, ): boolean { - if (uniqueBy === null) { + if (!uniqueBy) { return false } else if (typeof uniqueBy === 'string') { // TODO: fix types @@ -412,20 +514,19 @@ function objEquals( } function unionEquals( - uniqueBy: UniqueBy, - spec: ValueSpecUnion | ListValueSpecUnion, + uniqueBy: CT.UniqueBy, + spec: CT.ValueSpecUnion, val1: any, val2: any, ): boolean { - const tagId = spec.tag.id - const variant = spec.variants[val1[tagId]] - if (uniqueBy === null) { + const variantSpec = spec.variants[val1.selection].spec + if (!uniqueBy) { return false } else if (typeof uniqueBy === 'string') { - if (uniqueBy === tagId) { - return val1[tagId] === val2[tagId] + if (uniqueBy === 'selection') { + return val1.selection === val2.selection } else { - return itemEquals(variant[uniqueBy], val1[uniqueBy], val2[uniqueBy]) + return itemEquals(variantSpec[uniqueBy], val1[uniqueBy], val2[uniqueBy]) } } else if ('any' in uniqueBy) { for (let subSpec of uniqueBy.any) { @@ -446,20 +547,10 @@ function unionEquals( } function uniqueByMessageWrapper( - uniqueBy: UniqueBy, - spec: ListValueSpecObject | ListValueSpecUnion, - obj: Record, + uniqueBy: CT.UniqueBy, + spec: CT.ListValueSpecObject, ) { - let configSpec: ConfigSpec - if (isUnion(spec)) { - const tagId = spec.tag.id - configSpec = { - [tagId]: { name: spec.tag.name } as ValueSpec, - ...spec.variants[obj[tagId]], - } - } else { - configSpec = spec.spec - } + let configSpec = spec.spec const message = uniqueByMessage(uniqueBy, configSpec) if (message) { @@ -468,17 +559,17 @@ function uniqueByMessageWrapper( } function uniqueByMessage( - uniqueBy: UniqueBy, - configSpec: ConfigSpec, + uniqueBy: CT.UniqueBy, + configSpec: CT.InputSpec, outermost = true, ): string { let joinFunc const subSpecs: string[] = [] - if (uniqueBy === null) { + if (!uniqueBy) { return '' } else if (typeof uniqueBy === 'string') { return configSpec[uniqueBy] - ? (configSpec[uniqueBy] as ValueSpecObject).name + ? (configSpec[uniqueBy] as CT.ValueSpecObject).name : uniqueBy } else if ('any' in uniqueBy) { joinFunc = ' OR ' @@ -497,20 +588,15 @@ function uniqueByMessage( : '(' + ret + ')' } -function isObjectOrUnion( - spec: ListValueSpecOf, -): spec is ListValueSpecObject | ListValueSpecUnion { - // only lists of objects and unions have unique-by - return 'unique-by' in spec -} - -function isUnion(spec: any): spec is ListValueSpecUnion { - // only unions have tag - return !!spec.tag +function isObject( + spec: CT.ListValueSpecOf, +): spec is CT.ListValueSpecObject { + // only lists of objects have uniqueBy + return 'uniqueBy' in spec } export function convertValuesRecursive( - configSpec: ConfigSpec, + configSpec: CT.InputSpec, group: UntypedFormGroup, ) { Object.entries(configSpec).forEach(([key, valueSpec]) => { @@ -522,40 +608,27 @@ export function convertValuesRecursive( control.setValue( control.value || control.value === 0 ? Number(control.value) : null, ) - } else if (valueSpec.type === 'string') { + } else if (valueSpec.type === 'text' || valueSpec.type === 'textarea') { if (!control.value) control.setValue(null) } else if (valueSpec.type === 'object') { convertValuesRecursive(valueSpec.spec, group.get(key) as UntypedFormGroup) } else if (valueSpec.type === 'union') { const formGr = group.get(key) as UntypedFormGroup - const spec = valueSpec.variants[formGr.controls[valueSpec.tag.id].value] + const spec = valueSpec.variants[formGr.controls['selection'].value].spec convertValuesRecursive(spec, formGr) } else if (valueSpec.type === 'list') { const formArr = group.get(key) as UntypedFormArray const { controls } = formArr - if (valueSpec.subtype === 'number') { - controls.forEach(control => { - control.setValue(control.value ? Number(control.value) : null) - }) - } else if (valueSpec.subtype === 'string') { + if (valueSpec.spec.type === 'text') { controls.forEach(control => { if (!control.value) control.setValue(null) }) - } else if (valueSpec.subtype === 'object') { + } else if (valueSpec.spec.type === 'object') { controls.forEach(formGroup => { - const objectSpec = valueSpec.spec as ListValueSpecObject + const objectSpec = valueSpec.spec as CT.ListValueSpecObject convertValuesRecursive(objectSpec.spec, formGroup as UntypedFormGroup) }) - } else if (valueSpec.subtype === 'union') { - controls.forEach(formGroup => { - const unionSpec = valueSpec.spec as ListValueSpecUnion - const spec = - unionSpec.variants[ - (formGroup as UntypedFormGroup).controls[unionSpec.tag.id].value - ] - convertValuesRecursive(spec, formGroup as UntypedFormGroup) - }) } } }) diff --git a/web/projects/ui/src/app/services/modal.service.ts b/web/projects/ui/src/app/services/modal.service.ts deleted file mode 100644 index c34fce9a2..000000000 --- a/web/projects/ui/src/app/services/modal.service.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Injectable } from '@angular/core' -import { ModalController } from '@ionic/angular' -import { DependentInfo } from 'src/app/types/dependent-info' -import { AppConfigPage } from 'src/app/modals/app-config/app-config.page' - -@Injectable({ - providedIn: 'root', -}) -export class ModalService { - constructor(private readonly modalCtrl: ModalController) {} - - async presentModalConfig(componentProps: ComponentProps): Promise { - const modal = await this.modalCtrl.create({ - component: AppConfigPage, - componentProps, - }) - await modal.present() - } -} - -interface ComponentProps { - pkgId: string - dependentInfo?: DependentInfo -} diff --git a/web/projects/ui/src/app/services/patch-db/patch-db-source.ts b/web/projects/ui/src/app/services/patch-db/patch-db-source.ts new file mode 100644 index 000000000..0b80370d0 --- /dev/null +++ b/web/projects/ui/src/app/services/patch-db/patch-db-source.ts @@ -0,0 +1,57 @@ +import { inject, Injectable, InjectionToken } from '@angular/core' +import { Dump, Revision, Update } from 'patch-db-client' +import { BehaviorSubject, EMPTY, Observable } from 'rxjs' +import { + bufferTime, + catchError, + filter, + startWith, + switchMap, + take, +} from 'rxjs/operators' +import { StateService } from 'src/app/services/state.service' +import { ApiService } from '../api/embassy-api.service' +import { AuthService } from '../auth.service' +import { DataModel } from './data-model' +import { LocalStorageBootstrap } from './local-storage-bootstrap' + +export const PATCH_CACHE = new InjectionToken('', { + factory: () => + new BehaviorSubject>({ + id: 0, + value: {} as DataModel, + }), +}) + +@Injectable({ + providedIn: 'root', +}) +export class PatchDbSource extends Observable[]> { + private readonly api = inject(ApiService) + private readonly state = inject(StateService) + private readonly stream$ = inject(AuthService).isVerified$.pipe( + switchMap(verified => (verified ? this.api.subscribeToPatchDB({}) : EMPTY)), + switchMap(({ dump, guid }) => + this.api.openWebsocket$(guid, {}).pipe( + bufferTime(250), + filter(revisions => !!revisions.length), + startWith([dump]), + ), + ), + catchError((_, original$) => { + this.state.retrigger() + + // @TODO this is returning right away, but we need to wait until state emits again from the retrigger() above. + return this.state.pipe( + filter(current => current === 'running'), + take(1), + switchMap(() => original$), + ) + }), + startWith([inject(LocalStorageBootstrap).init()]), + ) + + constructor() { + super(subscriber => this.stream$.subscribe(subscriber)) + } +} diff --git a/web/projects/ui/src/app/services/patch-db/patch-db.factory.ts b/web/projects/ui/src/app/services/patch-db/patch-db.factory.ts deleted file mode 100644 index bb2dcdf57..000000000 --- a/web/projects/ui/src/app/services/patch-db/patch-db.factory.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { InjectionToken, Injector } from '@angular/core' -import { Revision, Update } from 'patch-db-client' -import { defer, EMPTY, from, Observable } from 'rxjs' -import { - bufferTime, - catchError, - filter, - startWith, - switchMap, - take, -} from 'rxjs/operators' -import { StateService } from 'src/app/services/state.service' -import { ApiService } from '../api/embassy-api.service' -import { AuthService } from '../auth.service' -import { DataModel } from './data-model' -import { LocalStorageBootstrap } from './local-storage-bootstrap' - -export const PATCH_SOURCE = new InjectionToken[]>>( - '', -) - -export function sourceFactory( - injector: Injector, -): Observable[]> { - // defer() needed to avoid circular dependency with ApiService, since PatchDB is needed there - return defer(() => { - const api = injector.get(ApiService) - const auth = injector.get(AuthService) - const state = injector.get(StateService) - const bootstrapper = injector.get(LocalStorageBootstrap) - - return auth.isVerified$.pipe( - switchMap(verified => - verified ? from(api.subscribeToPatchDB({})) : EMPTY, - ), - switchMap(({ dump, guid }) => - api.openWebsocket$(guid, {}).pipe( - bufferTime(250), - filter(revisions => !!revisions.length), - startWith([dump]), - ), - ), - catchError((_, original$) => { - state.retrigger() - - return state.pipe( - filter(current => current === 'running'), - take(1), - switchMap(() => original$), - ) - }), - startWith([bootstrapper.init()]), - ) - }) -} diff --git a/web/projects/ui/src/app/services/patch-db/patch-db.module.ts b/web/projects/ui/src/app/services/patch-db/patch-db.module.ts deleted file mode 100644 index 3c816e339..000000000 --- a/web/projects/ui/src/app/services/patch-db/patch-db.module.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { PatchDB } from 'patch-db-client' -import { Injector, NgModule } from '@angular/core' -import { PATCH_SOURCE, sourceFactory } from './patch-db.factory' - -// This module is purely for providers organization purposes -@NgModule({ - providers: [ - { - provide: PATCH_SOURCE, - deps: [Injector], - useFactory: sourceFactory, - }, - { - provide: PatchDB, - deps: [PATCH_SOURCE], - useClass: PatchDB, - }, - ], -}) -export class PatchDbModule {} diff --git a/web/projects/ui/src/app/util/configBuilderToSpec.ts b/web/projects/ui/src/app/util/configBuilderToSpec.ts new file mode 100644 index 000000000..1f75329c5 --- /dev/null +++ b/web/projects/ui/src/app/util/configBuilderToSpec.ts @@ -0,0 +1,9 @@ +import { CB } from '@start9labs/start-sdk' + +export async function configBuilderToSpec( + builder: + | CB.Config, unknown> + | CB.Config, never>, +) { + return builder.build({} as any) +} diff --git a/web/projects/ui/src/index.html b/web/projects/ui/src/index.html index 0248b7462..9c0cc2e89 100644 --- a/web/projects/ui/src/index.html +++ b/web/projects/ui/src/index.html @@ -21,10 +21,36 @@ /> + - + + Start OS +

Loading

+ +
diff --git a/web/projects/ui/src/polyfills.ts b/web/projects/ui/src/polyfills.ts index a392d45cf..67caa24e8 100644 --- a/web/projects/ui/src/polyfills.ts +++ b/web/projects/ui/src/polyfills.ts @@ -52,8 +52,11 @@ * */ -(window as any).global = window -; (window as any).process = { env: { DEBUG: undefined }, browser: true } +;(window as any).global = window +;(window as any).process = { env: { DEBUG: undefined }, browser: true } + +import { Buffer } from 'buffer' +window.Buffer = Buffer import './zone-flags' diff --git a/web/projects/ui/src/styles.scss b/web/projects/ui/src/styles.scss index a00ca4ae2..fa4a6598e 100644 --- a/web/projects/ui/src/styles.scss +++ b/web/projects/ui/src/styles.scss @@ -347,4 +347,15 @@ p { svg:not(:root) { overflow: auto; -} \ No newline at end of file +} + +tui-dialog { + transform: translate3d(0, 0, 0); +} + +.g-buttons { + display: flex; + justify-content: flex-end; + gap: 16px; + margin-top: 24px; +}