From 1304960fa3299f9a577ee8ceb293127661223bdf Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Thu, 26 Jun 2025 17:51:27 +0500 Subject: [PATCH 001/136] cicd --- .forgejo/workflows/release.yml | 77 +++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 25 deletions(-) diff --git a/.forgejo/workflows/release.yml b/.forgejo/workflows/release.yml index 26470a9..14838a4 100644 --- a/.forgejo/workflows/release.yml +++ b/.forgejo/workflows/release.yml @@ -1,11 +1,14 @@ name: Gonets Release Debian Packaging on: + push: + branches: + - develop workflow_dispatch: jobs: build-and-release: - runs-on: debian + runs-on: debian-latest steps: - name: Checkout main uses: actions/checkout@v4 @@ -13,46 +16,70 @@ jobs: fetch-depth: 0 ref: main - - name: Установка всех необходимых зависимостей для сборки + - name: Install dependencies run: | sudo apt update - sudo apt install -y python3 python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make + sudo apt install -y python3 python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make dpkg-dev - - name: Сборка backend + - name: Prepare python dependencies + run: | + cd SRV + rm requirements.txt + poetry export -f requirements.txt --output requirements.txt --without-hashes + + - name: Build backend run: | cd SRV poetry install - - name: Сборка frontend + - name: Build frontend run: | - cd FRONT/BUILD/resources/app + cd FRONT/DEV npm install + npm run package + cd FRONT/DEV/dist/gonets-linux-x64/resources/app npm run build + sed -i 's/href="\/assets\//href=".\/assets\//g' FRONT/DEV/dist/gonets-linux-x64/resources/app/dist/index.html + sed -i 's/src="\/assets\//src=".\/assets\//g' FRONT/DEV/dist/gonets-linux-x64/resources/app/dist/index.html + rm -rf FRONT/BUILD/* + cp -r FRONT/DEV/dist/gonets-linux-x64/* FRONT/BUILD/ + rm -rf FRONT/DEV - - name: Build deb package + - name: Preparing build debian package + run: | + DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --createorig + cd debian/ + rm *.ex + rm README.* + + - name: Clone debian configuration + run: | + git clone https://s.galanskiy:${{e5eaa40af9805f83a05ef70a0c946c03e1688633.GONETS}}@dev.gossys.dev/s.galanskiy/gonets-debian-template.git + mv gonets-debian-template/changelog gonets/debian/ + mv gonets-debian-template/control gonets/debian/ + mv gonets-debian-template/copyright gonets/debian/ + mv gonets-debian-template/install gonets/debian/ + mv gonets-debian-template/postinst gonets/debian/ + mv gonets-debian-template/postrm gonets/debian/ + mv gonets-debian-template/rules gonets/debian/ + + - name: Build package run: | dpkg-buildpackage -us -uc -b - name: Get version from changelog - id: get_version run: | - VERSION=$(dpkg-parsechangelog | awk '/^Version:/ {print $2}') - echo "version=$VERSION" >> $GITHUB_OUTPUT + dpkg-parsechangelog -l./debian/changelog --show-field VERSION + echo "VERSION=$VERSION" >> $GITHUB_OUTPUT - - name: Create git tag - env: - GIT_PUSH_TOKEN: ${{ secrets.GIT_PUSH_TOKEN }} + - name: Commit changes to develop run: | - git config --global user.email "ci-bot@example.com" - git config --global user.name "CI Bot" - git tag gonets-${{ steps.get_version.outputs.version }} - git push https://ci-bot:${GIT_PUSH_TOKEN}@${GITEA_SERVER}/${GITEA_REPO}.git gonets-${{ steps.get_version.outputs.version }} - - - name: Create release and upload deb - uses: softprops/action-gh-release@v2 - with: - tag_name: gonets-${{ steps.get_version.outputs.version }} - name: "Gonets ${{ steps.get_version.outputs.version }}" - files: ../*.deb + git config user.name "s.galanskiy" + git config user.email "s.galanskiy@gossys.dev" + git checkout develop + git commit -m "Релиз $VERSION" + git tag "v$VERSION" + git push origin develop + git push origin "v$VERSION" env: - GITHUB_TOKEN: ${{ secrets.GIT_PUSH_TOKEN }} \ No newline at end of file + VERSION: ${{ env.VERSION }} \ No newline at end of file From ed6b634bd6859e8df8db4d7522682e4043644cae Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 10:00:52 +0500 Subject: [PATCH 002/136] ci/cd --- .forgejo/workflows/release.yml | 85 ------------------------------- .woodpecker/release.yml | 91 ++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 85 deletions(-) delete mode 100644 .forgejo/workflows/release.yml create mode 100644 .woodpecker/release.yml diff --git a/.forgejo/workflows/release.yml b/.forgejo/workflows/release.yml deleted file mode 100644 index 14838a4..0000000 --- a/.forgejo/workflows/release.yml +++ /dev/null @@ -1,85 +0,0 @@ -name: Gonets Release Debian Packaging - -on: - push: - branches: - - develop - workflow_dispatch: - -jobs: - build-and-release: - runs-on: debian-latest - steps: - - name: Checkout main - uses: actions/checkout@v4 - with: - fetch-depth: 0 - ref: main - - - name: Install dependencies - run: | - sudo apt update - sudo apt install -y python3 python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make dpkg-dev - - - name: Prepare python dependencies - run: | - cd SRV - rm requirements.txt - poetry export -f requirements.txt --output requirements.txt --without-hashes - - - name: Build backend - run: | - cd SRV - poetry install - - - name: Build frontend - run: | - cd FRONT/DEV - npm install - npm run package - cd FRONT/DEV/dist/gonets-linux-x64/resources/app - npm run build - sed -i 's/href="\/assets\//href=".\/assets\//g' FRONT/DEV/dist/gonets-linux-x64/resources/app/dist/index.html - sed -i 's/src="\/assets\//src=".\/assets\//g' FRONT/DEV/dist/gonets-linux-x64/resources/app/dist/index.html - rm -rf FRONT/BUILD/* - cp -r FRONT/DEV/dist/gonets-linux-x64/* FRONT/BUILD/ - rm -rf FRONT/DEV - - - name: Preparing build debian package - run: | - DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --createorig - cd debian/ - rm *.ex - rm README.* - - - name: Clone debian configuration - run: | - git clone https://s.galanskiy:${{e5eaa40af9805f83a05ef70a0c946c03e1688633.GONETS}}@dev.gossys.dev/s.galanskiy/gonets-debian-template.git - mv gonets-debian-template/changelog gonets/debian/ - mv gonets-debian-template/control gonets/debian/ - mv gonets-debian-template/copyright gonets/debian/ - mv gonets-debian-template/install gonets/debian/ - mv gonets-debian-template/postinst gonets/debian/ - mv gonets-debian-template/postrm gonets/debian/ - mv gonets-debian-template/rules gonets/debian/ - - - name: Build package - run: | - dpkg-buildpackage -us -uc -b - - - name: Get version from changelog - run: | - dpkg-parsechangelog -l./debian/changelog --show-field VERSION - echo "VERSION=$VERSION" >> $GITHUB_OUTPUT - - - name: Commit changes to develop - run: | - git config user.name "s.galanskiy" - git config user.email "s.galanskiy@gossys.dev" - git checkout develop - git commit -m "Релиз $VERSION" - git tag "v$VERSION" - git push origin develop - git push origin "v$VERSION" - env: - VERSION: ${{ env.VERSION }} \ No newline at end of file diff --git a/.woodpecker/release.yml b/.woodpecker/release.yml new file mode 100644 index 0000000..999a641 --- /dev/null +++ b/.woodpecker/release.yml @@ -0,0 +1,91 @@ +environment: + GIT_AUTHOR_NAME: s.galanskiy + GIT_AUTHOR_EMAIL: s.galanskiy@gossys.dev + GIT_COMMITTER_NAME: s.galanskiy + GIT_COMMITTER_EMAIL: s.galanskiy@gossys.dev + +pipeline: + checkout: + image: woodpeckerci/plugin-git-checkout:latest + settings: + depth: 0 + ref: main + + install_deps: + image: debian:latest + commands: + - apt update + - apt install -y python3 python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make dpkg-dev + + prepare_python_deps: + image: debian:latest + commands: + - cd SRV + - rm -f requirements.txt + - poetry export -f requirements.txt --output requirements.txt --without-hashes + + build_backend: + image: debian:latest + commands: + - cd SRV + - poetry install + + build_frontend: + image: debian:latest + commands: + - cd FRONT/DEV + - npm install + - npm run package + - cd dist/gonets-linux-x64/resources/app + - npm run build + - sed -i 's/href="\/assets\//href=".\/assets\//g' dist/index.html + - sed -i 's/src="\/assets\//src=".\/assets\//g' dist/index.html + - cd ../../../.. + - rm -rf FRONT/BUILD/* + - cp -r dist/gonets-linux-x64/* ../../BUILD/ + - cd ../.. + - rm -rf DEV + + prepare_debian: + image: debian:latest + commands: + - DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --createorig + - cd debian/ + - rm -f *.ex + - rm -f README.* + + clone_debian_config: + image: debian:latest + secrets: [ GONETS ] + commands: + - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets-debian-template.git + - mv gonets-debian-template/changelog gonets/debian/ + - mv gonets-debian-template/control gonets/debian/ + - mv gonets-debian-template/copyright gonets/debian/ + - mv gonets-debian-template/install gonets/debian/ + - mv gonets-debian-template/postinst gonets/debian/ + - mv gonets-debian-template/postrm gonets/debian/ + - mv gonets-debian-template/rules gonets/debian/ + + build_package: + image: debian:latest + commands: + - dpkg-buildpackage -us -uc -b + + get_version: + image: debian:latest + commands: + - VERSION=$(dpkg-parsechangelog -l./debian/changelog --show-field VERSION) + - echo "VERSION=$VERSION" > version.env + + commit_changes: + image: debian:latest + commands: + - source version.env + - git config user.name "$GIT_AUTHOR_NAME" + - git config user.email "$GIT_AUTHOR_EMAIL" + - git checkout develop + - git commit -am "Релиз $VERSION" + - git tag "v$VERSION" + - git push origin develop + - git push origin "v$VERSION" From 47ab2d09108476f57784599abb8b3e470c9360f9 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 10:02:38 +0500 Subject: [PATCH 003/136] ci/cd-2 --- .woodpecker/release.yml | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/.woodpecker/release.yml b/.woodpecker/release.yml index 999a641..94d6af0 100644 --- a/.woodpecker/release.yml +++ b/.woodpecker/release.yml @@ -1,10 +1,6 @@ -environment: - GIT_AUTHOR_NAME: s.galanskiy - GIT_AUTHOR_EMAIL: s.galanskiy@gossys.dev - GIT_COMMITTER_NAME: s.galanskiy - GIT_COMMITTER_EMAIL: s.galanskiy@gossys.dev +name: release -pipeline: +steps: checkout: image: woodpeckerci/plugin-git-checkout:latest settings: @@ -75,17 +71,18 @@ pipeline: get_version: image: debian:latest commands: - - VERSION=$(dpkg-parsechangelog -l./debian/changelog --show-field VERSION) + - VERSION=$(dpkg-parsechangelog -l./debian/changelog --show-field Version) - echo "VERSION=$VERSION" > version.env commit_changes: image: debian:latest + secrets: [ GONETS ] commands: - source version.env - - git config user.name "$GIT_AUTHOR_NAME" - - git config user.email "$GIT_AUTHOR_EMAIL" + - git config user.name "s.galanskiy" + - git config user.email "s.galanskiy@gossys.dev" - git checkout develop - git commit -am "Релиз $VERSION" - git tag "v$VERSION" - - git push origin develop - - git push origin "v$VERSION" + - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git develop + - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git "v$VERSION" From a1ae57124bf67e05932db4005da7329fd0a17e68 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 10:04:47 +0500 Subject: [PATCH 004/136] ci/cd-2 --- .woodpecker/release.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.woodpecker/release.yml b/.woodpecker/release.yml index 94d6af0..5af06c0 100644 --- a/.woodpecker/release.yml +++ b/.woodpecker/release.yml @@ -1,4 +1,5 @@ -name: release +when: + event: [push, tag] steps: checkout: @@ -52,7 +53,9 @@ steps: clone_debian_config: image: debian:latest - secrets: [ GONETS ] + environment: + GONETS: + from_secret: GONETS commands: - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets-debian-template.git - mv gonets-debian-template/changelog gonets/debian/ @@ -76,7 +79,9 @@ steps: commit_changes: image: debian:latest - secrets: [ GONETS ] + environment: + GONETS: + from_secret: GONETS commands: - source version.env - git config user.name "s.galanskiy" From 88992e6d5bd5ce0305831036f52a3bfc9b0a510c Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 10:34:59 +0500 Subject: [PATCH 005/136] ci/cd-3 --- .woodpecker/release.yml => .woodpecker.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .woodpecker/release.yml => .woodpecker.yml (100%) diff --git a/.woodpecker/release.yml b/.woodpecker.yml similarity index 100% rename from .woodpecker/release.yml rename to .woodpecker.yml From 5017258f8cb166a471927a041100e620943f1bce Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 10:42:33 +0500 Subject: [PATCH 006/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.woodpecker.yml b/.woodpecker.yml index 5af06c0..8773b75 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -7,6 +7,11 @@ steps: settings: depth: 0 ref: main + commands: + - apt update + - apt install -y git-lfs + - git lfs install + - git lfs fetch install_deps: image: debian:latest From 3671127db65ee6a7990216f7be2972534f13dd60 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 10:43:39 +0500 Subject: [PATCH 007/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker.yml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index 8773b75..eaa1f30 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -3,15 +3,17 @@ when: steps: checkout: - image: woodpeckerci/plugin-git-checkout:latest - settings: - depth: 0 - ref: main + image: debian:latest commands: - - apt update - - apt install -y git-lfs + - apt-get update + - apt-get install -y git git-lfs - git lfs install + - git init + - git remote add origin https://dev.gossys.dev/s.galanskiy/gonets.git + - git fetch --no-tags --depth=1 origin main + - git checkout main - git lfs fetch + - git submodule update --init --recursive --depth=1 --recommend-shallow install_deps: image: debian:latest @@ -51,7 +53,7 @@ steps: prepare_debian: image: debian:latest commands: - - DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --createorig + - DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --only - cd debian/ - rm -f *.ex - rm -f README.* @@ -95,4 +97,4 @@ steps: - git commit -am "Релиз $VERSION" - git tag "v$VERSION" - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git develop - - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git "v$VERSION" + - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git "v$VERSION" \ No newline at end of file From 654281046e495cc913520c882c9a7d31e041cbca Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 10:45:06 +0500 Subject: [PATCH 008/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index eaa1f30..50f20d8 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -4,14 +4,17 @@ when: steps: checkout: image: debian:latest + environment: + GONETS: + from_secret: GONETS commands: - apt-get update - apt-get install -y git git-lfs - git lfs install - git init - - git remote add origin https://dev.gossys.dev/s.galanskiy/gonets.git - - git fetch --no-tags --depth=1 origin main - - git checkout main + - git remote add origin https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git + - git fetch --no-tags --depth=1 --filter=tree:0 origin 3671127db65ee6a7990216f7be2972534f13dd60 + - git checkout 3671127db65ee6a7990216f7be2972534f13dd60 - git lfs fetch - git submodule update --init --recursive --depth=1 --recommend-shallow From f60568fcf0b1e8f6d2ce13eee9c6f70293823a2c Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 11:08:30 +0500 Subject: [PATCH 009/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker.yml | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index 50f20d8..5af06c0 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -3,20 +3,10 @@ when: steps: checkout: - image: debian:latest - environment: - GONETS: - from_secret: GONETS - commands: - - apt-get update - - apt-get install -y git git-lfs - - git lfs install - - git init - - git remote add origin https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git - - git fetch --no-tags --depth=1 --filter=tree:0 origin 3671127db65ee6a7990216f7be2972534f13dd60 - - git checkout 3671127db65ee6a7990216f7be2972534f13dd60 - - git lfs fetch - - git submodule update --init --recursive --depth=1 --recommend-shallow + image: woodpeckerci/plugin-git-checkout:latest + settings: + depth: 0 + ref: main install_deps: image: debian:latest @@ -56,7 +46,7 @@ steps: prepare_debian: image: debian:latest commands: - - DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --only + - DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --createorig - cd debian/ - rm -f *.ex - rm -f README.* @@ -100,4 +90,4 @@ steps: - git commit -am "Релиз $VERSION" - git tag "v$VERSION" - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git develop - - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git "v$VERSION" \ No newline at end of file + - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git "v$VERSION" From deebb7150a63762693dd14f1f060897ca577002c Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 11:56:10 +0500 Subject: [PATCH 010/136] ci-cd-4 --- SRV/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/SRV/README.md b/SRV/README.md index e69de29..56a6051 100644 --- a/SRV/README.md +++ b/SRV/README.md @@ -0,0 +1 @@ +1 \ No newline at end of file From 5b82137f630326530b3a6221b26ff0b677dd5170 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 12:00:42 +0500 Subject: [PATCH 011/136] ci-cd-5 --- .woodpecker.yml => .woodpecker/.woodpecker.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .woodpecker.yml => .woodpecker/.woodpecker.yml (100%) diff --git a/.woodpecker.yml b/.woodpecker/.woodpecker.yml similarity index 100% rename from .woodpecker.yml rename to .woodpecker/.woodpecker.yml From 03caa031eebda53e654aab11f8f7f384081c076d Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 12:02:18 +0500 Subject: [PATCH 012/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index 5af06c0..50f20d8 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -3,10 +3,20 @@ when: steps: checkout: - image: woodpeckerci/plugin-git-checkout:latest - settings: - depth: 0 - ref: main + image: debian:latest + environment: + GONETS: + from_secret: GONETS + commands: + - apt-get update + - apt-get install -y git git-lfs + - git lfs install + - git init + - git remote add origin https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git + - git fetch --no-tags --depth=1 --filter=tree:0 origin 3671127db65ee6a7990216f7be2972534f13dd60 + - git checkout 3671127db65ee6a7990216f7be2972534f13dd60 + - git lfs fetch + - git submodule update --init --recursive --depth=1 --recommend-shallow install_deps: image: debian:latest @@ -46,7 +56,7 @@ steps: prepare_debian: image: debian:latest commands: - - DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --createorig + - DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --only - cd debian/ - rm -f *.ex - rm -f README.* @@ -90,4 +100,4 @@ steps: - git commit -am "Релиз $VERSION" - git tag "v$VERSION" - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git develop - - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git "v$VERSION" + - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git "v$VERSION" \ No newline at end of file From 3ccfee809a39ad911243093ac745e947cb164bf5 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 12:06:34 +0500 Subject: [PATCH 013/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index 50f20d8..5510036 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -16,6 +16,7 @@ steps: - git fetch --no-tags --depth=1 --filter=tree:0 origin 3671127db65ee6a7990216f7be2972534f13dd60 - git checkout 3671127db65ee6a7990216f7be2972534f13dd60 - git lfs fetch + - git lfs checkout - git submodule update --init --recursive --depth=1 --recommend-shallow install_deps: From 7f137f02c36f446df6a7a6e69fbc508592017a8c Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 12:11:03 +0500 Subject: [PATCH 014/136] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/my-first-workflow.yaml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/my-first-workflow.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .woodpecker/my-first-workflow.yaml diff --git a/.woodpecker/my-first-workflow.yaml b/.woodpecker/my-first-workflow.yaml new file mode 100644 index 0000000..57b9fa0 --- /dev/null +++ b/.woodpecker/my-first-workflow.yaml @@ -0,0 +1,16 @@ +when: + - event: push + branch: main + +steps: + - name: build + image: debian + commands: + - echo "This is the build step" + - echo "binary-data-123" > executable + - name: a-test-step + image: golang:1.16 + commands: + - echo "Testing ..." + - ./executable + From cee1f650bc63b00eca0919061ed1d0620bbc8df3 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 12:11:26 +0500 Subject: [PATCH 015/136] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 104 ------------------------------------ 1 file changed, 104 deletions(-) delete mode 100644 .woodpecker/.woodpecker.yml diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml deleted file mode 100644 index 5510036..0000000 --- a/.woodpecker/.woodpecker.yml +++ /dev/null @@ -1,104 +0,0 @@ -when: - event: [push, tag] - -steps: - checkout: - image: debian:latest - environment: - GONETS: - from_secret: GONETS - commands: - - apt-get update - - apt-get install -y git git-lfs - - git lfs install - - git init - - git remote add origin https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git - - git fetch --no-tags --depth=1 --filter=tree:0 origin 3671127db65ee6a7990216f7be2972534f13dd60 - - git checkout 3671127db65ee6a7990216f7be2972534f13dd60 - - git lfs fetch - - git lfs checkout - - git submodule update --init --recursive --depth=1 --recommend-shallow - - install_deps: - image: debian:latest - commands: - - apt update - - apt install -y python3 python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make dpkg-dev - - prepare_python_deps: - image: debian:latest - commands: - - cd SRV - - rm -f requirements.txt - - poetry export -f requirements.txt --output requirements.txt --without-hashes - - build_backend: - image: debian:latest - commands: - - cd SRV - - poetry install - - build_frontend: - image: debian:latest - commands: - - cd FRONT/DEV - - npm install - - npm run package - - cd dist/gonets-linux-x64/resources/app - - npm run build - - sed -i 's/href="\/assets\//href=".\/assets\//g' dist/index.html - - sed -i 's/src="\/assets\//src=".\/assets\//g' dist/index.html - - cd ../../../.. - - rm -rf FRONT/BUILD/* - - cp -r dist/gonets-linux-x64/* ../../BUILD/ - - cd ../.. - - rm -rf DEV - - prepare_debian: - image: debian:latest - commands: - - DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --only - - cd debian/ - - rm -f *.ex - - rm -f README.* - - clone_debian_config: - image: debian:latest - environment: - GONETS: - from_secret: GONETS - commands: - - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets-debian-template.git - - mv gonets-debian-template/changelog gonets/debian/ - - mv gonets-debian-template/control gonets/debian/ - - mv gonets-debian-template/copyright gonets/debian/ - - mv gonets-debian-template/install gonets/debian/ - - mv gonets-debian-template/postinst gonets/debian/ - - mv gonets-debian-template/postrm gonets/debian/ - - mv gonets-debian-template/rules gonets/debian/ - - build_package: - image: debian:latest - commands: - - dpkg-buildpackage -us -uc -b - - get_version: - image: debian:latest - commands: - - VERSION=$(dpkg-parsechangelog -l./debian/changelog --show-field Version) - - echo "VERSION=$VERSION" > version.env - - commit_changes: - image: debian:latest - environment: - GONETS: - from_secret: GONETS - commands: - - source version.env - - git config user.name "s.galanskiy" - - git config user.email "s.galanskiy@gossys.dev" - - git checkout develop - - git commit -am "Релиз $VERSION" - - git tag "v$VERSION" - - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git develop - - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git "v$VERSION" \ No newline at end of file From 385b843e5ceca42cc353baf58ffec20b53f4e058 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 12:13:37 +0500 Subject: [PATCH 016/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yaml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/{my-first-workflow.yaml => .woodpecker.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .woodpecker/{my-first-workflow.yaml => .woodpecker.yaml} (100%) diff --git a/.woodpecker/my-first-workflow.yaml b/.woodpecker/.woodpecker.yaml similarity index 100% rename from .woodpecker/my-first-workflow.yaml rename to .woodpecker/.woodpecker.yaml From 549e873f57fe71f62e50425befe08bc6e091bd3e Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 12:15:04 +0500 Subject: [PATCH 017/136] ci-cd-6 --- SRV/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRV/README.md b/SRV/README.md index 56a6051..d800886 100644 --- a/SRV/README.md +++ b/SRV/README.md @@ -1 +1 @@ -1 \ No newline at end of file +123 \ No newline at end of file From 2784dc682a7739b9514e687c8e6faed8546a3683 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 12:20:59 +0500 Subject: [PATCH 018/136] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .woodpecker.yml diff --git a/.woodpecker.yml b/.woodpecker.yml new file mode 100644 index 0000000..57b9fa0 --- /dev/null +++ b/.woodpecker.yml @@ -0,0 +1,16 @@ +when: + - event: push + branch: main + +steps: + - name: build + image: debian + commands: + - echo "This is the build step" + - echo "binary-data-123" > executable + - name: a-test-step + image: golang:1.16 + commands: + - echo "Testing ..." + - ./executable + From 91a3331003436f101efd8a78d40ed595f648854e Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 12:27:01 +0500 Subject: [PATCH 019/136] ci-cd-7 --- .woodpecker.yml | 11 +++++------ .woodpecker/.woodpecker.yaml | 16 ---------------- 2 files changed, 5 insertions(+), 22 deletions(-) delete mode 100644 .woodpecker/.woodpecker.yaml diff --git a/.woodpecker.yml b/.woodpecker.yml index 57b9fa0..ae3b872 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -1,16 +1,15 @@ when: - - event: push - branch: main + event: push + branch: main steps: - - name: build + build: image: debian commands: - echo "This is the build step" - echo "binary-data-123" > executable - - name: a-test-step + a-test-step: image: golang:1.16 commands: - echo "Testing ..." - - ./executable - + - ./executable \ No newline at end of file diff --git a/.woodpecker/.woodpecker.yaml b/.woodpecker/.woodpecker.yaml deleted file mode 100644 index 57b9fa0..0000000 --- a/.woodpecker/.woodpecker.yaml +++ /dev/null @@ -1,16 +0,0 @@ -when: - - event: push - branch: main - -steps: - - name: build - image: debian - commands: - - echo "This is the build step" - - echo "binary-data-123" > executable - - name: a-test-step - image: golang:1.16 - commands: - - echo "Testing ..." - - ./executable - From fa737495a61e83b4df1e1d1c8f11bf0a04a8a7c4 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 12:34:51 +0500 Subject: [PATCH 020/136] ci-cd-8 --- .woodpecker.yml | 15 ------ .woodpecker/.woodpecker.yml | 105 ++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 15 deletions(-) delete mode 100644 .woodpecker.yml create mode 100644 .woodpecker/.woodpecker.yml diff --git a/.woodpecker.yml b/.woodpecker.yml deleted file mode 100644 index ae3b872..0000000 --- a/.woodpecker.yml +++ /dev/null @@ -1,15 +0,0 @@ -when: - event: push - branch: main - -steps: - build: - image: debian - commands: - - echo "This is the build step" - - echo "binary-data-123" > executable - a-test-step: - image: golang:1.16 - commands: - - echo "Testing ..." - - ./executable \ No newline at end of file diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml new file mode 100644 index 0000000..2a0055e --- /dev/null +++ b/.woodpecker/.woodpecker.yml @@ -0,0 +1,105 @@ +when: + event: [push, tag] + branch: main + +steps: + checkout: + image: debian:latest + environment: + GONETS: + from_secret: GONETS + commands: + - apt-get update + - apt-get install -y git git-lfs + - git lfs install + - git init + - git remote add origin https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git + - git fetch --no-tags --depth=1 --filter=tree:0 origin main + - git checkout main + - git lfs fetch + - git lfs checkout + - git submodule update --init --recursive --depth=1 --recommend-shallow + + install_deps: + image: debian:latest + commands: + - apt update + - apt install -y python3 python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make dpkg-dev + + prepare_python_deps: + image: debian:latest + commands: + - cd SRV + - rm -f requirements.txt + - poetry export -f requirements.txt --output requirements.txt --without-hashes + + build_backend: + image: debian:latest + commands: + - cd SRV + - poetry install + + build_frontend: + image: debian:latest + commands: + - cd FRONT/DEV + - npm install + - npm run package + - cd dist/gonets-linux-x64/resources/app + - npm run build + - sed -i 's/href="\/assets\//href=".\/assets\//g' dist/index.html + - sed -i 's/src="\/assets\//src=".\/assets\//g' dist/index.html + - cd ../../../.. + - rm -rf FRONT/BUILD/* + - cp -r dist/gonets-linux-x64/* ../../BUILD/ + - cd ../.. + - rm -rf DEV + + prepare_debian: + image: debian:latest + commands: + - DESKTOP=1 DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --single -y + - cd debian/ + - rm -f *.ex + - rm -f README.* + + clone_debian_config: + image: debian:latest + environment: + GONETS: + from_secret: GONETS + commands: + - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets-debian-template.git + - mv gonets-debian-template/changelog gonets/debian/ + - mv gonets-debian-template/control gonets/debian/ + - mv gonets-debian-template/copyright gonets/debian/ + - mv gonets-debian-template/install gonets/debian/ + - mv gonets-debian-template/postinst gonets/debian/ + - mv gonets-debian-template/postrm gonets/debian/ + - mv gonets-debian-template/rules gonets/debian/ + + build_package: + image: debian:latest + commands: + - dpkg-buildpackage -us -uc -b + + get_version: + image: debian:latest + commands: + - VERSION=$(dpkg-parsechangelog -l./debian/changelog --show-field Version) + - echo "VERSION=$VERSION" > version.env + + commit_changes: + image: debian:latest + environment: + GONETS: + from_secret: GONETS + commands: + - source version.env + - git config user.name "s.galanskiy" + - git config user.email "s.galanskiy@gossys.dev" + - git checkout develop + - git commit -am "Релиз $VERSION" + - git tag "v$VERSION" + - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git develop + - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git "v$VERSION" \ No newline at end of file From 29c5ad24403ddfd4be66c61eef0cf98f52dfaa0c Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 14:06:48 +0500 Subject: [PATCH 021/136] ci-cd-9 --- SRV/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SRV/README.md b/SRV/README.md index d800886..274c005 100644 --- a/SRV/README.md +++ b/SRV/README.md @@ -1 +1 @@ -123 \ No newline at end of file +1234 \ No newline at end of file From 9a601844a4e230998a7c71d4d4262909d58ec7bc Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 14:11:16 +0500 Subject: [PATCH 022/136] ci-cd-10 --- .woodpecker/my-first-worlflow.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .woodpecker/my-first-worlflow.yaml diff --git a/.woodpecker/my-first-worlflow.yaml b/.woodpecker/my-first-worlflow.yaml new file mode 100644 index 0000000..16fb1bd --- /dev/null +++ b/.woodpecker/my-first-worlflow.yaml @@ -0,0 +1,15 @@ +when: + - event: push + branch: main + +steps: + - name: build + image: debian + commands: + - echo "This is the build step" + - echo "binary-data-123" > executable + - name: a-test-step + image: golang:1.16 + commands: + - echo "Testing ..." + - ./executable \ No newline at end of file From e1abdbba966fbf560961237e85abe38ca79d4dd5 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 14:14:30 +0500 Subject: [PATCH 023/136] ci-cd-11 --- .woodpecker/my-first-worlflow.yaml | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 .woodpecker/my-first-worlflow.yaml diff --git a/.woodpecker/my-first-worlflow.yaml b/.woodpecker/my-first-worlflow.yaml deleted file mode 100644 index 16fb1bd..0000000 --- a/.woodpecker/my-first-worlflow.yaml +++ /dev/null @@ -1,15 +0,0 @@ -when: - - event: push - branch: main - -steps: - - name: build - image: debian - commands: - - echo "This is the build step" - - echo "binary-data-123" > executable - - name: a-test-step - image: golang:1.16 - commands: - - echo "Testing ..." - - ./executable \ No newline at end of file From aabd3ef8f4350ffc9260fdaae4531db0c2fb3fbd Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 14:16:52 +0500 Subject: [PATCH 024/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index 2a0055e..c17a382 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -12,13 +12,7 @@ steps: - apt-get update - apt-get install -y git git-lfs - git lfs install - - git init - - git remote add origin https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git - - git fetch --no-tags --depth=1 --filter=tree:0 origin main - - git checkout main - - git lfs fetch - - git lfs checkout - - git submodule update --init --recursive --depth=1 --recommend-shallow + - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git install_deps: image: debian:latest From f16ddecd19f43dbf325b64e8939ca68029f7d01c Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 14:22:56 +0500 Subject: [PATCH 025/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index c17a382..f05652b 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -30,7 +30,8 @@ steps: build_backend: image: debian:latest commands: - - cd SRV + - cd gonets/SRV + - curl -sSL https://install.python-poetry.org | python3 - - poetry install build_frontend: From 930167cf9197a4aa72538618e0725bae63d7b6ea Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 14:26:51 +0500 Subject: [PATCH 026/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index f05652b..7ad8960 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -23,7 +23,8 @@ steps: prepare_python_deps: image: debian:latest commands: - - cd SRV + - cd gonets/SRV + - curl -sSL https://install.python-poetry.org | python3 - - rm -f requirements.txt - poetry export -f requirements.txt --output requirements.txt --without-hashes @@ -31,7 +32,6 @@ steps: image: debian:latest commands: - cd gonets/SRV - - curl -sSL https://install.python-poetry.org | python3 - - poetry install build_frontend: From df0d4f195e2d9933b88fff0f0e5bdc1638c4ead3 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 14:38:33 +0500 Subject: [PATCH 027/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index 7ad8960..4e89890 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -18,8 +18,8 @@ steps: image: debian:latest commands: - apt update - - apt install -y python3 python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make dpkg-dev - + - apt install -y python3 #python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make dpkg-dev + - python3 --version prepare_python_deps: image: debian:latest commands: From 5e2a10f21139e129ac0e176fff1f4217b78531c5 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 14:47:34 +0500 Subject: [PATCH 028/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index 4e89890..c0bc036 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -15,13 +15,12 @@ steps: - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git install_deps: - image: debian:latest commands: - apt update - apt install -y python3 #python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make dpkg-dev - python3 --version + prepare_python_deps: - image: debian:latest commands: - cd gonets/SRV - curl -sSL https://install.python-poetry.org | python3 - @@ -29,13 +28,11 @@ steps: - poetry export -f requirements.txt --output requirements.txt --without-hashes build_backend: - image: debian:latest commands: - cd gonets/SRV - poetry install build_frontend: - image: debian:latest commands: - cd FRONT/DEV - npm install @@ -51,7 +48,6 @@ steps: - rm -rf DEV prepare_debian: - image: debian:latest commands: - DESKTOP=1 DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --single -y - cd debian/ @@ -59,7 +55,6 @@ steps: - rm -f README.* clone_debian_config: - image: debian:latest environment: GONETS: from_secret: GONETS @@ -74,18 +69,15 @@ steps: - mv gonets-debian-template/rules gonets/debian/ build_package: - image: debian:latest commands: - dpkg-buildpackage -us -uc -b get_version: - image: debian:latest commands: - VERSION=$(dpkg-parsechangelog -l./debian/changelog --show-field Version) - echo "VERSION=$VERSION" > version.env commit_changes: - image: debian:latest environment: GONETS: from_secret: GONETS From 448102dbeb97c585c176da173cb04c763b0798e9 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 14:54:54 +0500 Subject: [PATCH 029/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 154 +++++++++++++++++------------------- 1 file changed, 72 insertions(+), 82 deletions(-) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index c0bc036..c047b51 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -1,92 +1,82 @@ -when: - event: [push, tag] - branch: main +environment: + GONETS: your_token_here + GIT_AUTHOR_NAME: s.galanskiy + GIT_AUTHOR_EMAIL: s.galanskiy@gossys.dev + GIT_COMMITTER_NAME: s.galanskiy + GIT_COMMITTER_EMAIL: s.galanskiy@gossys.dev -steps: - checkout: - image: debian:latest - environment: - GONETS: - from_secret: GONETS - commands: - - apt-get update - - apt-get install -y git git-lfs - - git lfs install - - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git +pipeline: + image: debian:latest + steps: + - name: Checkout + commands: + - git clone --depth 0 --branch main . . - install_deps: - commands: - - apt update - - apt install -y python3 #python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make dpkg-dev - - python3 --version + - name: Install dependencies + commands: + - apt update + - apt install -y python3 python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make dpkg-dev - prepare_python_deps: - commands: - - cd gonets/SRV - - curl -sSL https://install.python-poetry.org | python3 - - - rm -f requirements.txt - - poetry export -f requirements.txt --output requirements.txt --without-hashes + - name: Prepare python dependencies + commands: + - cd SRV + - rm -f requirements.txt + - poetry export -f requirements.txt --output requirements.txt --without-hashes - build_backend: - commands: - - cd gonets/SRV - - poetry install + - name: Build backend + commands: + - cd SRV + - poetry install - build_frontend: - commands: - - cd FRONT/DEV - - npm install - - npm run package - - cd dist/gonets-linux-x64/resources/app - - npm run build - - sed -i 's/href="\/assets\//href=".\/assets\//g' dist/index.html - - sed -i 's/src="\/assets\//src=".\/assets\//g' dist/index.html - - cd ../../../.. - - rm -rf FRONT/BUILD/* - - cp -r dist/gonets-linux-x64/* ../../BUILD/ - - cd ../.. - - rm -rf DEV + - name: Build frontend + commands: + - cd FRONT/DEV + - npm install + - npm run package + - cd dist/gonets-linux-x64/resources/app + - npm run build + - sed -i 's/href="\/assets\//href=".\/assets\//g' dist/index.html + - sed -i 's/src="\/assets\//src=".\/assets\//g' dist/index.html + - cd ../../../.. + - rm -rf FRONT/BUILD/* + - cp -r dist/gonets-linux-x64/* ../../BUILD/ + - cd ../.. + - rm -rf DEV - prepare_debian: - commands: - - DESKTOP=1 DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --single -y - - cd debian/ - - rm -f *.ex - - rm -f README.* + - name: Prepare debian package + commands: + - DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --createorig + - cd debian/ + - rm -f *.ex + - rm -f README.* - clone_debian_config: - environment: - GONETS: - from_secret: GONETS - commands: - - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets-debian-template.git - - mv gonets-debian-template/changelog gonets/debian/ - - mv gonets-debian-template/control gonets/debian/ - - mv gonets-debian-template/copyright gonets/debian/ - - mv gonets-debian-template/install gonets/debian/ - - mv gonets-debian-template/postinst gonets/debian/ - - mv gonets-debian-template/postrm gonets/debian/ - - mv gonets-debian-template/rules gonets/debian/ + - name: Clone debian configuration + commands: + - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets-debian-template.git + - mv gonets-debian-template/changelog gonets/debian/ + - mv gonets-debian-template/control gonets/debian/ + - mv gonets-debian-template/copyright gonets/debian/ + - mv gonets-debian-template/install gonets/debian/ + - mv gonets-debian-template/postinst gonets/debian/ + - mv gonets-debian-template/postrm gonets/debian/ + - mv gonets-debian-template/rules gonets/debian/ - build_package: - commands: - - dpkg-buildpackage -us -uc -b + - name: Build package + commands: + - dpkg-buildpackage -us -uc -b - get_version: - commands: - - VERSION=$(dpkg-parsechangelog -l./debian/changelog --show-field Version) - - echo "VERSION=$VERSION" > version.env + - name: Get version from changelog + commands: + - VERSION=$(dpkg-parsechangelog -l./debian/changelog --show-field VERSION) + - echo "VERSION=$VERSION" > version.env - commit_changes: - environment: - GONETS: - from_secret: GONETS - commands: - - source version.env - - git config user.name "s.galanskiy" - - git config user.email "s.galanskiy@gossys.dev" - - git checkout develop - - git commit -am "Релиз $VERSION" - - git tag "v$VERSION" - - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git develop - - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git "v$VERSION" \ No newline at end of file + - name: Commit changes to develop + commands: + - source version.env + - git config user.name "$GIT_AUTHOR_NAME" + - git config user.email "$GIT_AUTHOR_EMAIL" + - git checkout develop + - git commit -am "Релиз $VERSION" + - git tag "v$VERSION" + - git push origin develop + - git push origin "v$VERSION" From c1cf4f33f583b29a7c08ef422dbf961136fdc6d5 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 14:55:47 +0500 Subject: [PATCH 030/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 144 ++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 74 deletions(-) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index c047b51..b1649cb 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -1,82 +1,78 @@ -environment: - GONETS: your_token_here - GIT_AUTHOR_NAME: s.galanskiy - GIT_AUTHOR_EMAIL: s.galanskiy@gossys.dev - GIT_COMMITTER_NAME: s.galanskiy - GIT_COMMITTER_EMAIL: s.galanskiy@gossys.dev +steps: + checkout_and_install: + image: debian:latest + commands: + - git clone --depth 0 --branch main . . + - apt update + - apt install -y python3 python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make dpkg-dev -pipeline: - image: debian:latest - steps: - - name: Checkout - commands: - - git clone --depth 0 --branch main . . + prepare_python_deps: + commands: + - cd SRV + - rm -f requirements.txt + - poetry export -f requirements.txt --output requirements.txt --without-hashes - - name: Install dependencies - commands: - - apt update - - apt install -y python3 python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make dpkg-dev + build_backend: + commands: + - cd SRV + - poetry install - - name: Prepare python dependencies - commands: - - cd SRV - - rm -f requirements.txt - - poetry export -f requirements.txt --output requirements.txt --without-hashes + build_frontend: + commands: + - cd FRONT/DEV + - npm install + - npm run package + - cd dist/gonets-linux-x64/resources/app + - npm run build + - sed -i 's/href="\/assets\//href=".\/assets\//g' dist/index.html + - sed -i 's/src="\/assets\//src=".\/assets\//g' dist/index.html + - cd ../../../.. + - rm -rf FRONT/BUILD/* + - cp -r dist/gonets-linux-x64/* ../../BUILD/ + - cd ../.. + - rm -rf DEV - - name: Build backend - commands: - - cd SRV - - poetry install + prepare_debian: + commands: + - DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --createorig + - cd debian/ + - rm -f *.ex + - rm -f README.* - - name: Build frontend - commands: - - cd FRONT/DEV - - npm install - - npm run package - - cd dist/gonets-linux-x64/resources/app - - npm run build - - sed -i 's/href="\/assets\//href=".\/assets\//g' dist/index.html - - sed -i 's/src="\/assets\//src=".\/assets\//g' dist/index.html - - cd ../../../.. - - rm -rf FRONT/BUILD/* - - cp -r dist/gonets-linux-x64/* ../../BUILD/ - - cd ../.. - - rm -rf DEV + clone_debian_config: + environment: + GONETS: your_token_here + commands: + - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets-debian-template.git + - mv gonets-debian-template/changelog gonets/debian/ + - mv gonets-debian-template/control gonets/debian/ + - mv gonets-debian-template/copyright gonets/debian/ + - mv gonets-debian-template/install gonets/debian/ + - mv gonets-debian-template/postinst gonets/debian/ + - mv gonets-debian-template/postrm gonets/debian/ + - mv gonets-debian-template/rules gonets/debian/ - - name: Prepare debian package - commands: - - DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --createorig - - cd debian/ - - rm -f *.ex - - rm -f README.* + build_package: + commands: + - dpkg-buildpackage -us -uc -b - - name: Clone debian configuration - commands: - - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets-debian-template.git - - mv gonets-debian-template/changelog gonets/debian/ - - mv gonets-debian-template/control gonets/debian/ - - mv gonets-debian-template/copyright gonets/debian/ - - mv gonets-debian-template/install gonets/debian/ - - mv gonets-debian-template/postinst gonets/debian/ - - mv gonets-debian-template/postrm gonets/debian/ - - mv gonets-debian-template/rules gonets/debian/ + get_version: + commands: + - VERSION=$(dpkg-parsechangelog -l./debian/changelog --show-field VERSION) + - echo "VERSION=$VERSION" > version.env - - name: Build package - commands: - - dpkg-buildpackage -us -uc -b - - - name: Get version from changelog - commands: - - VERSION=$(dpkg-parsechangelog -l./debian/changelog --show-field VERSION) - - echo "VERSION=$VERSION" > version.env - - - name: Commit changes to develop - commands: - - source version.env - - git config user.name "$GIT_AUTHOR_NAME" - - git config user.email "$GIT_AUTHOR_EMAIL" - - git checkout develop - - git commit -am "Релиз $VERSION" - - git tag "v$VERSION" - - git push origin develop - - git push origin "v$VERSION" + commit_changes: + environment: + GIT_AUTHOR_NAME: s.galanskiy + GIT_AUTHOR_EMAIL: s.galanskiy@gossys.dev + GIT_COMMITTER_NAME: s.galanskiy + GIT_COMMITTER_EMAIL: s.galanskiy@gossys.dev + commands: + - source version.env + - git config user.name "$GIT_AUTHOR_NAME" + - git config user.email "$GIT_AUTHOR_EMAIL" + - git checkout develop + - git commit -am "Релиз $VERSION" + - git tag "v$VERSION" + - git push origin develop + - git push origin "v$VERSION" From e64b5eeac437c0d1d228afb1e82c72c3c4346d7e Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 15:01:56 +0500 Subject: [PATCH 031/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 43 +++++++++++++++---------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index b1649cb..095cbb9 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -1,24 +1,26 @@ steps: - checkout_and_install: + all_in_one: image: debian:latest + environment: + GONETS: your_token_here + GIT_AUTHOR_NAME: s.galanskiy + GIT_AUTHOR_EMAIL: s.galanskiy@gossys.dev + GIT_COMMITTER_NAME: s.galanskiy + GIT_COMMITTER_EMAIL: s.galanskiy@gossys.dev commands: + - echo '=== Checkout and install dependencies ===' - git clone --depth 0 --branch main . . - apt update - apt install -y python3 python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make dpkg-dev - prepare_python_deps: - commands: + - echo '=== Prepare python dependencies ===' - cd SRV - rm -f requirements.txt - poetry export -f requirements.txt --output requirements.txt --without-hashes - - build_backend: - commands: - - cd SRV - poetry install + - cd .. - build_frontend: - commands: + - echo '=== Build frontend ===' - cd FRONT/DEV - npm install - npm run package @@ -32,17 +34,14 @@ steps: - cd ../.. - rm -rf DEV - prepare_debian: - commands: + - echo '=== Prepare debian package ===' - DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --createorig - cd debian/ - rm -f *.ex - rm -f README.* + - cd .. - clone_debian_config: - environment: - GONETS: your_token_here - commands: + - echo '=== Clone debian configuration ===' - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets-debian-template.git - mv gonets-debian-template/changelog gonets/debian/ - mv gonets-debian-template/control gonets/debian/ @@ -52,22 +51,14 @@ steps: - mv gonets-debian-template/postrm gonets/debian/ - mv gonets-debian-template/rules gonets/debian/ - build_package: - commands: + - echo '=== Build package ===' - dpkg-buildpackage -us -uc -b - get_version: - commands: + - echo '=== Get version from changelog ===' - VERSION=$(dpkg-parsechangelog -l./debian/changelog --show-field VERSION) - echo "VERSION=$VERSION" > version.env - commit_changes: - environment: - GIT_AUTHOR_NAME: s.galanskiy - GIT_AUTHOR_EMAIL: s.galanskiy@gossys.dev - GIT_COMMITTER_NAME: s.galanskiy - GIT_COMMITTER_EMAIL: s.galanskiy@gossys.dev - commands: + - echo '=== Commit changes to develop ===' - source version.env - git config user.name "$GIT_AUTHOR_NAME" - git config user.email "$GIT_AUTHOR_EMAIL" From bde392346a3ee8fcd1feabb69e755a56f0fdfadc Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 15:12:04 +0500 Subject: [PATCH 032/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 97 ++++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 28 deletions(-) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index 095cbb9..30f3612 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -1,27 +1,48 @@ +# Указываем рабочую директорию для сохранения состояния между шагами +workspace: + path: /woodpecker/src + +when: + event: [push, tag] + branch: main + steps: - all_in_one: + checkout: image: debian:latest environment: - GONETS: your_token_here - GIT_AUTHOR_NAME: s.galanskiy - GIT_AUTHOR_EMAIL: s.galanskiy@gossys.dev - GIT_COMMITTER_NAME: s.galanskiy - GIT_COMMITTER_EMAIL: s.galanskiy@gossys.dev + GONETS: + from_secret: GONETS commands: - - echo '=== Checkout and install dependencies ===' - - git clone --depth 0 --branch main . . - - apt update - - apt install -y python3 python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make dpkg-dev + - apt-get update + - apt-get install -y git git-lfs + - git lfs install + - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git - - echo '=== Prepare python dependencies ===' - - cd SRV + install_deps: + image: debian:latest + commands: + - apt update + - apt install -y python3 + - python3 --version + + prepare_python_deps: + image: debian:latest + commands: + - cd gonets/SRV + - curl -sSL https://install.python-poetry.org | python3 - - rm -f requirements.txt - poetry export -f requirements.txt --output requirements.txt --without-hashes - - poetry install - - cd .. - - echo '=== Build frontend ===' - - cd FRONT/DEV + build_backend: + image: debian:latest + commands: + - cd gonets/SRV + - poetry install + + build_frontend: + image: debian:latest + commands: + - cd gonets/FRONT/DEV - npm install - npm run package - cd dist/gonets-linux-x64/resources/app @@ -34,14 +55,22 @@ steps: - cd ../.. - rm -rf DEV - - echo '=== Prepare debian package ===' - - DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --createorig + prepare_debian: + image: debian:latest + commands: + - cd gonets + - DESKTOP=1 DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --single -y - cd debian/ - rm -f *.ex - rm -f README.* - - cd .. - - echo '=== Clone debian configuration ===' + clone_debian_config: + image: debian:latest + environment: + GONETS: + from_secret: GONETS + commands: + - cd /woodpecker/src - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets-debian-template.git - mv gonets-debian-template/changelog gonets/debian/ - mv gonets-debian-template/control gonets/debian/ @@ -51,19 +80,31 @@ steps: - mv gonets-debian-template/postrm gonets/debian/ - mv gonets-debian-template/rules gonets/debian/ - - echo '=== Build package ===' + build_package: + image: debian:latest + commands: + - cd gonets - dpkg-buildpackage -us -uc -b - - echo '=== Get version from changelog ===' - - VERSION=$(dpkg-parsechangelog -l./debian/changelog --show-field VERSION) + get_version: + image: debian:latest + commands: + - cd gonets + - VERSION=$(dpkg-parsechangelog -l./debian/changelog --show-field Version) - echo "VERSION=$VERSION" > version.env - - echo '=== Commit changes to develop ===' + commit_changes: + image: debian:latest + environment: + GONETS: + from_secret: GONETS + commands: + - cd gonets - source version.env - - git config user.name "$GIT_AUTHOR_NAME" - - git config user.email "$GIT_AUTHOR_EMAIL" + - git config user.name "s.galanskiy" + - git config user.email "s.galanskiy@gossys.dev" - git checkout develop - git commit -am "Релиз $VERSION" - git tag "v$VERSION" - - git push origin develop - - git push origin "v$VERSION" + - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git develop + - git push https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git "v$VERSION" \ No newline at end of file From cddbee6f36174a240dd7a6d6eb5e4f26bb379624 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 15:13:43 +0500 Subject: [PATCH 033/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index 30f3612..760f34c 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -28,6 +28,7 @@ steps: prepare_python_deps: image: debian:latest commands: + - python3 --version - cd gonets/SRV - curl -sSL https://install.python-poetry.org | python3 - - rm -f requirements.txt From dccf1ad4e275c916e5689ee10273e674fd9b6ee3 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 15:29:54 +0500 Subject: [PATCH 034/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index 760f34c..ed4c06b 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -1,7 +1,3 @@ -# Указываем рабочую директорию для сохранения состояния между шагами -workspace: - path: /woodpecker/src - when: event: [push, tag] branch: main @@ -19,7 +15,7 @@ steps: - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git install_deps: - image: debian:latest + image: workflow commands: - apt update - apt install -y python3 From acc154df36f8ebf12e994af1b1475eb7d1e11365 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 15:31:45 +0500 Subject: [PATCH 035/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index ed4c06b..b947f51 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -14,31 +14,19 @@ steps: - git lfs install - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git - install_deps: - image: workflow - commands: - apt update - apt install -y python3 - python3 --version - prepare_python_deps: - image: debian:latest - commands: - python3 --version - cd gonets/SRV - curl -sSL https://install.python-poetry.org | python3 - - rm -f requirements.txt - poetry export -f requirements.txt --output requirements.txt --without-hashes - build_backend: - image: debian:latest - commands: - cd gonets/SRV - poetry install - build_frontend: - image: debian:latest - commands: - cd gonets/FRONT/DEV - npm install - npm run package @@ -52,21 +40,12 @@ steps: - cd ../.. - rm -rf DEV - prepare_debian: - image: debian:latest - commands: - cd gonets - DESKTOP=1 DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --single -y - cd debian/ - rm -f *.ex - rm -f README.* - clone_debian_config: - image: debian:latest - environment: - GONETS: - from_secret: GONETS - commands: - cd /woodpecker/src - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets-debian-template.git - mv gonets-debian-template/changelog gonets/debian/ @@ -77,25 +56,13 @@ steps: - mv gonets-debian-template/postrm gonets/debian/ - mv gonets-debian-template/rules gonets/debian/ - build_package: - image: debian:latest - commands: - cd gonets - dpkg-buildpackage -us -uc -b - get_version: - image: debian:latest - commands: - cd gonets - VERSION=$(dpkg-parsechangelog -l./debian/changelog --show-field Version) - echo "VERSION=$VERSION" > version.env - commit_changes: - image: debian:latest - environment: - GONETS: - from_secret: GONETS - commands: - cd gonets - source version.env - git config user.name "s.galanskiy" From be49a3c67d83dff1f24b0a773ef564bb0e44027c Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 15:33:46 +0500 Subject: [PATCH 036/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index b947f51..b1dd8ec 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -15,7 +15,7 @@ steps: - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git - apt update - - apt install -y python3 + - apt install -y python3 python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make dpkg-dev - python3 --version - python3 --version From 2adbab5d58f6ec040b72f40cccff33efa617bc4f Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 15:41:54 +0500 Subject: [PATCH 037/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index b1dd8ec..58540b4 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -9,24 +9,30 @@ steps: GONETS: from_secret: GONETS commands: - - apt-get update - - apt-get install -y git git-lfs + # ПОДГОТОВКА ГИТА И КЛОНИРОВАНИЕ GONETS + - apt update + - apt install -y git git-lfs - git lfs install - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets.git + # УСТАНОВКА НЕОБХОДИМЫХ ЗАВИСИМОСТЕЙ НА СИСТЕМЕ - apt update - apt install -y python3 python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make dpkg-dev - python3 --version + - node -v + - npm -v - - python3 --version - - cd gonets/SRV + # ПОДГОТОВКА СПИСКА PYTHON ЗАВИСИМОСТЕЙ GONETS - curl -sSL https://install.python-poetry.org | python3 - + - export PATH="/root/.local/bin:$PATH" + - source ~/.bashrc + - poetry --version + - cd gonets/SRV + - poetry install - rm -f requirements.txt - poetry export -f requirements.txt --output requirements.txt --without-hashes - - cd gonets/SRV - - poetry install - + # ПОДГОТОВКА И СБОРКА FRONTEND ЧАСТИ GONETS - cd gonets/FRONT/DEV - npm install - npm run package @@ -40,13 +46,14 @@ steps: - cd ../.. - rm -rf DEV + # ИНИЦИАЛИЗАЦИЯ DEBIAN КОНФИГУРАЦИЙ ДЛЯ СБОРКИ - cd gonets - DESKTOP=1 DEBEMAIL="devteam@gossys.dev" DEBFULLNAME="GOSSYS LLC" dh_make --single -y - cd debian/ - rm -f *.ex - rm -f README.* - - cd /woodpecker/src + # КЛОНИРОВАНИЕ НЕОБХОДИМЫХ ШАБЛОНОВ КОНФИГОВ ДЕБИАНА ДЛЯ СБОРКИ - git clone https://s.galanskiy:${GONETS}@dev.gossys.dev/s.galanskiy/gonets-debian-template.git - mv gonets-debian-template/changelog gonets/debian/ - mv gonets-debian-template/control gonets/debian/ @@ -56,13 +63,16 @@ steps: - mv gonets-debian-template/postrm gonets/debian/ - mv gonets-debian-template/rules gonets/debian/ + # СБОРКА ДЕБИАН ПАКЕТА - cd gonets - dpkg-buildpackage -us -uc -b + # ИЗВЛЕЧЕНИЕ ВЕРСИИ ПАКЕТА ДЛЯ КОММИТА - cd gonets - VERSION=$(dpkg-parsechangelog -l./debian/changelog --show-field Version) - echo "VERSION=$VERSION" > version.env + # КОММИТ И ТЕГ НА ВЕТКУ DEVELOP - cd gonets - source version.env - git config user.name "s.galanskiy" From 1baf3d0805f9303899939e06161c5f0dde838250 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 15:46:57 +0500 Subject: [PATCH 038/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index 58540b4..d71ab55 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -25,7 +25,6 @@ steps: # ПОДГОТОВКА СПИСКА PYTHON ЗАВИСИМОСТЕЙ GONETS - curl -sSL https://install.python-poetry.org | python3 - - export PATH="/root/.local/bin:$PATH" - - source ~/.bashrc - poetry --version - cd gonets/SRV - poetry install From ef6f776734c8023accd8192bd0f758b193ca9510 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 15:47:33 +0500 Subject: [PATCH 039/136] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20.woodpecker/.woodpecker.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .woodpecker/.woodpecker.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index d71ab55..3d8398e 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -9,6 +9,7 @@ steps: GONETS: from_secret: GONETS commands: + bash # ПОДГОТОВКА ГИТА И КЛОНИРОВАНИЕ GONETS - apt update - apt install -y git git-lfs From 0448b9dadb6a71c61f654d1b7de1aafc9186e0dc Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 15:54:38 +0500 Subject: [PATCH 040/136] ci-cd-12 --- SRV/poetry.lock | 37 +---------------------- SRV/pyproject.toml | 1 - SRV/requirements.txt | 71 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 37 deletions(-) create mode 100644 SRV/requirements.txt diff --git a/SRV/poetry.lock b/SRV/poetry.lock index 6e20c28..23c263f 100644 --- a/SRV/poetry.lock +++ b/SRV/poetry.lock @@ -1295,27 +1295,6 @@ files = [ {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"}, ] -[[package]] -name = "pycairo" -version = "1.27.0" -description = "Python interface for cairo" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "pycairo-1.27.0-cp310-cp310-win32.whl", hash = "sha256:e20f431244634cf244ab6b4c3a2e540e65746eed1324573cf291981c3e65fc05"}, - {file = "pycairo-1.27.0-cp310-cp310-win_amd64.whl", hash = "sha256:03bf570e3919901572987bc69237b648fe0de242439980be3e606b396e3318c9"}, - {file = "pycairo-1.27.0-cp311-cp311-win32.whl", hash = "sha256:9a9b79f92a434dae65c34c830bb9abdbd92654195e73d52663cbe45af1ad14b2"}, - {file = "pycairo-1.27.0-cp311-cp311-win_amd64.whl", hash = "sha256:d40a6d80b15dacb3672dc454df4bc4ab3988c6b3f36353b24a255dc59a1c8aea"}, - {file = "pycairo-1.27.0-cp312-cp312-win32.whl", hash = "sha256:e2239b9bb6c05edae5f3be97128e85147a155465e644f4d98ea0ceac7afc04ee"}, - {file = "pycairo-1.27.0-cp312-cp312-win_amd64.whl", hash = "sha256:27cb4d3a80e3b9990af552818515a8e466e0317063a6e61585533f1a86f1b7d5"}, - {file = "pycairo-1.27.0-cp313-cp313-win32.whl", hash = "sha256:01505c138a313df2469f812405963532fc2511fb9bca9bdc8e0ab94c55d1ced8"}, - {file = "pycairo-1.27.0-cp313-cp313-win_amd64.whl", hash = "sha256:b0349d744c068b6644ae23da6ada111c8a8a7e323b56cbce3707cba5bdb474cc"}, - {file = "pycairo-1.27.0-cp39-cp39-win32.whl", hash = "sha256:f9ca8430751f1fdcd3f072377560c9e15608b9a42d61375469db853566993c9b"}, - {file = "pycairo-1.27.0-cp39-cp39-win_amd64.whl", hash = "sha256:1b1321652a6e27c4de3069709b1cae22aed2707fd8c5e889c04a95669228af2a"}, - {file = "pycairo-1.27.0.tar.gz", hash = "sha256:5cb21e7a00a2afcafea7f14390235be33497a2cce53a98a19389492a60628430"}, -] - [[package]] name = "pycparser" version = "2.22" @@ -1489,20 +1468,6 @@ files = [ [package.extras] windows-terminal = ["colorama (>=0.4.6)"] -[[package]] -name = "pygobject" -version = "3.50.0" -description = "Python bindings for GObject Introspection" -optional = false -python-versions = "<4.0,>=3.9" -groups = ["main"] -files = [ - {file = "pygobject-3.50.0.tar.gz", hash = "sha256:4500ad3dbf331773d8dedf7212544c999a76fc96b63a91b3dcac1e5925a1d103"}, -] - -[package.dependencies] -pycairo = ">=1.16" - [[package]] name = "pynacl" version = "1.5.0" @@ -2237,4 +2202,4 @@ propcache = ">=0.2.1" [metadata] lock-version = "2.1" python-versions = "^3.11" -content-hash = "6dfae73c0cdec175259066cdcf6fe6bceefc5ddfc84252b6093d1abf3ec82d58" +content-hash = "60c1f3007a3dcb4ef05162fcf9a2f3a3d8b39a56cd5df142db8afea958d182c6" diff --git a/SRV/pyproject.toml b/SRV/pyproject.toml index 1065870..5193ab8 100644 --- a/SRV/pyproject.toml +++ b/SRV/pyproject.toml @@ -19,7 +19,6 @@ python = "^3.11" pydbus = "^0.6.0" fastapi = {extras = ["standard"], version = "^0.115.11"} pydantic = "^2.10.3" -pygobject = "^3.50.0" sdbus-networkmanager = "^2.0.0" uvicorn = "^0.32.1" websockets = "^14.1" diff --git a/SRV/requirements.txt b/SRV/requirements.txt new file mode 100644 index 0000000..a8ffeca --- /dev/null +++ b/SRV/requirements.txt @@ -0,0 +1,71 @@ +aiofiles==24.1.0 ; python_version >= "3.11" and python_version < "4.0" +aiohappyeyeballs==2.6.1 ; python_version >= "3.11" and python_version < "4.0" +aiohttp==3.12.7 ; python_version >= "3.11" and python_version < "4.0" +aiosignal==1.3.2 ; python_version >= "3.11" and python_version < "4.0" +annotated-types==0.7.0 ; python_version >= "3.11" and python_version < "4.0" +anyio==4.7.0 ; python_version >= "3.11" and python_version < "4.0" +attrs==25.3.0 ; python_version >= "3.11" and python_version < "4.0" +bcrypt==4.3.0 ; python_version >= "3.11" and python_version < "4.0" +certifi==2025.1.31 ; python_version >= "3.11" and python_version < "4.0" +cffi==1.17.1 ; python_version >= "3.11" and python_version < "4.0" +click==8.1.7 ; python_version >= "3.11" and python_version < "4.0" +colorama==0.4.6 ; python_version >= "3.11" and python_version < "4.0" and (platform_system == "Windows" or sys_platform == "win32") +cryptography==44.0.2 ; python_version >= "3.11" and python_version < "4.0" +dbus-python==1.3.2 ; python_version >= "3.11" and python_version < "4.0" +dnspython==2.7.0 ; python_version >= "3.11" and python_version < "4.0" +ecdsa==0.19.0 ; python_version >= "3.11" and python_version < "4.0" +email-validator==2.2.0 ; python_version >= "3.11" and python_version < "4.0" +fastapi-cli==0.0.7 ; python_version >= "3.11" and python_version < "4.0" +fastapi==0.115.11 ; python_version >= "3.11" and python_version < "4.0" +frozenlist==1.6.0 ; python_version >= "3.11" and python_version < "4.0" +h11==0.14.0 ; python_version >= "3.11" and python_version < "4.0" +httpcore==1.0.7 ; python_version >= "3.11" and python_version < "4.0" +httptools==0.6.4 ; python_version >= "3.11" and python_version < "4.0" +httpx==0.28.1 ; python_version >= "3.11" and python_version < "4.0" +idna==3.10 ; python_version >= "3.11" and python_version < "4.0" +jinja2==3.1.5 ; python_version >= "3.11" and python_version < "4.0" +mac-vendor-lookup==0.1.12 ; python_version >= "3.11" and python_version < "4.0" +manuf==1.1.5 ; python_version >= "3.11" and python_version < "4.0" +markdown-it-py==3.0.0 ; python_version >= "3.11" and python_version < "4.0" +markupsafe==3.0.2 ; python_version >= "3.11" and python_version < "4.0" +mdurl==0.1.2 ; python_version >= "3.11" and python_version < "4.0" +multidict==6.4.4 ; python_version >= "3.11" and python_version < "4.0" +netaddr==1.3.0 ; python_version >= "3.11" and python_version < "4.0" +netifaces==0.11.0 ; python_version >= "3.11" and python_version < "4.0" +paramiko==3.5.1 ; python_version >= "3.11" and python_version < "4.0" +passlib==1.7.4 ; python_version >= "3.11" and python_version < "4.0" +propcache==0.3.1 ; python_version >= "3.11" and python_version < "4.0" +pyasn1==0.4.8 ; python_version >= "3.11" and python_version < "4.0" +pycairo==1.27.0 ; python_version >= "3.11" and python_version < "4.0" +pycparser==2.22 ; python_version >= "3.11" and python_version < "4.0" +pydantic-core==2.27.1 ; python_version >= "3.11" and python_version < "4.0" +pydantic==2.10.3 ; python_version >= "3.11" and python_version < "4.0" +pydbus==0.6.0 ; python_version >= "3.11" and python_version < "4.0" +pygments==2.19.1 ; python_version >= "3.11" and python_version < "4.0" +pygobject==3.50.0 ; python_version >= "3.11" and python_version < "4.0" +pynacl==1.5.0 ; python_version >= "3.11" and python_version < "4.0" +python-dotenv==1.0.1 ; python_version >= "3.11" and python_version < "4.0" +python-jose==3.4.0 ; python_version >= "3.11" and python_version < "4.0" +python-multipart==0.0.20 ; python_version >= "3.11" and python_version < "4.0" +python-pam==2.0.2 ; python_version >= "3.11" and python_version < "4.0" +pywifi==1.1.12 ; python_version >= "3.11" and python_version < "4.0" +pyyaml==6.0.2 ; python_version >= "3.11" and python_version < "4.0" +rich-toolkit==0.13.2 ; python_version >= "3.11" and python_version < "4.0" +rich==13.9.4 ; python_version >= "3.11" and python_version < "4.0" +rsa==4.9 ; python_version >= "3.11" and python_version < "4.0" +scapy==2.6.1 ; python_version >= "3.11" and python_version < "4.0" +sdbus-networkmanager==2.0.0 ; python_version >= "3.11" and python_version < "4.0" +sdbus==0.13.0 ; python_version >= "3.11" and python_version < "4.0" +shellingham==1.5.4 ; python_version >= "3.11" and python_version < "4.0" +six==1.17.0 ; python_version >= "3.11" and python_version < "4.0" +sniffio==1.3.1 ; python_version >= "3.11" and python_version < "4.0" +starlette==0.41.3 ; python_version >= "3.11" and python_version < "4.0" +storage==0.0.4.3 ; python_version >= "3.11" and python_version < "4.0" +typer==0.15.2 ; python_version >= "3.11" and python_version < "4.0" +typing-extensions==4.12.2 ; python_version >= "3.11" and python_version < "4.0" +uuid==1.30 ; python_version >= "3.11" and python_version < "4.0" +uvicorn==0.32.1 ; python_version >= "3.11" and python_version < "4.0" +uvloop==0.21.0 ; python_version >= "3.11" and python_version < "4.0" and sys_platform != "win32" and sys_platform != "cygwin" and platform_python_implementation != "PyPy" +watchfiles==1.0.4 ; python_version >= "3.11" and python_version < "4.0" +websockets==14.1 ; python_version >= "3.11" and python_version < "4.0" +yarl==1.20.0 ; python_version >= "3.11" and python_version < "4.0" From 6179b4c5f964379f1444cea1a05bc61a97635b43 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 16:00:25 +0500 Subject: [PATCH 041/136] ci-cd-12 --- SRV/poetry.lock | 1147 +++++++++++++++++++++++++++++++++++++++++++- SRV/pyproject.toml | 1 + 2 files changed, 1146 insertions(+), 2 deletions(-) diff --git a/SRV/poetry.lock b/SRV/poetry.lock index 23c263f..6024f0f 100644 --- a/SRV/poetry.lock +++ b/SRV/poetry.lock @@ -201,6 +201,23 @@ docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphi tests = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\""] +[[package]] +name = "backports-tarfile" +version = "1.2.0" +description = "Backport of CPython tarfile module" +optional = false +python-versions = ">=3.8" +groups = ["main"] +markers = "python_version == \"3.11\"" +files = [ + {file = "backports.tarfile-1.2.0-py3-none-any.whl", hash = "sha256:77e284d754527b01fb1e6fa8a1afe577858ebe4e9dad8919e34c862cb399bc34"}, + {file = "backports_tarfile-1.2.0.tar.gz", hash = "sha256:d75e02c268746e1b8144c278978b6e98e85de6ad16f8e4b0844a154557eca991"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["jaraco.test", "pytest (!=8.0.*)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)"] + [[package]] name = "bcrypt" version = "4.3.0" @@ -266,6 +283,52 @@ files = [ tests = ["pytest (>=3.2.1,!=3.3.0)"] typecheck = ["mypy"] +[[package]] +name = "build" +version = "1.2.2.post1" +description = "A simple, correct Python build frontend" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "build-1.2.2.post1-py3-none-any.whl", hash = "sha256:1d61c0887fa860c01971625baae8bdd338e517b836a2f70dd1f7aa3a6b2fc5b5"}, + {file = "build-1.2.2.post1.tar.gz", hash = "sha256:b36993e92ca9375a219c99e606a122ff365a760a2d4bba0caa09bd5278b608b7"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "os_name == \"nt\""} +packaging = ">=19.1" +pyproject_hooks = "*" + +[package.extras] +docs = ["furo (>=2023.08.17)", "sphinx (>=7.0,<8.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)", "sphinx-issues (>=3.0.0)"] +test = ["build[uv,virtualenv]", "filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0) ; python_version < \"3.10\"", "setuptools (>=56.0.0) ; python_version == \"3.10\"", "setuptools (>=56.0.0) ; python_version == \"3.11\"", "setuptools (>=67.8.0) ; python_version >= \"3.12\"", "wheel (>=0.36.0)"] +typing = ["build[uv]", "importlib-metadata (>=5.1)", "mypy (>=1.9.0,<1.10.0)", "tomli", "typing-extensions (>=3.7.4.3)"] +uv = ["uv (>=0.1.18)"] +virtualenv = ["virtualenv (>=20.0.35)"] + +[[package]] +name = "cachecontrol" +version = "0.14.3" +description = "httplib2 caching for requests" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "cachecontrol-0.14.3-py3-none-any.whl", hash = "sha256:b35e44a3113f17d2a31c1e6b27b9de6d4405f84ae51baa8c1d3cc5b633010cae"}, + {file = "cachecontrol-0.14.3.tar.gz", hash = "sha256:73e7efec4b06b20d9267b441c1f733664f989fb8688391b670ca812d70795d11"}, +] + +[package.dependencies] +filelock = {version = ">=3.8.0", optional = true, markers = "extra == \"filecache\""} +msgpack = ">=0.5.2,<2.0.0" +requests = ">=2.16.0" + +[package.extras] +dev = ["CacheControl[filecache,redis]", "build", "cherrypy", "codespell[tomli]", "furo", "mypy", "pytest", "pytest-cov", "ruff", "sphinx", "sphinx-copybutton", "tox", "types-redis", "types-requests"] +filecache = ["filelock (>=3.8.0)"] +redis = ["redis (>=2.10.5)"] + [[package]] name = "certifi" version = "2025.1.31" @@ -358,6 +421,124 @@ files = [ [package.dependencies] pycparser = "*" +[[package]] +name = "charset-normalizer" +version = "3.4.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "charset_normalizer-3.4.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c48ed483eb946e6c04ccbe02c6b4d1d48e51944b6db70f697e089c193404941"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2d318c11350e10662026ad0eb71bb51c7812fc8590825304ae0bdd4ac283acd"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9cbfacf36cb0ec2897ce0ebc5d08ca44213af24265bd56eca54bee7923c48fd6"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18dd2e350387c87dabe711b86f83c9c78af772c748904d372ade190b5c7c9d4d"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8075c35cd58273fee266c58c0c9b670947c19df5fb98e7b66710e04ad4e9ff86"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5bf4545e3b962767e5c06fe1738f951f77d27967cb2caa64c28be7c4563e162c"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a6ab32f7210554a96cd9e33abe3ddd86732beeafc7a28e9955cdf22ffadbab0"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b33de11b92e9f75a2b545d6e9b6f37e398d86c3e9e9653c4864eb7e89c5773ef"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8755483f3c00d6c9a77f490c17e6ab0c8729e39e6390328e42521ef175380ae6"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:68a328e5f55ec37c57f19ebb1fdc56a248db2e3e9ad769919a58672958e8f366"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:21b2899062867b0e1fde9b724f8aecb1af14f2778d69aacd1a5a1853a597a5db"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-win32.whl", hash = "sha256:e8082b26888e2f8b36a042a58307d5b917ef2b1cacab921ad3323ef91901c71a"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:f69a27e45c43520f5487f27627059b64aaf160415589230992cec34c5e18a509"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:be1e352acbe3c78727a16a455126d9ff83ea2dfdcbc83148d2982305a04714c2"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa88ca0b1932e93f2d961bf3addbb2db902198dca337d88c89e1559e066e7645"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d524ba3f1581b35c03cb42beebab4a13e6cdad7b36246bd22541fa585a56cccd"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28a1005facc94196e1fb3e82a3d442a9d9110b8434fc1ded7a24a2983c9888d8"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdb20a30fe1175ecabed17cbf7812f7b804b8a315a25f24678bcdf120a90077f"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f5d9ed7f254402c9e7d35d2f5972c9bbea9040e99cd2861bd77dc68263277c7"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:efd387a49825780ff861998cd959767800d54f8308936b21025326de4b5a42b9"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f0aa37f3c979cf2546b73e8222bbfa3dc07a641585340179d768068e3455e544"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e70e990b2137b29dc5564715de1e12701815dacc1d056308e2b17e9095372a82"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0c8c57f84ccfc871a48a47321cfa49ae1df56cd1d965a09abe84066f6853b9c0"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6b66f92b17849b85cad91259efc341dce9c1af48e2173bf38a85c6329f1033e5"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-win32.whl", hash = "sha256:daac4765328a919a805fa5e2720f3e94767abd632ae410a9062dff5412bae65a"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53efc7c7cee4c1e70661e2e112ca46a575f90ed9ae3fef200f2a25e954f4b28"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-win32.whl", hash = "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cad5f45b3146325bb38d6855642f6fd609c3f7cad4dbaf75549bf3b904d3184"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2680962a4848b3c4f155dc2ee64505a9c57186d0d56b43123b17ca3de18f0fa"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:36b31da18b8890a76ec181c3cf44326bf2c48e36d393ca1b72b3f484113ea344"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4074c5a429281bf056ddd4c5d3b740ebca4d43ffffe2ef4bf4d2d05114299da"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9e36a97bee9b86ef9a1cf7bb96747eb7a15c2f22bdb5b516434b00f2a599f02"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:1b1bde144d98e446b056ef98e59c256e9294f6b74d7af6846bf5ffdafd687a7d"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:915f3849a011c1f593ab99092f3cecfcb4d65d8feb4a64cf1bf2d22074dc0ec4"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:fb707f3e15060adf5b7ada797624a6c6e0138e2a26baa089df64c68ee98e040f"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:25a23ea5c7edc53e0f29bae2c44fcb5a1aa10591aae107f2a2b2583a9c5cbc64"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:770cab594ecf99ae64c236bc9ee3439c3f46be49796e265ce0cc8bc17b10294f"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-win32.whl", hash = "sha256:6a0289e4589e8bdfef02a80478f1dfcb14f0ab696b5a00e1f4b8a14a307a3c58"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6fc1f5b51fa4cecaa18f2bd7a003f3dd039dd615cd69a2afd6d3b19aed6775f2"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:76af085e67e56c8816c3ccf256ebd136def2ed9654525348cfa744b6802b69eb"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e45ba65510e2647721e35323d6ef54c7974959f6081b58d4ef5d87c60c84919a"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:046595208aae0120559a67693ecc65dd75d46f7bf687f159127046628178dc45"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75d10d37a47afee94919c4fab4c22b9bc2a8bf7d4f46f87363bcf0573f3ff4f5"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6333b3aa5a12c26b2a4d4e7335a28f1475e0e5e17d69d55141ee3cab736f66d1"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8323a9b031aa0393768b87f04b4164a40037fb2a3c11ac06a03ffecd3618027"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:24498ba8ed6c2e0b56d4acbf83f2d989720a93b41d712ebd4f4979660db4417b"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:844da2b5728b5ce0e32d863af26f32b5ce61bc4273a9c720a9f3aa9df73b1455"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:65c981bdbd3f57670af8b59777cbfae75364b483fa8a9f420f08094531d54a01"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:3c21d4fca343c805a52c0c78edc01e3477f6dd1ad7c47653241cf2a206d4fc58"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:dc7039885fa1baf9be153a0626e337aa7ec8bf96b0128605fb0d77788ddc1681"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-win32.whl", hash = "sha256:8272b73e1c5603666618805fe821edba66892e2870058c94c53147602eab29c7"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:70f7172939fdf8790425ba31915bfbe8335030f05b9913d7ae00a87d4395620a"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:005fa3432484527f9732ebd315da8da8001593e2cf46a3d817669f062c3d9ed4"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e92fca20c46e9f5e1bb485887d074918b13543b1c2a1185e69bb8d17ab6236a7"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50bf98d5e563b83cc29471fa114366e6806bc06bc7a25fd59641e41445327836"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:721c76e84fe669be19c5791da68232ca2e05ba5185575086e384352e2c309597"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d8fd25b7f4675d0c47cf95b594d4e7b158aca33b76aa63d07186e13c0e0ab7"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3daeac64d5b371dea99714f08ffc2c208522ec6b06fbc7866a450dd446f5c0f"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dccab8d5fa1ef9bfba0590ecf4d46df048d18ffe3eec01eeb73a42e0d9e7a8ba"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:aaf27faa992bfee0264dc1f03f4c75e9fcdda66a519db6b957a3f826e285cf12"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:eb30abc20df9ab0814b5a2524f23d75dcf83cde762c161917a2b4b7b55b1e518"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c72fbbe68c6f32f251bdc08b8611c7b3060612236e960ef848e0a517ddbe76c5"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:982bb1e8b4ffda883b3d0a521e23abcd6fd17418f6d2c4118d257a10199c0ce3"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-win32.whl", hash = "sha256:43e0933a0eff183ee85833f341ec567c0980dae57c464d8a508e1b2ceb336471"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:d11b54acf878eef558599658b0ffca78138c8c3655cf4f3a4a673c437e67732e"}, + {file = "charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0"}, + {file = "charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63"}, +] + +[[package]] +name = "cleo" +version = "2.1.0" +description = "Cleo allows you to create beautiful and testable command-line interfaces." +optional = false +python-versions = ">=3.7,<4.0" +groups = ["main"] +files = [ + {file = "cleo-2.1.0-py3-none-any.whl", hash = "sha256:4a31bd4dd45695a64ee3c4758f583f134267c2bc518d8ae9a29cf237d009b07e"}, + {file = "cleo-2.1.0.tar.gz", hash = "sha256:0b2c880b5d13660a7ea651001fb4acb527696c01f15c9ee650f377aa543fd523"}, +] + +[package.dependencies] +crashtest = ">=0.4.1,<0.5.0" +rapidfuzz = ">=3.0.0,<4.0.0" + [[package]] name = "click" version = "8.1.7" @@ -380,12 +561,24 @@ description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" groups = ["main"] -markers = "platform_system == \"Windows\" or sys_platform == \"win32\"" +markers = "platform_system == \"Windows\" or sys_platform == \"win32\" or os_name == \"nt\"" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "crashtest" +version = "0.4.1" +description = "Manage Python errors with ease" +optional = false +python-versions = ">=3.7,<4.0" +groups = ["main"] +files = [ + {file = "crashtest-0.4.1-py3-none-any.whl", hash = "sha256:8d23eac5fa660409f57472e3851dab7ac18aba459a8d19cbbba86d3d5aecd2a5"}, + {file = "crashtest-0.4.1.tar.gz", hash = "sha256:80d7b1f316ebfbd429f648076d6275c877ba30ba48979de4191714a75266f0ce"}, +] + [[package]] name = "cryptography" version = "44.0.2" @@ -459,6 +652,18 @@ files = [ doc = ["sphinx", "sphinx_rtd_theme"] test = ["tap.py"] +[[package]] +name = "distlib" +version = "0.3.9" +description = "Distribution utilities" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, + {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, +] + [[package]] name = "dnspython" version = "2.7.0" @@ -480,6 +685,73 @@ idna = ["idna (>=3.7)"] trio = ["trio (>=0.23)"] wmi = ["wmi (>=1.5.1)"] +[[package]] +name = "dulwich" +version = "0.22.8" +description = "Python Git Library" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "dulwich-0.22.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:546176d18b8cc0a492b0f23f07411e38686024cffa7e9d097ae20512a2e57127"}, + {file = "dulwich-0.22.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d2434dd72b2ae09b653c9cfe6764a03c25cfbd99fbbb7c426f0478f6fb1100f"}, + {file = "dulwich-0.22.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe8318bc0921d42e3e69f03716f983a301b5ee4c8dc23c7f2c5bbb28581257a9"}, + {file = "dulwich-0.22.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7a0f96a2a87f3b4f7feae79d2ac6b94107d6b7d827ac08f2f331b88c8f597a1"}, + {file = "dulwich-0.22.8-cp310-cp310-win32.whl", hash = "sha256:432a37b25733202897b8d67cdd641688444d980167c356ef4e4dd15a17a39a24"}, + {file = "dulwich-0.22.8-cp310-cp310-win_amd64.whl", hash = "sha256:f3a15e58dac8b8a76073ddca34e014f66f3672a5540a99d49ef6a9c09ab21285"}, + {file = "dulwich-0.22.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0852edc51cff4f4f62976bdaa1d82f6ef248356c681c764c0feb699bc17d5782"}, + {file = "dulwich-0.22.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:826aae8b64ac1a12321d6b272fc13934d8f62804fda2bc6ae46f93f4380798eb"}, + {file = "dulwich-0.22.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7ae726f923057d36cdbb9f4fb7da0d0903751435934648b13f1b851f0e38ea1"}, + {file = "dulwich-0.22.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6987d753227f55cf75ba29a8dab69d1d83308ce483d7a8c6d223086f7a42e125"}, + {file = "dulwich-0.22.8-cp311-cp311-win32.whl", hash = "sha256:7757b4a2aad64c6f1920082fc1fccf4da25c3923a0ae7b242c08d06861dae6e1"}, + {file = "dulwich-0.22.8-cp311-cp311-win_amd64.whl", hash = "sha256:12b243b7e912011c7225dc67480c313ac8d2990744789b876016fb593f6f3e19"}, + {file = "dulwich-0.22.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d81697f74f50f008bb221ab5045595f8a3b87c0de2c86aa55be42ba97421f3cd"}, + {file = "dulwich-0.22.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bff1da8e2e6a607c3cb45f5c2e652739589fe891245e1d5b770330cdecbde41"}, + {file = "dulwich-0.22.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9969099e15b939d3936f8bee8459eaef7ef5a86cd6173393a17fe28ca3d38aff"}, + {file = "dulwich-0.22.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:017152c51b9a613f0698db28c67cf3e0a89392d28050dbf4f4ac3f657ea4c0dc"}, + {file = "dulwich-0.22.8-cp312-cp312-win32.whl", hash = "sha256:ee70e8bb8798b503f81b53f7a103cb869c8e89141db9005909f79ab1506e26e9"}, + {file = "dulwich-0.22.8-cp312-cp312-win_amd64.whl", hash = "sha256:dc89c6f14dcdcbfee200b0557c59ae243835e42720be143526d834d0e53ed3af"}, + {file = "dulwich-0.22.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbade3342376be1cd2409539fe1b901d2d57a531106bbae204da921ef4456a74"}, + {file = "dulwich-0.22.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71420ffb6deebc59b2ce875e63d814509f9c1dc89c76db962d547aebf15670c7"}, + {file = "dulwich-0.22.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a626adbfac44646a125618266a24133763bdc992bf8bd0702910d67e6b994443"}, + {file = "dulwich-0.22.8-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f1476c9c4e4ede95714d06c4831883a26680e37b040b8b6230f506e5ba39f51"}, + {file = "dulwich-0.22.8-cp313-cp313-win32.whl", hash = "sha256:b2b31913932bb5bd41658dd398b33b1a2d4d34825123ad54e40912cfdfe60003"}, + {file = "dulwich-0.22.8-cp313-cp313-win_amd64.whl", hash = "sha256:7a44e5a61a7989aca1e301d39cfb62ad2f8853368682f524d6e878b4115d823d"}, + {file = "dulwich-0.22.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f9cd0c67fb44a38358b9fcabee948bf11044ef6ce7a129e50962f54c176d084e"}, + {file = "dulwich-0.22.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b79b94726c3f4a9e5a830c649376fd0963236e73142a4290bac6bc9fc9cb120"}, + {file = "dulwich-0.22.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16bbe483d663944972e22d64e1f191201123c3b5580fbdaac6a4f66bfaa4fc11"}, + {file = "dulwich-0.22.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e02d403af23d93dc1f96eb2408e25efd50046e38590a88c86fa4002adc9849b0"}, + {file = "dulwich-0.22.8-cp39-cp39-win32.whl", hash = "sha256:8bdd9543a77fb01be704377f5e634b71f955fec64caa4a493dc3bfb98e3a986e"}, + {file = "dulwich-0.22.8-cp39-cp39-win_amd64.whl", hash = "sha256:3b6757c6b3ba98212b854a766a4157b9cb79a06f4e1b06b46dec4bd834945b8e"}, + {file = "dulwich-0.22.8-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7bb18fa09daa1586c1040b3e2777d38d4212a5cdbe47d384ba66a1ac336fcc4c"}, + {file = "dulwich-0.22.8-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b2fda8e87907ed304d4a5962aea0338366144df0df60f950b8f7f125871707f"}, + {file = "dulwich-0.22.8-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1748cd573a0aee4d530bc223a23ccb8bb5b319645931a37bd1cfb68933b720c1"}, + {file = "dulwich-0.22.8-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a631b2309feb9a9631eabd896612ba36532e3ffedccace57f183bb868d7afc06"}, + {file = "dulwich-0.22.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:00e7d9a3d324f9e0a1b27880eec0e8e276ff76519621b66c1a429ca9eb3f5a8d"}, + {file = "dulwich-0.22.8-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f8aa3de93201f9e3e40198725389aa9554a4ee3318a865f96a8e9bc9080f0b25"}, + {file = "dulwich-0.22.8-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e8da9dd8135884975f5be0563ede02179240250e11f11942801ae31ac293f37"}, + {file = "dulwich-0.22.8-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4fc5ce2435fb3abdf76f1acabe48f2e4b3f7428232cadaef9daaf50ea7fa30ee"}, + {file = "dulwich-0.22.8-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:982b21cc3100d959232cadb3da0a478bd549814dd937104ea50f43694ec27153"}, + {file = "dulwich-0.22.8-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6bde2b13a05cc0ec2ecd4597a99896663544c40af1466121f4d046119b874ce3"}, + {file = "dulwich-0.22.8-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:6d446cb7d272a151934ad4b48ba691f32486d5267cf2de04ee3b5e05fc865326"}, + {file = "dulwich-0.22.8-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f6338e6cf95cd76a0191b3637dc3caed1f988ae84d8e75f876d5cd75a8dd81a"}, + {file = "dulwich-0.22.8-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e004fc532ea262f2d5f375068101ca4792becb9d4aa663b050f5ac31fda0bb5c"}, + {file = "dulwich-0.22.8-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6bfdbc6fa477dee00d04e22d43a51571cd820cfaaaa886f0f155b8e29b3e3d45"}, + {file = "dulwich-0.22.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ae900c8e573f79d714c1d22b02cdadd50b64286dd7203028f0200f82089e4950"}, + {file = "dulwich-0.22.8-py3-none-any.whl", hash = "sha256:ffc7a02e62b72884de58baaa3b898b7f6427893e79b1289ffa075092efe59181"}, + {file = "dulwich-0.22.8.tar.gz", hash = "sha256:701547310415de300269331abe29cb5717aa1ea377af826bf513d0adfb1c209b"}, +] + +[package.dependencies] +urllib3 = ">=1.25" + +[package.extras] +dev = ["mypy (==1.15.0)", "ruff (==0.9.7)"] +fastimport = ["fastimport"] +https = ["urllib3 (>=1.24.1)"] +paramiko = ["paramiko"] +pgp = ["gpg"] + [[package]] name = "ecdsa" version = "0.19.0" @@ -562,6 +834,53 @@ uvicorn = {version = ">=0.15.0", extras = ["standard"]} [package.extras] standard = ["uvicorn[standard] (>=0.15.0)"] +[[package]] +name = "fastjsonschema" +version = "2.21.1" +description = "Fastest Python implementation of JSON schema" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "fastjsonschema-2.21.1-py3-none-any.whl", hash = "sha256:c9e5b7e908310918cf494a434eeb31384dd84a98b57a30bcb1f535015b554667"}, + {file = "fastjsonschema-2.21.1.tar.gz", hash = "sha256:794d4f0a58f848961ba16af7b9c85a3e88cd360df008c59aac6fc5ae9323b5d4"}, +] + +[package.extras] +devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] + +[[package]] +name = "filelock" +version = "3.18.0" +description = "A platform independent file lock." +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de"}, + {file = "filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2"}, +] + +[package.extras] +docs = ["furo (>=2024.8.6)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.6.10)", "diff-cover (>=9.2.1)", "pytest (>=8.3.4)", "pytest-asyncio (>=0.25.2)", "pytest-cov (>=6)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.28.1)"] +typing = ["typing-extensions (>=4.12.2) ; python_version < \"3.11\""] + +[[package]] +name = "findpython" +version = "0.6.3" +description = "A utility to find python versions on your system" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "findpython-0.6.3-py3-none-any.whl", hash = "sha256:a85bb589b559cdf1b87227cc233736eb7cad894b9e68021ee498850611939ebc"}, + {file = "findpython-0.6.3.tar.gz", hash = "sha256:5863ea55556d8aadc693481a14ac4f3624952719efc1c5591abb0b4a9e965c94"}, +] + +[package.dependencies] +packaging = ">=20" + [[package]] name = "frozenlist" version = "1.6.0" @@ -806,6 +1125,121 @@ files = [ [package.extras] all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] +[[package]] +name = "importlib-metadata" +version = "8.7.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.9" +groups = ["main"] +markers = "python_version == \"3.11\"" +files = [ + {file = "importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd"}, + {file = "importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000"}, +] + +[package.dependencies] +zipp = ">=3.20" + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +perf = ["ipython"] +test = ["flufl.flake8", "importlib_resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] +type = ["pytest-mypy"] + +[[package]] +name = "installer" +version = "0.7.0" +description = "A library for installing Python wheels." +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "installer-0.7.0-py3-none-any.whl", hash = "sha256:05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53"}, + {file = "installer-0.7.0.tar.gz", hash = "sha256:a26d3e3116289bb08216e0d0f7d925fcef0b0194eedfa0c944bcaaa106c4b631"}, +] + +[[package]] +name = "jaraco-classes" +version = "3.4.0" +description = "Utility functions for Python class constructs" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "jaraco.classes-3.4.0-py3-none-any.whl", hash = "sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790"}, + {file = "jaraco.classes-3.4.0.tar.gz", hash = "sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd"}, +] + +[package.dependencies] +more-itertools = "*" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)"] + +[[package]] +name = "jaraco-context" +version = "6.0.1" +description = "Useful decorators and context managers" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "jaraco.context-6.0.1-py3-none-any.whl", hash = "sha256:f797fc481b490edb305122c9181830a3a5b76d84ef6d1aef2fb9b47ab956f9e4"}, + {file = "jaraco_context-6.0.1.tar.gz", hash = "sha256:9bae4ea555cf0b14938dc0aee7c9f32ed303aa20a3b73e7dc80111628792d1b3"}, +] + +[package.dependencies] +"backports.tarfile" = {version = "*", markers = "python_version < \"3.12\""} + +[package.extras] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["portend", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] + +[[package]] +name = "jaraco-functools" +version = "4.2.1" +description = "Functools like those found in stdlib" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "jaraco_functools-4.2.1-py3-none-any.whl", hash = "sha256:590486285803805f4b1f99c60ca9e94ed348d4added84b74c7a12885561e524e"}, + {file = "jaraco_functools-4.2.1.tar.gz", hash = "sha256:be634abfccabce56fa3053f8c7ebe37b682683a4ee7793670ced17bab0087353"}, +] + +[package.dependencies] +more_itertools = "*" + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["jaraco.classes", "pytest (>=6,!=8.1.*)"] +type = ["pytest-mypy"] + +[[package]] +name = "jeepney" +version = "0.9.0" +description = "Low-level, pure Python DBus protocol wrapper." +optional = false +python-versions = ">=3.7" +groups = ["main"] +markers = "sys_platform == \"linux\"" +files = [ + {file = "jeepney-0.9.0-py3-none-any.whl", hash = "sha256:97e5714520c16fc0a45695e5365a2e11b81ea79bba796e26f9f1d178cb182683"}, + {file = "jeepney-0.9.0.tar.gz", hash = "sha256:cf0e9e845622b81e4a28df94c40345400256ec608d0e55bb8a3feaa9163f5732"}, +] + +[package.extras] +test = ["async-timeout ; python_version < \"3.11\"", "pytest", "pytest-asyncio (>=0.17)", "pytest-trio", "testpath", "trio"] +trio = ["trio"] + [[package]] name = "jinja2" version = "3.1.5" @@ -824,6 +1258,36 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "keyring" +version = "25.6.0" +description = "Store and access your passwords safely." +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "keyring-25.6.0-py3-none-any.whl", hash = "sha256:552a3f7af126ece7ed5c89753650eec89c7eaae8617d0aa4d9ad2b75111266bd"}, + {file = "keyring-25.6.0.tar.gz", hash = "sha256:0b39998aa941431eb3d9b0d4b2460bc773b9df6fed7621c2dfb291a7e0187a66"}, +] + +[package.dependencies] +importlib_metadata = {version = ">=4.11.4", markers = "python_version < \"3.12\""} +"jaraco.classes" = "*" +"jaraco.context" = "*" +"jaraco.functools" = "*" +jeepney = {version = ">=0.4.2", markers = "sys_platform == \"linux\""} +pywin32-ctypes = {version = ">=0.2.0", markers = "sys_platform == \"win32\""} +SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +completion = ["shtab (>=1.1.0)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["pyfakefs", "pytest (>=6,!=8.1.*)"] +type = ["pygobject-stubs", "pytest-mypy", "shtab", "types-pywin32"] + [[package]] name = "mac-vendor-lookup" version = "0.1.12" @@ -963,6 +1427,87 @@ files = [ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] +[[package]] +name = "more-itertools" +version = "10.7.0" +description = "More routines for operating on iterables, beyond itertools" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "more_itertools-10.7.0-py3-none-any.whl", hash = "sha256:d43980384673cb07d2f7d2d918c616b30c659c089ee23953f601d6609c67510e"}, + {file = "more_itertools-10.7.0.tar.gz", hash = "sha256:9fddd5403be01a94b204faadcff459ec3568cf110265d3c54323e1e866ad29d3"}, +] + +[[package]] +name = "msgpack" +version = "1.1.1" +description = "MessagePack serializer" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "msgpack-1.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:353b6fc0c36fde68b661a12949d7d49f8f51ff5fa019c1e47c87c4ff34b080ed"}, + {file = "msgpack-1.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:79c408fcf76a958491b4e3b103d1c417044544b68e96d06432a189b43d1215c8"}, + {file = "msgpack-1.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78426096939c2c7482bf31ef15ca219a9e24460289c00dd0b94411040bb73ad2"}, + {file = "msgpack-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b17ba27727a36cb73aabacaa44b13090feb88a01d012c0f4be70c00f75048b4"}, + {file = "msgpack-1.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a17ac1ea6ec3c7687d70201cfda3b1e8061466f28f686c24f627cae4ea8efd0"}, + {file = "msgpack-1.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:88d1e966c9235c1d4e2afac21ca83933ba59537e2e2727a999bf3f515ca2af26"}, + {file = "msgpack-1.1.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f6d58656842e1b2ddbe07f43f56b10a60f2ba5826164910968f5933e5178af75"}, + {file = "msgpack-1.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:96decdfc4adcbc087f5ea7ebdcfd3dee9a13358cae6e81d54be962efc38f6338"}, + {file = "msgpack-1.1.1-cp310-cp310-win32.whl", hash = "sha256:6640fd979ca9a212e4bcdf6eb74051ade2c690b862b679bfcb60ae46e6dc4bfd"}, + {file = "msgpack-1.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:8b65b53204fe1bd037c40c4148d00ef918eb2108d24c9aaa20bc31f9810ce0a8"}, + {file = "msgpack-1.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:71ef05c1726884e44f8b1d1773604ab5d4d17729d8491403a705e649116c9558"}, + {file = "msgpack-1.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:36043272c6aede309d29d56851f8841ba907a1a3d04435e43e8a19928e243c1d"}, + {file = "msgpack-1.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a32747b1b39c3ac27d0670122b57e6e57f28eefb725e0b625618d1b59bf9d1e0"}, + {file = "msgpack-1.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a8b10fdb84a43e50d38057b06901ec9da52baac6983d3f709d8507f3889d43f"}, + {file = "msgpack-1.1.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba0c325c3f485dc54ec298d8b024e134acf07c10d494ffa24373bea729acf704"}, + {file = "msgpack-1.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:88daaf7d146e48ec71212ce21109b66e06a98e5e44dca47d853cbfe171d6c8d2"}, + {file = "msgpack-1.1.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d8b55ea20dc59b181d3f47103f113e6f28a5e1c89fd5b67b9140edb442ab67f2"}, + {file = "msgpack-1.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4a28e8072ae9779f20427af07f53bbb8b4aa81151054e882aee333b158da8752"}, + {file = "msgpack-1.1.1-cp311-cp311-win32.whl", hash = "sha256:7da8831f9a0fdb526621ba09a281fadc58ea12701bc709e7b8cbc362feabc295"}, + {file = "msgpack-1.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:5fd1b58e1431008a57247d6e7cc4faa41c3607e8e7d4aaf81f7c29ea013cb458"}, + {file = "msgpack-1.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ae497b11f4c21558d95de9f64fff7053544f4d1a17731c866143ed6bb4591238"}, + {file = "msgpack-1.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:33be9ab121df9b6b461ff91baac6f2731f83d9b27ed948c5b9d1978ae28bf157"}, + {file = "msgpack-1.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f64ae8fe7ffba251fecb8408540c34ee9df1c26674c50c4544d72dbf792e5ce"}, + {file = "msgpack-1.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a494554874691720ba5891c9b0b39474ba43ffb1aaf32a5dac874effb1619e1a"}, + {file = "msgpack-1.1.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb643284ab0ed26f6957d969fe0dd8bb17beb567beb8998140b5e38a90974f6c"}, + {file = "msgpack-1.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d275a9e3c81b1093c060c3837e580c37f47c51eca031f7b5fb76f7b8470f5f9b"}, + {file = "msgpack-1.1.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4fd6b577e4541676e0cc9ddc1709d25014d3ad9a66caa19962c4f5de30fc09ef"}, + {file = "msgpack-1.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb29aaa613c0a1c40d1af111abf025f1732cab333f96f285d6a93b934738a68a"}, + {file = "msgpack-1.1.1-cp312-cp312-win32.whl", hash = "sha256:870b9a626280c86cff9c576ec0d9cbcc54a1e5ebda9cd26dab12baf41fee218c"}, + {file = "msgpack-1.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:5692095123007180dca3e788bb4c399cc26626da51629a31d40207cb262e67f4"}, + {file = "msgpack-1.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3765afa6bd4832fc11c3749be4ba4b69a0e8d7b728f78e68120a157a4c5d41f0"}, + {file = "msgpack-1.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8ddb2bcfd1a8b9e431c8d6f4f7db0773084e107730ecf3472f1dfe9ad583f3d9"}, + {file = "msgpack-1.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:196a736f0526a03653d829d7d4c5500a97eea3648aebfd4b6743875f28aa2af8"}, + {file = "msgpack-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d592d06e3cc2f537ceeeb23d38799c6ad83255289bb84c2e5792e5a8dea268a"}, + {file = "msgpack-1.1.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4df2311b0ce24f06ba253fda361f938dfecd7b961576f9be3f3fbd60e87130ac"}, + {file = "msgpack-1.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e4141c5a32b5e37905b5940aacbc59739f036930367d7acce7a64e4dec1f5e0b"}, + {file = "msgpack-1.1.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b1ce7f41670c5a69e1389420436f41385b1aa2504c3b0c30620764b15dded2e7"}, + {file = "msgpack-1.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4147151acabb9caed4e474c3344181e91ff7a388b888f1e19ea04f7e73dc7ad5"}, + {file = "msgpack-1.1.1-cp313-cp313-win32.whl", hash = "sha256:500e85823a27d6d9bba1d057c871b4210c1dd6fb01fbb764e37e4e8847376323"}, + {file = "msgpack-1.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:6d489fba546295983abd142812bda76b57e33d0b9f5d5b71c09a583285506f69"}, + {file = "msgpack-1.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bba1be28247e68994355e028dcd668316db30c1f758d3241a7b903ac78dcd285"}, + {file = "msgpack-1.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8f93dcddb243159c9e4109c9750ba5b335ab8d48d9522c5308cd05d7e3ce600"}, + {file = "msgpack-1.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fbbc0b906a24038c9958a1ba7ae0918ad35b06cb449d398b76a7d08470b0ed9"}, + {file = "msgpack-1.1.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:61e35a55a546a1690d9d09effaa436c25ae6130573b6ee9829c37ef0f18d5e78"}, + {file = "msgpack-1.1.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:1abfc6e949b352dadf4bce0eb78023212ec5ac42f6abfd469ce91d783c149c2a"}, + {file = "msgpack-1.1.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:996f2609ddf0142daba4cefd767d6db26958aac8439ee41db9cc0db9f4c4c3a6"}, + {file = "msgpack-1.1.1-cp38-cp38-win32.whl", hash = "sha256:4d3237b224b930d58e9d83c81c0dba7aacc20fcc2f89c1e5423aa0529a4cd142"}, + {file = "msgpack-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:da8f41e602574ece93dbbda1fab24650d6bf2a24089f9e9dbb4f5730ec1e58ad"}, + {file = "msgpack-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5be6b6bc52fad84d010cb45433720327ce886009d862f46b26d4d154001994b"}, + {file = "msgpack-1.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3a89cd8c087ea67e64844287ea52888239cbd2940884eafd2dcd25754fb72232"}, + {file = "msgpack-1.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d75f3807a9900a7d575d8d6674a3a47e9f227e8716256f35bc6f03fc597ffbf"}, + {file = "msgpack-1.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d182dac0221eb8faef2e6f44701812b467c02674a322c739355c39e94730cdbf"}, + {file = "msgpack-1.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b13fe0fb4aac1aa5320cd693b297fe6fdef0e7bea5518cbc2dd5299f873ae90"}, + {file = "msgpack-1.1.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:435807eeb1bc791ceb3247d13c79868deb22184e1fc4224808750f0d7d1affc1"}, + {file = "msgpack-1.1.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4835d17af722609a45e16037bb1d4d78b7bdf19d6c0128116d178956618c4e88"}, + {file = "msgpack-1.1.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a8ef6e342c137888ebbfb233e02b8fbd689bb5b5fcc59b34711ac47ebd504478"}, + {file = "msgpack-1.1.1-cp39-cp39-win32.whl", hash = "sha256:61abccf9de335d9efd149e2fff97ed5974f2481b3353772e8e2dd3402ba2bd57"}, + {file = "msgpack-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:40eae974c873b2992fd36424a5d9407f93e97656d999f43fca9d29f820899084"}, + {file = "msgpack-1.1.1.tar.gz", hash = "sha256:77b79ce34a2bdab2594f490c8e80dd62a02d650b91a75159a63ec413b8d104cd"}, +] + [[package]] name = "multidict" version = "6.4.4" @@ -1132,6 +1677,18 @@ files = [ {file = "netifaces-0.11.0.tar.gz", hash = "sha256:043a79146eb2907edf439899f262b3dfe41717d34124298ed281139a8b93ca32"}, ] +[[package]] +name = "packaging" +version = "25.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, + {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, +] + [[package]] name = "paramiko" version = "3.5.1" @@ -1175,6 +1732,122 @@ bcrypt = ["bcrypt (>=3.1.0)"] build-docs = ["cloud-sptheme (>=1.10.1)", "sphinx (>=1.6)", "sphinxcontrib-fulltoc (>=1.2.0)"] totp = ["cryptography"] +[[package]] +name = "pbs-installer" +version = "2025.6.12" +description = "Installer for Python Build Standalone" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "pbs_installer-2025.6.12-py3-none-any.whl", hash = "sha256:438e75de131a2114ac5e86156fc51da7dadd6734844de329ad162cca63709297"}, + {file = "pbs_installer-2025.6.12.tar.gz", hash = "sha256:ae2d3990848652dca699a680b00ea8e19b970cb6172967cb00539bfeed5a7465"}, +] + +[package.dependencies] +httpx = {version = ">=0.27.0,<1", optional = true, markers = "extra == \"download\""} +zstandard = {version = ">=0.21.0", optional = true, markers = "extra == \"install\""} + +[package.extras] +all = ["pbs-installer[download,install]"] +download = ["httpx (>=0.27.0,<1)"] +install = ["zstandard (>=0.21.0)"] + +[[package]] +name = "pkginfo" +version = "1.12.1.2" +description = "Query metadata from sdists / bdists / installed packages." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "pkginfo-1.12.1.2-py3-none-any.whl", hash = "sha256:c783ac885519cab2c34927ccfa6bf64b5a704d7c69afaea583dd9b7afe969343"}, + {file = "pkginfo-1.12.1.2.tar.gz", hash = "sha256:5cd957824ac36f140260964eba3c6be6442a8359b8c48f4adf90210f33a04b7b"}, +] + +[package.extras] +testing = ["pytest", "pytest-cov", "wheel"] + +[[package]] +name = "platformdirs" +version = "4.3.8" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4"}, + {file = "platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc"}, +] + +[package.extras] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.4)", "pytest-cov (>=6)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.14.1)"] + +[[package]] +name = "poetry" +version = "2.1.3" +description = "Python dependency management and packaging made easy." +optional = false +python-versions = "<4.0,>=3.9" +groups = ["main"] +files = [ + {file = "poetry-2.1.3-py3-none-any.whl", hash = "sha256:7054d3f97ccce7f31961ead16250407c4577bfe57e2037a190ae2913fc40a20c"}, + {file = "poetry-2.1.3.tar.gz", hash = "sha256:f2c9bd6790b19475976d88ea4553bcc3533c0dc73f740edc4fffe9e2add50594"}, +] + +[package.dependencies] +build = ">=1.2.1,<2.0.0" +cachecontrol = {version = ">=0.14.0,<0.15.0", extras = ["filecache"]} +cleo = ">=2.1.0,<3.0.0" +dulwich = ">=0.22.6,<0.23.0" +fastjsonschema = ">=2.18.0,<3.0.0" +findpython = ">=0.6.2,<0.7.0" +installer = ">=0.7.0,<0.8.0" +keyring = ">=25.1.0,<26.0.0" +packaging = ">=24.0" +pbs-installer = {version = ">=2025.1.6,<2026.0.0", extras = ["download", "install"]} +pkginfo = ">=1.12,<2.0" +platformdirs = ">=3.0.0,<5" +poetry-core = "2.1.3" +pyproject-hooks = ">=1.0.0,<2.0.0" +requests = ">=2.26,<3.0" +requests-toolbelt = ">=1.0.0,<2.0.0" +shellingham = ">=1.5,<2.0" +tomlkit = ">=0.11.4,<1.0.0" +trove-classifiers = ">=2022.5.19" +virtualenv = ">=20.26.6,<21.0.0" +xattr = {version = ">=1.0.0,<2.0.0", markers = "sys_platform == \"darwin\""} + +[[package]] +name = "poetry-core" +version = "2.1.3" +description = "Poetry PEP 517 Build Backend" +optional = false +python-versions = "<4.0,>=3.9" +groups = ["main"] +files = [ + {file = "poetry_core-2.1.3-py3-none-any.whl", hash = "sha256:2c704f05016698a54ca1d327f46ce2426d72eaca6ff614132c8477c292266771"}, + {file = "poetry_core-2.1.3.tar.gz", hash = "sha256:0522a015477ed622c89aad56a477a57813cace0c8e7ff2a2906b7ef4a2e296a4"}, +] + +[[package]] +name = "poetry-plugin-export" +version = "1.9.0" +description = "Poetry plugin to export the dependencies to various formats" +optional = false +python-versions = "<4.0,>=3.9" +groups = ["main"] +files = [ + {file = "poetry_plugin_export-1.9.0-py3-none-any.whl", hash = "sha256:e2621dd8c260dd705a8227f076075246a7ff5c697e18ddb90ff68081f47ee642"}, + {file = "poetry_plugin_export-1.9.0.tar.gz", hash = "sha256:6fc8755cfac93c74752f85510b171983e2e47d782d4ab5be4ffc4f6945be7967"}, +] + +[package.dependencies] +poetry = ">=2.0.0,<3.0.0" +poetry-core = ">=1.7.0,<3.0.0" + [[package]] name = "propcache" version = "0.3.1" @@ -1495,6 +2168,18 @@ cffi = ">=1.4.1" docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] +[[package]] +name = "pyproject-hooks" +version = "1.2.0" +description = "Wrappers to call pyproject.toml-based build backend hooks." +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "pyproject_hooks-1.2.0-py3-none-any.whl", hash = "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913"}, + {file = "pyproject_hooks-1.2.0.tar.gz", hash = "sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8"}, +] + [[package]] name = "python-dotenv" version = "1.0.1" @@ -1570,6 +2255,19 @@ files = [ {file = "pywifi-1.1.12.tar.gz", hash = "sha256:6da15de5d573635a461a95919920788b6f61748e1bd93a5e3504f456cf2e8bcc"}, ] +[[package]] +name = "pywin32-ctypes" +version = "0.2.3" +description = "A (partial) reimplementation of pywin32 using ctypes/cffi" +optional = false +python-versions = ">=3.6" +groups = ["main"] +markers = "sys_platform == \"win32\"" +files = [ + {file = "pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755"}, + {file = "pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8"}, +] + [[package]] name = "pyyaml" version = "6.0.2" @@ -1633,6 +2331,150 @@ files = [ {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] +[[package]] +name = "rapidfuzz" +version = "3.13.0" +description = "rapid fuzzy string matching" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "rapidfuzz-3.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:aafc42a1dc5e1beeba52cd83baa41372228d6d8266f6d803c16dbabbcc156255"}, + {file = "rapidfuzz-3.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:85c9a131a44a95f9cac2eb6e65531db014e09d89c4f18c7b1fa54979cb9ff1f3"}, + {file = "rapidfuzz-3.13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d7cec4242d30dd521ef91c0df872e14449d1dffc2a6990ede33943b0dae56c3"}, + {file = "rapidfuzz-3.13.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e297c09972698c95649e89121e3550cee761ca3640cd005e24aaa2619175464e"}, + {file = "rapidfuzz-3.13.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ef0f5f03f61b0e5a57b1df7beafd83df993fd5811a09871bad6038d08e526d0d"}, + {file = "rapidfuzz-3.13.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d8cf5f7cd6e4d5eb272baf6a54e182b2c237548d048e2882258336533f3f02b7"}, + {file = "rapidfuzz-3.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9256218ac8f1a957806ec2fb9a6ddfc6c32ea937c0429e88cf16362a20ed8602"}, + {file = "rapidfuzz-3.13.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e1bdd2e6d0c5f9706ef7595773a81ca2b40f3b33fd7f9840b726fb00c6c4eb2e"}, + {file = "rapidfuzz-3.13.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5280be8fd7e2bee5822e254fe0a5763aa0ad57054b85a32a3d9970e9b09bbcbf"}, + {file = "rapidfuzz-3.13.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fd742c03885db1fce798a1cd87a20f47f144ccf26d75d52feb6f2bae3d57af05"}, + {file = "rapidfuzz-3.13.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:5435fcac94c9ecf0504bf88a8a60c55482c32e18e108d6079a0089c47f3f8cf6"}, + {file = "rapidfuzz-3.13.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:93a755266856599be4ab6346273f192acde3102d7aa0735e2f48b456397a041f"}, + {file = "rapidfuzz-3.13.0-cp310-cp310-win32.whl", hash = "sha256:3abe6a4e8eb4cfc4cda04dd650a2dc6d2934cbdeda5def7e6fd1c20f6e7d2a0b"}, + {file = "rapidfuzz-3.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:e8ddb58961401da7d6f55f185512c0d6bd24f529a637078d41dd8ffa5a49c107"}, + {file = "rapidfuzz-3.13.0-cp310-cp310-win_arm64.whl", hash = "sha256:c523620d14ebd03a8d473c89e05fa1ae152821920c3ff78b839218ff69e19ca3"}, + {file = "rapidfuzz-3.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d395a5cad0c09c7f096433e5fd4224d83b53298d53499945a9b0e5a971a84f3a"}, + {file = "rapidfuzz-3.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b7b3eda607a019169f7187328a8d1648fb9a90265087f6903d7ee3a8eee01805"}, + {file = "rapidfuzz-3.13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98e0bfa602e1942d542de077baf15d658bd9d5dcfe9b762aff791724c1c38b70"}, + {file = "rapidfuzz-3.13.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bef86df6d59667d9655905b02770a0c776d2853971c0773767d5ef8077acd624"}, + {file = "rapidfuzz-3.13.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fedd316c165beed6307bf754dee54d3faca2c47e1f3bcbd67595001dfa11e969"}, + {file = "rapidfuzz-3.13.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5158da7f2ec02a930be13bac53bb5903527c073c90ee37804090614cab83c29e"}, + {file = "rapidfuzz-3.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b6f913ee4618ddb6d6f3e387b76e8ec2fc5efee313a128809fbd44e65c2bbb2"}, + {file = "rapidfuzz-3.13.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d25fdbce6459ccbbbf23b4b044f56fbd1158b97ac50994eaae2a1c0baae78301"}, + {file = "rapidfuzz-3.13.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:25343ccc589a4579fbde832e6a1e27258bfdd7f2eb0f28cb836d6694ab8591fc"}, + {file = "rapidfuzz-3.13.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a9ad1f37894e3ffb76bbab76256e8a8b789657183870be11aa64e306bb5228fd"}, + {file = "rapidfuzz-3.13.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5dc71ef23845bb6b62d194c39a97bb30ff171389c9812d83030c1199f319098c"}, + {file = "rapidfuzz-3.13.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b7f4c65facdb94f44be759bbd9b6dda1fa54d0d6169cdf1a209a5ab97d311a75"}, + {file = "rapidfuzz-3.13.0-cp311-cp311-win32.whl", hash = "sha256:b5104b62711565e0ff6deab2a8f5dbf1fbe333c5155abe26d2cfd6f1849b6c87"}, + {file = "rapidfuzz-3.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:9093cdeb926deb32a4887ebe6910f57fbcdbc9fbfa52252c10b56ef2efb0289f"}, + {file = "rapidfuzz-3.13.0-cp311-cp311-win_arm64.whl", hash = "sha256:f70f646751b6aa9d05be1fb40372f006cc89d6aad54e9d79ae97bd1f5fce5203"}, + {file = "rapidfuzz-3.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a1a6a906ba62f2556372282b1ef37b26bca67e3d2ea957277cfcefc6275cca7"}, + {file = "rapidfuzz-3.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2fd0975e015b05c79a97f38883a11236f5a24cca83aa992bd2558ceaa5652b26"}, + {file = "rapidfuzz-3.13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d4e13593d298c50c4f94ce453f757b4b398af3fa0fd2fde693c3e51195b7f69"}, + {file = "rapidfuzz-3.13.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed6f416bda1c9133000009d84d9409823eb2358df0950231cc936e4bf784eb97"}, + {file = "rapidfuzz-3.13.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1dc82b6ed01acb536b94a43996a94471a218f4d89f3fdd9185ab496de4b2a981"}, + {file = "rapidfuzz-3.13.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9d824de871daa6e443b39ff495a884931970d567eb0dfa213d234337343835f"}, + {file = "rapidfuzz-3.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d18228a2390375cf45726ce1af9d36ff3dc1f11dce9775eae1f1b13ac6ec50f"}, + {file = "rapidfuzz-3.13.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9f5fe634c9482ec5d4a6692afb8c45d370ae86755e5f57aa6c50bfe4ca2bdd87"}, + {file = "rapidfuzz-3.13.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:694eb531889f71022b2be86f625a4209c4049e74be9ca836919b9e395d5e33b3"}, + {file = "rapidfuzz-3.13.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:11b47b40650e06147dee5e51a9c9ad73bb7b86968b6f7d30e503b9f8dd1292db"}, + {file = "rapidfuzz-3.13.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:98b8107ff14f5af0243f27d236bcc6e1ef8e7e3b3c25df114e91e3a99572da73"}, + {file = "rapidfuzz-3.13.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b836f486dba0aceb2551e838ff3f514a38ee72b015364f739e526d720fdb823a"}, + {file = "rapidfuzz-3.13.0-cp312-cp312-win32.whl", hash = "sha256:4671ee300d1818d7bdfd8fa0608580d7778ba701817216f0c17fb29e6b972514"}, + {file = "rapidfuzz-3.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:6e2065f68fb1d0bf65adc289c1bdc45ba7e464e406b319d67bb54441a1b9da9e"}, + {file = "rapidfuzz-3.13.0-cp312-cp312-win_arm64.whl", hash = "sha256:65cc97c2fc2c2fe23586599686f3b1ceeedeca8e598cfcc1b7e56dc8ca7e2aa7"}, + {file = "rapidfuzz-3.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:09e908064d3684c541d312bd4c7b05acb99a2c764f6231bd507d4b4b65226c23"}, + {file = "rapidfuzz-3.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:57c390336cb50d5d3bfb0cfe1467478a15733703af61f6dffb14b1cd312a6fae"}, + {file = "rapidfuzz-3.13.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0da54aa8547b3c2c188db3d1c7eb4d1bb6dd80baa8cdaeaec3d1da3346ec9caa"}, + {file = "rapidfuzz-3.13.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df8e8c21e67afb9d7fbe18f42c6111fe155e801ab103c81109a61312927cc611"}, + {file = "rapidfuzz-3.13.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:461fd13250a2adf8e90ca9a0e1e166515cbcaa5e9c3b1f37545cbbeff9e77f6b"}, + {file = "rapidfuzz-3.13.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c2b3dd5d206a12deca16870acc0d6e5036abeb70e3cad6549c294eff15591527"}, + {file = "rapidfuzz-3.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1343d745fbf4688e412d8f398c6e6d6f269db99a54456873f232ba2e7aeb4939"}, + {file = "rapidfuzz-3.13.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b1b065f370d54551dcc785c6f9eeb5bd517ae14c983d2784c064b3aa525896df"}, + {file = "rapidfuzz-3.13.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:11b125d8edd67e767b2295eac6eb9afe0b1cdc82ea3d4b9257da4b8e06077798"}, + {file = "rapidfuzz-3.13.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c33f9c841630b2bb7e69a3fb5c84a854075bb812c47620978bddc591f764da3d"}, + {file = "rapidfuzz-3.13.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ae4574cb66cf1e85d32bb7e9ec45af5409c5b3970b7ceb8dea90168024127566"}, + {file = "rapidfuzz-3.13.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e05752418b24bbd411841b256344c26f57da1148c5509e34ea39c7eb5099ab72"}, + {file = "rapidfuzz-3.13.0-cp313-cp313-win32.whl", hash = "sha256:0e1d08cb884805a543f2de1f6744069495ef527e279e05370dd7c83416af83f8"}, + {file = "rapidfuzz-3.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9a7c6232be5f809cd39da30ee5d24e6cadd919831e6020ec6c2391f4c3bc9264"}, + {file = "rapidfuzz-3.13.0-cp313-cp313-win_arm64.whl", hash = "sha256:3f32f15bacd1838c929b35c84b43618481e1b3d7a61b5ed2db0291b70ae88b53"}, + {file = "rapidfuzz-3.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cc64da907114d7a18b5e589057e3acaf2fec723d31c49e13fedf043592a3f6a7"}, + {file = "rapidfuzz-3.13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4d9d7f84c8e992a8dbe5a3fdbea73d733da39bf464e62c912ac3ceba9c0cff93"}, + {file = "rapidfuzz-3.13.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a79a2f07786a2070669b4b8e45bd96a01c788e7a3c218f531f3947878e0f956"}, + {file = "rapidfuzz-3.13.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9f338e71c45b69a482de8b11bf4a029993230760120c8c6e7c9b71760b6825a1"}, + {file = "rapidfuzz-3.13.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:adb40ca8ddfcd4edd07b0713a860be32bdf632687f656963bcbce84cea04b8d8"}, + {file = "rapidfuzz-3.13.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48719f7dcf62dfb181063b60ee2d0a39d327fa8ad81b05e3e510680c44e1c078"}, + {file = "rapidfuzz-3.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9327a4577f65fc3fb712e79f78233815b8a1c94433d0c2c9f6bc5953018b3565"}, + {file = "rapidfuzz-3.13.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:200030dfc0a1d5d6ac18e993c5097c870c97c41574e67f227300a1fb74457b1d"}, + {file = "rapidfuzz-3.13.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:cc269e74cad6043cb8a46d0ce580031ab642b5930562c2bb79aa7fbf9c858d26"}, + {file = "rapidfuzz-3.13.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:e62779c6371bd2b21dbd1fdce89eaec2d93fd98179d36f61130b489f62294a92"}, + {file = "rapidfuzz-3.13.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f4797f821dc5d7c2b6fc818b89f8a3f37bcc900dd9e4369e6ebf1e525efce5db"}, + {file = "rapidfuzz-3.13.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d21f188f6fe4fbf422e647ae9d5a68671d00218e187f91859c963d0738ccd88c"}, + {file = "rapidfuzz-3.13.0-cp39-cp39-win32.whl", hash = "sha256:45dd4628dd9c21acc5c97627dad0bb791764feea81436fb6e0a06eef4c6dceaa"}, + {file = "rapidfuzz-3.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:624a108122039af89ddda1a2b7ab2a11abe60c1521956f142f5d11bcd42ef138"}, + {file = "rapidfuzz-3.13.0-cp39-cp39-win_arm64.whl", hash = "sha256:435071fd07a085ecbf4d28702a66fd2e676a03369ee497cc38bcb69a46bc77e2"}, + {file = "rapidfuzz-3.13.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fe5790a36d33a5d0a6a1f802aa42ecae282bf29ac6f7506d8e12510847b82a45"}, + {file = "rapidfuzz-3.13.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:cdb33ee9f8a8e4742c6b268fa6bd739024f34651a06b26913381b1413ebe7590"}, + {file = "rapidfuzz-3.13.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c99b76b93f7b495eee7dcb0d6a38fb3ce91e72e99d9f78faa5664a881cb2b7d"}, + {file = "rapidfuzz-3.13.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6af42f2ede8b596a6aaf6d49fdee3066ca578f4856b85ab5c1e2145de367a12d"}, + {file = "rapidfuzz-3.13.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c0efa73afbc5b265aca0d8a467ae2a3f40d6854cbe1481cb442a62b7bf23c99"}, + {file = "rapidfuzz-3.13.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7ac21489de962a4e2fc1e8f0b0da4aa1adc6ab9512fd845563fecb4b4c52093a"}, + {file = "rapidfuzz-3.13.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1ba007f4d35a45ee68656b2eb83b8715e11d0f90e5b9f02d615a8a321ff00c27"}, + {file = "rapidfuzz-3.13.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d7a217310429b43be95b3b8ad7f8fc41aba341109dc91e978cd7c703f928c58f"}, + {file = "rapidfuzz-3.13.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:558bf526bcd777de32b7885790a95a9548ffdcce68f704a81207be4a286c1095"}, + {file = "rapidfuzz-3.13.0-pp311-pypy311_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:202a87760f5145140d56153b193a797ae9338f7939eb16652dd7ff96f8faf64c"}, + {file = "rapidfuzz-3.13.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfcccc08f671646ccb1e413c773bb92e7bba789e3a1796fd49d23c12539fe2e4"}, + {file = "rapidfuzz-3.13.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:1f219f1e3c3194d7a7de222f54450ce12bc907862ff9a8962d83061c1f923c86"}, + {file = "rapidfuzz-3.13.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ccbd0e7ea1a216315f63ffdc7cd09c55f57851afc8fe59a74184cb7316c0598b"}, + {file = "rapidfuzz-3.13.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a50856f49a4016ef56edd10caabdaf3608993f9faf1e05c3c7f4beeac46bd12a"}, + {file = "rapidfuzz-3.13.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fd05336db4d0b8348d7eaaf6fa3c517b11a56abaa5e89470ce1714e73e4aca7"}, + {file = "rapidfuzz-3.13.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:573ad267eb9b3f6e9b04febce5de55d8538a87c56c64bf8fd2599a48dc9d8b77"}, + {file = "rapidfuzz-3.13.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:30fd1451f87ccb6c2f9d18f6caa483116bbb57b5a55d04d3ddbd7b86f5b14998"}, + {file = "rapidfuzz-3.13.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6dd36d4916cf57ddb05286ed40b09d034ca5d4bca85c17be0cb6a21290597d9"}, + {file = "rapidfuzz-3.13.0.tar.gz", hash = "sha256:d2eaf3839e52cbcc0accbe9817a67b4b0fcf70aaeb229cfddc1c28061f9ce5d8"}, +] + +[package.extras] +all = ["numpy"] + +[[package]] +name = "requests" +version = "2.32.4" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c"}, + {file = "requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset_normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +description = "A utility belt for advanced users of python-requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +groups = ["main"] +files = [ + {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, + {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, +] + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + [[package]] name = "rich" version = "13.9.4" @@ -1729,6 +2571,23 @@ files = [ [package.dependencies] sdbus = ">=0.8rc2" +[[package]] +name = "secretstorage" +version = "3.3.3" +description = "Python bindings to FreeDesktop.org Secret Service API" +optional = false +python-versions = ">=3.6" +groups = ["main"] +markers = "sys_platform == \"linux\"" +files = [ + {file = "SecretStorage-3.3.3-py3-none-any.whl", hash = "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99"}, + {file = "SecretStorage-3.3.3.tar.gz", hash = "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77"}, +] + +[package.dependencies] +cryptography = ">=2.0" +jeepney = ">=0.6" + [[package]] name = "shellingham" version = "1.5.4" @@ -1797,6 +2656,30 @@ files = [ [package.dependencies] paramiko = ">=1.8.0" +[[package]] +name = "tomlkit" +version = "0.13.3" +description = "Style preserving TOML library" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0"}, + {file = "tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1"}, +] + +[[package]] +name = "trove-classifiers" +version = "2025.5.9.12" +description = "Canonical source for classifiers on PyPI (pypi.org)." +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "trove_classifiers-2025.5.9.12-py3-none-any.whl", hash = "sha256:e381c05537adac78881c8fa345fd0e9970159f4e4a04fcc42cfd3129cca640ce"}, + {file = "trove_classifiers-2025.5.9.12.tar.gz", hash = "sha256:7ca7c8a7a76e2cd314468c677c69d12cc2357711fcab4a60f87994c1589e5cb5"}, +] + [[package]] name = "typer" version = "0.15.2" @@ -1827,6 +2710,24 @@ files = [ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] +[[package]] +name = "urllib3" +version = "2.5.0" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}, + {file = "urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + [[package]] name = "uuid" version = "1.30" @@ -1917,6 +2818,27 @@ dev = ["Cython (>=3.0,<4.0)", "setuptools (>=60)"] docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] test = ["aiohttp (>=3.10.5)", "flake8 (>=5.0,<6.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=23.0.0,<23.1.0)", "pycodestyle (>=2.9.0,<2.10.0)"] +[[package]] +name = "virtualenv" +version = "20.31.2" +description = "Virtual Python Environment builder" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "virtualenv-20.31.2-py3-none-any.whl", hash = "sha256:36efd0d9650ee985f0cad72065001e66d49a6f24eb44d98980f630686243cf11"}, + {file = "virtualenv-20.31.2.tar.gz", hash = "sha256:e10c0a9d02835e592521be48b332b6caee6887f332c111aa79a09b9e79efc2af"}, +] + +[package.dependencies] +distlib = ">=0.3.7,<1" +filelock = ">=3.12.2,<4" +platformdirs = ">=3.9.1,<5" + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8) ; platform_python_implementation == \"PyPy\" or platform_python_implementation == \"GraalVM\" or platform_python_implementation == \"CPython\" and sys_platform == \"win32\" and python_version >= \"3.13\"", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10) ; platform_python_implementation == \"CPython\""] + [[package]] name = "watchfiles" version = "1.0.4" @@ -2080,6 +3002,93 @@ files = [ {file = "websockets-14.1.tar.gz", hash = "sha256:398b10c77d471c0aab20a845e7a60076b6390bfdaac7a6d2edb0d2c59d75e8d8"}, ] +[[package]] +name = "xattr" +version = "1.1.4" +description = "Python wrapper for extended filesystem attributes" +optional = false +python-versions = ">=3.8" +groups = ["main"] +markers = "sys_platform == \"darwin\"" +files = [ + {file = "xattr-1.1.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:acb85b6249e9f3ea10cbb56df1021d43f4027212f0d004304bc9075dc7f54769"}, + {file = "xattr-1.1.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1a848ab125c0fafdc501ccd83b4c9018bba576a037a4ca5960a22f39e295552e"}, + {file = "xattr-1.1.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:467ee77471d26ae5187ee7081b82175b5ca56ead4b71467ec2e6119d1b08beed"}, + {file = "xattr-1.1.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fd35f46cb0154f7033f9d5d0960f226857acb0d1e0d71fd7af18ed84663007c"}, + {file = "xattr-1.1.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d956478e9bb98a1efd20ebc6e5703497c1d2d690d5a13c4df4abf59881eed50"}, + {file = "xattr-1.1.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f25dfdcd974b700fb04a40e14a664a80227ee58e02ea062ac241f0d7dc54b4e"}, + {file = "xattr-1.1.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:33b63365c1fcbc80a79f601575bac0d6921732e0245b776876f3db3fcfefe22d"}, + {file = "xattr-1.1.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:544542be95c9b49e211f0a463758f200de88ba6d5a94d3c4f42855a484341acd"}, + {file = "xattr-1.1.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac14c9893f3ea046784b7702be30889b200d31adcd2e6781a8a190b6423f9f2d"}, + {file = "xattr-1.1.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bb4bbe37ba95542081890dd34fa5347bef4651e276647adaa802d5d0d7d86452"}, + {file = "xattr-1.1.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3da489ecef798705f9a39ea8cea4ead0d1eeed55f92c345add89740bd930bab6"}, + {file = "xattr-1.1.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:798dd0cbe696635a6f74b06fc430818bf9c3b24314e1502eadf67027ab60c9b0"}, + {file = "xattr-1.1.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b2b6361626efad5eb5a6bf8172c6c67339e09397ee8140ec41258737bea9681"}, + {file = "xattr-1.1.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e7fa20a0c9ce022d19123b1c5b848d00a68b837251835a7929fe041ee81dcd0"}, + {file = "xattr-1.1.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e20eeb08e2c57fc7e71f050b1cfae35cbb46105449853a582bf53fd23c5379e"}, + {file = "xattr-1.1.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:477370e75821bded901487e5e752cffe554d1bd3bd4839b627d4d1ee8c95a093"}, + {file = "xattr-1.1.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a8682091cd34a9f4a93c8aaea4101aae99f1506e24da00a3cc3dd2eca9566f21"}, + {file = "xattr-1.1.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2e079b3b1a274ba2121cf0da38bbe5c8d2fb1cc49ecbceb395ce20eb7d69556d"}, + {file = "xattr-1.1.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ae6579dea05bf9f335a082f711d5924a98da563cac72a2d550f5b940c401c0e9"}, + {file = "xattr-1.1.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cd6038ec9df2e67af23c212693751481d5f7e858156924f14340376c48ed9ac7"}, + {file = "xattr-1.1.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:608b2877526674eb15df4150ef4b70b7b292ae00e65aecaae2f192af224be200"}, + {file = "xattr-1.1.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c54dad1a6a998c6a23edfd25e99f4d38e9b942d54e518570044edf8c767687ea"}, + {file = "xattr-1.1.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c0dab6ff72bb2b508f3850c368f8e53bd706585012676e1f71debba3310acde8"}, + {file = "xattr-1.1.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a3c54c6af7cf09432b2c461af257d5f4b1cb2d59eee045f91bacef44421a46d"}, + {file = "xattr-1.1.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e346e05a158d554639fbf7a0db169dc693c2d2260c7acb3239448f1ff4a9d67f"}, + {file = "xattr-1.1.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3ff6d9e2103d0d6e5fcd65b85a2005b66ea81c0720a37036445faadc5bbfa424"}, + {file = "xattr-1.1.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7a2ee4563c6414dfec0d1ac610f59d39d5220531ae06373eeb1a06ee37cd193f"}, + {file = "xattr-1.1.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:878df1b38cfdadf3184ad8c7b0f516311128d5597b60ac0b3486948953658a83"}, + {file = "xattr-1.1.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0c9b8350244a1c5454f93a8d572628ff71d7e2fc2f7480dcf4c4f0e8af3150fe"}, + {file = "xattr-1.1.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a46bf48fb662b8bd745b78bef1074a1e08f41a531168de62b5d7bd331dadb11a"}, + {file = "xattr-1.1.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83fc3c07b583777b1dda6355329f75ca6b7179fe0d1002f1afe0ef96f7e3b5de"}, + {file = "xattr-1.1.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6308b19cff71441513258699f0538394fad5d66e1d324635207a97cb076fd439"}, + {file = "xattr-1.1.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48c00ddc15ddadc9c729cd9504dabf50adb3d9c28f647d4ac9a3df45a046b1a0"}, + {file = "xattr-1.1.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a06136196f26293758e1b244200b73156a0274af9a7349fa201c71c7af3bb9e8"}, + {file = "xattr-1.1.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8fc2631a3c6cfcdc71f7f0f847461839963754e76a2015de71e7e71e3304abc0"}, + {file = "xattr-1.1.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d6e1e835f9c938d129dd45e7eb52ebf7d2d6816323dab93ce311bf331f7d2328"}, + {file = "xattr-1.1.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:60dea2d369a6484e8b7136224fc2971e10e2c46340d83ab780924afe78c90066"}, + {file = "xattr-1.1.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:85c2b778b09d919523f80f244d799a142302582d76da18903dc693207c4020b0"}, + {file = "xattr-1.1.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ee0abba9e1b890d39141714ff43e9666864ca635ea8a5a2194d989e6b17fe862"}, + {file = "xattr-1.1.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e4174ba7f51f46b95ea7918d907c91cd579575d59e6a2f22ca36a0551026737"}, + {file = "xattr-1.1.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2b05e52e99d82d87528c54c2c5c8c5fb0ba435f85ac6545511aeea136e49925"}, + {file = "xattr-1.1.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a3696fad746be37de34eb73c60ea67144162bd08106a5308a90ce9dea9a3287"}, + {file = "xattr-1.1.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a3a7149439a26b68904c14fdc4587cde4ac7d80303e9ff0fefcfd893b698c976"}, + {file = "xattr-1.1.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:507b36a126ce900dbfa35d4e2c2db92570c933294cba5d161ecd6a89f7b52f43"}, + {file = "xattr-1.1.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:9392b417b54923e031041940d396b1d709df1d3779c6744454e1f1c1f4dad4f5"}, + {file = "xattr-1.1.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e9f00315e6c02943893b77f544776b49c756ac76960bea7cb8d7e1b96aefc284"}, + {file = "xattr-1.1.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c8f98775065260140efb348b1ff8d50fd66ddcbf0c685b76eb1e87b380aaffb3"}, + {file = "xattr-1.1.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b471c6a515f434a167ca16c5c15ff34ee42d11956baa749173a8a4e385ff23e7"}, + {file = "xattr-1.1.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee0763a1b7ceb78ba2f78bee5f30d1551dc26daafcce4ac125115fa1def20519"}, + {file = "xattr-1.1.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:099e6e9ce7999b403d36d9cf943105a3d25d8233486b54ec9d1b78623b050433"}, + {file = "xattr-1.1.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3e56faef9dde8d969f0d646fb6171883693f88ae39163ecd919ec707fbafa85"}, + {file = "xattr-1.1.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:328156d4e594c9ae63e1072503c168849e601a153ad37f0290743544332d6b6f"}, + {file = "xattr-1.1.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:a57a55a27c7864d6916344c9a91776afda6c3b8b2209f8a69b79cdba93fbe128"}, + {file = "xattr-1.1.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3c19cdde08b040df1e99d2500bf8a9cff775ab0e6fa162bf8afe6d84aa93ed04"}, + {file = "xattr-1.1.4-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c72667f19d3a9acf324aed97f58861d398d87e42314731e7c6ab3ac7850c971"}, + {file = "xattr-1.1.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:67ae934d75ea2563fc48a27c5945749575c74a6de19fdd38390917ddcb0e4f24"}, + {file = "xattr-1.1.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a1b0c348dd8523554dc535540d2046c0c8a535bb086561d8359f3667967b6ca"}, + {file = "xattr-1.1.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22284255d2a8e8f3da195bd8e8d43ce674dbc7c38d38cb6ecfb37fae7755d31f"}, + {file = "xattr-1.1.4-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b38aac5ef4381c26d3ce147ca98fba5a78b1e5bcd6be6755b4908659f2705c6d"}, + {file = "xattr-1.1.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:803f864af528f6f763a5be1e7b1ccab418e55ae0e4abc8bda961d162f850c991"}, + {file = "xattr-1.1.4-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:40354ebfb5cecd60a5fbb9833a8a452d147486b0ffec547823658556625d98b5"}, + {file = "xattr-1.1.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2abaf5d06be3361bfa8e0db2ee123ba8e92beab5bceed5e9d7847f2145a32e04"}, + {file = "xattr-1.1.4-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3e638e5ffedc3565242b5fa3296899d35161bad771f88d66277b58f03a1ba9fe"}, + {file = "xattr-1.1.4-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0597e919d116ec39997804288d77bec3777228368efc0f2294b84a527fc4f9c2"}, + {file = "xattr-1.1.4-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3cee9455c501d19f065527afda974418b3ef7c61e85d9519d122cd6eb3cb7a00"}, + {file = "xattr-1.1.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:89ed62ce430f5789e15cfc1ccabc172fd8b349c3a17c52d9e6c64ecedf08c265"}, + {file = "xattr-1.1.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e25b824f4b9259cd8bb6e83c4873cf8bf080f6e4fa034a02fe778e07aba8d345"}, + {file = "xattr-1.1.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8fba66faa0016dfc0af3dd7ac5782b5786a1dfb851f9f3455e266f94c2a05a04"}, + {file = "xattr-1.1.4-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ec4b0c3e0a7bcd103f3cf31dd40c349940b2d4223ce43d384a3548992138ef1"}, + {file = "xattr-1.1.4.tar.gz", hash = "sha256:b7b02ecb2270da5b7e7deaeea8f8b528c17368401c2b9d5f63e91f545b45d372"}, +] + +[package.dependencies] +cffi = ">=1.16.0" + +[package.extras] +test = ["pytest"] + [[package]] name = "yarl" version = "1.20.0" @@ -2199,7 +3208,141 @@ idna = ">=2.0" multidict = ">=4.0" propcache = ">=0.2.1" +[[package]] +name = "zipp" +version = "3.23.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.9" +groups = ["main"] +markers = "python_version == \"3.11\"" +files = [ + {file = "zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e"}, + {file = "zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166"}, +] + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more_itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +type = ["pytest-mypy"] + +[[package]] +name = "zstandard" +version = "0.23.0" +description = "Zstandard bindings for Python" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "zstandard-0.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bf0a05b6059c0528477fba9054d09179beb63744355cab9f38059548fedd46a9"}, + {file = "zstandard-0.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fc9ca1c9718cb3b06634c7c8dec57d24e9438b2aa9a0f02b8bb36bf478538880"}, + {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77da4c6bfa20dd5ea25cbf12c76f181a8e8cd7ea231c673828d0386b1740b8dc"}, + {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2170c7e0367dde86a2647ed5b6f57394ea7f53545746104c6b09fc1f4223573"}, + {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c16842b846a8d2a145223f520b7e18b57c8f476924bda92aeee3a88d11cfc391"}, + {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:157e89ceb4054029a289fb504c98c6a9fe8010f1680de0201b3eb5dc20aa6d9e"}, + {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:203d236f4c94cd8379d1ea61db2fce20730b4c38d7f1c34506a31b34edc87bdd"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dc5d1a49d3f8262be192589a4b72f0d03b72dcf46c51ad5852a4fdc67be7b9e4"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:752bf8a74412b9892f4e5b58f2f890a039f57037f52c89a740757ebd807f33ea"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80080816b4f52a9d886e67f1f96912891074903238fe54f2de8b786f86baded2"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:84433dddea68571a6d6bd4fbf8ff398236031149116a7fff6f777ff95cad3df9"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ab19a2d91963ed9e42b4e8d77cd847ae8381576585bad79dbd0a8837a9f6620a"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:59556bf80a7094d0cfb9f5e50bb2db27fefb75d5138bb16fb052b61b0e0eeeb0"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:27d3ef2252d2e62476389ca8f9b0cf2bbafb082a3b6bfe9d90cbcbb5529ecf7c"}, + {file = "zstandard-0.23.0-cp310-cp310-win32.whl", hash = "sha256:5d41d5e025f1e0bccae4928981e71b2334c60f580bdc8345f824e7c0a4c2a813"}, + {file = "zstandard-0.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:519fbf169dfac1222a76ba8861ef4ac7f0530c35dd79ba5727014613f91613d4"}, + {file = "zstandard-0.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:34895a41273ad33347b2fc70e1bff4240556de3c46c6ea430a7ed91f9042aa4e"}, + {file = "zstandard-0.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:77ea385f7dd5b5676d7fd943292ffa18fbf5c72ba98f7d09fc1fb9e819b34c23"}, + {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:983b6efd649723474f29ed42e1467f90a35a74793437d0bc64a5bf482bedfa0a"}, + {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80a539906390591dd39ebb8d773771dc4db82ace6372c4d41e2d293f8e32b8db"}, + {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:445e4cb5048b04e90ce96a79b4b63140e3f4ab5f662321975679b5f6360b90e2"}, + {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd30d9c67d13d891f2360b2a120186729c111238ac63b43dbd37a5a40670b8ca"}, + {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d20fd853fbb5807c8e84c136c278827b6167ded66c72ec6f9a14b863d809211c"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ed1708dbf4d2e3a1c5c69110ba2b4eb6678262028afd6c6fbcc5a8dac9cda68e"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:be9b5b8659dff1f913039c2feee1aca499cfbc19e98fa12bc85e037c17ec6ca5"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:65308f4b4890aa12d9b6ad9f2844b7ee42c7f7a4fd3390425b242ffc57498f48"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:98da17ce9cbf3bfe4617e836d561e433f871129e3a7ac16d6ef4c680f13a839c"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8ed7d27cb56b3e058d3cf684d7200703bcae623e1dcc06ed1e18ecda39fee003"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:b69bb4f51daf461b15e7b3db033160937d3ff88303a7bc808c67bbc1eaf98c78"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:034b88913ecc1b097f528e42b539453fa82c3557e414b3de9d5632c80439a473"}, + {file = "zstandard-0.23.0-cp311-cp311-win32.whl", hash = "sha256:f2d4380bf5f62daabd7b751ea2339c1a21d1c9463f1feb7fc2bdcea2c29c3160"}, + {file = "zstandard-0.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:62136da96a973bd2557f06ddd4e8e807f9e13cbb0bfb9cc06cfe6d98ea90dfe0"}, + {file = "zstandard-0.23.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b4567955a6bc1b20e9c31612e615af6b53733491aeaa19a6b3b37f3b65477094"}, + {file = "zstandard-0.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e172f57cd78c20f13a3415cc8dfe24bf388614324d25539146594c16d78fcc8"}, + {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0e166f698c5a3e914947388c162be2583e0c638a4703fc6a543e23a88dea3c1"}, + {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12a289832e520c6bd4dcaad68e944b86da3bad0d339ef7989fb7e88f92e96072"}, + {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d50d31bfedd53a928fed6707b15a8dbeef011bb6366297cc435accc888b27c20"}, + {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72c68dda124a1a138340fb62fa21b9bf4848437d9ca60bd35db36f2d3345f373"}, + {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53dd9d5e3d29f95acd5de6802e909ada8d8d8cfa37a3ac64836f3bc4bc5512db"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6a41c120c3dbc0d81a8e8adc73312d668cd34acd7725f036992b1b72d22c1772"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:40b33d93c6eddf02d2c19f5773196068d875c41ca25730e8288e9b672897c105"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9206649ec587e6b02bd124fb7799b86cddec350f6f6c14bc82a2b70183e708ba"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76e79bc28a65f467e0409098fa2c4376931fd3207fbeb6b956c7c476d53746dd"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:66b689c107857eceabf2cf3d3fc699c3c0fe8ccd18df2219d978c0283e4c508a"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9c236e635582742fee16603042553d276cca506e824fa2e6489db04039521e90"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a8fffdbd9d1408006baaf02f1068d7dd1f016c6bcb7538682622c556e7b68e35"}, + {file = "zstandard-0.23.0-cp312-cp312-win32.whl", hash = "sha256:dc1d33abb8a0d754ea4763bad944fd965d3d95b5baef6b121c0c9013eaf1907d"}, + {file = "zstandard-0.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:64585e1dba664dc67c7cdabd56c1e5685233fbb1fc1966cfba2a340ec0dfff7b"}, + {file = "zstandard-0.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:576856e8594e6649aee06ddbfc738fec6a834f7c85bf7cadd1c53d4a58186ef9"}, + {file = "zstandard-0.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38302b78a850ff82656beaddeb0bb989a0322a8bbb1bf1ab10c17506681d772a"}, + {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2240ddc86b74966c34554c49d00eaafa8200a18d3a5b6ffbf7da63b11d74ee2"}, + {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ef230a8fd217a2015bc91b74f6b3b7d6522ba48be29ad4ea0ca3a3775bf7dd5"}, + {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:774d45b1fac1461f48698a9d4b5fa19a69d47ece02fa469825b442263f04021f"}, + {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f77fa49079891a4aab203d0b1744acc85577ed16d767b52fc089d83faf8d8ed"}, + {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac184f87ff521f4840e6ea0b10c0ec90c6b1dcd0bad2f1e4a9a1b4fa177982ea"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c363b53e257246a954ebc7c488304b5592b9c53fbe74d03bc1c64dda153fb847"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e7792606d606c8df5277c32ccb58f29b9b8603bf83b48639b7aedf6df4fe8171"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a0817825b900fcd43ac5d05b8b3079937073d2b1ff9cf89427590718b70dd840"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9da6bc32faac9a293ddfdcb9108d4b20416219461e4ec64dfea8383cac186690"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fd7699e8fd9969f455ef2926221e0233f81a2542921471382e77a9e2f2b57f4b"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d477ed829077cd945b01fc3115edd132c47e6540ddcd96ca169facff28173057"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ce8b52c5987b3e34d5674b0ab529a4602b632ebab0a93b07bfb4dfc8f8a33"}, + {file = "zstandard-0.23.0-cp313-cp313-win32.whl", hash = "sha256:a9b07268d0c3ca5c170a385a0ab9fb7fdd9f5fd866be004c4ea39e44edce47dd"}, + {file = "zstandard-0.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:f3513916e8c645d0610815c257cbfd3242adfd5c4cfa78be514e5a3ebb42a41b"}, + {file = "zstandard-0.23.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2ef3775758346d9ac6214123887d25c7061c92afe1f2b354f9388e9e4d48acfc"}, + {file = "zstandard-0.23.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4051e406288b8cdbb993798b9a45c59a4896b6ecee2f875424ec10276a895740"}, + {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2d1a054f8f0a191004675755448d12be47fa9bebbcffa3cdf01db19f2d30a54"}, + {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f83fa6cae3fff8e98691248c9320356971b59678a17f20656a9e59cd32cee6d8"}, + {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:32ba3b5ccde2d581b1e6aa952c836a6291e8435d788f656fe5976445865ae045"}, + {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f146f50723defec2975fb7e388ae3a024eb7151542d1599527ec2aa9cacb152"}, + {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1bfe8de1da6d104f15a60d4a8a768288f66aa953bbe00d027398b93fb9680b26"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:29a2bc7c1b09b0af938b7a8343174b987ae021705acabcbae560166567f5a8db"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:61f89436cbfede4bc4e91b4397eaa3e2108ebe96d05e93d6ccc95ab5714be512"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:53ea7cdc96c6eb56e76bb06894bcfb5dfa93b7adcf59d61c6b92674e24e2dd5e"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:a4ae99c57668ca1e78597d8b06d5af837f377f340f4cce993b551b2d7731778d"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:379b378ae694ba78cef921581ebd420c938936a153ded602c4fea612b7eaa90d"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:50a80baba0285386f97ea36239855f6020ce452456605f262b2d33ac35c7770b"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:61062387ad820c654b6a6b5f0b94484fa19515e0c5116faf29f41a6bc91ded6e"}, + {file = "zstandard-0.23.0-cp38-cp38-win32.whl", hash = "sha256:b8c0bd73aeac689beacd4e7667d48c299f61b959475cdbb91e7d3d88d27c56b9"}, + {file = "zstandard-0.23.0-cp38-cp38-win_amd64.whl", hash = "sha256:a05e6d6218461eb1b4771d973728f0133b2a4613a6779995df557f70794fd60f"}, + {file = "zstandard-0.23.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa014d55c3af933c1315eb4bb06dd0459661cc0b15cd61077afa6489bec63bb"}, + {file = "zstandard-0.23.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7f0804bb3799414af278e9ad51be25edf67f78f916e08afdb983e74161b916"}, + {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb2b1ecfef1e67897d336de3a0e3f52478182d6a47eda86cbd42504c5cbd009a"}, + {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:837bb6764be6919963ef41235fd56a6486b132ea64afe5fafb4cb279ac44f259"}, + {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1516c8c37d3a053b01c1c15b182f3b5f5eef19ced9b930b684a73bad121addf4"}, + {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48ef6a43b1846f6025dde6ed9fee0c24e1149c1c25f7fb0a0585572b2f3adc58"}, + {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11e3bf3c924853a2d5835b24f03eeba7fc9b07d8ca499e247e06ff5676461a15"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2fb4535137de7e244c230e24f9d1ec194f61721c86ebea04e1581d9d06ea1269"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8c24f21fa2af4bb9f2c492a86fe0c34e6d2c63812a839590edaf177b7398f700"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a8c86881813a78a6f4508ef9daf9d4995b8ac2d147dcb1a450448941398091c9"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fe3b385d996ee0822fd46528d9f0443b880d4d05528fd26a9119a54ec3f91c69"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:82d17e94d735c99621bf8ebf9995f870a6b3e6d14543b99e201ae046dfe7de70"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c7c517d74bea1a6afd39aa612fa025e6b8011982a0897768a2f7c8ab4ebb78a2"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fd7e0f1cfb70eb2f95a19b472ee7ad6d9a0a992ec0ae53286870c104ca939e5"}, + {file = "zstandard-0.23.0-cp39-cp39-win32.whl", hash = "sha256:43da0f0092281bf501f9c5f6f3b4c975a8a0ea82de49ba3f7100e64d422a1274"}, + {file = "zstandard-0.23.0-cp39-cp39-win_amd64.whl", hash = "sha256:f8346bfa098532bc1fb6c7ef06783e969d87a99dd1d2a5a18a892c1d7a643c58"}, + {file = "zstandard-0.23.0.tar.gz", hash = "sha256:b2d8c62d08e7255f68f7a740bae85b3c9b8e5466baa9cbf7f57f1cde0ac6bc09"}, +] + +[package.dependencies] +cffi = {version = ">=1.11", markers = "platform_python_implementation == \"PyPy\""} + +[package.extras] +cffi = ["cffi (>=1.11)"] + [metadata] lock-version = "2.1" python-versions = "^3.11" -content-hash = "60c1f3007a3dcb4ef05162fcf9a2f3a3d8b39a56cd5df142db8afea958d182c6" +content-hash = "7139a70d2eb0c9e91e792256388371d98f71538cbbdd3722b0fc33d980f3a210" diff --git a/SRV/pyproject.toml b/SRV/pyproject.toml index 5193ab8..e32b59f 100644 --- a/SRV/pyproject.toml +++ b/SRV/pyproject.toml @@ -37,6 +37,7 @@ bcrypt = "^4.3.0" mac-vendor-lookup = "^0.1.12" pywifi = "^1.1.12" manuf = "^1.1.5" +poetry-plugin-export = "^1.9.0" [build-system] From 6f7b821c8b91f2cee78443da4e3cd88e339c0bff Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Fri, 27 Jun 2025 16:02:35 +0500 Subject: [PATCH 042/136] ci-cd-13 --- .woodpecker/.woodpecker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index 3d8398e..4b83667 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -9,7 +9,7 @@ steps: GONETS: from_secret: GONETS commands: - bash + - bash # ПОДГОТОВКА ГИТА И КЛОНИРОВАНИЕ GONETS - apt update - apt install -y git git-lfs From 3a5b0bdcbc020c8afa16447894b1bfa013acfc15 Mon Sep 17 00:00:00 2001 From: "s.galanskiy" Date: Mon, 30 Jun 2025 13:16:33 +0500 Subject: [PATCH 043/136] front/dev --- .woodpecker/.woodpecker.yml | 20 +- FRONT/BUILD/index.html | 13 + FRONT/BUILD/resources/app/src/api/request.ts | 4 +- .../src/components/UI/Dropdown/DeviceCard.tsx | 2 +- .../src/components/UI/tables/TableScanner.tsx | 52 +- .../workSpace/modules/appModules/about.tsx | 206 +- .../usersScanner/modules/ListUsers.tsx | 15 +- .../usersScanner/modules/TableUsers.tsx | 4 +- .../appModules/usersScanner/userScanner.tsx | 6 +- .../appModules/wifiScanner/WifiScanner.tsx | 13 +- .../wifiScanner/modules/WifiDot.tsx | 40 +- .../modules/workModules/networkInterfaces.tsx | 2 +- .../sideBar/toolSpace/devicesBar.tsx | 2 +- .../resources/app/src/const/buttons/icons.tsx | 2 - .../resources/app/src/const/buttons/names.ts | 3 +- .../app/src/const/menus/sideBar/icons.tsx | 2 +- .../resources/app/src/const/theme/theme.ts | 2 +- FRONT/DEV/.gitignore | 2 + FRONT/DEV/assets/icon.png | Bin 0 -> 129501 bytes FRONT/DEV/eslint.config.js | 28 + FRONT/DEV/index.html | 12 + FRONT/DEV/index.tsx | 52 + FRONT/DEV/main.js | 61 + FRONT/DEV/package-lock.json | 4845 +++++++++++++++++ FRONT/DEV/package.json | 39 + FRONT/DEV/preload.js | 19 + FRONT/DEV/public/assets/images/back1.svg | 836 +++ FRONT/DEV/public/assets/images/bigLogo.svg | 20 + FRONT/DEV/public/assets/images/bukvi.svg | 15 + FRONT/DEV/public/assets/images/cancel.svg | 12 + FRONT/DEV/public/assets/images/check.svg | 5 + FRONT/DEV/public/assets/images/edit.svg | 5 + FRONT/DEV/public/assets/images/ethernet.svg | 11 + FRONT/DEV/public/assets/images/gossys.png | Bin 0 -> 70993 bytes FRONT/DEV/public/assets/images/logo.svg | 23 + FRONT/DEV/public/assets/images/signal.svg | 17 + FRONT/DEV/public/assets/images/vite.svg | 1 + FRONT/DEV/public/assets/images/vpn.svg | 27 + FRONT/DEV/public/assets/images/wifi.svg | 6 + FRONT/DEV/src/api/request.ts | 160 + FRONT/DEV/src/assets/css/flow.css | 108 + FRONT/DEV/src/assets/css/index.css | 36 + .../src/components/UI/Dropdown/DeviceCard.tsx | 137 + .../components/UI/Dropdown/DropdownType.tsx | 130 + .../src/components/UI/Pagination.tsx | 0 FRONT/DEV/src/components/UI/animDot.tsx | 29 + .../src/components/UI/buttons/mainButton.tsx | 75 + .../src/components/UI/buttons/quitButton.tsx | 45 + .../src/components/UI/buttons/toggletheme.tsx | 26 + FRONT/DEV/src/components/UI/inputs/input.tsx | 65 + FRONT/DEV/src/components/UI/loader.tsx | 101 + FRONT/DEV/src/components/UI/routerLoader.tsx | 103 + FRONT/DEV/src/components/UI/signalSvg.tsx | 63 + .../src/components/UI/tables/TableScanner.tsx | 137 + .../nodes/baseForm/circle/circleNode.tsx | 38 + .../nodes/baseForm/circle/style.ts | 20 + .../nodes/baseForm/default/defaultNode.tsx | 37 + .../nodes/baseForm/default/style.ts | 20 + .../nodes/baseForm/diamond/diamondNode.tsx | 45 + .../nodes/baseForm/diamond/style.ts | 32 + .../customeNodes/nodes/baseForm/index.ts | 5 + .../paralelogram/paralelogramNode.tsx | 35 + .../nodes/baseForm/paralelogram/style.ts | 43 + .../nodes/baseForm/pill/pillNode.tsx | 40 + .../customeNodes/nodes/baseForm/pill/style.ts | 19 + .../nodes/networkInterface/index.ts | 5 + .../networkInterface/ipGroup/ipGroup.tsx | 18 + .../nodes/networkInterface/ipGroup/style.ts | 12 + .../nodes/networkInterface/ipNode/ipNode.tsx | 245 + .../nodes/networkInterface/ipNode/style.ts | 74 + .../networkGroup/nodeGroup.tsx | 64 + .../networkInterface/networkGroup/style.ts | 47 + .../networkNode/networkNode.tsx | 110 + .../networkInterface/networkNode/style.ts | 93 + .../networkInterface/portNode/portNode.tsx | 48 + .../nodes/networkInterface/portNode/style.ts | 30 + .../components/customeNodes/types/colors.ts | 11 + .../components/customeNodes/types/types.ts | 16 + .../DEV/src/components/modalwindows/modal.tsx | 10 + .../modalContainers/ConnectNetwork.tsx | 84 + .../modalContainers/NoteDevice.tsx | 82 + .../modalwindows/modalContainers/NoteWifi.tsx | 82 + .../modalContainers/addDevice.tsx | 58 + .../modalContainers/connectionError.tsx | 38 + .../modalContainers/disconnectConfirm.tsx | 54 + .../modalwindows/modalContainers/index.ts | 4 + .../modalContainers/ipConfirm.tsx | 211 + .../modalContainers/rightsConfirm.tsx | 135 + .../components/modalwindows/modalWindow.tsx | 81 + .../DEV/src/components/modalwindows/style.ts | 70 + .../components/modalwindows/windowsType.ts | 13 + FRONT/DEV/src/components/register.tsx | 194 + .../workSpace/modules/appModules/about.tsx | 249 + .../workSpace/modules/appModules/header.tsx | 46 + .../modules/appModules/helloWindow.tsx | 82 + .../usersScanner/modules/ListUsers.tsx | 78 + .../usersScanner/modules/TableUsers.tsx | 45 + .../appModules/usersScanner/userScanner.tsx | 191 + .../appModules/wifiScanner/WifiScanner.tsx | 202 + .../wifiScanner/modules/ModalWifiScaner.tsx | 225 + .../wifiScanner/modules/WifiDot.tsx | 81 + .../modules/workModules/networkInterfaces.tsx | 282 + .../components/workSpace/sideBar/sideBar.tsx | 17 + .../sideBar/toolBar/toolBar-button.tsx | 32 + .../workSpace/sideBar/toolBar/toolBar.tsx | 87 + .../sideBar/toolSpace/devicesBar.tsx | 244 + .../workSpace/sideBar/toolSpace/toolSpace.tsx | 31 + .../src/components/workSpace/workSpace.tsx | 101 + FRONT/DEV/src/const/buttons/icons.tsx | 65 + FRONT/DEV/src/const/buttons/names.ts | 21 + FRONT/DEV/src/const/menus/othersMenus/data.ts | 9 + .../DEV/src/const/menus/othersMenus/names.ts | 5 + .../src/const/menus/sideBar/components.tsx | 20 + FRONT/DEV/src/const/menus/sideBar/data.ts | 13 + FRONT/DEV/src/const/menus/sideBar/icons.tsx | 32 + FRONT/DEV/src/const/menus/sideBar/names.ts | 5 + FRONT/DEV/src/const/modals/names.ts | 8 + FRONT/DEV/src/const/theme/globalStyles.ts | 55 + FRONT/DEV/src/const/theme/icons.tsx | 36 + FRONT/DEV/src/const/theme/names.ts | 10 + FRONT/DEV/src/const/theme/theme.ts | 30 + FRONT/DEV/src/const/types/types.ts | 213 + FRONT/DEV/src/const/workspace/names.ts | 10 + FRONT/DEV/src/electron.d.ts | 5 + FRONT/DEV/src/hooks/useMenu.ts | 15 + FRONT/DEV/src/hooks/useToolBar.ts | 16 + FRONT/DEV/src/router.tsx | 43 + FRONT/DEV/src/store/adminStore.ts | 11 + FRONT/DEV/src/store/devicesStore.ts | 39 + FRONT/DEV/src/store/flowStore.ts | 22 + FRONT/DEV/src/store/groupStore.ts | 13 + FRONT/DEV/src/store/index.ts | 9 + FRONT/DEV/src/store/ipStore.ts | 20 + FRONT/DEV/src/store/menusStore.ts | 28 + FRONT/DEV/src/store/modalContext.tsx | 63 + FRONT/DEV/src/store/pannableStore.ts | 11 + FRONT/DEV/src/store/posStore.ts | 11 + FRONT/DEV/src/store/themeContext.tsx | 78 + FRONT/DEV/src/store/toolBarStore.ts | 50 + FRONT/DEV/src/store/useDeviceStore.ts | 51 + FRONT/DEV/src/store/workSpaceStore.ts | 26 + FRONT/DEV/src/utils/checkAdmin.ts | 19 + .../utils/nodeController/autosavePosition.ts | 104 + .../src/utils/nodeController/collapseGroup.ts | 65 + .../DEV/src/utils/nodeController/groupSort.ts | 37 + FRONT/DEV/src/utils/nodeController/index.ts | 6 + .../utils/nodeController/initNetIntData.ts | 60 + .../nodeController/nodeCreator/deviceState.ts | 33 + .../nodeCreator/inits/initEdges.ts | 19 + .../nodeCreator/inits/initIpArray.ts | 44 + .../nodeCreator/inits/initNodes.ts | 297 + .../nodeCreator/inits/initor.ts | 15 + .../utils/nodeController/updateWifiData.ts | 21 + .../DEV/src/utils/nodeController/validator.ts | 35 + FRONT/DEV/src/utils/pageReloads.ts | 18 + FRONT/DEV/tsconfig.app.json | 26 + FRONT/DEV/tsconfig.json | 33 + FRONT/DEV/tsconfig.node.json | 11 + FRONT/DEV/vite-env.d.ts | 1 + FRONT/DEV/vite.config.ts | 11 + FRONT/DEV/yarn.lock | 2228 ++++++++ SRV/requirements.txt | 44 +- 162 files changed, 15801 insertions(+), 224 deletions(-) create mode 100644 FRONT/BUILD/index.html create mode 100644 FRONT/DEV/.gitignore create mode 100644 FRONT/DEV/assets/icon.png create mode 100644 FRONT/DEV/eslint.config.js create mode 100644 FRONT/DEV/index.html create mode 100644 FRONT/DEV/index.tsx create mode 100644 FRONT/DEV/main.js create mode 100644 FRONT/DEV/package-lock.json create mode 100644 FRONT/DEV/package.json create mode 100644 FRONT/DEV/preload.js create mode 100644 FRONT/DEV/public/assets/images/back1.svg create mode 100644 FRONT/DEV/public/assets/images/bigLogo.svg create mode 100644 FRONT/DEV/public/assets/images/bukvi.svg create mode 100644 FRONT/DEV/public/assets/images/cancel.svg create mode 100644 FRONT/DEV/public/assets/images/check.svg create mode 100644 FRONT/DEV/public/assets/images/edit.svg create mode 100644 FRONT/DEV/public/assets/images/ethernet.svg create mode 100644 FRONT/DEV/public/assets/images/gossys.png create mode 100644 FRONT/DEV/public/assets/images/logo.svg create mode 100644 FRONT/DEV/public/assets/images/signal.svg create mode 100644 FRONT/DEV/public/assets/images/vite.svg create mode 100644 FRONT/DEV/public/assets/images/vpn.svg create mode 100644 FRONT/DEV/public/assets/images/wifi.svg create mode 100644 FRONT/DEV/src/api/request.ts create mode 100644 FRONT/DEV/src/assets/css/flow.css create mode 100644 FRONT/DEV/src/assets/css/index.css create mode 100644 FRONT/DEV/src/components/UI/Dropdown/DeviceCard.tsx create mode 100644 FRONT/DEV/src/components/UI/Dropdown/DropdownType.tsx rename FRONT/{BUILD/resources/app => DEV}/src/components/UI/Pagination.tsx (100%) create mode 100644 FRONT/DEV/src/components/UI/animDot.tsx create mode 100644 FRONT/DEV/src/components/UI/buttons/mainButton.tsx create mode 100644 FRONT/DEV/src/components/UI/buttons/quitButton.tsx create mode 100644 FRONT/DEV/src/components/UI/buttons/toggletheme.tsx create mode 100644 FRONT/DEV/src/components/UI/inputs/input.tsx create mode 100644 FRONT/DEV/src/components/UI/loader.tsx create mode 100644 FRONT/DEV/src/components/UI/routerLoader.tsx create mode 100644 FRONT/DEV/src/components/UI/signalSvg.tsx create mode 100644 FRONT/DEV/src/components/UI/tables/TableScanner.tsx create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/baseForm/circle/circleNode.tsx create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/baseForm/circle/style.ts create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/baseForm/default/defaultNode.tsx create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/baseForm/default/style.ts create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/baseForm/diamond/diamondNode.tsx create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/baseForm/diamond/style.ts create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/baseForm/index.ts create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/baseForm/paralelogram/paralelogramNode.tsx create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/baseForm/paralelogram/style.ts create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/baseForm/pill/pillNode.tsx create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/baseForm/pill/style.ts create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/networkInterface/index.ts create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/networkInterface/ipGroup/ipGroup.tsx create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/networkInterface/ipGroup/style.ts create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/networkInterface/ipNode/ipNode.tsx create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/networkInterface/ipNode/style.ts create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/networkInterface/networkGroup/nodeGroup.tsx create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/networkInterface/networkGroup/style.ts create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/networkInterface/networkNode/networkNode.tsx create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/networkInterface/networkNode/style.ts create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/networkInterface/portNode/portNode.tsx create mode 100644 FRONT/DEV/src/components/customeNodes/nodes/networkInterface/portNode/style.ts create mode 100644 FRONT/DEV/src/components/customeNodes/types/colors.ts create mode 100644 FRONT/DEV/src/components/customeNodes/types/types.ts create mode 100644 FRONT/DEV/src/components/modalwindows/modal.tsx create mode 100644 FRONT/DEV/src/components/modalwindows/modalContainers/ConnectNetwork.tsx create mode 100644 FRONT/DEV/src/components/modalwindows/modalContainers/NoteDevice.tsx create mode 100644 FRONT/DEV/src/components/modalwindows/modalContainers/NoteWifi.tsx create mode 100644 FRONT/DEV/src/components/modalwindows/modalContainers/addDevice.tsx create mode 100644 FRONT/DEV/src/components/modalwindows/modalContainers/connectionError.tsx create mode 100644 FRONT/DEV/src/components/modalwindows/modalContainers/disconnectConfirm.tsx create mode 100644 FRONT/DEV/src/components/modalwindows/modalContainers/index.ts create mode 100644 FRONT/DEV/src/components/modalwindows/modalContainers/ipConfirm.tsx create mode 100644 FRONT/DEV/src/components/modalwindows/modalContainers/rightsConfirm.tsx create mode 100644 FRONT/DEV/src/components/modalwindows/modalWindow.tsx create mode 100644 FRONT/DEV/src/components/modalwindows/style.ts create mode 100644 FRONT/DEV/src/components/modalwindows/windowsType.ts create mode 100644 FRONT/DEV/src/components/register.tsx create mode 100644 FRONT/DEV/src/components/workSpace/modules/appModules/about.tsx create mode 100644 FRONT/DEV/src/components/workSpace/modules/appModules/header.tsx create mode 100644 FRONT/DEV/src/components/workSpace/modules/appModules/helloWindow.tsx create mode 100644 FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/modules/ListUsers.tsx create mode 100644 FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx create mode 100644 FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx create mode 100644 FRONT/DEV/src/components/workSpace/modules/appModules/wifiScanner/WifiScanner.tsx create mode 100644 FRONT/DEV/src/components/workSpace/modules/appModules/wifiScanner/modules/ModalWifiScaner.tsx create mode 100644 FRONT/DEV/src/components/workSpace/modules/appModules/wifiScanner/modules/WifiDot.tsx create mode 100644 FRONT/DEV/src/components/workSpace/modules/workModules/networkInterfaces.tsx create mode 100644 FRONT/DEV/src/components/workSpace/sideBar/sideBar.tsx create mode 100644 FRONT/DEV/src/components/workSpace/sideBar/toolBar/toolBar-button.tsx create mode 100644 FRONT/DEV/src/components/workSpace/sideBar/toolBar/toolBar.tsx create mode 100644 FRONT/DEV/src/components/workSpace/sideBar/toolSpace/devicesBar.tsx create mode 100644 FRONT/DEV/src/components/workSpace/sideBar/toolSpace/toolSpace.tsx create mode 100644 FRONT/DEV/src/components/workSpace/workSpace.tsx create mode 100644 FRONT/DEV/src/const/buttons/icons.tsx create mode 100644 FRONT/DEV/src/const/buttons/names.ts create mode 100644 FRONT/DEV/src/const/menus/othersMenus/data.ts create mode 100644 FRONT/DEV/src/const/menus/othersMenus/names.ts create mode 100644 FRONT/DEV/src/const/menus/sideBar/components.tsx create mode 100644 FRONT/DEV/src/const/menus/sideBar/data.ts create mode 100644 FRONT/DEV/src/const/menus/sideBar/icons.tsx create mode 100644 FRONT/DEV/src/const/menus/sideBar/names.ts create mode 100644 FRONT/DEV/src/const/modals/names.ts create mode 100644 FRONT/DEV/src/const/theme/globalStyles.ts create mode 100644 FRONT/DEV/src/const/theme/icons.tsx create mode 100644 FRONT/DEV/src/const/theme/names.ts create mode 100644 FRONT/DEV/src/const/theme/theme.ts create mode 100644 FRONT/DEV/src/const/types/types.ts create mode 100644 FRONT/DEV/src/const/workspace/names.ts create mode 100644 FRONT/DEV/src/electron.d.ts create mode 100644 FRONT/DEV/src/hooks/useMenu.ts create mode 100644 FRONT/DEV/src/hooks/useToolBar.ts create mode 100644 FRONT/DEV/src/router.tsx create mode 100644 FRONT/DEV/src/store/adminStore.ts create mode 100644 FRONT/DEV/src/store/devicesStore.ts create mode 100644 FRONT/DEV/src/store/flowStore.ts create mode 100644 FRONT/DEV/src/store/groupStore.ts create mode 100644 FRONT/DEV/src/store/index.ts create mode 100644 FRONT/DEV/src/store/ipStore.ts create mode 100644 FRONT/DEV/src/store/menusStore.ts create mode 100644 FRONT/DEV/src/store/modalContext.tsx create mode 100644 FRONT/DEV/src/store/pannableStore.ts create mode 100644 FRONT/DEV/src/store/posStore.ts create mode 100644 FRONT/DEV/src/store/themeContext.tsx create mode 100644 FRONT/DEV/src/store/toolBarStore.ts create mode 100644 FRONT/DEV/src/store/useDeviceStore.ts create mode 100644 FRONT/DEV/src/store/workSpaceStore.ts create mode 100644 FRONT/DEV/src/utils/checkAdmin.ts create mode 100644 FRONT/DEV/src/utils/nodeController/autosavePosition.ts create mode 100644 FRONT/DEV/src/utils/nodeController/collapseGroup.ts create mode 100644 FRONT/DEV/src/utils/nodeController/groupSort.ts create mode 100644 FRONT/DEV/src/utils/nodeController/index.ts create mode 100644 FRONT/DEV/src/utils/nodeController/initNetIntData.ts create mode 100644 FRONT/DEV/src/utils/nodeController/nodeCreator/deviceState.ts create mode 100644 FRONT/DEV/src/utils/nodeController/nodeCreator/inits/initEdges.ts create mode 100644 FRONT/DEV/src/utils/nodeController/nodeCreator/inits/initIpArray.ts create mode 100644 FRONT/DEV/src/utils/nodeController/nodeCreator/inits/initNodes.ts create mode 100644 FRONT/DEV/src/utils/nodeController/nodeCreator/inits/initor.ts create mode 100644 FRONT/DEV/src/utils/nodeController/updateWifiData.ts create mode 100644 FRONT/DEV/src/utils/nodeController/validator.ts create mode 100644 FRONT/DEV/src/utils/pageReloads.ts create mode 100644 FRONT/DEV/tsconfig.app.json create mode 100644 FRONT/DEV/tsconfig.json create mode 100644 FRONT/DEV/tsconfig.node.json create mode 100644 FRONT/DEV/vite-env.d.ts create mode 100644 FRONT/DEV/vite.config.ts create mode 100644 FRONT/DEV/yarn.lock diff --git a/.woodpecker/.woodpecker.yml b/.woodpecker/.woodpecker.yml index 4b83667..801de92 100644 --- a/.woodpecker/.woodpecker.yml +++ b/.woodpecker/.woodpecker.yml @@ -9,7 +9,7 @@ steps: GONETS: from_secret: GONETS commands: - - bash + - echo $SHELL # ПОДГОТОВКА ГИТА И КЛОНИРОВАНИЕ GONETS - apt update - apt install -y git git-lfs @@ -18,19 +18,29 @@ steps: # УСТАНОВКА НЕОБХОДИМЫХ ЗАВИСИМОСТЕЙ НА СИСТЕМЕ - apt update - - apt install -y python3 python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make dpkg-dev + - apt install -y python3 python3.11-venv python3-pip python3-poetry nodejs npm debhelper devscripts build-essential fakeroot dh-make dpkg-dev cmake libgirepository1.0-dev gobject-introspection libcairo2-dev pkg-config python3-dev libdbus-1-dev - python3 --version - node -v - npm -v # ПОДГОТОВКА СПИСКА PYTHON ЗАВИСИМОСТЕЙ GONETS - - curl -sSL https://install.python-poetry.org | python3 - - - export PATH="/root/.local/bin:$PATH" + - rm -rf /usr/lib/python3.11/EXTERNALLY-MANAGED + - rm -rf /root/.local/share/pypoetry + - rm -rf /root/.poetry + - rm -rf /usr/bin/poetry + - pip install pipx + - pipx ensurepath + - pipx install poetry + - echo 'export PATH="$HOME/.local/bin:$PATH"' >> /root/.bashrc + - . /root/.bashrc - poetry --version - cd gonets/SRV + - poetry env activate + - poetry add poetry-plugin-export - poetry install + - poetry self update - rm -f requirements.txt - - poetry export -f requirements.txt --output requirements.txt --without-hashes + - poetry run poetry export -f requirements.txt --output requirements.txt --without-hashes # ПОДГОТОВКА И СБОРКА FRONTEND ЧАСТИ GONETS - cd gonets/FRONT/DEV diff --git a/FRONT/BUILD/index.html b/FRONT/BUILD/index.html new file mode 100644 index 0000000..8f4d4d1 --- /dev/null +++ b/FRONT/BUILD/index.html @@ -0,0 +1,13 @@ + + + + + GoNets + + + + + +
+ + \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/api/request.ts b/FRONT/BUILD/resources/app/src/api/request.ts index 99f1f22..27dafd1 100644 --- a/FRONT/BUILD/resources/app/src/api/request.ts +++ b/FRONT/BUILD/resources/app/src/api/request.ts @@ -1,13 +1,13 @@ import axios, { AxiosResponse } from "axios"; const axiosWithoutCredentials = axios.create({ - baseURL: `http://localhost:8001`, + baseURL: `https://localhost:8001`, }) export class NetworkService { static createAxiosInstance(ipAddress: string) { return axios.create({ - baseURL: `http://${ipAddress}:8001`, + baseURL: `https://${ipAddress}:8001`, }); } diff --git a/FRONT/BUILD/resources/app/src/components/UI/Dropdown/DeviceCard.tsx b/FRONT/BUILD/resources/app/src/components/UI/Dropdown/DeviceCard.tsx index 0345346..cfed6c4 100644 --- a/FRONT/BUILD/resources/app/src/components/UI/Dropdown/DeviceCard.tsx +++ b/FRONT/BUILD/resources/app/src/components/UI/Dropdown/DeviceCard.tsx @@ -100,7 +100,7 @@ const DeviceCard: React.FC = ({ device, status }) => { - {device.hostname || device.ip} + {device.hostname || 'Неизвестно'} diff --git a/FRONT/BUILD/resources/app/src/components/UI/tables/TableScanner.tsx b/FRONT/BUILD/resources/app/src/components/UI/tables/TableScanner.tsx index 8657a17..e1b8c6f 100644 --- a/FRONT/BUILD/resources/app/src/components/UI/tables/TableScanner.tsx +++ b/FRONT/BUILD/resources/app/src/components/UI/tables/TableScanner.tsx @@ -1,4 +1,4 @@ -import React, {useState} from 'react'; +import React from 'react'; import { DeviceUser } from '../../../store/useDeviceStore'; interface TableScannerProps { @@ -9,19 +9,18 @@ import {IconComponent} from "../../../const/buttons/icons"; import {buttonNames} from "../../../const/buttons/names"; import {ModalMap} from "../../modalwindows/windowsType"; import {useModalContext} from "../../../store"; -import Pagination from "../Pagination"; const TableContainer = styled.div` width: 100%; + box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08); + background: ${({ theme }) => theme.primary}; margin: 24px 0; `; const StyledTable = styled.table` - width: 100%; - border-collapse: separate; - border-spacing: 0; - box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08); - background: ${({ theme }) => theme.primary}; + width: 100%; + border-collapse: separate; + border-spacing: 0; `; const TableHeaderCell = styled.th<{ sortable?: boolean }>` @@ -29,7 +28,7 @@ const TableHeaderCell = styled.th<{ sortable?: boolean }>` text-align: left; font-weight: 600; font-size: 14px; - color: ${({ theme }) => theme.textColor}; + color: ${({ theme }) => theme.textSecondary}; background: ${({ theme }) => theme.primary}; border-bottom: 1px solid ${({ theme }) => theme.borderColor}; transition: all 0.2s ease; @@ -48,11 +47,6 @@ const TableCell = styled.td` color: ${({ theme }) => theme.text}; border-bottom: 1px solid ${({ theme }) => theme.borderColor}; transition: all 0.2s ease; - button{ - background-color: transparent; - border: none; - cursor: pointer; - } `; const StatusBadge = styled.span<{ status:string }>` @@ -74,23 +68,7 @@ const TableScanner = ({devices}:TableScannerProps) => { }); }; - // Пагинация - const [currentPage, setCurrentPage] = useState(1); - const [devicesPerPage] = useState(10); - - const indexOfLastDevice = currentPage * devicesPerPage; - const indexOfFirstDevice = indexOfLastDevice - devicesPerPage; - const currentDevices = devices.slice(indexOfFirstDevice, indexOfLastDevice); - const totalPages = Math.ceil(devices.length / devicesPerPage); - - const handlePrevPage = () => { - if(currentPage > 1) setCurrentPage(currentPage - 1); - } - const handleNextPage = () => { - if(currentPage < totalPages) setCurrentPage(currentPage + 1); - } - - return ( + return ( @@ -106,30 +84,24 @@ const TableScanner = ({devices}:TableScannerProps) => { - {currentDevices.map((item, i) => ( + {devices.map((item, i) => ( - {item.hostname || item.ip} + {item.hostname || 'Неизвестен'} {item.vendor} {item.ip} {item.open_ports.join(', ') || '-'} {item.last_seen} {item.note || '-'} - + ))} - ); }; diff --git a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/about.tsx b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/about.tsx index 59a4c39..57207b9 100644 --- a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/about.tsx +++ b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/about.tsx @@ -2,10 +2,8 @@ import { MainButton } from "../../../UI/buttons/mainButton" import { workSpaceNames } from "../../../../const/workspace/names" import { useWorkSpaceStore } from "../../../../store" -import styled, {useTheme} from "styled-components" +import styled from "styled-components" import ThemeButton from "../../../UI/buttons/toggletheme" -import {buttonNames} from "../../../../const/buttons/names"; -import {IconComponent} from "../../../../const/buttons/icons"; type Props = { from: 'reg' | 'helloWindow' | 'workSpace' @@ -31,41 +29,23 @@ const Content = styled.div` justify-content: space-between; height: 100%; box-sizing: border-box; - padding: 40px 50px; - background: ${(props => props.theme.primary)}; + padding: 25px 50px; + background: ${(props => props.theme.secondary)}; border-radius: 18px; - position: relative; ` const Listing = styled.div` display: flex; flex-direction: column; - background-color: ${(props => props.theme.secondary)}; - border-radius: 10px; - padding: 24px 20px; - p{ - font-weight: bold; - font-size: 24px; - } + gap: 15px; + ` -const List = styled.ul` +const List = styled.div` display: flex; flex-direction: column; - margin: 10px 0; - padding: 0; - list-style-type: none; - font-size: 18px; - gap: 4px; - & li:before { - color: ${(props => props.theme.accent)}; - content: "•"; - font-size: 28px; - width: .8em; - display: inline-block; - position: relative; - top: 2px; - } + gap: 15px; + margin-left: 10px; ` const Title = styled.div` @@ -75,55 +55,43 @@ const Title = styled.div` const SubTitle = styled.div` display: flex; flex-direction: column; - gap: 24px; - background-color:rgba(255, 248, 225, 0.6); - border-left: #ff9800 solid 4px; - border-radius: 0 8px 8px 0; - padding: 20px 12px; - - a{ - text-decoration: none; - color: ${(props => props.theme.errorColor)}; - font-weight: 500; - font-size: 18px; - width: max-content; - } + gap: 10px; + p{ font-size: 18px; - color: ${(props=>props.theme.textColor)}; - } - .icon{ - width: 32px; - height: 32px; - fill: #ff9800; } + ` const Links = styled.div` display: flex; - justify-content: start; + flex-direction: column; gap: 20px; ` -const LinkBlock = styled.a` - text-decoration: none; - color: ${(props => props.theme.accent)};; +const LinkColumn = styled.div` + display: flex; + flex-direction: column; + gap: 10px; +` + + +const LinkBlock = styled.div` + display: flex; + gap: 5px; ` const Copyright = styled.div` width: 100%; - text-align: start; - color: ${(props => props.theme.offlineColor)}; + text-align: center; + margin-top: 50px; ` const ButtonContainer = styled.div` - position: absolute; - top: 12px; - right: 14px; -` -const AboutLine = styled.hr` - border: ${(props => props.theme.hoverBtn)} 1px solid; width: 100%; + display: flex; + justifi-content: flex-start; + align-items: center; ` const MainTitle = styled.div` @@ -131,33 +99,24 @@ const MainTitle = styled.div` display: flex; gap: 15px; align-items: center; - justify-content: space-between; - padding-top: 10px; + justify-content: center; + padding-top: 50px; box-sizing: border-box; img{ - width: 50px; - height: 50px; - } - .version{ - text-wrap: nowrap; - background-color: ${(props => props.theme.hoverBtn)}; - color: ${(props => props.theme.borderColor)}; - border-radius: 20px; - font-size: 18px; - padding: 10px 18px; - line-height: 1; - } - .title{ - display: flex; - justify-content: center; - align-items: center; - gap: 24px; + width: 40px; + height: 40px; } ` +const Text = styled.div` + display: flex; + flex-direction: column; + gap: 30px; +` export default function About({ from, onBack }: Props) { const { setWorkModule } = useWorkSpaceStore() + const getBackHandler = () => { switch (from) { case 'reg': @@ -179,63 +138,68 @@ export default function About({ from, onBack }: Props) { -
- -

О приложении

-
-

v 0.0.3

+ +

О приложении

+
- - - <p>ГоNets — минимально работоспособный кроссплатформенный продукт (MVP) для демонстрации нашего подхода к управлению настройками ПК в корпоративной среде.</p> - + - -

Возможности:

- -
  • Визуализация активных сетевых ресурсов
  • -
  • Настройка параметров локальных и удалённых сетевых ресурсов
  • -
  • Управление взаимодействием ресурсов с Клиентом ГoNets
  • -
    -
    + + <p>Приложение ГоNets является минимально работоспособным кроссплатформенным продуктом (MVP) для демонстрации нашего подхода к управлению настройками ПК в корпоративной среде.</p> + - - - - -

    Программное обеспечение исключительно для ознакомления и домашнего использования.

    - Перейти на ГоNets-PRO -
    - - - Домашняя страницa - + +

    Данное приложение умеет:

    + +

    - Отображать в графическом виде активные сетевые ресурсы

    +

    - Настраивать сетевые параметры локального и удаленных сетевых ресурсов

    +

    - Отображать и изменять взаимодействие сетевых ресурсов с установленным Клиентом ГоNets

    +
    +
    - - Документация - + +

    Программное обеспечение исключительно для ознакомления и домашнего использования.

    +

    Для коммерческого использования приобретите версию ГоNets-PRO (Подробная информация на странице продукта)

    +
    - - Лицензия - -
    + + +

    Ссылка на домашнюю страницу:

    + https://gossys.dev/pages/projects/gonets +
    + + +

    Инструкции и информация:

    + https://wiki.gossys.dev/ru/gonets +
    + + +

    Распространяется под лицензией GosysPUB текущей версии.

    + +

    Полный текст актуальной лицензии:

    + https://wiki.gossys.dev/ru/lic/GosysPUB +
    +
    + +
    + + +

    Разработано и поддерживается ООО «Гибридные Офисные Системы» 2024-2025 г. Все права защищены.

    +
    + +
    - - Разработано и поддерживается ООО «Гибридные Офисные Системы» 2024-2025 г. Все права защищены. - {showBackButton && backHandler && ( - - )} {from == 'reg' && diff --git a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/ListUsers.tsx b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/ListUsers.tsx index 52f146e..1075a09 100644 --- a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/ListUsers.tsx +++ b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/ListUsers.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React from 'react'; import styled from 'styled-components'; import DeviceCard from "../../../../../UI/Dropdown/DeviceCard"; import {DeviceUser} from "../../../../../../store/useDeviceStore"; @@ -28,15 +28,10 @@ const ListUsers = ({loading, handleScan, devices, scanInitiated}: ListUsersProps const activeDevices = devices.filter(device => device.status === 'online'); const inactiveDevices = devices.filter(device => device.status !== 'online'); - // Пагинация - const [currentPage, setCurrentPage] = useState(1); - const [devicesPerPage] = useState(10); - - return ( <> - {devices.length > 0 ? 'Обновить список' : 'Сканировать узлы'} + {devices.length > 0 ? 'Обновить список' : 'Сканировать сеть'} {devices.length > 0 ? ( @@ -47,7 +42,7 @@ const ListUsers = ({loading, handleScan, devices, scanInitiated}: ListUsersProps }}> {/* Колонка активных устройств */}
    -

    Активные узлы ({activeDevices.length})

    +

    Активные устройства ({activeDevices.length})

    {activeDevices.map((device, index) => ( {/* Колонка неактивных устройств */}
    -

    Неактивные узлы ({inactiveDevices.length})

    +

    Неактивные устройства ({inactiveDevices.length})

    {inactiveDevices.map((device, index) => (
    ) : scanInitiated ? ( -

    Узлы не найдены

    +

    Устройства не найдены

    ) : null} ); diff --git a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx index 77e064c..ebe71a9 100644 --- a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx +++ b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx @@ -30,13 +30,13 @@ const ListUsers = ({loading, handleScan, devices, scanInitiated}: ListUsersProps return ( <> - {devices.length > 0 ? 'Обновить список' : 'Сканировать узлы'} + {devices.length > 0 ? 'Обновить список' : 'Сканировать сеть'} {devices.length > 0 ? ( ) : scanInitiated ? ( -

    Узлы не найдены

    +

    Устройства не найдены

    ) : null} ); diff --git a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx index 19ca497..cb816ca 100644 --- a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx +++ b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx @@ -77,7 +77,7 @@ const UserLocate = styled.div<{ loading: boolean, scanInitiated: boolean }>` span { position: absolute; display: inline-block; - background: ${(props) => props.theme.scannerColor}; + background: ${(props) => props.theme.accent}; top: 50%; left: 50%; transform: translate(-50%, -50%); @@ -163,7 +163,7 @@ export default function UserScanner() { return ( - {(!scanInitiated || loading) && (Сканирование узлов подсети)} + {(!scanInitiated || loading) && (Сканирование пользователей в сети)} @@ -177,7 +177,7 @@ export default function UserScanner() { {loading ? ( - Сканирование узлов + Сканирование сети ) : selectedView.value == 1 ? ( diff --git a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/wifiScanner/WifiScanner.tsx b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/wifiScanner/WifiScanner.tsx index 25000eb..b24e367 100644 --- a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/wifiScanner/WifiScanner.tsx +++ b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/wifiScanner/WifiScanner.tsx @@ -136,8 +136,7 @@ const ScanBtn = styled.button<{scanInitiated: boolean}>` ` export function WifiScanner() { - //const { ipAddress } = useIpStore(); - const ipAddress = '192.168.1.147' + const { ipAddress } = useIpStore(); const [loading, setLoading] = useState(false); const [scanInitiated, setScanInitiated] = useState(false); const { wifiNetworks, setWifiNetworks } = useNetworkStore(); @@ -162,19 +161,17 @@ export function WifiScanner() { return ( - Сканирование точек доступа Wi-Fi сети + Сканирование Wi-Fi сети - {wifiNetworks.map((network, index) => ( + {wifiNetworks.map((network) => ( ))} @@ -189,11 +186,11 @@ export function WifiScanner() { {loading ? ( - Сканирование точек доступа + Сканирование сети ) : ( 0 }> - {wifiNetworks.length > 0 ? 'Обновить список' : 'Сканировать точки доступа'} + {wifiNetworks.length > 0 ? 'Обновить список' : 'Сканировать сеть'} )} diff --git a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/wifiScanner/modules/WifiDot.tsx b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/wifiScanner/modules/WifiDot.tsx index 54fee2b..eccd601 100644 --- a/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/wifiScanner/modules/WifiDot.tsx +++ b/FRONT/BUILD/resources/app/src/components/workSpace/modules/appModules/wifiScanner/modules/WifiDot.tsx @@ -31,45 +31,43 @@ const Dot = styled.div<{ top: string; left: string }>` } `; -const getPositionInRing = (index: number, total: number, ringSize: number) => { - const angle = (index * (2 * Math.PI / total)) + (Math.PI / total * (index % 2)); - const innerRadius = ringSize * 0.4; - const outerRadius = ringSize * 0.5; - const radius = innerRadius + (outerRadius - innerRadius) * (0.3 + 0.7 * (index % 10) / 10); +const WifiDot = ({ network, onSelect }: { network: WifiNetworkScanner, onSelect: (n: WifiNetworkScanner) => void }) => { + const getPositionInRing = (bssid: string, ringSize: number) => { + const hash = bssid.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0); + const randomAngle = (hash % 360) * (Math.PI / 180); + const innerRadius = ringSize * 0.4; + const outerRadius = ringSize * 0.5; + const randomValue = (hash % 1000) / 1000; + const randomRadius = Math.sqrt(innerRadius * innerRadius + randomValue * (outerRadius * outerRadius - innerRadius * innerRadius)); - return { - x: Math.cos(angle) * radius, - y: Math.sin(angle) * radius + return { + x: Math.cos(randomAngle) * randomRadius, + y: Math.sin(randomAngle) * randomRadius + }; }; -}; -const WifiDot = ({ network, index, total, onSelect }: { - network: WifiNetworkScanner, - index: number, - total: number, - onSelect: (n: WifiNetworkScanner) => void -}) => { - const getPosition = (signal: number, index: number, total: number) => { + const getPosition = (signal: number, bssid: string) => { let strength: 1 | 2 | 3; if (signal >= -50) { strength = 3; } else if (signal >= -70) { strength = 2; + } else if (signal >= -90) { + strength = 1; } else { strength = 1; } - const ringSizes = { 1: 550, 2: 400, 3: 250 }; const ringSize = ringSizes[strength]; - const offset = getPositionInRing(index, total, ringSize); + const offset = getPositionInRing(bssid, ringSize); return { - top: `calc(50% + ${offset.y}px)`, - left: `calc(50% + ${offset.x}px)` + top: `calc(50% - ${offset.y}px)`, + left: `calc(50% - ${offset.x}px)` }; }; - const position = getPosition(network.signal, index, total); + const position = getPosition(network.signal, network.bssid); return ( onSelect(network)}> diff --git a/FRONT/BUILD/resources/app/src/components/workSpace/modules/workModules/networkInterfaces.tsx b/FRONT/BUILD/resources/app/src/components/workSpace/modules/workModules/networkInterfaces.tsx index d0325ef..1996ddd 100644 --- a/FRONT/BUILD/resources/app/src/components/workSpace/modules/workModules/networkInterfaces.tsx +++ b/FRONT/BUILD/resources/app/src/components/workSpace/modules/workModules/networkInterfaces.tsx @@ -76,7 +76,7 @@ export const NetworkInterfaces = ({ startConnection, ws }: Props) => { setHasInited(false) initializationAttempt.current = 0; - const newSocket = new WebSocket(`ws://${ws}:8001/api/v1`); + const newSocket = new WebSocket(`wss://${ws}:8001/api/v1`); let connectionTimeout; setSocket(newSocket); diff --git a/FRONT/BUILD/resources/app/src/components/workSpace/sideBar/toolSpace/devicesBar.tsx b/FRONT/BUILD/resources/app/src/components/workSpace/sideBar/toolSpace/devicesBar.tsx index dd5ca2b..8b919f4 100644 --- a/FRONT/BUILD/resources/app/src/components/workSpace/sideBar/toolSpace/devicesBar.tsx +++ b/FRONT/BUILD/resources/app/src/components/workSpace/sideBar/toolSpace/devicesBar.tsx @@ -115,7 +115,7 @@ export const DevicesBar = () => { const checkWebSocketAvailability = async (ip: string): Promise => { return new Promise((resolve) => { - const testSocket = new WebSocket(`ws://${ip}:8001/api/v1`); + const testSocket = new WebSocket(`wss://${ip}:8001/api/v1`); const timeout = setTimeout(() => { testSocket.close(); resolve(false); diff --git a/FRONT/BUILD/resources/app/src/const/buttons/icons.tsx b/FRONT/BUILD/resources/app/src/const/buttons/icons.tsx index 9cab629..301b1d6 100644 --- a/FRONT/BUILD/resources/app/src/const/buttons/icons.tsx +++ b/FRONT/BUILD/resources/app/src/const/buttons/icons.tsx @@ -9,7 +9,6 @@ import settings from '@iconify/icons-ic/baseline-settings'; import info from '@iconify/icons-ic/baseline-info'; import arrowDown from '@iconify/icons-ic/baseline-keyboard-arrow-down'; import arrowRight from '@iconify/icons-ic/baseline-keyboard-arrow-right'; -import arrowLeft from '@iconify/icons-ic/baseline-keyboard-arrow-left'; import edit from '@iconify/icons-ic/baseline-edit'; import checkCircle from '@iconify/icons-ic/round-check-circle'; import cancel from '@iconify/icons-ic/baseline-cancel'; @@ -38,7 +37,6 @@ export const ICONS = { [buttonNames[14]]: userSearch, [buttonNames[15]]: wifiFind, [buttonNames[16]]: noteEdit, - [buttonNames[17]]: arrowLeft, } as const; type IconName = keyof typeof ICONS; diff --git a/FRONT/BUILD/resources/app/src/const/buttons/names.ts b/FRONT/BUILD/resources/app/src/const/buttons/names.ts index 052321e..54c1d40 100644 --- a/FRONT/BUILD/resources/app/src/const/buttons/names.ts +++ b/FRONT/BUILD/resources/app/src/const/buttons/names.ts @@ -16,6 +16,5 @@ export const buttonNames: names ={ 13: 'noAdmin', 14: 'userSearch', 15: 'wifiFind', - 16: 'noteEdit', - 17: 'arrowLeft', + 16: 'noteEdit' } \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/const/menus/sideBar/icons.tsx b/FRONT/BUILD/resources/app/src/const/menus/sideBar/icons.tsx index b5560ce..1d80d6b 100644 --- a/FRONT/BUILD/resources/app/src/const/menus/sideBar/icons.tsx +++ b/FRONT/BUILD/resources/app/src/const/menus/sideBar/icons.tsx @@ -3,7 +3,7 @@ import { toolBarNames } from "./names" import { useTheme } from "styled-components" import { Icon } from '@iconify/react'; -import desktop from '@iconify/icons-ic/baseline-menu'; +import desktop from '@iconify/icons-ic/round-desktop-windows'; export const ICONS = { [toolBarNames[1]]: desktop, diff --git a/FRONT/BUILD/resources/app/src/const/theme/theme.ts b/FRONT/BUILD/resources/app/src/const/theme/theme.ts index dbf1cb3..aab3658 100644 --- a/FRONT/BUILD/resources/app/src/const/theme/theme.ts +++ b/FRONT/BUILD/resources/app/src/const/theme/theme.ts @@ -24,7 +24,7 @@ export const dark = { background: '#3A3A3A', textColor: '#FFFFFF', borderColor: '#b6b6b6', - scannerColor: '#00E5FF', + scannerColor: '#0E9C9D', offlineColor: '#656565', hoverBtn: '#4a4a4a', }; \ No newline at end of file diff --git a/FRONT/DEV/.gitignore b/FRONT/DEV/.gitignore new file mode 100644 index 0000000..b2d59d1 --- /dev/null +++ b/FRONT/DEV/.gitignore @@ -0,0 +1,2 @@ +/node_modules +/dist \ No newline at end of file diff --git a/FRONT/DEV/assets/icon.png b/FRONT/DEV/assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b39bc87e4e512daba45f91f3151ed3e92c77f0a9 GIT binary patch literal 129501 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 z%0D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 literal 0 HcmV?d00001 diff --git a/FRONT/DEV/eslint.config.js b/FRONT/DEV/eslint.config.js new file mode 100644 index 0000000..092408a --- /dev/null +++ b/FRONT/DEV/eslint.config.js @@ -0,0 +1,28 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' + +export default tseslint.config( + { ignores: ['dist'] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ['**/*.{ts,tsx}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, + }, +) diff --git a/FRONT/DEV/index.html b/FRONT/DEV/index.html new file mode 100644 index 0000000..7e0fab5 --- /dev/null +++ b/FRONT/DEV/index.html @@ -0,0 +1,12 @@ + + + + + GoNets + + + +
    + + + \ No newline at end of file diff --git a/FRONT/DEV/index.tsx b/FRONT/DEV/index.tsx new file mode 100644 index 0000000..eeb0635 --- /dev/null +++ b/FRONT/DEV/index.tsx @@ -0,0 +1,52 @@ +import React from 'react'; +import { createRoot } from 'react-dom/client'; +import { HashRouter } from 'react-router-dom'; +import { useIpStore } from './src/store'; +import { useEffect } from 'react'; +import {useCheckAdmin} from './src/utils/checkAdmin.ts' + +import { + ModalProvider, + useModalContext, + ThemeProvider +} from './src/store'; + +import WindowComponent from './src/components/modalwindows/modalWindow.tsx'; +import Router from './src/router.tsx'; + +const MainComponent = () => { + + const checkAdmin = useCheckAdmin() + const {ipAddress} = useIpStore() + + useEffect(() => { + const checkAdminStatus = async () => { + await checkAdmin() + } + checkAdminStatus() + }, [ipAddress]) + + + const { isOpen, modalType, modalData } = useModalContext(); + return ( + <> + + + + ); +}; + +const container = document.getElementById('root'); +if (!container) { + throw new Error('Root element with id "root" not found'); +} +const root = createRoot(container); +root.render( + + + + + + + +); \ No newline at end of file diff --git a/FRONT/DEV/main.js b/FRONT/DEV/main.js new file mode 100644 index 0000000..df09e91 --- /dev/null +++ b/FRONT/DEV/main.js @@ -0,0 +1,61 @@ +const { app, BrowserWindow, session, Menu, ipcMain } = require('electron'); +const path = require('path'); + +ipcMain.on('quit-app', () => { + app.quit(); +}); + +app.commandLine.appendSwitch('ignore-certificate-errors'); + +function createWindow() { + const win = new BrowserWindow({ + icon: path.join(__dirname, 'assets/icon.png'), + webPreferences: { + preload: path.join(__dirname, 'preload.js'), + contextIsolation: true, + }, + show: false + }); + + win.maximize(); + win.show(); + + if (process.env.NODE_ENV === 'development') { + win.loadURL('https://localhost:8001'); + win.webContents.openDevTools(); + } else { + win.loadFile(path.join(__dirname, 'dist/index.html')); + } +} + +app.whenReady().then(() => { + session.defaultSession.setCertificateVerifyProc((request, callback) => { + // Разрешаем для: + // 1. localhost + // 2. Всех IP в локальной сети (192.168.x.x, 10.x.x.x и т.д.) + // 3. Конкретного домена (если есть) + if ( + request.hostname === 'localhost' || + request.hostname === '127.0.0.1' || + request.hostname === '0.0.0.0' || + /^(192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)/.test(request.hostname) + ) { + return callback(0); + } + callback(-2); + }); + Menu.setApplicationMenu(null); + createWindow(); +}); + +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { + app.quit(); + } +}); + +app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) { + createWindow(); + } +}); \ No newline at end of file diff --git a/FRONT/DEV/package-lock.json b/FRONT/DEV/package-lock.json new file mode 100644 index 0000000..d77a3e1 --- /dev/null +++ b/FRONT/DEV/package-lock.json @@ -0,0 +1,4845 @@ +{ + "name": "gonets", + "version": "0.0.2", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "gonets", + "version": "0.0.2", + "dependencies": { + "@iconify/icons-ic": "^1.2.13", + "@iconify/icons-ph": "^1.2.5", + "@iconify/react": "^5.2.0", + "@reduxjs/toolkit": "^2.6.0", + "@xyflow/react": "^12.3.5", + "axios": "^1.7.9", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-flow-renderer": "^10.3.17", + "react-redux": "^9.2.0", + "react-router-dom": "^7.0.2", + "styled-components": "^6.1.13", + "zustand": "^5.0.3" + }, + "devDependencies": { + "@iconify-json/ic": "^1.2.2", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "@vitejs/plugin-basic-ssl": "^2.0.0", + "@vitejs/plugin-react": "^4.4.1", + "electron": "^34.0.2", + "electron-packager": "^17.1.2", + "esbuild-wasm": "^0.17.12", + "typescript": "^4.9.5", + "vite": "^6.3.4" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", + "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", + "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.10", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.10", + "@babel/parser": "^7.26.10", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.10", + "@babel/types": "^7.26.10", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz", + "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz", + "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.26.8", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz", + "integrity": "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", + "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", + "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", + "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz", + "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", + "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz", + "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.27.0", + "@babel/parser": "^7.27.0", + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", + "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@electron/asar": { + "version": "3.2.18", + "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.18.tgz", + "integrity": "sha512-2XyvMe3N3Nrs8cV39IKELRHTYUWFKrmqqSY1U+GMlc0jvqjIVnoxhNd2H4JolWQncbJi1DCvb5TNxZuI2fEjWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^5.0.0", + "glob": "^7.1.6", + "minimatch": "^3.0.4" + }, + "bin": { + "asar": "bin/asar.js" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/@electron/get": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", + "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "got": "^11.8.5", + "progress": "^2.0.3", + "semver": "^6.2.0", + "sumchecker": "^3.0.1" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "global-agent": "^3.0.0" + } + }, + "node_modules/@electron/notarize": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-1.2.4.tgz", + "integrity": "sha512-W5GQhJEosFNafewnS28d3bpQ37/s91CDWqxVchHfmv2dQSTWpOzNlUVQwYzC1ay5bChRV/A9BTL68yj0Pa+TSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "fs-extra": "^9.0.1" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/notarize/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", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/notarize/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" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/notarize/node_modules/universalify": { + "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/@electron/osx-sign": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.2.tgz", + "integrity": "sha512-KqVlm9WMWq19lBpCXQoThC/Koaiji2zotUDYwZDaZlZZym+FXY9mQW8wN6sUQ93nkVc42f3TQ1S/XN9S1kjM5Q==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "compare-version": "^0.1.2", + "debug": "^4.3.4", + "fs-extra": "^10.0.0", + "isbinaryfile": "^4.0.8", + "minimist": "^1.2.6", + "plist": "^3.0.5" + }, + "bin": { + "electron-osx-flat": "bin/electron-osx-flat.js", + "electron-osx-sign": "bin/electron-osx-sign.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@electron/osx-sign/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron/osx-sign/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" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/osx-sign/node_modules/universalify": { + "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/@electron/universal": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.5.1.tgz", + "integrity": "sha512-kbgXxyEauPJiQQUNG2VgUeyfQNFk6hBF11ISN2PNI6agUgPl55pv4eQmaqHzTAzchBvqZ2tQuRVaPStGf0mxGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron/asar": "^3.2.1", + "@malept/cross-spawn-promise": "^1.1.0", + "debug": "^4.3.1", + "dir-compare": "^3.0.0", + "fs-extra": "^9.0.1", + "minimatch": "^3.0.4", + "plist": "^3.0.4" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/@electron/universal/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", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/universal/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" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/universal/node_modules/universalify": { + "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/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", + "license": "MIT" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", + "license": "MIT" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.3.tgz", + "integrity": "sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.3.tgz", + "integrity": "sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.3.tgz", + "integrity": "sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.3.tgz", + "integrity": "sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.3.tgz", + "integrity": "sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.3.tgz", + "integrity": "sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.3.tgz", + "integrity": "sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.3.tgz", + "integrity": "sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.3.tgz", + "integrity": "sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.3.tgz", + "integrity": "sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.3.tgz", + "integrity": "sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.3.tgz", + "integrity": "sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.3.tgz", + "integrity": "sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.3.tgz", + "integrity": "sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.3.tgz", + "integrity": "sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.3.tgz", + "integrity": "sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.3.tgz", + "integrity": "sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.3.tgz", + "integrity": "sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.3.tgz", + "integrity": "sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.3.tgz", + "integrity": "sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.3.tgz", + "integrity": "sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.3.tgz", + "integrity": "sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.3.tgz", + "integrity": "sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.3.tgz", + "integrity": "sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.3.tgz", + "integrity": "sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@iconify-json/ic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@iconify-json/ic/-/ic-1.2.2.tgz", + "integrity": "sha512-QmjwS3lYiOmVWgTCEOTFyGODaR/+689+ajep/VsrCcsUN0Gdle5PmIcibDsdmRyrOsW/E77G41UUijdbjQUofw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@iconify/types": "*" + } + }, + "node_modules/@iconify/icons-ic": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@iconify/icons-ic/-/icons-ic-1.2.13.tgz", + "integrity": "sha512-TphrhwOvgd7CTmUhz6jgXF+SPnMtvTm03bZsAYbny2kwq4zlkhr9e16YEyPGMvKhjtTqNooA3iZ9Wa+pZ8moXQ==", + "license": "Apache-2.0", + "dependencies": { + "@iconify/types": "*" + } + }, + "node_modules/@iconify/icons-ph": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@iconify/icons-ph/-/icons-ph-1.2.5.tgz", + "integrity": "sha512-ewrnpL0u3MAP0wLDnXb/39W9W71ObyY8DNig6rYj7NEwcndWWlrGHt1RxEGYE3eqILl/IUcNIQQF1CXZAhwr/w==", + "license": "MIT", + "dependencies": { + "@iconify/types": "*" + } + }, + "node_modules/@iconify/react": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@iconify/react/-/react-5.2.0.tgz", + "integrity": "sha512-7Sdjrqq3fkkQNks9SY3adGC37NQTHsBJL2PRKlQd455PoDi9s+Es9AUTY+vGLFOYs5yO9w9yCE42pmxCwG26WA==", + "license": "MIT", + "dependencies": { + "@iconify/types": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/cyberalien" + }, + "peerDependencies": { + "react": ">=16" + } + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "license": "MIT" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@malept/cross-spawn-promise": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", + "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" + } + ], + "license": "Apache-2.0", + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@reduxjs/toolkit": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.6.0.tgz", + "integrity": "sha512-mWJCYpewLRyTuuzRSEC/IwIBBkYg2dKtQas8mty5MaV2iXzcmicS3gW554FDeOvLnY3x13NIk8MB1e8wHO7rqQ==", + "license": "MIT", + "dependencies": { + "immer": "^10.0.3", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.1.tgz", + "integrity": "sha512-kxz0YeeCrRUHz3zyqvd7n+TVRlNyTifBsmnmNPtk3hQURUyG9eAB+usz6DAwagMusjx/zb3AjvDUvhFGDAexGw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.1.tgz", + "integrity": "sha512-PPkxTOisoNC6TpnDKatjKkjRMsdaWIhyuMkA4UsBXT9WEZY4uHezBTjs6Vl4PbqQQeu6oION1w2voYZv9yquCw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.1.tgz", + "integrity": "sha512-VWXGISWFY18v/0JyNUy4A46KCFCb9NVsH+1100XP31lud+TzlezBbz24CYzbnA4x6w4hx+NYCXDfnvDVO6lcAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.1.tgz", + "integrity": "sha512-nIwkXafAI1/QCS7pxSpv/ZtFW6TXcNUEHAIA9EIyw5OzxJZQ1YDrX+CL6JAIQgZ33CInl1R6mHet9Y/UZTg2Bw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.1.tgz", + "integrity": "sha512-BdrLJ2mHTrIYdaS2I99mriyJfGGenSaP+UwGi1kB9BLOCu9SR8ZpbkmmalKIALnRw24kM7qCN0IOm6L0S44iWw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.1.tgz", + "integrity": "sha512-VXeo/puqvCG8JBPNZXZf5Dqq7BzElNJzHRRw3vjBE27WujdzuOPecDPc/+1DcdcTptNBep3861jNq0mYkT8Z6Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.1.tgz", + "integrity": "sha512-ehSKrewwsESPt1TgSE/na9nIhWCosfGSFqv7vwEtjyAqZcvbGIg4JAcV7ZEh2tfj/IlfBeZjgOXm35iOOjadcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.1.tgz", + "integrity": "sha512-m39iO/aaurh5FVIu/F4/Zsl8xppd76S4qoID8E+dSRQvTyZTOI2gVk3T4oqzfq1PtcvOfAVlwLMK3KRQMaR8lg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.1.tgz", + "integrity": "sha512-Y+GHnGaku4aVLSgrT0uWe2o2Rq8te9hi+MwqGF9r9ORgXhmHK5Q71N757u0F8yU1OIwUIFy6YiJtKjtyktk5hg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.1.tgz", + "integrity": "sha512-jEwjn3jCA+tQGswK3aEWcD09/7M5wGwc6+flhva7dsQNRZZTe30vkalgIzV4tjkopsTS9Jd7Y1Bsj6a4lzz8gQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.1.tgz", + "integrity": "sha512-ySyWikVhNzv+BV/IDCsrraOAZ3UaC8SZB67FZlqVwXwnFhPihOso9rPOxzZbjp81suB1O2Topw+6Ug3JNegejQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.1.tgz", + "integrity": "sha512-BvvA64QxZlh7WZWqDPPdt0GH4bznuL6uOO1pmgPnnv86rpUpc8ZxgZwcEgXvo02GRIZX1hQ0j0pAnhwkhwPqWg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.1.tgz", + "integrity": "sha512-EQSP+8+1VuSulm9RKSMKitTav89fKbHymTf25n5+Yr6gAPZxYWpj3DzAsQqoaHAk9YX2lwEyAf9S4W8F4l3VBQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.1.tgz", + "integrity": "sha512-n/vQ4xRZXKuIpqukkMXZt9RWdl+2zgGNx7Uda8NtmLJ06NL8jiHxUawbwC+hdSq1rrw/9CghCpEONor+l1e2gA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.1.tgz", + "integrity": "sha512-h8d28xzYb98fMQKUz0w2fMc1XuGzLLjdyxVIbhbil4ELfk5/orZlSTpF/xdI9C8K0I8lCkq+1En2RJsawZekkg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.1.tgz", + "integrity": "sha512-XiK5z70PEFEFqcNj3/zRSz/qX4bp4QIraTy9QjwJAb/Z8GM7kVUsD0Uk8maIPeTyPCP03ChdI+VVmJriKYbRHQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.1.tgz", + "integrity": "sha512-2BRORitq5rQ4Da9blVovzNCMaUlyKrzMSvkVR0D4qPuOy/+pMCrh1d7o01RATwVy+6Fa1WBw+da7QPeLWU/1mQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.1.tgz", + "integrity": "sha512-b2bcNm9Kbde03H+q+Jjw9tSfhYkzrDUf2d5MAd1bOJuVplXvFhWz7tRtWvD8/ORZi7qSCy0idW6tf2HgxSXQSg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.1.tgz", + "integrity": "sha512-DfcogW8N7Zg7llVEfpqWMZcaErKfsj9VvmfSyRjCyo4BI3wPEfrzTtJkZG6gKP/Z92wFm6rz2aDO7/JfiR/whA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.1.tgz", + "integrity": "sha512-ECyOuDeH3C1I8jH2MK1RtBJW+YPMvSfT0a5NN0nHfQYnDSJ6tUiZH3gzwVP5/Kfh/+Tt7tpWVF9LXNTnhTJ3kA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz", + "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/d3": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", + "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", + "license": "MIT" + }, + "node_modules/@types/d3-axis": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", + "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-brush": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", + "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-chord": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-contour": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", + "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", + "license": "MIT" + }, + "node_modules/@types/d3-dispatch": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz", + "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==", + "license": "MIT" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "license": "MIT", + "dependencies": { + "@types/d3-dsv": "*" + } + }, + "node_modules/@types/d3-force": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", + "license": "MIT" + }, + "node_modules/@types/d3-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", + "license": "MIT" + }, + "node_modules/@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==", + "license": "MIT" + }, + "node_modules/@types/d3-polygon": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", + "license": "MIT" + }, + "node_modules/@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", + "license": "MIT" + }, + "node_modules/@types/d3-random": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", + "license": "MIT" + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "license": "MIT" + }, + "node_modules/@types/d3-shape": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-time-format": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "license": "MIT", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/geojson": { + "version": "7946.0.14", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", + "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==", + "license": "MIT" + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "20.17.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.17.tgz", + "integrity": "sha512-/WndGO4kIfMicEQLTi/mDANUu/iVUhT7KboZPdEqqHQ4aTS+3qT3U5gIqWDFV+XouorjfgGqvKILJeHhuQgFYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.13", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", + "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", + "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/resize-observer-browser": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.11.tgz", + "integrity": "sha512-cNw5iH8JkMkb3QkCoe7DaZiawbDQEUX8t7iuQaRTyLOyQCR2h+ibBD4GJt7p5yhUHrlOeL7ZtbxNHeipqNsBzQ==", + "license": "MIT" + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/stylis": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz", + "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==", + "license": "MIT" + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "license": "MIT" + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.0.0.tgz", + "integrity": "sha512-gc9Tjg8bUxBVSTzeWT3Njc0Cl3PakHFKdNfABnZWiUgbxqmHDEn7uECv3fHVylxoYgNzAcmU7ZrILz+BwSo3sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "peerDependencies": { + "vite": "^6.0.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.4.1.tgz", + "integrity": "sha512-IpEm5ZmeXAP/osiBXVVP5KjFMzbWOonMs0NaQQl+xYnUAcq4oHUBsF2+p4MgKWG4YMmFYJU8A6sxRPuowllm6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.26.10", + "@babel/plugin-transform-react-jsx-self": "^7.25.9", + "@babel/plugin-transform-react-jsx-source": "^7.25.9", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@xyflow/react": { + "version": "12.3.5", + "resolved": "https://registry.npmjs.org/@xyflow/react/-/react-12.3.5.tgz", + "integrity": "sha512-wAYqpicdrVo1rxCu0X3M9s3YIF45Agqfabw0IBryTGqjWvr2NyfciI8gIP4MB+NKpWWN5kxZ9tiZ9u8lwC7iAg==", + "license": "MIT", + "dependencies": { + "@xyflow/system": "0.0.46", + "classcat": "^5.0.3", + "zustand": "^4.4.0" + }, + "peerDependencies": { + "react": ">=17", + "react-dom": ">=17" + } + }, + "node_modules/@xyflow/react/node_modules/zustand": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.6.tgz", + "integrity": "sha512-ibr/n1hBzLLj5Y+yUcU7dYw8p6WnIVzdJbnX+1YpaScvZVF2ziugqHs+LAmHw4lWO9c/zRj+K1ncgWDQuthEdQ==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.2.2" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "node_modules/@xyflow/system": { + "version": "0.0.46", + "resolved": "https://registry.npmjs.org/@xyflow/system/-/system-0.0.46.tgz", + "integrity": "sha512-bmFXvboVdiydIFZmDCjrbBCYgB0d5pYdkcZPWbAxGmhMRUZ+kW3CksYgYxWabrw51rwpWitLEadvLrivG0mVfA==", + "license": "MIT", + "dependencies": { + "@types/d3-drag": "^3.0.7", + "@types/d3-selection": "^3.0.10", + "@types/d3-transition": "^3.0.8", + "@types/d3-zoom": "^3.0.8", + "d3-drag": "^3.0.0", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/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/author-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz", + "integrity": "sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/axios": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", + "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "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==", + "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/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/browserslist": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", + "integrity": "sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001716", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001716.tgz", + "integrity": "sha512-49/c1+x3Kwz7ZIWt+4DvK3aMJy9oYXXG6/97JKsnjdCk/6n9vVyWL8NAwVt95Lwt9eigI10Hl782kDfZUUlRXw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/classcat": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz", + "integrity": "sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==", + "license": "MIT" + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/compare-version": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", + "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn-windows-exe": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cross-spawn-windows-exe/-/cross-spawn-windows-exe-1.2.0.tgz", + "integrity": "sha512-mkLtJJcYbDCxEG7Js6eUnUNndWjyUZwJ3H7bErmmtOYU/Zb99DyUkpamuIZE0b3bhmJyZ7D90uS6f+CGxRRjOw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-cross-spawn-windows-exe?utm_medium=referral&utm_source=npm_fund" + } + ], + "license": "Apache-2.0", + "dependencies": { + "@malept/cross-spawn-promise": "^1.1.0", + "is-wsl": "^2.2.0", + "which": "^2.0.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "license": "MIT", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-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, + "license": "MIT", + "optional": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/dir-compare": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz", + "integrity": "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-equal": "^1.0.0", + "minimatch": "^3.0.4" + } + }, + "node_modules/electron": { + "version": "34.0.2", + "resolved": "https://registry.npmjs.org/electron/-/electron-34.0.2.tgz", + "integrity": "sha512-u3F+DSUlg9NaGS+9qnYmSRN8VjAnc3LJDDk1ye1uISJnh4gjG76y3681qLowsPMx4obvCP2eBINnmbLo0yT5WA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@electron/get": "^2.0.0", + "@types/node": "^20.9.0", + "extract-zip": "^2.0.1" + }, + "bin": { + "electron": "cli.js" + }, + "engines": { + "node": ">= 12.20.55" + } + }, + "node_modules/electron-packager": { + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-17.1.2.tgz", + "integrity": "sha512-XofXdikjYI7MVBcnXeoOvRR+yFFFHOLs3J7PF5KYQweigtgLshcH4W660PsvHr4lYZ03JBpLyEcUB8DzHZ+BNw==", + "deprecated": "Please use @electron/packager moving forward. There is no API change, just a package name change", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@electron/asar": "^3.2.1", + "@electron/get": "^2.0.0", + "@electron/notarize": "^1.2.3", + "@electron/osx-sign": "^1.0.5", + "@electron/universal": "^1.3.2", + "cross-spawn-windows-exe": "^1.2.0", + "debug": "^4.0.1", + "extract-zip": "^2.0.0", + "filenamify": "^4.1.0", + "fs-extra": "^11.1.0", + "galactus": "^1.0.0", + "get-package-info": "^1.0.0", + "junk": "^3.1.0", + "parse-author": "^2.0.0", + "plist": "^3.0.0", + "rcedit": "^3.0.1", + "resolve": "^1.1.6", + "semver": "^7.1.3", + "yargs-parser": "^21.1.1" + }, + "bin": { + "electron-packager": "bin/electron-packager.js" + }, + "engines": { + "node": ">= 14.17.5" + }, + "funding": { + "url": "https://github.com/electron/electron-packager?sponsor=1" + } + }, + "node_modules/electron-packager/node_modules/fs-extra": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/electron-packager/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" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-packager/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-packager/node_modules/universalify": { + "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/electron-to-chromium": { + "version": "1.5.145", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.145.tgz", + "integrity": "sha512-pZ5EcTWRq/055MvSBgoFEyKf2i4apwfoqJbK/ak2jnFq8oHjZ+vzc3AhRcz37Xn+ZJfL58R666FLJx0YOK9yTw==", + "dev": true, + "license": "ISC" + }, + "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/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "optional": true, + "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, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/esbuild": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.3.tgz", + "integrity": "sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.3", + "@esbuild/android-arm": "0.25.3", + "@esbuild/android-arm64": "0.25.3", + "@esbuild/android-x64": "0.25.3", + "@esbuild/darwin-arm64": "0.25.3", + "@esbuild/darwin-x64": "0.25.3", + "@esbuild/freebsd-arm64": "0.25.3", + "@esbuild/freebsd-x64": "0.25.3", + "@esbuild/linux-arm": "0.25.3", + "@esbuild/linux-arm64": "0.25.3", + "@esbuild/linux-ia32": "0.25.3", + "@esbuild/linux-loong64": "0.25.3", + "@esbuild/linux-mips64el": "0.25.3", + "@esbuild/linux-ppc64": "0.25.3", + "@esbuild/linux-riscv64": "0.25.3", + "@esbuild/linux-s390x": "0.25.3", + "@esbuild/linux-x64": "0.25.3", + "@esbuild/netbsd-arm64": "0.25.3", + "@esbuild/netbsd-x64": "0.25.3", + "@esbuild/openbsd-arm64": "0.25.3", + "@esbuild/openbsd-x64": "0.25.3", + "@esbuild/sunos-x64": "0.25.3", + "@esbuild/win32-arm64": "0.25.3", + "@esbuild/win32-ia32": "0.25.3", + "@esbuild/win32-x64": "0.25.3" + } + }, + "node_modules/esbuild-wasm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.17.19.tgz", + "integrity": "sha512-X9UQEMJMZXwlGCfqcBmJ1jEa+KrLfd+gCBypO/TSzo5hZvbVwFqpxj1YCuX54ptTF75wxmrgorR4RL40AKtLVg==", + "dev": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fdir": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", + "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/filenamify": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", + "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flora-colossus": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flora-colossus/-/flora-colossus-2.0.0.tgz", + "integrity": "sha512-dz4HxH6pOvbUzZpZ/yXhafjbR2I8cenK5xL0KtBFb7U2ADsR+OwXifnxZjij/pZWF775uSCMzWVd+jDik2H2IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "fs-extra": "^10.1.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/flora-colossus/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/flora-colossus/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" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/flora-colossus/node_modules/universalify": { + "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/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "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", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/galactus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/galactus/-/galactus-1.0.0.tgz", + "integrity": "sha512-R1fam6D4CyKQGNlvJne4dkNF+PvUUl7TAJInvTGa9fti9qAv95quQz29GXapA4d8Ec266mJJxFVh82M4GIIGDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "flora-colossus": "^2.0.0", + "fs-extra": "^10.1.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/galactus/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/galactus/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" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/galactus/node_modules/universalify": { + "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/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-package-info": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz", + "integrity": "sha512-SCbprXGAPdIhKAXiG+Mk6yeoFH61JlYunqdFQFHDtLjJlDjFf6x07dsS8acO+xWt52jpdVo49AlVDnUVK1sDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bluebird": "^3.1.1", + "debug": "^2.2.0", + "lodash.get": "^4.0.0", + "read-pkg-up": "^2.0.0" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/get-package-info/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/get-package-info/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "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" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/global-agent/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/immer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz", + "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "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.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "license": "ISC", + "optional": true + }, + "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" + }, + "engines": { + "node": ">=6" + } + }, + "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/junk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", + "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "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/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/parse-author": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz", + "integrity": "sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "author-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "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", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "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/plist": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", + "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rcedit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/rcedit/-/rcedit-3.1.0.tgz", + "integrity": "sha512-WRlRdY1qZbu1L11DklT07KuHfRk42l0NFFJdaExELEu4fEQ982bP5Z6OWGPj/wLLIuKRQDCxZJGAwoFsxhZhNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn-windows-exe": "^1.1.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-flow-renderer": { + "version": "10.3.17", + "resolved": "https://registry.npmjs.org/react-flow-renderer/-/react-flow-renderer-10.3.17.tgz", + "integrity": "sha512-bywiqVErlh5kCDqw3x0an5Ur3mT9j9CwJsDwmhmz4i1IgYM1a0SPqqEhClvjX+s5pU4nHjmVaGXWK96pwsiGcQ==", + "deprecated": "react-flow-renderer has been renamed to reactflow, please use this package from now on https://reactflow.dev/docs/guides/migrate-to-v11/", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.9", + "@types/d3": "^7.4.0", + "@types/resize-observer-browser": "^0.1.7", + "classcat": "^5.0.3", + "d3-drag": "^3.0.0", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0", + "zustand": "^3.7.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "16 || 17 || 18", + "react-dom": "16 || 17 || 18" + } + }, + "node_modules/react-flow-renderer/node_modules/zustand": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", + "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==", + "license": "MIT", + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } + }, + "node_modules/react-redux": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", + "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", + "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25 || ^19", + "react": "^18.0 || ^19", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-redux/node_modules/use-sync-external-store": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz", + "integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.5.2.tgz", + "integrity": "sha512-9Rw8r199klMnlGZ8VAsV/I8WrIF6IyJ90JQUdboupx1cdkgYqwnrYjH+I/nY/7cA1X5zia4mDJqH36npP7sxGQ==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0", + "turbo-stream": "2.4.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.5.2.tgz", + "integrity": "sha512-yk1XW8Fj7gK7flpYBXF3yzd2NbX6P7Kxjvs2b5nu1M04rb5pg/Zc4fGdBNTeT4eDYL2bvzWNyKaIMJX/RKHTTg==", + "license": "MIT", + "dependencies": { + "react-router": "7.5.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "license": "MIT" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "license": "MIT", + "peerDependencies": { + "redux": "^5.0.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/rollup": { + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.1.tgz", + "integrity": "sha512-C5VvvgCCyfyotVITIAv+4efVytl5F7wt+/I2i9q9GZcEXW9BP52YYOXC58igUi+LFZVHukErIIqQSWwv/M3WRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.7" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.40.1", + "@rollup/rollup-android-arm64": "4.40.1", + "@rollup/rollup-darwin-arm64": "4.40.1", + "@rollup/rollup-darwin-x64": "4.40.1", + "@rollup/rollup-freebsd-arm64": "4.40.1", + "@rollup/rollup-freebsd-x64": "4.40.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.40.1", + "@rollup/rollup-linux-arm-musleabihf": "4.40.1", + "@rollup/rollup-linux-arm64-gnu": "4.40.1", + "@rollup/rollup-linux-arm64-musl": "4.40.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.40.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.40.1", + "@rollup/rollup-linux-riscv64-gnu": "4.40.1", + "@rollup/rollup-linux-riscv64-musl": "4.40.1", + "@rollup/rollup-linux-s390x-gnu": "4.40.1", + "@rollup/rollup-linux-x64-gnu": "4.40.1", + "@rollup/rollup-linux-x64-musl": "4.40.1", + "@rollup/rollup-win32-arm64-msvc": "4.40.1", + "@rollup/rollup-win32-ia32-msvc": "4.40.1", + "@rollup/rollup-win32-x64-msvc": "4.40.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "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, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "license": "MIT" + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "license": "MIT" + }, + "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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/sprintf-js": { + "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==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-outer/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/styled-components": { + "version": "6.1.13", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.13.tgz", + "integrity": "sha512-M0+N2xSnAtwcVAQeFEsGWFFxXDftHUD7XrKla06QbpUMmbmtFBMMTcKWvFXtWxuD5qQkB8iU5gk6QASlx2ZRMw==", + "license": "MIT", + "dependencies": { + "@emotion/is-prop-valid": "1.2.2", + "@emotion/unitless": "0.8.1", + "@types/stylis": "4.2.5", + "css-to-react-native": "3.2.0", + "csstype": "3.1.3", + "postcss": "8.4.38", + "shallowequal": "1.1.0", + "stylis": "4.3.2", + "tslib": "2.6.2" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0" + } + }, + "node_modules/stylis": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", + "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==", + "license": "MIT" + }, + "node_modules/sumchecker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", + "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.1.0" + }, + "engines": { + "node": ">= 8.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", + "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/trim-repeated/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "license": "0BSD" + }, + "node_modules/turbo-stream": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz", + "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==", + "license": "ISC" + }, + "node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + }, + "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/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vite": { + "version": "6.3.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.4.tgz", + "integrity": "sha512-BiReIiMS2fyFqbqNT/Qqt4CVITDU9M9vE+DKcVAsB+ZV0wvTKd+3hMbkpxz1b+NmEDMegpVbisKiAZOnvO92Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "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==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/zustand": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.3.tgz", + "integrity": "sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } + } + } +} diff --git a/FRONT/DEV/package.json b/FRONT/DEV/package.json new file mode 100644 index 0000000..304540a --- /dev/null +++ b/FRONT/DEV/package.json @@ -0,0 +1,39 @@ +{ + "name": "gonets", + "version": "0.0.2", + "main": "main.js", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview", + "start": "electron .", + "package": "vite build && electron-packager . --out=dist --overwrite --icon=assets/icon" + }, + "dependencies": { + "@iconify/icons-ic": "^1.2.13", + "@iconify/icons-ph": "^1.2.5", + "@iconify/react": "^5.2.0", + "@reduxjs/toolkit": "^2.6.0", + "@xyflow/react": "^12.3.5", + "axios": "^1.7.9", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-flow-renderer": "^10.3.17", + "react-redux": "^9.2.0", + "react-router-dom": "^7.0.2", + "styled-components": "^6.1.13", + "zustand": "^5.0.3" + }, + "devDependencies": { + "@iconify-json/ic": "^1.2.2", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "@vitejs/plugin-basic-ssl": "^2.0.0", + "@vitejs/plugin-react": "^4.4.1", + "electron": "^34.0.2", + "electron-packager": "^17.1.2", + "esbuild-wasm": "^0.17.12", + "typescript": "^4.9.5", + "vite": "^6.3.4" + } +} diff --git a/FRONT/DEV/preload.js b/FRONT/DEV/preload.js new file mode 100644 index 0000000..3e21ba6 --- /dev/null +++ b/FRONT/DEV/preload.js @@ -0,0 +1,19 @@ +const { contextBridge, ipcRenderer } = require('electron'); + +contextBridge.exposeInMainWorld('electron', { + send: (channel, data) => { + ipcRenderer.send(channel, data); + }, + on: (channel, func) => { + ipcRenderer.on(channel, (event, ...args) => func(...args)); + }, + quitApp: () => { + ipcRenderer.send('quit-app'); + }, + + onThemeChange: (callback) => { + ipcRenderer.on('theme-update', (event, theme) => { + callback(theme); + }); + } +}); \ No newline at end of file diff --git a/FRONT/DEV/public/assets/images/back1.svg b/FRONT/DEV/public/assets/images/back1.svg new file mode 100644 index 0000000..6c1ae68 --- /dev/null +++ b/FRONT/DEV/public/assets/images/back1.svg @@ -0,0 +1,836 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FRONT/DEV/public/assets/images/bigLogo.svg b/FRONT/DEV/public/assets/images/bigLogo.svg new file mode 100644 index 0000000..fbc2512 --- /dev/null +++ b/FRONT/DEV/public/assets/images/bigLogo.svg @@ -0,0 +1,20 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + diff --git a/FRONT/DEV/public/assets/images/bukvi.svg b/FRONT/DEV/public/assets/images/bukvi.svg new file mode 100644 index 0000000..88ba39c --- /dev/null +++ b/FRONT/DEV/public/assets/images/bukvi.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/FRONT/DEV/public/assets/images/cancel.svg b/FRONT/DEV/public/assets/images/cancel.svg new file mode 100644 index 0000000..a39ab7f --- /dev/null +++ b/FRONT/DEV/public/assets/images/cancel.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/FRONT/DEV/public/assets/images/check.svg b/FRONT/DEV/public/assets/images/check.svg new file mode 100644 index 0000000..a91a6c0 --- /dev/null +++ b/FRONT/DEV/public/assets/images/check.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FRONT/DEV/public/assets/images/edit.svg b/FRONT/DEV/public/assets/images/edit.svg new file mode 100644 index 0000000..f3f1b8e --- /dev/null +++ b/FRONT/DEV/public/assets/images/edit.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FRONT/DEV/public/assets/images/ethernet.svg b/FRONT/DEV/public/assets/images/ethernet.svg new file mode 100644 index 0000000..ef4cdcd --- /dev/null +++ b/FRONT/DEV/public/assets/images/ethernet.svg @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/FRONT/DEV/public/assets/images/gossys.png b/FRONT/DEV/public/assets/images/gossys.png new file mode 100644 index 0000000000000000000000000000000000000000..5b01b0eabdeb95c7f122c1d20dcfe9e60ac9c9d7 GIT binary patch literal 70993 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 + + + + + + + + + + + + + + + + + + + + + + diff --git a/FRONT/DEV/public/assets/images/signal.svg b/FRONT/DEV/public/assets/images/signal.svg new file mode 100644 index 0000000..a589c67 --- /dev/null +++ b/FRONT/DEV/public/assets/images/signal.svg @@ -0,0 +1,17 @@ + + + + + + + + + + \ No newline at end of file diff --git a/FRONT/DEV/public/assets/images/vite.svg b/FRONT/DEV/public/assets/images/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/FRONT/DEV/public/assets/images/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FRONT/DEV/public/assets/images/vpn.svg b/FRONT/DEV/public/assets/images/vpn.svg new file mode 100644 index 0000000..8999c36 --- /dev/null +++ b/FRONT/DEV/public/assets/images/vpn.svg @@ -0,0 +1,27 @@ + + + + + + + + + diff --git a/FRONT/DEV/public/assets/images/wifi.svg b/FRONT/DEV/public/assets/images/wifi.svg new file mode 100644 index 0000000..dad2dd2 --- /dev/null +++ b/FRONT/DEV/public/assets/images/wifi.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/FRONT/DEV/src/api/request.ts b/FRONT/DEV/src/api/request.ts new file mode 100644 index 0000000..99f1f22 --- /dev/null +++ b/FRONT/DEV/src/api/request.ts @@ -0,0 +1,160 @@ +import axios, { AxiosResponse } from "axios"; + +const axiosWithoutCredentials = axios.create({ + baseURL: `http://localhost:8001`, +}) + +export class NetworkService { + static createAxiosInstance(ipAddress: string) { + return axios.create({ + baseURL: `http://${ipAddress}:8001`, + }); + } + + static async checkIp(ipAddress: string, data: any): Promise { + try { + const axiosInstance = this.createAxiosInstance(ipAddress); + return await axiosInstance.post('/ip/check_ip', data); + } catch (error: any) { + return error.response; + } + } + + static async saveIp(ipAddress: string, data: any): Promise { + try { + const axiosInstance = this.createAxiosInstance(ipAddress); + return await axiosInstance.post('/ip/apply_ip', data); + } catch (error: any) { + return error.response; + } + } + + static async getHostname(): Promise{ + try{ + const response = await axiosWithoutCredentials.get('/network/get_hostname') + return response + } catch (error: any){ + return error.response + } + } + + static async createUser(ipAddress: string, data: any): Promise { + try { + const axiosInstance = this.createAxiosInstance(ipAddress); + return await axiosInstance.post('/auth/register', data); + } catch (error: any) { + return error.response; + } + } + + static async login(ipAddress: string, data: any): Promise { + try { + const axiosInstance = this.createAxiosInstance(ipAddress); + return await axiosInstance.post('/auth/login', data); + } catch (error: any) { + return error.response; + } + } + + static async logout(ipAddress: string): Promise { + try { + const axiosInstance = this.createAxiosInstance(ipAddress); + return await axiosInstance.get('/auth/logout'); + } catch (error: any) { + return error.response; + } + } + + static async checkServerConf(ipAddress: string): Promise { + try { + const axiosInstance = this.createAxiosInstance(ipAddress); + return await axiosInstance.get('/auth/check_json'); + } catch (error: any) { + return error.response; + } + } + + static async whoami(ipAddress: string): Promise { + try { + const axiosInstance = this.createAxiosInstance(ipAddress); + return await axiosInstance.get('/auth/me'); + } catch (error: any) { + return error.response; + } + } + + static async scanUser(ipAddress: string): Promise { + try { + const axiosInstance = this.createAxiosInstance(ipAddress); + return await axiosInstance.get('/subnet/devices'); + } catch (error: any) { + return error.response; + } + } + + static async scanWifi(ipAddress: string): Promise { + try { + const axiosInstance = this.createAxiosInstance(ipAddress); + return await axiosInstance.get('/subnet/wifi'); + } catch (error: any) { + return error.response; + } + } + static async addNote(ipAddress: string, address:string, note: string,type:string): Promise { + try { + const axiosInstance = this.createAxiosInstance(ipAddress); + return await axiosInstance.post(`/subnet/${type}/${address}/note`, { + note: note + }); + } catch (error: any) { + return error.response; + } + } + static async editNote(ipAddress: string, address:string, note: string,type:string): Promise { + try { + const axiosInstance = this.createAxiosInstance(ipAddress); + return await axiosInstance.put(`/subnet/${type}/${address}/note`, { + note: note + }); + } catch (error: any) { + return error.response; + } + } + static async deleteNote(ipAddress: string, address:string, type:string): Promise { + try { + const axiosInstance = this.createAxiosInstance(ipAddress); + return await axiosInstance.delete(`/subnet/${type}/${address}/note`); + } catch (error: any) { + return error.response; + } + } + static async statusNetwork(ipAddress: string): Promise { + try { + const axiosInstance = this.createAxiosInstance(ipAddress); + return await axiosInstance.get(`/subnet/wifi/status`); + } catch (error: any) { + return error.response; + } + } + static async connectNetwork(ipAddress: string, password:string, address: string): Promise { + try { + const axiosInstance = this.createAxiosInstance(ipAddress); + return await axiosInstance.post(`/subnet/wifi/connect`, { + ssid: address, + password: password, + }); + } catch (error: any) { + return error.response; + } + } + static async disconnectNetwork(ipAddress: string, ssid: string): Promise { + try { + const axiosInstance = this.createAxiosInstance(ipAddress); + return await axiosInstance.post(`/subnet/wifi/disconnect`, { + ssid: ssid, + }); + } catch (error: any) { + return error.response; + } + } +} \ No newline at end of file diff --git a/FRONT/DEV/src/assets/css/flow.css b/FRONT/DEV/src/assets/css/flow.css new file mode 100644 index 0000000..0a79079 --- /dev/null +++ b/FRONT/DEV/src/assets/css/flow.css @@ -0,0 +1,108 @@ +.react-flow { + /* Custom Variables */ + --xy-theme-selected: #F57DBD; + --xy-theme-hover: #C5C5C5; + --xy-theme-edge-hover: black; + --xy-theme-color-focus: #E8E8E8; + + /* Built-in Variables see https://reactflow.dev/learn/customization/theming */ + --xy-node-border-default: 1px solid #EDEDED; + + /* --xy-node-boxshadow-default: + 0px 3.54px 4.55px 0px #00000005, + 0px 3.54px 4.55px 0px #0000000D, + 0px 0.51px 1.01px 0px #0000001A; */ + + --xy-node-border-radius-default: 8px; + + --xy-handle-background-color-default: #ffffff; + --xy-handle-border-color-default: #AAAAAA; + + --xy-edge-label-color-default: #505050; +} + +.react-flow.dark { + --xy-node-boxshadow-default: + 0px 3.54px 4.55px 0px rgba(255, 255, 255, 0.05), /* light shadow */ + 0px 3.54px 4.55px 0px rgba(255, 255, 255, 0.13), /* medium shadow */ + 0px 0.51px 1.01px 0px rgba(255, 255, 255, 0.2); /* smallest shadow */ + --xy-theme-color-focus: #535353; +} + +/* Customizing Default Theming */ + +.react-flow__node { + /* box-shadow: var(--xy-node-boxshadow-default); + border-radius: var(--xy-node-border-radius-default); + background-color: var(--xy-node-background-color-default); */ + display: flex; + justify-content: center; + align-items: center; + text-align: center; + font-size: 12px; + flex-direction: column; + /* border: var(--xy-node-border-default); + color: var(--xy-node-color, var(--xy-node-color-default)); */ + pointer-events: all; + user-select: none; +} + +.react-flow__node.selectable:focus { + box-shadow: 0px 0px 0px 4px var(--xy-theme-color-focus); + border-color: #d9d9d9; +} + +.react-flow__node.selectable:focus:active { + box-shadow: var(--xy-node-boxshadow-default); +} + + +.react-flow__node.selectable:hover, +.react-flow__node.draggable:hover { + border-color: var(--xy-theme-hover); +} + +.react-flow__node.selectable.selected { + border-color: var(--xy-theme-selected); + box-shadow: var(--xy-node-boxshadow-default); +} + +.react-flow__node-group { + background-color: rgba(207, 182, 255, 0.4); + border-color: #9E86ED; +} + +.react-flow__edge.selectable:hover .react-flow__edge-path, +.react-flow__edge.selectable.selected .react-flow__edge-path { + stroke: var(--xy-theme-edge-hover); +} + +.react-flow__handle { + width: 15px; + height: 15px; +} + +.react-flow__handle.connectionindicator:hover { + pointer-events: all; + border-color: var(--xy-theme-edge-hover); + background-color: white; +} + +.react-flow__handle.connectionindicator:focus , +.react-flow__handle.connectingfrom, +.react-flow__handle.connectingto { + border-color: var(--xy-theme-edge-hover); +} + +.react-flow__node-resizer { + border-radius: 0; + border: none; +} + +.react-flow__resize-control.handle { + background-color: #ffffff; + border-color: #9E86ED; + border-radius: 0; + width: 5px; + height: 5px; +} \ No newline at end of file diff --git a/FRONT/DEV/src/assets/css/index.css b/FRONT/DEV/src/assets/css/index.css new file mode 100644 index 0000000..c597aa3 --- /dev/null +++ b/FRONT/DEV/src/assets/css/index.css @@ -0,0 +1,36 @@ +html, +body { + margin: 0; + font-family: sans-serif; + box-sizing: border-box; + min-height: 100%; + height: 100%; +} + +#root{ + width: 100%; + height: 100%; + margin: 0; + padding: 0; +} + +#app { + width: 100%; + height: 100%; + margin: 0; + padding: 0; +} + +button{ + background-color: #006666; + border: none; + padding: 6px 10px; + border-radius: 8px; + color: white; + font-size: 14px; + cursor: pointer; + + &:hover{ + background-color: #255252; + } +} \ No newline at end of file diff --git a/FRONT/DEV/src/components/UI/Dropdown/DeviceCard.tsx b/FRONT/DEV/src/components/UI/Dropdown/DeviceCard.tsx new file mode 100644 index 0000000..0345346 --- /dev/null +++ b/FRONT/DEV/src/components/UI/Dropdown/DeviceCard.tsx @@ -0,0 +1,137 @@ +import React, {useState} from 'react'; +import styled, { css } from 'styled-components'; +import { DeviceUser } from "../../../store/useDeviceStore"; +import {buttonNames} from "../../../const/buttons/names"; +import {ModalMap} from "../../modalwindows/windowsType"; +import {IconComponent} from "../../../const/buttons/icons"; +import {useModalContext} from "../../../store"; + +interface DeviceCardProps { + device: DeviceUser; + status: 'online' | 'offline'; +} + +const CardWrapper = styled.div<{ status: 'online' | 'offline' }>` + background: white; + border-radius: 12px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + overflow: hidden; + transition: all 0.3s ease; + cursor: pointer; + margin-bottom: 16px; + + &:hover { + transform: translateY(-2px); + box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15); + } +`; + +const CardHeader = styled.div<{ status: 'online' | 'offline' }>` + background: ${({ status, theme }) => + status === 'online' ? theme.successColor : theme.offlineColor}; + color: white; + padding: 16px; + font-size: 18px; + font-weight: 500; + display: flex; + justify-content: space-between; + align-items: center; +`; + + +const CardContent = styled.div<{ isExpanded: boolean }>` + max-height: 0; + opacity: 0; + padding: 0 16px; + transition: all 0.3s ease; + color: #333; + font-size: 14px; + display: grid; + gap: 12px; + + ${({ isExpanded }) => isExpanded && css` + max-height: 500px; + opacity: 1; + padding: 16px; + `} +`; + +const InfoRow = styled.div` + display: flex; + justify-content: space-between; + align-items: center; +`; + +const Label = styled.span` + font-weight: 500; + color: #666; +`; + +const Value = styled.span` + color: #333; +`; + + +const DeviceCard: React.FC = ({ device, status }) => { + const [isExpanded, setIsExpanded] = useState(false); + const toggleExpanded = () => setIsExpanded(!isExpanded); + const { openModal } = useModalContext(); + + const openModalNote = (e: React.MouseEvent) => { + e.stopPropagation(); + openModal(ModalMap['6'], { + address: device.mac, + currentNote: device.note || '' + }); + }; + + + return ( + + +

    + MAC: {device.mac} +

    + + + +
    + + + + + {device.hostname || device.ip} + + + + + {device.vendor || 'Неизвестно'} + + + + + {device.ip} + + + {device.open_ports?.length > 0 && ( + + + {device.open_ports.join(', ')} + + )} + + + + {device.last_seen} + + + + + {device.note || '-'} + + +
    + ); +}; + +export default DeviceCard; \ No newline at end of file diff --git a/FRONT/DEV/src/components/UI/Dropdown/DropdownType.tsx b/FRONT/DEV/src/components/UI/Dropdown/DropdownType.tsx new file mode 100644 index 0000000..d1e90c5 --- /dev/null +++ b/FRONT/DEV/src/components/UI/Dropdown/DropdownType.tsx @@ -0,0 +1,130 @@ +import React, {useEffect, useRef, useState} from 'react'; +import styled from "styled-components"; +import {buttonNames} from "../../../const/buttons/names"; +import {IconComponent} from "../../../const/buttons/icons"; + +type Option = { + value: number, + label: string, +} + +interface DropdownTypeProps { + options: Option[]; + label?: string; + onChange?: (selectedItem: Option) => void; + value: Option | null; +} + +const DropdownWrapper = styled.div` + position: absolute; + top: 18px; + right:20px; + display: inline-block; + background-color: ${({theme}) => theme.background}; + padding: 12px 16px; + border-radius: 12px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + z-index: 10; +` +const Label = styled.p` + color: ${({theme}) => theme.textColor}; + font-size: 16px; +` + +const Dropdown = styled.div` + background-color: ${({theme}) => theme.primary}; + border-radius: 15px; + overflow: hidden; + transition: all .3s ease; + cursor: pointer; + z-index: 10; + margin-top: 6px; +` + +const DropdownHeader = styled.div` + display: flex; + justify-content: space-between; + gap: 14px; + padding: 12px 24px; + font-size: 16px; + align-items: center; + height: 100%; + min-width: 200px; +` + +const DropdownContent = styled.div<{$isOpen: boolean}>` + max-height: ${({$isOpen}) => $isOpen ? '500px' : '0'}; + opacity: ${({$isOpen}) => $isOpen ? 1 : 0}; + transition: all .3s ease; + display: flex; + flex-direction: column; + overflow: hidden; +` + +const DropdownRow = styled.button` + padding: 12px 24px; + background-color: transparent; + text-align: start; + font-size: 16px; + border: none; + width: 100%; + color: ${({theme}) => theme.textColor}; + transition: all .3s ease; + cursor: pointer; + + &:hover { + background-color: ${({theme}) => theme.background}; + } +` + +const DropdownArrow = styled.div<{ $isOpen: boolean }>` + transition: transform 0.3s ease; + transform: rotate(${({ $isOpen }) => ($isOpen ? "90deg" : "0deg")}); +`; + +const DropdownType = ({options, value, onChange, label}: DropdownTypeProps) => { + const [isOpen, setIsOpen] = useState(false); + const dropdownRef = useRef(null); + + function toggleOpen() { + setIsOpen((prev) => !prev); + } + + function handleSelect(option: Option) { + onChange?.(option); + setIsOpen(false); + } + + useEffect(() => { + function handleClickOutside(event: MouseEvent) { + if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { + setIsOpen(false); + } + } + document.addEventListener("mousedown", handleClickOutside); + return () => document.removeEventListener("mousedown", handleClickOutside); + }, []); + + return ( + + + + +

    {value?.label || 'Select an option'}

    + + + +
    + + {options.map((option, i) => ( + handleSelect(option)}> + {option.label} + + ))} + +
    +
    + ); +}; + +export default DropdownType; \ No newline at end of file diff --git a/FRONT/BUILD/resources/app/src/components/UI/Pagination.tsx b/FRONT/DEV/src/components/UI/Pagination.tsx similarity index 100% rename from FRONT/BUILD/resources/app/src/components/UI/Pagination.tsx rename to FRONT/DEV/src/components/UI/Pagination.tsx diff --git a/FRONT/DEV/src/components/UI/animDot.tsx b/FRONT/DEV/src/components/UI/animDot.tsx new file mode 100644 index 0000000..48bee7e --- /dev/null +++ b/FRONT/DEV/src/components/UI/animDot.tsx @@ -0,0 +1,29 @@ +import styled, { keyframes } from "styled-components"; + +const blink = keyframes` + 0%, 100% { opacity: 0.3; } + 50% { opacity: 1; } +`; + +interface DotProps { + $delay: number; +} + +const Dot = styled.span` + animation: ${blink} 1s infinite; + animation-delay: ${({ $delay }) => $delay}s; + margin: 0; +`; + +const Wrapper = styled.div` + display: flex; + gap: 4px; +`; + +export const AnimDot = () => ( + + . + . + . + +); diff --git a/FRONT/DEV/src/components/UI/buttons/mainButton.tsx b/FRONT/DEV/src/components/UI/buttons/mainButton.tsx new file mode 100644 index 0000000..55ca7e3 --- /dev/null +++ b/FRONT/DEV/src/components/UI/buttons/mainButton.tsx @@ -0,0 +1,75 @@ +import styled from "styled-components"; +import { useTheme } from "styled-components"; +import { IconComponent } from "../../../const/buttons/icons"; + +const Button = styled.button.withConfig({ + shouldForwardProp: (prop) => !['color', '$hoverсolor', 'size', '$iconpos'].includes(prop), + })<{ color: string; size?: string, $hoverсolor: string, $iconpos: string }>` + background-color: ${(props) => props.color}; + border: none; + padding: ${(props) => + props.size === "small" + ? "10px 28px" + : props.size === "big" + ? "10px 20px" + : "12px 20px"}; // По умолчанию + border-radius: 8px; + color: white; + font-size: ${(props) => + props.size === "small" + ? "14px" + : props.size === "big" + ? "16px" + : "14px"}; // По умолчанию + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + flex-direction: ${(props) => + props.$iconpos === 'right' + ? 'row-reverse' + : 'row'}; + gap: 10px; + transition: all .3s ease; + &:hover{ + background-color: ${(props) => props.$hoverсolor}; + } +`; + +type Props = { + color?: string; + hoverColor?: string + size?: "small" | "big"; + title: string + onClick?: () => void; + type?: "button" | "submit" | "reset" | undefined + icon?: string + iconPosition?: 'left' | 'right' + iconSize?: { + width: string, + height: string + } + style?: any +}; + +export const MainButton = ({ color, size, title, hoverColor, type, icon, iconPosition, iconSize, onClick, style }: Props) => { + const theme = useTheme(); + const defaultColor: string = theme.accent; + const defaultHoverColor: string = theme.accentHover + + + return ( + + ); +}; \ No newline at end of file diff --git a/FRONT/DEV/src/components/UI/buttons/quitButton.tsx b/FRONT/DEV/src/components/UI/buttons/quitButton.tsx new file mode 100644 index 0000000..373655f --- /dev/null +++ b/FRONT/DEV/src/components/UI/buttons/quitButton.tsx @@ -0,0 +1,45 @@ +import { MainButton } from "./mainButton"; +import styled from "styled-components"; +import { buttonNames } from "../../../const/buttons/names"; +import { IconComponent as Icon } from '../../../const/buttons/icons'; +import { useWorkSpaceStore } from "../../../store"; + +type Props = { + size: "small" | "big"; +}; + +const Container = styled.div<{ size: "small" | "big" }>` + ${(props) => props.size === "small" && "width: 100%;"} +`; + +const Button = styled.div` + width: 100%; + cursor: pointer; + color: ${(props) => props.theme.textColor}; +`; + +const IconContainer = styled.div` + padding: 10px; +`; + +export const QuitButton = ({ size }: Props) => { + const handleExit = () => { + window.electron.quitApp(); + }; + + const { setWorkModule } = useWorkSpaceStore() + + return ( + setWorkModule('helloWindow')}> + {size === "big" ? ( + + ) : ( + + )} + + ); +}; \ No newline at end of file diff --git a/FRONT/DEV/src/components/UI/buttons/toggletheme.tsx b/FRONT/DEV/src/components/UI/buttons/toggletheme.tsx new file mode 100644 index 0000000..f1ca231 --- /dev/null +++ b/FRONT/DEV/src/components/UI/buttons/toggletheme.tsx @@ -0,0 +1,26 @@ +import styled, { useTheme } from "styled-components"; +import { IconComponent as Icon } from '../../../const/theme/icons'; +import { ThemName } from "../../../const/theme/names"; + +const Button = styled.div` + width: 100%; + cursor: pointer; +` + +const IconContainer = styled.div` + padding: 10px; + color: ${props => props.theme.text}; +` + +export default function ThemeButton() { + const theme = useTheme(); + const name = localStorage.getItem('theme') as ThemName + + return ( + + ); +} \ No newline at end of file diff --git a/FRONT/DEV/src/components/UI/inputs/input.tsx b/FRONT/DEV/src/components/UI/inputs/input.tsx new file mode 100644 index 0000000..dd2b9c9 --- /dev/null +++ b/FRONT/DEV/src/components/UI/inputs/input.tsx @@ -0,0 +1,65 @@ +import React from 'react'; +import styled from 'styled-components'; + +type Props = { + placeholderText: string; + id: string; + value?: string; + onChange?: (value: string) => void; + onFileChange?: (event: React.ChangeEvent) => void; + type?: string; + multiple?: boolean; + style?: React.CSSProperties; + search?: boolean; + onFocus?: any + onBlur?: any + $size?: string +} + +const InputContainer = styled.div` + width: 100%; + display: flex; + flex: 3; + +`; + +const StyledInput = styled.input` + padding: 8px 10px; + color: black; + border-radius: 8px; + border: 1px solid #A1A1A1; + background-color: transparent; + &:focus{ + border: 1px solid #adadad; + } + width: 100%; + font-size: 18px; + color: ${props=>props.theme.textColor} +`; + +const Input = React.forwardRef(({ placeholderText, id, value, onChange, onFileChange, type = "text", multiple, style, onFocus, onBlur }, ref) => { + const handleInputChange = (e: React.ChangeEvent) => { + const { value } = e.target; + if (onChange) { + onChange(value); + } + }; + + return ( + + + + ); +}); + +export default Input; \ No newline at end of file diff --git a/FRONT/DEV/src/components/UI/loader.tsx b/FRONT/DEV/src/components/UI/loader.tsx new file mode 100644 index 0000000..c13bd3f --- /dev/null +++ b/FRONT/DEV/src/components/UI/loader.tsx @@ -0,0 +1,101 @@ +type Props = { + loaderText: string; //Тип передаваемых данных loaderText - string +} + +import styled, { keyframes } from 'styled-components' +import { AnimDot } from './animDot'; + + +//Константа которая устанавливает кейфвреймы для вращения +const spinAnimation = keyframes` + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +` + +//Стиль экрана загрузки +export const LoaderContainer = styled.div` + top: 0px; + z-index:998; + background-color: rgba(0,0,0, 0.7); + position: fixed; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + overflow-y: hidden; +` + + +//Стиль блока с элементами загрузки +export const Loaderblock = styled.div` + display: flex; + flex-direction: column; + align-items: center; + gap: 15px; + + p{ + font-size: 24px; + color: white; + } +` +//Стиль для блока с кольцом загрузки +export const LoadingSpinner = styled.div` + position: relative; + width: 65px; + height: 65px; +` + +//Стиль для кольца загрузки +export const LoadingRing = styled.div` + position: absolute; + top: 0; + left: 0; + width: 65px; + height: 65px; + border-radius: 50%; + border: 12px solid white; +` +//Стиль для части кольца загрузки, которая будет вращаться +export const LoadingPart = styled.div` + position: absolute; + top: 0; + left: 0; + width: 65px; + height: 65px; + border-radius: 50%; + border: 12px solid transparent; + border-top: 12px solid ${props => props.theme.accent}; + + // Добавление аниманции и использование кейфремов + animation: ${spinAnimation} 1s linear infinite; +` + +const Text = styled.div` + display: flex; + gap: 3px; + font-size: 24px; + color: white; + margin-top: 30px; + margin-left: 25px; +` + +export default function Loader({ loaderText }: Props) { + return ( + + + + + + + + + {/* Текст экрана загрузки устанавливается с помощью передаваемых данных loaderText */} + {loaderText} + + ) +} \ No newline at end of file diff --git a/FRONT/DEV/src/components/UI/routerLoader.tsx b/FRONT/DEV/src/components/UI/routerLoader.tsx new file mode 100644 index 0000000..9a788f4 --- /dev/null +++ b/FRONT/DEV/src/components/UI/routerLoader.tsx @@ -0,0 +1,103 @@ +type Props = { + loaderText: string; //Тип передаваемых данных loaderText - string +} + +import styled, { keyframes } from 'styled-components' +import { AnimDot } from './animDot'; +import { ModalWindow } from '../modalwindows/style'; + + +//Константа которая устанавливает кейфвреймы для вращения +const spinAnimation = keyframes` + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +` + +//Стиль экрана загрузки +export const LoaderContainer = styled.div` + top: 0px; + z-index:998; + background-color: rgba(0,0,0, 0.7); + position: fixed; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + overflow-y: hidden; +` + + +//Стиль блока с элементами загрузки +export const Loaderblock = styled.div` + display: flex; + flex-direction: column; + align-items: center; + gap: 15px; + + p{ + font-size: 24px; + color: white; + } +` +//Стиль для блока с кольцом загрузки +export const LoadingSpinner = styled.div` + position: relative; + width: 65px; + height: 65px; +` + +//Стиль для кольца загрузки +export const LoadingRing = styled.div` + position: absolute; + top: 0; + left: 0; + width: 65px; + height: 65px; + border-radius: 50%; + border: 12px solid white; +` +//Стиль для части кольца загрузки, которая будет вращаться +export const LoadingPart = styled.div` + position: absolute; + top: 0; + left: 0; + width: 65px; + height: 65px; + border-radius: 50%; + border: 12px solid transparent; + border-top: 12px solid ${props => props.theme.accent}; + + // Добавление аниманции и использование кейфремов + animation: ${spinAnimation} 1s linear infinite; +` + +const Text = styled.div` + display: flex; + gap: 3px; + font-size: 24px; + color: white; + margin-top: 30px; + margin-left: 25px; +` + +export default function RouterLoader({ loaderText }: Props) { + return ( + + + + + + + + {/* Текст экрана загрузки устанавливается с помощью передаваемых данных loaderText */} + {loaderText} + + + + ) +} \ No newline at end of file diff --git a/FRONT/DEV/src/components/UI/signalSvg.tsx b/FRONT/DEV/src/components/UI/signalSvg.tsx new file mode 100644 index 0000000..9590433 --- /dev/null +++ b/FRONT/DEV/src/components/UI/signalSvg.tsx @@ -0,0 +1,63 @@ +import React, { useEffect, useRef } from 'react'; + +interface SignalSVGProps { + signal: number; // Принимаем signal как пропс + color: string; + size: string; +} + +const SignalSVG: React.FC = ({ signal, color, size }) => { + const svgRef = useRef(null); + + useEffect(() => { + // Устанавливаем цвета в зависимости от signal + const colors = { + '--st1-color': signal >= 1 ? color : 'black', + '--st2-color': signal >= 2 ? color : 'black', + '--st3-color': signal >= 3 ? color : 'black', + '--st4-color': signal >= 4 ? color : 'black', + '--st5-color': signal === 5 ? color : 'black', + }; + + // Применяем стили к SVG + if (svgRef.current) { + Object.entries(colors).forEach(([key, value]) => { + svgRef.current?.style.setProperty(key, value); + }); + } + }, [signal]); + + return ( + + + + + + + + + + + ); +}; + +export default SignalSVG; \ No newline at end of file diff --git a/FRONT/DEV/src/components/UI/tables/TableScanner.tsx b/FRONT/DEV/src/components/UI/tables/TableScanner.tsx new file mode 100644 index 0000000..8657a17 --- /dev/null +++ b/FRONT/DEV/src/components/UI/tables/TableScanner.tsx @@ -0,0 +1,137 @@ +import React, {useState} from 'react'; +import { DeviceUser } from '../../../store/useDeviceStore'; + +interface TableScannerProps { + devices: DeviceUser[]; +} +import styled from 'styled-components'; +import {IconComponent} from "../../../const/buttons/icons"; +import {buttonNames} from "../../../const/buttons/names"; +import {ModalMap} from "../../modalwindows/windowsType"; +import {useModalContext} from "../../../store"; +import Pagination from "../Pagination"; + +const TableContainer = styled.div` + width: 100%; + margin: 24px 0; +`; + +const StyledTable = styled.table` + width: 100%; + border-collapse: separate; + border-spacing: 0; + box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08); + background: ${({ theme }) => theme.primary}; +`; + +const TableHeaderCell = styled.th<{ sortable?: boolean }>` + padding: 16px 24px; + text-align: left; + font-weight: 600; + font-size: 14px; + color: ${({ theme }) => theme.textColor}; + background: ${({ theme }) => theme.primary}; + border-bottom: 1px solid ${({ theme }) => theme.borderColor}; + transition: all 0.2s ease; +`; + +const TableRow = styled.tr<{ clickable?: boolean }>` + transition: all 0.2s ease; + &:hover { + background-color: ${({ theme }) => theme.background}; + } +`; + +const TableCell = styled.td` + padding: 16px 24px; + font-size: 14px; + color: ${({ theme }) => theme.text}; + border-bottom: 1px solid ${({ theme }) => theme.borderColor}; + transition: all 0.2s ease; + button{ + background-color: transparent; + border: none; + cursor: pointer; + } +`; + +const StatusBadge = styled.span<{ status:string }>` + width: 10px; + height: 30px; + background-color: ${({theme, status}) => (status==='online' ? theme.successColor : theme.offlineColor)}; + display: inline-block; + border-radius:4px; +` + +const TableScanner = ({devices}:TableScannerProps) => { + const { openModal } = useModalContext(); + + const openModalNote = (e: React.MouseEvent, device:DeviceUser ) => { + e.stopPropagation(); + openModal(ModalMap['6'], { + address: device.mac, + currentNote: device.note || '' + }); + }; + + // Пагинация + const [currentPage, setCurrentPage] = useState(1); + const [devicesPerPage] = useState(10); + + const indexOfLastDevice = currentPage * devicesPerPage; + const indexOfFirstDevice = indexOfLastDevice - devicesPerPage; + const currentDevices = devices.slice(indexOfFirstDevice, indexOfLastDevice); + const totalPages = Math.ceil(devices.length / devicesPerPage); + + const handlePrevPage = () => { + if(currentPage > 1) setCurrentPage(currentPage - 1); + } + const handleNextPage = () => { + if(currentPage < totalPages) setCurrentPage(currentPage + 1); + } + + return ( + + + + + + Имя + Производитель + IP адрес + Открытые порты + Последняя активность + Заметка + + + + + {currentDevices.map((item, i) => ( + + + {item.hostname || item.ip} + {item.vendor} + {item.ip} + {item.open_ports.join(', ') || '-'} + {item.last_seen} + {item.note || '-'} + + + + + ))} + + + + + ); +}; + +export default TableScanner; \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/baseForm/circle/circleNode.tsx b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/circle/circleNode.tsx new file mode 100644 index 0000000..94eb76c --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/circle/circleNode.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { Handle, Position } from '@xyflow/react'; +import { Circle } from './style'; + +interface CustomNodeProps { + data: { + label: string; + style:{ + width: any; + height: any; + borderType: any; + borderColor: any; + } + }; +} + +export const CircleNode = ({ data }: CustomNodeProps) => { + return ( + {/* */} + {/*
    */} + {data.label} + + {/* Узлы для подключения */} + + + + + + {/* Для входящих подключений */} + + + + + {/*
    */} + +
    + ); +}; \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/baseForm/circle/style.ts b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/circle/style.ts new file mode 100644 index 0000000..df61ace --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/circle/style.ts @@ -0,0 +1,20 @@ +import styled from "styled-components"; + +type Props={ + width: string, + height: string, + bordertype: string, + bordercolor: string +} + + +export const Circle = styled.div` + background-color: white; + border-radius: 100%; + display: flex; + align-items: center; + justify-content: center; + border: 2px ${(props) => props.bordertype} ${(props) => props.bordercolor}; + width: ${(props) => props.width}px; + height: ${(props) => props.height}px; +` \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/baseForm/default/defaultNode.tsx b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/default/defaultNode.tsx new file mode 100644 index 0000000..388e9fb --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/default/defaultNode.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { Handle, Position } from '@xyflow/react'; +import { Default } from './style'; + +interface CustomNodeProps { + data: { + label: string; + style:{ + width: any; + height: any; + borderType: any; + borderColor: any; + } + }; +} + +export const DefaultNode = ({ data }: CustomNodeProps) => { + return ( + + {data.label} + + {/* Узлы для подключения */} + {/* + + + */} + + {/* Для входящих подключений */} + {/* */} + + {/* + */} + {/*
    */} + + + ); +}; \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/baseForm/default/style.ts b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/default/style.ts new file mode 100644 index 0000000..62595bc --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/default/style.ts @@ -0,0 +1,20 @@ +import styled from "styled-components"; + +type Props={ + width: string, + height: string, + bordertype: string, + bordercolor: string +} + +export const Default = styled.div` + background-color: white; + border: 2px ${(props) => props.bordertype} ${(props) => props.bordercolor}; + width: ${(props) => props.width}px; + height: ${(props) => props.height}px; + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + visibility: visible; +` \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/baseForm/diamond/diamondNode.tsx b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/diamond/diamondNode.tsx new file mode 100644 index 0000000..49ab61c --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/diamond/diamondNode.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { Handle, Position } from '@xyflow/react'; +import { Diamond, InnerDiamond, Border } from './style'; + +interface CustomNodeProps { + data: { + label: string; + style:{ + width: any; + height: any; + borderType: any; + borderColor: any; + } + }; +} + +export const DiamondNode = ({ data }: CustomNodeProps) => { + + const baseSize = Math.max(data.style.width, data.style.height); + + return ( + {/* */} + + + {data.label} + + + +
    + {/* Узлы для подключения */} + + + + + + {/* Для входящих подключений */} + + + + +
    + +
    + ); +}; \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/baseForm/diamond/style.ts b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/diamond/style.ts new file mode 100644 index 0000000..5eb0ba0 --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/diamond/style.ts @@ -0,0 +1,32 @@ +import styled from "styled-components"; + +interface StyledDefaultProps { + width: any; + height: any; +} + +export const Diamond = styled.div` + position: relative; + width: ${(props) => props.width}px; + height: ${(props) => props.height}px; +`; + +export const InnerDiamond = styled.div` + clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); + width: ${(props) => props.width - 6}px; + height: ${(props) => props.height - 4}px; + background-color: white; + display: flex; + align-items: center; + justify-content: center; +` + +export const Border = styled.div<{ width: number; height: number, bordercolor: any }>` + clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); + width: ${(props) => props.width}px; + height: ${(props) => props.height}px; + background-color: ${(props) => props.bordercolor}; + display: flex; + align-items: center; + justify-content: center; +`; \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/baseForm/index.ts b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/index.ts new file mode 100644 index 0000000..9827eef --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/index.ts @@ -0,0 +1,5 @@ +export {DefaultNode} from './default/defaultNode' +export {PillNode} from './pill/pillNode' +export {ParalelorgamNode} from './paralelogram/paralelogramNode' +export {CircleNode} from './circle/circleNode' +export {DiamondNode} from './diamond/diamondNode' \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/baseForm/paralelogram/paralelogramNode.tsx b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/paralelogram/paralelogramNode.tsx new file mode 100644 index 0000000..699f00c --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/paralelogram/paralelogramNode.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { Handle, Position } from '@xyflow/react'; +import { Paralelorgam } from './style'; + +interface CustomNodeProps { + data: { + label: string; + style:{ + width: any; + height: any; + borderType: any; + borderColor: any; + } + }; +} + +export const ParalelorgamNode = ({ data }: CustomNodeProps) => { + return ( + + {data.label} + + {/* Узлы для подключения */} + + + + + + {/* Для входящих подключений */} + + + + + + ); +}; \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/baseForm/paralelogram/style.ts b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/paralelogram/style.ts new file mode 100644 index 0000000..46791e4 --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/paralelogram/style.ts @@ -0,0 +1,43 @@ +import styled from "styled-components"; + +type Props={ + width: string, + height: string, + bordertype: string, + bordercolor: string +} + + +export const Paralelorgam = styled.div` + transform: skewX(-20deg); + background-color: white; + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + border: 2px ${(props) => props.bordertype} ${(props) => props.bordercolor}; + width: ${(props) => props.width}px; + height: ${(props) => props.height}px; + + .react-flow__handle-top{ + transform: skewX(20deg); + top: -5px; + } + + .react-flow__handle-bottom{ + transform: skewX(20deg); + bottom: -5px; + } + + .react-flow__handle-right{ + transform: skewX(20deg); + right: -5px; + top: 25px; + } + + .react-flow__handle-left{ + transform: skewX(20deg); + left: -5px; + top: 25px; + } +` \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/baseForm/pill/pillNode.tsx b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/pill/pillNode.tsx new file mode 100644 index 0000000..7adf271 --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/pill/pillNode.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { Handle, Position } from '@xyflow/react'; +import { Pill } from './style'; + +interface CustomNodeProps { + data: { + label: string; + style:{ + width: any; + height: any; + borderType: any; + borderColor: any; + } + }; +} + +export const PillNode = ({ data }: CustomNodeProps) => { + return ( + {/* */} + {/*
    */} + {data.label} + + {/* Узлы для подключения */} + + + + + + {/* Для входящих подключений */} + + + + + {/*
    */} + +
    + ); +}; + +export default PillNode; \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/baseForm/pill/style.ts b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/pill/style.ts new file mode 100644 index 0000000..d08fe21 --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/baseForm/pill/style.ts @@ -0,0 +1,19 @@ +import styled from "styled-components"; + +type Props={ + width: string, + height: string, + bordertype: string, + bordercolor: string +} + +export const Pill = styled.div` + background-color: white; + border-radius: 50px; + display: flex; + align-items: center; + justify-content: center; + border: 2px ${(props) => props.bordertype} ${(props) => props.bordercolor}; + width: ${(props) => props.width}px; + height: ${(props) => props.height}px; +` \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/index.ts b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/index.ts new file mode 100644 index 0000000..64b1036 --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/index.ts @@ -0,0 +1,5 @@ +export {NodeGroupNode} from './networkGroup/nodeGroup' +export {NetWorkNode} from './networkNode/networkNode' +export {IpGroupeNode} from './ipGroup/ipGroup' +export {IpNode} from './ipNode/ipNode' +export {PortNode} from './portNode/portNode' \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/ipGroup/ipGroup.tsx b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/ipGroup/ipGroup.tsx new file mode 100644 index 0000000..750e612 --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/ipGroup/ipGroup.tsx @@ -0,0 +1,18 @@ + +import { IpGroup } from "./style"; + +interface CustomNodeProps { + data: { + style: { + width: any, + height: any, + } + }; +} + +export const IpGroupeNode = ({ data }: CustomNodeProps) => { + return ( + + ); +}; + diff --git a/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/ipGroup/style.ts b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/ipGroup/style.ts new file mode 100644 index 0000000..606ce1a --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/ipGroup/style.ts @@ -0,0 +1,12 @@ +import styled from "styled-components" + +type Props={ + $width: string, + $height?: any +} + + +export const IpGroup = styled.div` + width: ${(props) => props.$width}px; + height: ${(props) => typeof props.$height === 'number' ? `${props.$height}px` : props.$height}; +` \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/ipNode/ipNode.tsx b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/ipNode/ipNode.tsx new file mode 100644 index 0000000..d04af92 --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/ipNode/ipNode.tsx @@ -0,0 +1,245 @@ +import { useState } from 'react'; +import { Handle, Position } from '@xyflow/react'; +import { Ip } from './style'; +import { Row, IpTitle, IpContent } from './style'; +import Input from '../../../../UI/inputs/input'; +import { useModalContext, usePannableStore } from '../../../../../store'; +import { ModalMap } from '../../../../modalwindows/windowsType'; +import { validateIPAddress, validateSameSubnet } from '../../../../../utils/nodeController/validator'; +import {changeIp} from '../../../../../const/types/types' +import { IconComponent } from "../../../../../const/buttons/icons"; +import { buttonNames } from "../../../../../const/buttons/names"; + +interface IIp { + ipType: string + ipAdress: string, + ipGate: string, + ipDns: string[] + ipVersion: string +} + +type StateType = Record; +const typeMap: StateType = { + 'auto': "DHCP", + 'manual': "Static" +} + +interface CustomNodeProps { + data: { + ipData: IIp, + interfaceData: { + device: string, + connection: string + }, + style: { + width: any, + height: any, + borderType: string, + borderColor: string, + } + route: boolean + } +} + +export const IpNode = ({ data }: CustomNodeProps) => { + const { toggleEditingMode } = usePannableStore(); + const [isInput, setIsInput] = useState(false) + const { openModal } = useModalContext(); + + const [ipData, setIpData] = useState( + { + currentIp: data.ipData.ipAdress, + newIp: data.ipData.ipAdress, + currentGate: data.ipData.ipGate, + newGate: data.ipData.ipGate, + currentDns: data.ipData.ipDns, + newDns: data.ipData.ipDns, + device: data.interfaceData.device, + connection: data.interfaceData.connection, + version: data.ipData.ipVersion, + prefix: 0 + } + ) + + const handleFocus = () => { + toggleEditingMode(); + }; + + const handleBlur = () => { + toggleEditingMode(); + }; + + const handleClick = () => { + if (isInput) { + setIsInput(false) + setIpData(prevData => ({ + ...prevData, + newIp: data.ipData.ipAdress, + newGate: data.ipData.ipGate, + newDns: data.ipData.ipDns + })); + } + else { + setIsInput(true) + } + } + + const handleChange = (id: string, value: string) => { + if (id === 'newDns') { + const dnsArray = value.split(',').map(dns => dns.trim()); + setIpData(prevData => ({ + ...prevData, + [id]: dnsArray + })); + } else { + setIpData(prevData => ({ + ...prevData, + [id]: value + })); + } + }; + + function getSubnetMask(ipAddress: string, ipVersion: string): number { + if (ipVersion === "6") { + return 64; + } + + const firstOctet = parseInt(ipAddress.split(".")[0], 10); + if (firstOctet >= 0 && firstOctet <= 127) { + return 8; + } else if (firstOctet >= 128 && firstOctet <= 191) { + return 16; + } else if (firstOctet >= 192 && firstOctet <= 223) { + return 24; + } else { + return 24; + } + } + + + const handleConfirm = () => { + if ( + !validateIPAddress(ipData.newIp) || + !validateIPAddress(ipData.newGate) || + !ipData.newDns.every(dns => validateIPAddress(dns)) + ) { + alert('Один или несколько IP-адресов некорректны.'); + return; + } + + if (!validateSameSubnet(ipData.newIp, ipData.newGate, ipData.newDns)) { + alert('Адрес, шлюз и хотя бы один DNS должны находиться в одной подсети.'); + return; + } + + const calculatedPrefix = getSubnetMask(ipData.newIp, data.ipData.ipVersion); + + setIpData(prevData => ({ + ...prevData, + prefix: calculatedPrefix, + })); + + openModal(ModalMap['1'], { + ...ipData, + prefix: calculatedPrefix, + }); + + setIsInput(false) + }; + + + return ( + <> + + + + {/* +

    Версия IP:

    +

    v{data.ipData.ipVersion}

    +
    */} + + +

    Метод:

    +

    {typeMap[data.ipData.ipType]}

    +
    + + {isInput ? ( + + + + + + ) : ( + + )} + +
    + + + +

    IPv{data.ipData.ipVersion}-Addr:

    + {isInput ? ( + handleChange('newIp', value)} + onBlur={handleBlur} + onFocus={handleFocus} + style={{fontSize: '12px', padding: '4px 10px'}} + /> + ) : ( +

    {data.ipData.ipAdress}

    + )} + +
    + + +

    IPv{data.ipData.ipVersion}-GW:

    + {isInput ? ( + handleChange('newGate', value)} + onBlur={handleBlur} + onFocus={handleFocus} + style={{fontSize: '12px', padding: '4px 10px'}} + /> + ) : ( +

    {data.ipData.ipGate}

    + )} +
    + + +

    IPv{data.ipData.ipVersion}-DNS:

    + {isInput ? ( + handleChange('newDns', value)} + onBlur={handleBlur} + onFocus={handleFocus} + style={{fontSize: '12px', padding: '4px 10px'}} + /> + ) : ( +

    {data.ipData.ipDns.join(', ')}

    + )} +
    + + {data.route && + <> + + + + } +
    +
    + + + ); +}; \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/ipNode/style.ts b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/ipNode/style.ts new file mode 100644 index 0000000..3355417 --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/ipNode/style.ts @@ -0,0 +1,74 @@ +import styled from "styled-components"; + +type Props={ + $width: string, + $height?: any + $bordertype: string, + $bordercolor: string +} + +export const Ip = styled.div` + background-color: ${(props)=>props.theme.secondary}; + display: flex; + flex-direction: column; + width: ${(props) => props.$width}px; + height: ${(props) => typeof props.$height === 'number' ? `${props.$height}px` : props.$height}; + // box-shadow: 0px 0px 15px 2px rgba(0, 0, 0, 0.1); + border-radius: 8px; + + p{ + margin: 0; + } + + img{ + width: 15px; + height: 15px; + } +` + +export const IpTitle = styled.div` + background: ${(props)=>props.theme.accent}; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + color: white; + display: flex; + justify-content: space-between; + padding: 10px; + +` + +export const IpContent = styled.div` + display: flex; + flex-direction: column; + justify-content: space-between; + height: 100%; + padding: 10px; + + .row{ + height: 24px; + + .row-label{ + flex: 1; + } + + .row-text{ + flex: 3; + } + + p{ + + text-wrap: nowrap; + text-align: left; + } + } +` + +export const Row = styled.div` + display: flex; + align-items: center; + gap: 5px; + + p{ + margin: 0; + } +` diff --git a/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/networkGroup/nodeGroup.tsx b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/networkGroup/nodeGroup.tsx new file mode 100644 index 0000000..e7b3f66 --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/networkGroup/nodeGroup.tsx @@ -0,0 +1,64 @@ +import { useState } from "react"; +import { NodeGroup, Row, CollapseButton } from "./style"; +import { useGroupStore } from "../../../../../store"; +import { MainButton } from "../../../../UI/buttons/mainButton"; +import { IconComponent } from "../../../../../const/buttons/icons"; +import { buttonNames } from "../../../../../const/buttons/names"; + +interface CustomNodeProps { + data: { + id: string; + label: string; + height: any + style: { + width: any; + height: any; + borderType: any; + borderColor: any; + }; + }; +} + +export const NodeGroupNode = ({ data }: CustomNodeProps) => { + const [click, setClick] = useState(false); + const { groups, setGroups } = useGroupStore(); + + const handleClick = () => { + const newClickState = !click; + setClick(newClickState); + + const updatedNodes = groups.map((groups) => + groups.id === data.id ? { ...groups, click: newClickState } : groups + ); + + if (!groups.some((groups) => groups.id === data.id)) { + updatedNodes.push({ id: data.id, click: newClickState }); + } + + setGroups(updatedNodes); + }; + + return ( + + +

    {data.label}

    + + {/* */} + + {click ?( + 'Развернуть' + ):( + 'Свернуть' + )} + + {/* */} + +
    +
    + ); +}; \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/networkGroup/style.ts b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/networkGroup/style.ts new file mode 100644 index 0000000..9311bd5 --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/networkGroup/style.ts @@ -0,0 +1,47 @@ +import styled from "styled-components" + +type Props={ + $width?: string, + $height?: any + $bordertype?: string, + $bordercolor?: string + $backgroundcolor?: string +} + + +export const NodeGroup = styled.div` + border: 2px ${(props) => props.$bordertype} ${(props) => props.$bordercolor}; + width: ${(props) => props.$width}px; + height: ${(props) => typeof props.$height === 'number' ? `${props.$height}px` : props.$height}; + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + visibility: visible; +` + +export const Row = styled.div` + position: absolute; + top: -25px; + left: 10px; + display: flex; + justify-content: space-between; + align-items: center; + width: ${props=>props.$width}px; + gap: 5px; + padding-right: 10px; + + p{ + margin: 0; + } +` + +export const CollapseButton = styled.p` + padding: unset; + background: none; + color: ${(props)=>props.theme.textColor}; + margin-right: 15px !important; + &:hover{ + background: none; + } +` \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/networkNode/networkNode.tsx b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/networkNode/networkNode.tsx new file mode 100644 index 0000000..0c0bfa4 --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/networkNode/networkNode.tsx @@ -0,0 +1,110 @@ +import React, { useEffect, useState } from 'react'; +import { Handle, Position } from '@xyflow/react'; +import { Network, TitleContainer, Device, Status, Content, Row, MAC, LabelColumn } from './style'; +import SignalSVG from '../../../../UI/signalSvg'; + +interface CustomNodeProps { + data: { + networkData: { + device: string + type: string + mac: string + mtu: number + state: string + connection: string + id: string, + strength: string + } + style: { + width: any, + height: any, + borderType: string, + borderColor: string, + backgroundColor: string + } + height: string + visible: true + }; +} + +export const NetWorkNode = ({ data }: CustomNodeProps) => { + const [signal, setSignal] = useState(1); + + useEffect(() => { + const perc = Number(data.networkData.strength); + + switch (true) { + case perc < 20: + setSignal(1); + break; + case perc < 40: + setSignal(2); + break; + case perc < 60: + setSignal(3); + break; + case perc < 80: + setSignal(4); + break; + default: + setSignal(5); + break; + } + + }, [data.networkData.strength]) + + return ( + + + + {data.networkData.type == "WIFI" && + + } + + {data.networkData.type == "ETHERNET" && + + } + + {data.networkData.type == "TUN" && + + } + + {data.networkData.device} + + {data.networkData.type == 'WIFI' && data.networkData.state === "Подключено" ? ( + + + + ) : ( +
    + ) + } + +
    + + {data.visible && + + +

    Конфигурация

    + + +

    MAC:

    +

    {data.networkData.mac}

    +
    + +

    MTU:

    +

    {data.networkData.mtu}

    +
    +
    +
    +
    + } + + {data.networkData.connection !== 'unknown' && + + } +
    + ); +}; + +export default NetWorkNode \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/networkNode/style.ts b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/networkNode/style.ts new file mode 100644 index 0000000..f73753f --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/networkNode/style.ts @@ -0,0 +1,93 @@ +import styled from "styled-components"; + +type Props = { + $width?: string, + $height?: any + $bordertype?: string, + $bordercolor?: string + $backgroundcolor?: string +} + +export const Network = styled.div` + background-color: ${(props) => props.theme.primary}; + border: 2px ${(props) => props.$bordertype} ${(props) => props.$bordercolor}; + min-width: ${(props) => props.$width}px; + height: ${(props) => typeof props.$height === 'number' ? `${props.$height}px` : props.$height}; + border-radius: 8px; + display: flex; + flex-direction: column; + gap: 10px; + visibility: visible; + overflow: hidden; + p{ + margin: 0; + } +` + +export const TitleContainer = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + background: ${(props) => props.$backgroundcolor}; + color: white; + padding: 15px; + height: ${(props) => props.$height ? props.$height : 'unset'}; + + img{ + width: 20px + } +` + +export const Device = styled.p` + font-size: 18px; +` + +export const Status = styled.p` + font-size: 14px; + + + img{ + width: 20px; + height: 20px; + } +` + +export const Content = styled.div` + display: flex; + flex-direction: column; + gap: 15px; + padding: 15px; +` + +export const Row = styled.div` + display: flex; + gap: 5px; +` + +export const MAC = styled.div` + display: flex; + justify-content: space-between; + background: ${(props) => props.theme.secondary}; + border-radius: 8px; + // box-shadow: 0px 0px 15px 2px rgba(0, 0, 0, 0.1); + width: 100%; + + .networkNode-row{ + padding: 10px; + } +` + +export const LabelColumn = styled.div` + display: flex; + flex-direction: column; + align-items: center; + gap: 5px; + width: 100%; + + .networkNode-label{ + font-size: 10px; + width: 100%; + text-align: left; + margin-left: 15px; + } +` \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/portNode/portNode.tsx b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/portNode/portNode.tsx new file mode 100644 index 0000000..68939f7 --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/portNode/portNode.tsx @@ -0,0 +1,48 @@ +import { Handle, Position } from '@xyflow/react'; +import { Port, Column } from './style'; + +interface CustomNodeProps { + data: { + label: string; + port: string + id: string; + style: { + width: any; + height: any; + borderType: any; + borderColor: any; + } + }; +} + +export const PortNode = ({ data }: CustomNodeProps) => { + return ( + + + +

    {data.label}

    + + + {data.port && +

    {data.port}

    + } +
    + + + {data.port ? ( + <> + + + + + ) : ( + <> + + + + + )} + +
    + ); +}; \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/portNode/style.ts b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/portNode/style.ts new file mode 100644 index 0000000..17a1b0f --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/nodes/networkInterface/portNode/style.ts @@ -0,0 +1,30 @@ +import styled from "styled-components" + +type Props={ + $width: string, + $height?: any + $bordertype: string, + $bordercolor: string +} + +export const Port = styled.div` + background-color: ${(props)=>props.theme.primary}; + border: 2px ${(props) => props.$bordertype} ${(props) => props.$bordercolor}; + width: ${(props) => props.$width}px; + height: ${(props) => typeof props.$height === 'number' ? `${props.$height}px` : props.$height}; + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + visibility: visible; +` + +export const Column = styled.div` + display: flex; + flex-direction: column; + gap: 15px; + + p{ + margin: 0; + } +` \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/types/colors.ts b/FRONT/DEV/src/components/customeNodes/types/colors.ts new file mode 100644 index 0000000..342c6f7 --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/types/colors.ts @@ -0,0 +1,11 @@ +type ColorType = Record; + +export const NodeColors: ColorType = { + '0': '#c0c0c0', + '1': '#ef6e7d', + '2': '#f19e4c', + '3': '#e9c44c', + '4': '#51ce82', + '5': '#4cd2d0', + '6': '#a085f3', +}; \ No newline at end of file diff --git a/FRONT/DEV/src/components/customeNodes/types/types.ts b/FRONT/DEV/src/components/customeNodes/types/types.ts new file mode 100644 index 0000000..5b7ce87 --- /dev/null +++ b/FRONT/DEV/src/components/customeNodes/types/types.ts @@ -0,0 +1,16 @@ + +import { DefaultNode, PillNode, ParalelorgamNode, DiamondNode, CircleNode } from '../nodes/baseForm' +import { NodeGroupNode, NetWorkNode, IpGroupeNode, IpNode, PortNode } from '../nodes/networkInterface'; + +export const nodeTypes = { + custom: DefaultNode, + pill: PillNode, + parallelogram: ParalelorgamNode, + diamond: DiamondNode, + circle: CircleNode, + nodegroup: NodeGroupNode, + portNode: PortNode, + network: NetWorkNode, + ipgroup: IpGroupeNode, + ip: IpNode, +}; \ No newline at end of file diff --git a/FRONT/DEV/src/components/modalwindows/modal.tsx b/FRONT/DEV/src/components/modalwindows/modal.tsx new file mode 100644 index 0000000..b030ace --- /dev/null +++ b/FRONT/DEV/src/components/modalwindows/modal.tsx @@ -0,0 +1,10 @@ +import { ModalWindow, ModalContainer } from "./style" +import { modalNames } from "../../const/modals/names" + +export const WindowComponent = ()=>{ + return( + + + + ) +} \ No newline at end of file diff --git a/FRONT/DEV/src/components/modalwindows/modalContainers/ConnectNetwork.tsx b/FRONT/DEV/src/components/modalwindows/modalContainers/ConnectNetwork.tsx new file mode 100644 index 0000000..ff3532f --- /dev/null +++ b/FRONT/DEV/src/components/modalwindows/modalContainers/ConnectNetwork.tsx @@ -0,0 +1,84 @@ +// components/modalContainers/NoteDevice.tsx +import { ModalContainer, ModalTitle, ModalContent, ButtonContainer } from "../style"; +import { MainButton } from "../../UI/buttons/mainButton"; +import Input from "../../UI/inputs/input"; +import { useState } from "react"; +import {NetworkService} from "../../../api/request"; +import useNetworkStore from "../../../store/useDeviceStore"; +import RouterLoader from "../../UI/routerLoader"; +import {useTheme} from "styled-components"; +import {useIpStore} from "../../../store"; + +interface Props { + address: string; + onClose: () => void; +} + + + +export const ConnectNetwork = ({address, onClose}: Props) => { + const [password, setPassword] = useState(''); + const theme = useTheme(); + const { ipAddress } = useIpStore(); + const [error, setError] = useState(''); + const [isLoading, setIsLoading] = useState(false); + + const handleSave = async () => { + try { + setIsLoading(true); + setError('') + const res = await NetworkService.connectNetwork(ipAddress, password, address); + if(res.status === 200) { + onClose() + }else{ + setError(res.data.detail) + } + } catch (error) { + console.error('Error connection:', error); + setError('Ошибка подключения к сети') + }finally { + setIsLoading(false); + } + }; + + + return ( + + +

    Подключение к сети

    +
    + + + setPassword(value)} + /> +

    + {error} +

    +
    + + + + + + + {isLoading && } +
    + ); +}; \ No newline at end of file diff --git a/FRONT/DEV/src/components/modalwindows/modalContainers/NoteDevice.tsx b/FRONT/DEV/src/components/modalwindows/modalContainers/NoteDevice.tsx new file mode 100644 index 0000000..6d0b666 --- /dev/null +++ b/FRONT/DEV/src/components/modalwindows/modalContainers/NoteDevice.tsx @@ -0,0 +1,82 @@ +// components/modalContainers/NoteDevice.tsx +import { ModalContainer, ModalTitle, ModalContent, ButtonContainer } from "../style"; +import { MainButton } from "../../UI/buttons/mainButton"; +import Input from "../../UI/inputs/input"; +import { useState } from "react"; +import {useIpStore} from "../../../store"; +import {NetworkService} from "../../../api/request"; +import useNetworkStore from "../../../store/useDeviceStore"; + +interface Props { + address: string; + onClose: () => void; + currentNote?: string; + type: string +} + + + +export const NoteDevice = ({ address, onClose, currentNote, type}: Props) => { + const [note, setNote] = useState(currentNote || ''); + const { ipAddress } = useIpStore(); + const { devices, setDevices } = useNetworkStore(); + + const handleSave = async () => { + try { + if (!currentNote && note.trim() !== '') { + await NetworkService.addNote(ipAddress, address, note, type); + }else if (currentNote && note.trim() !== '' && note !== currentNote) { + await NetworkService.editNote(ipAddress, address, note, type); + }else if (currentNote && note.trim() === '') { + await NetworkService.deleteNote(ipAddress, address, type); + }else { + onClose(); + return; + } + + const updatedDevices = devices.map(device => + device.mac === address + ? { ...device, note: note.trim() } + : device + ); + setDevices(updatedDevices); + onClose(); + + } catch (error) { + console.error('Error saving note:', error); + } + }; + + return ( + + +

    {currentNote ? 'Редактирование заметки' : 'Добавление заметки'}

    +
    + + + setNote(value)} + /> + + + + + + +
    + ); +}; \ No newline at end of file diff --git a/FRONT/DEV/src/components/modalwindows/modalContainers/NoteWifi.tsx b/FRONT/DEV/src/components/modalwindows/modalContainers/NoteWifi.tsx new file mode 100644 index 0000000..c03a48a --- /dev/null +++ b/FRONT/DEV/src/components/modalwindows/modalContainers/NoteWifi.tsx @@ -0,0 +1,82 @@ +// components/modalContainers/NoteDevice.tsx +import { ModalContainer, ModalTitle, ModalContent, ButtonContainer } from "../style"; +import { MainButton } from "../../UI/buttons/mainButton"; +import Input from "../../UI/inputs/input"; +import { useState } from "react"; +import {NetworkService} from "../../../api/request"; +import useNetworkStore from "../../../store/useDeviceStore"; +import {useIpStore} from "../../../store"; + +interface Props { + address: string; + onClose: () => void; + currentNote?: string; + type: string +} + + + +export const NoteWifi = ({ address, onClose, currentNote, type}: Props) => { + const [note, setNote] = useState(currentNote || ''); + const { ipAddress } = useIpStore(); + const { wifiNetworks, setWifiNetworks } = useNetworkStore(); + + const handleSave = async () => { + try { + if (!currentNote && note.trim() !== '') { + await NetworkService.addNote(ipAddress, address, note, type); + }else if (currentNote && note.trim() !== '' && note !== currentNote) { + await NetworkService.editNote(ipAddress, address, note, type); + }else if (currentNote && note.trim() === '') { + await NetworkService.deleteNote(ipAddress, address, type); + }else { + onClose(); + return; + } + const updatedNetworks = wifiNetworks.map(network => + network.ssid === address + ? { ...network, note: note.trim() } + : { ...network } + ); + setWifiNetworks(updatedNetworks); + onClose(); + + } catch (error) { + console.error('Error saving note:', error); + } + }; + + + return ( + + +

    {currentNote ? 'Редактирование заметки' : 'Добавление заметки'}

    +
    + + + setNote(value)} + /> + + + + + + +
    + ); +}; \ No newline at end of file diff --git a/FRONT/DEV/src/components/modalwindows/modalContainers/addDevice.tsx b/FRONT/DEV/src/components/modalwindows/modalContainers/addDevice.tsx new file mode 100644 index 0000000..5611792 --- /dev/null +++ b/FRONT/DEV/src/components/modalwindows/modalContainers/addDevice.tsx @@ -0,0 +1,58 @@ +import Input from "../../UI/inputs/input" +import { MainButton } from "../../UI/buttons/mainButton"; +import { useState } from "react"; +import { ModalContainer, ModalTitle, ModalContent, ModalText, ButtonContainer } from "../style" +import { validateIPAddress } from "../../../utils/nodeController/validator"; + +interface Props { + onSave?: (data: string) => void; + onClose: () => void; +} + +export const AddDevice = ({ onSave, onClose }: Props) => { + const [ipAddress, setIpAddress] = useState('') + const [error, setError] = useState(false) + + const handleSubmit = () => { + if (!validateIPAddress(ipAddress)) { + setError(true) + return; + } + // e.preventDefault(); // Предотвращаем перезагрузку страницы + if (onSave && ipAddress) { + setError(false) + onSave(ipAddress); + onClose(); + } + }; + + return ( + + {/*
    */} + +

    Добавление узла

    +
    + + + setIpAddress(value)} + /> + {error && ( +

    + Некорректный адрес узла +

    + )} +
    + + + + + + {/*
    */} +
    + ) +} \ No newline at end of file diff --git a/FRONT/DEV/src/components/modalwindows/modalContainers/connectionError.tsx b/FRONT/DEV/src/components/modalwindows/modalContainers/connectionError.tsx new file mode 100644 index 0000000..224ba6e --- /dev/null +++ b/FRONT/DEV/src/components/modalwindows/modalContainers/connectionError.tsx @@ -0,0 +1,38 @@ +import { ModalContainer, ModalTitle, ModalContent, ModalText, ButtonContainer } from "../style" +import { useModalContext } from "../../../store" +import { useIpStore } from "../../../store" +import { MainButton } from "../../UI/buttons/mainButton" + +type Props={ + message: string +} + +export const ConnectionError = ({message}: Props)=>{ + const {closeModal} = useModalContext() + const { setIpAddress } = useIpStore(); + + const close = ()=>{ + setIpAddress('localhost') + closeModal() + } + + return( + + +

    Соединение прервано

    +
    + + + +

    Произошёл разрыв с сервером

    +

    Пожалуйста, проверьте доступ к адресу и попробуйте снова.

    +
    +
    + + + + + +
    + ) +} \ No newline at end of file diff --git a/FRONT/DEV/src/components/modalwindows/modalContainers/disconnectConfirm.tsx b/FRONT/DEV/src/components/modalwindows/modalContainers/disconnectConfirm.tsx new file mode 100644 index 0000000..148d657 --- /dev/null +++ b/FRONT/DEV/src/components/modalwindows/modalContainers/disconnectConfirm.tsx @@ -0,0 +1,54 @@ +import { ModalContainer, ModalTitle, ModalContent, ModalText, ButtonContainer } from "../style" +import { useModalContext } from "../../../store" +import { useIpStore } from "../../../store" +import { MainButton } from "../../UI/buttons/mainButton" +import {useState} from "react"; +import {NetworkService} from "../../../api/request"; +import RouterLoader from "../../UI/routerLoader"; +import {useTheme} from "styled-components"; + +type Props={ + address: string, + onClose: () => void +} + +export const DisconnectConfirm = ({address, onClose}: Props)=>{ + const { ipAddress } = useIpStore(); + const theme = useTheme() + const [isLoading, setIsLoading] = useState(false); + + const handleDisconnect = async () => { + try { + setIsLoading(true); + const res = await NetworkService.disconnectNetwork(ipAddress, address); + if(res.status === 200) { + onClose() + } + } catch (error) { + console.error('Error connection:', error); + }finally { + setIsLoading(false); + } + }; + + return( + + +

    Отключение от Wi-Fi сети

    +
    + + + +

    Подтверждение отключения

    +

    Вы собираетесь отключиться от сети "{address}". Все активные подключения будут прерваны.

    +
    +
    + + + + + + {isLoading && } +
    + ) +} \ No newline at end of file diff --git a/FRONT/DEV/src/components/modalwindows/modalContainers/index.ts b/FRONT/DEV/src/components/modalwindows/modalContainers/index.ts new file mode 100644 index 0000000..ed95168 --- /dev/null +++ b/FRONT/DEV/src/components/modalwindows/modalContainers/index.ts @@ -0,0 +1,4 @@ +export {IpConfirm} from './ipConfirm' +export {ConnectionError} from './connectionError' +export {AddDevice} from './addDevice' +export {RightsConfirm} from './rightsConfirm' \ No newline at end of file diff --git a/FRONT/DEV/src/components/modalwindows/modalContainers/ipConfirm.tsx b/FRONT/DEV/src/components/modalwindows/modalContainers/ipConfirm.tsx new file mode 100644 index 0000000..2e2b998 --- /dev/null +++ b/FRONT/DEV/src/components/modalwindows/modalContainers/ipConfirm.tsx @@ -0,0 +1,211 @@ +import styled from "styled-components"; +import Loader from "../../UI/loader"; +import { useEffect, useState } from "react"; +import { changeIp } from '../../../const/types/types' +import { NetworkService } from '../../../api/request' +import { ModalContainer, ModalTitle, ModalContent, ModalText, ButtonContainer, ErrorMessage } from "../style" +import { useIpStore } from "../../../store"; +import { MainButton } from "../../UI/buttons/mainButton"; +import { useAdminStore } from "../../../store/adminStore"; +import { useDevicesStore } from "../../../store"; + +type Props = { + ipData: changeIp + onClose: () => void; + smoothClose: () => void; +} + +const Information = styled.div` + display: flex; + flex-direction: column; + gap: 15px; +` + +const Info = styled.div` + display: flex; + gap: 10px; +` + +const DataContainer = styled.div` + display: flex; + gap: 35px; +` + +const CurrentData = styled.div` + display: flex; + flex-direction: column; + gap: 10px; +` + +const NewData = styled.div` + display: flex; + flex-direction: column; + gap: 10px; +` + +export const IpConfirm = ({ ipData, onClose, smoothClose }: Props) => { + const [loader, setLoader] = useState(true) + const [newIP, setNewIp] = useState(null) + const [currentIp, setCurrentIP] = useState({}) + const [checkStatus, setcheckStatus] = useState(false) + const [message, setMessgae] = useState('') + const { ipAddress, setIpAddress } = useIpStore(); + const {isAdmin} = useAdminStore() + const { devices, addDevice, deleteDevice } = useDevicesStore(); + + useEffect(() => { + if (ipData && isAdmin) { + const data = { + "connection_id": ipData.connection, + "ipv4_updates": { + "ipv4.method": "manual", + "ipv4.address-data": [ + { + "address": ipData.newIp, + "prefix": ipData.prefix + } + ], + "ipv4.gateway": ipData.newGate, + "ipv4.dns-data": ipData.newDns + } + }; + + const oldData = { + "connection_id": ipData.connection, + "ipv4_updates": { + "ipv4.method": "manual", + "ipv4.address-data": [ + { + "address": ipData.currentIp, + "prefix": ipData.prefix + } + ], + "ipv4.gateway": ipData.currentGate, + "ipv4.dns-data": ipData.currentDns + } + } + + setCurrentIP(oldData) + + checkIp(data); + } + }, [ipData, isAdmin]); + + const checkIp = async (data: any) => { + try { + const result = await NetworkService.checkIp(ipAddress, data); + setcheckStatus(result.data.available) + setMessgae(result.data.message) + if (result.data.available) { + setNewIp(data) + } + } catch (err) { + console.error('Error:', err); + } finally { + setLoader(false); + } + }; + + const saveIp = async (data: any) => { + try { + const result = await NetworkService.saveIp(ipAddress, data); + if (result.status === 200) { + if(ipAddress!=='localhost'){ + setIpAddress(ipData.newIp) + + const updatedDevices = devices.map(device => + device.address === ipData.currentIp + ? { ...device, address: ipData.newIp } + : device + ); + useDevicesStore.setState({ devices: updatedDevices }); + } + + onClose() + } + } catch (err) { + console.error('Error:', err); + } finally { + setLoader(false); + } + }; + + const cancelIp = async (data: any) => { + try { + const result = await NetworkService.saveIp(ipAddress, data); + if (result.status === 200) { + onClose() + } + } catch (err) { + console.error('Error:', err); + } finally { + setLoader(false); + } + }; + + return ( + <> + {loader && isAdmin ? ( + + ) : ( + + +

    Изменение IP-Адреса

    +
    + {checkStatus ? ( + + +

    Общие сведения

    + +

    Интерфейс: {ipData.device}

    +

    --{'>'}

    +

    {ipData.connection}

    +
    +

    Сведения об IP

    + + +

    Текущий ip: {ipData.currentIp}

    +

    Текущий шлюз: {ipData.currentGate}

    +

    Текущий DNS: {ipData.currentDns}

    +
    + + +

    Новый ip: {ipData.newIp}

    +

    Новый шлюз: {ipData.newGate}

    +

    Новый DNS: {ipData.newDns}

    +
    +
    +
    + + + cancelIp(currentIp)}/> + saveIp(newIP)}/> + +
    + ) : ( + <> + + + {isAdmin ? ( + <> +

    Произошла ошибка проверки корректности

    + {message} + + + ):( +

    Для изменения сетевых настроек необходимо авторизироваться под администратором

    + )} + +
    +
    + + + + + + )} +
    + )} + + ) +} \ No newline at end of file diff --git a/FRONT/DEV/src/components/modalwindows/modalContainers/rightsConfirm.tsx b/FRONT/DEV/src/components/modalwindows/modalContainers/rightsConfirm.tsx new file mode 100644 index 0000000..24351dd --- /dev/null +++ b/FRONT/DEV/src/components/modalwindows/modalContainers/rightsConfirm.tsx @@ -0,0 +1,135 @@ +import { useEffect, useState } from "react" +import { ModalContainer, ModalTitle, ModalContent, ModalText, ButtonContainer } from "../style" +import Input from "../../UI/inputs/input" +import { MainButton } from "../../UI/buttons/mainButton" +import { NetworkService } from "../../../api/request" +import { useIpStore } from "../../../store" +import { useAdminStore } from "../../../store/adminStore" +import { useCheckAdmin } from "../../../utils/checkAdmin" + +import { buttonNames } from "../../../const/buttons/names" +import { IconComponent } from "../../../const/buttons/icons" + +interface Props { + onClose: () => void; +} + +export const RightsConfirm = ({ onClose }: Props) => { + + const { ipAddress } = useIpStore(); + const { isAdmin, setAdmin } = useAdminStore() + const checkAdmin = useCheckAdmin(); + const [error, setError] = useState(false) + const [success, setSuccess] = useState({ + message: '', + status: false + }) + + const [user, setUser] = useState({ + username: 'operator', + password: "" + }) + + const handleChange = (id: string, value: string) => { + setUser(prevData => ({ + ...prevData, + [id]: value + })); + } + + const login = async (user: object) => { + try { + const response = await NetworkService.login(ipAddress, user); + if(response.status === 200){ + await checkAdmin(); + setError(false) + setSuccess(prevData => ({ + ...prevData, + message: 'Успешный вход', + status: true + })); + await new Promise(resolve => setTimeout(resolve, 3000)); + onClose(); + }else{ + setError(true) + } + } catch (err) { + console.error('Error:', err); + } + } + + const logout = async () => { + await NetworkService.logout(ipAddress); + await checkAdmin(); + setSuccess(prevData => ({ + ...prevData, + message: 'Успешный выход', + status: true + })); + await new Promise(resolve => setTimeout(resolve, 3000)); + onClose(); + } + + return ( + + {!success.status ? ( + !isAdmin ? ( + <> + +

    Получение прав доступа

    +
    + + + +

    Включить административный доступ

    + handleChange('password', value)} + /> + + {error && ( +

    + Неверный пароль оператора +

    + )} + +
    + + + + login(user)} /> + + + ) : ( + <> + +

    Переключиться на ограниченный доступ

    +
    + + +

    В данном режиме доступа ограничиваются полномочия администратора.

    +
    + + + + + + + + ) + ):( + + +

    {success.message}

    +

    Это окно можно закрыть, либо оно пропадёт само

    + +
    + )} + + +
    + ) +} \ No newline at end of file diff --git a/FRONT/DEV/src/components/modalwindows/modalWindow.tsx b/FRONT/DEV/src/components/modalwindows/modalWindow.tsx new file mode 100644 index 0000000..7edf179 --- /dev/null +++ b/FRONT/DEV/src/components/modalwindows/modalWindow.tsx @@ -0,0 +1,81 @@ +import { useModalContext } from "../../store"; +import { IpConfirm, ConnectionError, AddDevice, RightsConfirm } from "./modalContainers"; +import { ModalMap } from "./windowsType"; +import Loader from "../UI/loader"; +import { ModalWindow } from "./style"; +import {NoteDevice} from "./modalContainers/NoteDevice"; +import { NoteWifi } from "./modalContainers/NoteWifi"; +import {ConnectNetwork} from "./modalContainers/ConnectNetwork"; +import {DisconnectConfirm} from "./modalContainers/disconnectConfirm"; + +type Props = { + isOpen: boolean, + type: string + data: any; +} + +export default function WindowComponent({ isOpen, type, data }: Props) { + + const { closeModal, closeLoader } = useModalContext() + + return ( + <> + {isOpen && + + {type == ModalMap['1'] && data && + + } + + {type == ModalMap['2'] && + + } + + {type === ModalMap['3'] && + + } + {type === ModalMap['6'] && ( + + )} + {type === ModalMap['7'] && ( + + )} + {type === ModalMap['8'] && ( + + )} + {type === ModalMap['9'] && ( + + )} + {type === ModalMap['4'] && ( + + )} + + {type === ModalMap['5'] && ( + + )} + + } + + ) +} \ No newline at end of file diff --git a/FRONT/DEV/src/components/modalwindows/style.ts b/FRONT/DEV/src/components/modalwindows/style.ts new file mode 100644 index 0000000..2b75bd3 --- /dev/null +++ b/FRONT/DEV/src/components/modalwindows/style.ts @@ -0,0 +1,70 @@ +import styled from "styled-components"; + +export const ModalWindow = styled.div` + width: 100%; + position: fixed; + top: 0; + left: 0; + z-index: 9999; + background-color: rgba(0, 0, 0, 0.8); + display: flex; + align-items: center; + justify-content: center; + height: 100%; +` + +export const ModalContainer = styled.div<{height?: string}>` + border-radius: 12px; + background: ${(props)=>props.theme.secondary}; + color: ${(props=>props.theme.textColor)}; + position: relative; + max-height: 100%; + overflow: auto; + display: flex; + flex-direction: column; + justify-content: space-between; + gap: 15px; + height: ${(props) => props.height ? props.height : '230px'}; + width: 520px; +` + +export const ModalTitle = styled.div` + padding: 20px; + border-bottom: 1px solid #9D9D9D; + display: flex; + justify-content: space-between; + + h3{ + font-size: 18px; + } +` + +export const ModalContent = styled.div` + padding: 0 20px; + + h3{ + font-size: 14px; + } + + p{ + font-size: 12px; + } +` + +export const ModalText = styled.div` + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 10px; +` + +export const ErrorMessage = styled.p` + color: #d95454; +` + +export const ButtonContainer = styled.div` + justify-content: flex-end; + display: flex; + gap: 10px; + padding: 10px 20px 20px; +` \ No newline at end of file diff --git a/FRONT/DEV/src/components/modalwindows/windowsType.ts b/FRONT/DEV/src/components/modalwindows/windowsType.ts new file mode 100644 index 0000000..ae6d760 --- /dev/null +++ b/FRONT/DEV/src/components/modalwindows/windowsType.ts @@ -0,0 +1,13 @@ +export type ModalType = Record; + +export const ModalMap: ModalType = { + '1': 'ipConfirm', + '2': 'loader', + '3': 'connectionError', + '4': 'addDevice', + '5': 'sudo', + '6': 'noteDevice', + '7': 'noteWifi', + '8': 'connectNetwork', + '9': 'disconnectConfirm', +} diff --git a/FRONT/DEV/src/components/register.tsx b/FRONT/DEV/src/components/register.tsx new file mode 100644 index 0000000..a043285 --- /dev/null +++ b/FRONT/DEV/src/components/register.tsx @@ -0,0 +1,194 @@ +import { ModalContainer, ModalTitle, ModalContent, ModalText } from "./modalwindows/style" +import Input from "./UI/inputs/input" +import { MainButton } from "./UI/buttons/mainButton" +import styled from "styled-components" +import { useEffect, useState } from "react" +import { useIpStore } from "../store" +import { NetworkService } from "../api/request" +import { IconComponent } from "../const/buttons/icons" +import { buttonNames } from "../const/buttons/names" +import ThemeButton from "./UI/buttons/toggletheme" +import About from "./workSpace/modules/appModules/about" + +const Wrapper = styled.div` + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100%; + background: ${(props) => props.theme.background}; +` + +const Container = styled.form` + display: flex; + flex-direction: column; + gap: 25px; + align-items: center; + background: ${(props) => props.theme.primary}; + padding: 25px; + border-radius: 18px; + width: 350px; +` + +const Title = styled.div` + display: flex; + flex-direction: column; + gap: 15px; + align-items: center; + text-align: center; + font-size: 20px; +` + +const Content = styled.div` + display: flex; + flex-direction: column; + gap: 25px; + text-align: center; +` + +const ButtonContainer = styled.div` + width: 100%; + display: flex; + justify-content: center; +` + +const Menu = styled.div` + display: flex; + align-items: center; +` + +const Button = styled.div` + width: 100%; + cursor: pointer; +` + +const IconContainer = styled.div` + padding: 10px; + color: ${props => props.theme.text}; +` + +export const CreateUser = () => { + + const { ipAddress, setIpAddress } = useIpStore(); + const [repeatPassword, setRepeatPassword] = useState(''); + const [passwordsMatch, setPasswordsMatch] = useState(true); + const [about, setAbout] = useState(false) + + const [user, setUser] = useState({ + username: 'operator', + password: '', + is_admin: true + }) + + const handleChange = (id: string, value: string) => { + if (id === 'repeatPassword') { + setRepeatPassword(value); + setPasswordsMatch(user.password === value); + } else { + setUser(prevData => ({ + ...prevData, + [id]: value + })); + if (id === 'password') { + setPasswordsMatch(value === repeatPassword); + } + } + } + + const handleSave = async (user: object) => { + try { + const result = await NetworkService.createUser(ipAddress, user); + if (result.status === 200) { window.location.reload() } + } catch (err) { + console.error('Error:', err); + } + } + + const handleSubmit = () => { + if (passwordsMatch) { + handleSave(user); + } + }; + + const back = ()=>{ + setIpAddress('localhost') + } + + const toAbout = ()=>{ + setAbout(true) + } + return ( + + <> + {!about ? ( + + + + + <IconComponent name={buttonNames[3]} width="52" height="52"></IconComponent> + <h3>Настройка оператора узла</h3> + {ipAddress != 'localhost' && + <p>{ipAddress}</p> + } + + + + + +
    +

    Перед началом работы необходимо создать пароль оператора приложения

    +
    + +
    + handleChange('password', value)} + /> + + handleChange('repeatPassword', value)} + style={{ marginTop: '10px' }} + /> + {!passwordsMatch && ( +

    + Пароли не совпадают! +

    + )} +
    + +
    + + + + + + +
    + + + + {ipAddress != 'localhost' && + + } + + + +
    + ): ( + setAbout(false)} /> + )} + + + ) +} \ No newline at end of file diff --git a/FRONT/DEV/src/components/workSpace/modules/appModules/about.tsx b/FRONT/DEV/src/components/workSpace/modules/appModules/about.tsx new file mode 100644 index 0000000..59a4c39 --- /dev/null +++ b/FRONT/DEV/src/components/workSpace/modules/appModules/about.tsx @@ -0,0 +1,249 @@ + +import { MainButton } from "../../../UI/buttons/mainButton" +import { workSpaceNames } from "../../../../const/workspace/names" +import { useWorkSpaceStore } from "../../../../store" +import styled, {useTheme} from "styled-components" +import ThemeButton from "../../../UI/buttons/toggletheme" +import {buttonNames} from "../../../../const/buttons/names"; +import {IconComponent} from "../../../../const/buttons/icons"; + +type Props = { + from: 'reg' | 'helloWindow' | 'workSpace' + onBack?: () => void +} + +const Wrapper = styled.div` + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100%; + width: 100%; + background: ${(props => props.theme.background)}; + padding: 50px; + box-sizing: border-box; +` + +const Content = styled.div` + max-width: 1200px; + display: flex; + flex-direction: column; + justify-content: space-between; + height: 100%; + box-sizing: border-box; + padding: 40px 50px; + background: ${(props => props.theme.primary)}; + border-radius: 18px; + position: relative; +` + +const Listing = styled.div` + display: flex; + flex-direction: column; + background-color: ${(props => props.theme.secondary)}; + border-radius: 10px; + padding: 24px 20px; + p{ + font-weight: bold; + font-size: 24px; + } +` + +const List = styled.ul` + display: flex; + flex-direction: column; + margin: 10px 0; + padding: 0; + list-style-type: none; + font-size: 18px; + gap: 4px; + & li:before { + color: ${(props => props.theme.accent)}; + content: "•"; + font-size: 28px; + width: .8em; + display: inline-block; + position: relative; + top: 2px; + } +` + +const Title = styled.div` + font-size: 20px; +` + +const SubTitle = styled.div` + display: flex; + flex-direction: column; + gap: 24px; + background-color:rgba(255, 248, 225, 0.6); + border-left: #ff9800 solid 4px; + border-radius: 0 8px 8px 0; + padding: 20px 12px; + + a{ + text-decoration: none; + color: ${(props => props.theme.errorColor)}; + font-weight: 500; + font-size: 18px; + width: max-content; + } + p{ + font-size: 18px; + color: ${(props=>props.theme.textColor)}; + } + .icon{ + width: 32px; + height: 32px; + fill: #ff9800; + } +` + +const Links = styled.div` + display: flex; + justify-content: start; + gap: 20px; +` + +const LinkBlock = styled.a` + text-decoration: none; + color: ${(props => props.theme.accent)};; +` + +const Copyright = styled.div` + width: 100%; + text-align: start; + color: ${(props => props.theme.offlineColor)}; +` + +const ButtonContainer = styled.div` + position: absolute; + top: 12px; + right: 14px; +` +const AboutLine = styled.hr` + border: ${(props => props.theme.hoverBtn)} 1px solid; + width: 100%; +` + +const MainTitle = styled.div` + width: 100%; + display: flex; + gap: 15px; + align-items: center; + justify-content: space-between; + padding-top: 10px; + box-sizing: border-box; + + img{ + width: 50px; + height: 50px; + } + .version{ + text-wrap: nowrap; + background-color: ${(props => props.theme.hoverBtn)}; + color: ${(props => props.theme.borderColor)}; + border-radius: 20px; + font-size: 18px; + padding: 10px 18px; + line-height: 1; + } + .title{ + display: flex; + justify-content: center; + align-items: center; + gap: 24px; + } +` + +export default function About({ from, onBack }: Props) { + const { setWorkModule } = useWorkSpaceStore() + const getBackHandler = () => { + switch (from) { + case 'reg': + return onBack + case 'helloWindow': + return () => setWorkModule(workSpaceNames[1]) + case 'workSpace': + return () => setWorkModule(workSpaceNames[3]) + default: + return undefined + } + } + + const backHandler = getBackHandler() + const showBackButton = from !== 'reg' || (from === 'reg' && onBack) + + return ( + + + + +
    + +

    О приложении

    +
    +

    v 0.0.3

    +
    + + + + + <p>ГоNets — минимально работоспособный кроссплатформенный продукт (MVP) для демонстрации нашего подхода к управлению настройками ПК в корпоративной среде.</p> + + + +

    Возможности:

    + +
  • Визуализация активных сетевых ресурсов
  • +
  • Настройка параметров локальных и удалённых сетевых ресурсов
  • +
  • Управление взаимодействием ресурсов с Клиентом ГoNets
  • +
    +
    + + + + + +

    Программное обеспечение исключительно для ознакомления и домашнего использования.

    +
    Перейти на ГоNets-PRO + + + + + Домашняя страницa + + + + Документация + + + + Лицензия + + + + + Разработано и поддерживается ООО «Гибридные Офисные Системы» 2024-2025 г. Все права защищены. + + + + {showBackButton && backHandler && ( + + + )} + + {from == 'reg' && + + } + +
    + + + ) +} \ No newline at end of file diff --git a/FRONT/DEV/src/components/workSpace/modules/appModules/header.tsx b/FRONT/DEV/src/components/workSpace/modules/appModules/header.tsx new file mode 100644 index 0000000..356764b --- /dev/null +++ b/FRONT/DEV/src/components/workSpace/modules/appModules/header.tsx @@ -0,0 +1,46 @@ +import styled from "styled-components" +import { IconComponent } from "../../../../const/buttons/icons" +import { buttonNames } from "../../../../const/buttons/names" +import { useWorkSpaceStore } from "../../../../store" +import { useModalContext } from "../../../../store" +import { useAdminStore } from "../../../../store/adminStore" +import { ModalMap } from "../../../modalwindows/windowsType" +import { QuitButton } from "../../../UI/buttons/quitButton" +import { usePosStore } from "../../../../store/posStore" + +const Container = styled.div` + display: flex; + align-items: center; + justify-content: flex-end; + background-color: ${(props) => props.theme.primary}; + padding: 0 5px; +` + +const ButtonContainer = styled.div` + display: flex; + align-items: center; +` + +const IconContainer = styled.div` + padding: 10px; + + svg{ + cursor: pointer; + } +` + +export const Header = () => { + const {setNullPos} = usePosStore() + + return ( + + + + setNullPos(true)}/> + + + + + + ) +} \ No newline at end of file diff --git a/FRONT/DEV/src/components/workSpace/modules/appModules/helloWindow.tsx b/FRONT/DEV/src/components/workSpace/modules/appModules/helloWindow.tsx new file mode 100644 index 0000000..0a09826 --- /dev/null +++ b/FRONT/DEV/src/components/workSpace/modules/appModules/helloWindow.tsx @@ -0,0 +1,82 @@ + import styled from "styled-components" + import { MainButton } from "../../../UI/buttons/mainButton" + import { useWorkSpaceStore } from "../../../../store" + import { workSpaceNames } from "../../../../const/workspace/names" + import { buttonNames } from "../../../../const/buttons/names" + + const Wrapper = styled.div` + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + background-color: ${(props => props.theme.background)}; + background-image: url('./assets/images/back1.svg'); + background-size: 100%; + background-repeat: no-repeat; + background-position: bottom; + ` + + const Container = styled.div` + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 52px; + margin-bottom: 100px; + ` + + const ButtonWrapper = styled.div` + display: flex; + gap: 75px; + flex-direction: column; + ` + + const ButtonContainer = styled.div` + display: flex; + gap: 15px; + flex-direction: column; + ` + + const Title = styled.div` + display: flex; + align-items: flex-end; + gap: 10px; + + h1{ + font-size: 52px; + } + ` + + export const HelloWindow = () => { + + const { setWorkModule } = useWorkSpaceStore() + + return ( + + + + <img src="./assets/images/logo.svg" alt="" style={{width: '152px'}}/> + + + + + + setWorkModule(workSpaceNames[3])} + /> + setWorkModule(workSpaceNames[4])} + /> + + + + + ) + } \ No newline at end of file diff --git a/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/modules/ListUsers.tsx b/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/modules/ListUsers.tsx new file mode 100644 index 0000000..52f146e --- /dev/null +++ b/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/modules/ListUsers.tsx @@ -0,0 +1,78 @@ +import React, { useState } from 'react'; +import styled from 'styled-components'; +import DeviceCard from "../../../../../UI/Dropdown/DeviceCard"; +import {DeviceUser} from "../../../../../../store/useDeviceStore"; + +const ScanBtn = styled.button` + position: relative; + padding: 14px 22px; + background-color: #4CAF50; + color: white; + border: none; + border-radius: 12px; + font-size: 18px; + transition: .4s ease; + &:hover{ + transform: scale(1.03); + } +` + +interface ListUsersProps { + loading: boolean; + handleScan: ()=>void; + devices: DeviceUser[]; + scanInitiated: boolean; +} + +const ListUsers = ({loading, handleScan, devices, scanInitiated}: ListUsersProps) => { + const activeDevices = devices.filter(device => device.status === 'online'); + const inactiveDevices = devices.filter(device => device.status !== 'online'); + + // Пагинация + const [currentPage, setCurrentPage] = useState(1); + const [devicesPerPage] = useState(10); + + + return ( + <> + + {devices.length > 0 ? 'Обновить список' : 'Сканировать узлы'} + + + {devices.length > 0 ? ( +
    + {/* Колонка активных устройств */} +
    +

    Активные узлы ({activeDevices.length})

    + {activeDevices.map((device, index) => ( + + ))} +
    + {/* Колонка неактивных устройств */} +
    +

    Неактивные узлы ({inactiveDevices.length})

    + {inactiveDevices.map((device, index) => ( + + ))} +
    +
    + ) : scanInitiated ? ( +

    Узлы не найдены

    + ) : null} + + ); +}; + +export default ListUsers; \ No newline at end of file diff --git a/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx b/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx new file mode 100644 index 0000000..77e064c --- /dev/null +++ b/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import styled from 'styled-components'; +import DeviceCard from "../../../../../UI/Dropdown/DeviceCard"; +import {DeviceUser} from "../../../../../../store/useDeviceStore"; +import TableScanner from "../../../../../UI/tables/TableScanner"; + +const ScanBtn = styled.button` + position: relative; + padding: 14px 22px; + background-color: #4CAF50; + color: white; + border: none; + border-radius: 12px; + font-size: 18px; + transition: .4s ease; + &:hover{ + transform: scale(1.03); + } +` + +interface ListUsersProps { + loading: boolean; + handleScan: ()=>void; + devices: DeviceUser[]; + scanInitiated: boolean; +} + +const ListUsers = ({loading, handleScan, devices, scanInitiated}: ListUsersProps) => { + + return ( + <> + + {devices.length > 0 ? 'Обновить список' : 'Сканировать узлы'} + + + {devices.length > 0 ? ( + + ) : scanInitiated ? ( +

    Узлы не найдены

    + ) : null} + + ); +}; + +export default ListUsers; \ No newline at end of file diff --git a/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx b/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx new file mode 100644 index 0000000..19ca497 --- /dev/null +++ b/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/userScanner.tsx @@ -0,0 +1,191 @@ +import { useIpStore } from "../../../../../store"; +import styled, { keyframes } from "styled-components"; +import { useState } from "react"; +import { NetworkService } from "../../../../../api/request"; +import ListUsers from "./modules/ListUsers"; +import TableUsers from "./modules/TableUsers"; +import DropdownType from "../../../../UI/Dropdown/DropdownType"; +import useNetworkStore from "../../../../../store/useDeviceStore"; + +type Option ={ + value: number, + label: string, +} + +// Анимации +const ring1 = keyframes` + 0% { transform: translate(-50%, -50%) scale(1); opacity: 0.12; } + 50% { transform: translate(-50%, -50%) scale(1.1); opacity: 0.2; } + 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.12; } +`; + +const ring2 = keyframes` + 0% { transform: translate(-50%, -50%) scale(1); opacity: 0.08; } + 50% { transform: translate(-50%, -50%) scale(1.1); opacity: 0.15; } + 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.08; } +`; + +const ring3 = keyframes` + 0% { transform: translate(-50%, -50%) scale(1); opacity: 0.04; } + 50% { transform: translate(-50%, -50%) scale(1.1); opacity: 0.1; } + 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.04; } +`; +const dotAnimation = keyframes` + 0% { content: '.'; } + 33% { content: '..'; } + 66% { content: '...'; } + 100% { content: '.'; } +`; +const pulse = keyframes` + 0% { transform: translate(-50%, -50%) scale(1); } + 50% { transform: translate(-50%, -50%) scale(1.1); } + 100% { transform: translate(-50%, -50%) scale(1); } +`; + +// Стили +const Wrapper = styled.div<{ scanInitiated: boolean, loading: boolean}>` + display: flex; + flex-direction: column; + align-items: center; + justify-content:${({scanInitiated, loading})=>(scanInitiated && !loading ? 'start' : 'center')}; + height: 100%; + width: 100%; + background: ${(props) => props.theme.background}; + padding: 50px; + box-sizing: border-box; + gap: 24px; + transition: justify-content .4s ease; + overflow-y: auto; + overflow-x: hidden; + position: relative; +`; +const TitleWrapper = styled.h2` + position: absolute; + top: 20px; + left: 50%; + transform: translateX(-50%); + font-size: 32px; + width: max-content; +` +const UserLocate = styled.div<{ loading: boolean, scanInitiated: boolean }>` + width: 60px; + height: 60px; + border-radius: 50%; + position: relative; + transition: .4s ease; + transform: ${({scanInitiated,loading})=>(scanInitiated && !loading ? 'scale(0)' : 'scale(1)')}; + span { + position: absolute; + display: inline-block; + background: ${(props) => props.theme.scannerColor}; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + border-radius: 50%; + &.center { + width: 60px; + height: 60px; + animation: ${({ loading }) => (loading ? pulse : "none")} 2s ease infinite; + } + &.ring1 { + opacity: 0.12; + width: 250px; + height: 250px; + animation: ${({ loading }) => (loading ? ring1 : "none")} 4s linear infinite; + } + + &.ring2 { + opacity: 0.08; + width: 400px; + height: 400px; + animation: ${({ loading }) => (loading ? ring2 : "none")} 4s linear infinite; + animation-delay: ${({ loading }) => (loading ? "0.1s" : "0")}; + } + + &.ring3 { + opacity: 0.04; + width: 550px; + height: 550px; + animation: ${({ loading }) => (loading ? ring3 : "none")} 4s linear infinite; + animation-delay: ${({ loading }) => (loading ? "0.2s" : "0")}; + } + } +`; + +const LoadingText = styled.div` + position: relative; + padding: 14px 22px; + background-color: #4CAF50; + color: white; + border: none; + border-radius: 12px; + font-size: 18px; +`; +const ScanningText = styled.span` + &::after { + content: '.'; + animation: ${dotAnimation} 1.5s infinite; + } +`; + + +export default function UserScanner() { + const { ipAddress } = useIpStore(); + const [loading, setLoading] = useState(false); + const { devices, setDevices } = useNetworkStore(); + const [scanInitiated, setScanInitiated] = useState(devices.length > 0); + + // Сканирование + const handleScan = async () => { + try { + setLoading(true); + setScanInitiated(true); + const res = await NetworkService.scanUser(ipAddress); + console.log(res); + setDevices(res.data.devices || []); + } catch (err) { + console.error("Ошибка сканирования сети:", err); + setDevices([]) + } finally { + setLoading(false); + } + }; + + // Способ отображения + const viewOptions: Option[] = [ + { value: 1, label: 'Таблица' }, + { value: 2, label: 'Список' }, + ]; + const [selectedView, setSelectedView] = useState